mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-04-22 07:26:46 +00:00
图片与视频索引优化 #786;修复 #786;修复导出页面打开目录缺失路径的问题;完善朋友圈卡片封面解析
This commit is contained in:
@@ -2,6 +2,10 @@ import { ConfigService } from './config'
|
||||
import { chatService, type ChatSession, type Message } from './chatService'
|
||||
import { wcdbService } from './wcdbService'
|
||||
import { httpService } from './httpService'
|
||||
import { promises as fs } from 'fs'
|
||||
import path from 'path'
|
||||
import { createHash } from 'crypto'
|
||||
import { pathToFileURL } from 'url'
|
||||
|
||||
interface SessionBaseline {
|
||||
lastTimestamp: number
|
||||
@@ -33,6 +37,8 @@ class MessagePushService {
|
||||
private readonly sessionBaseline = new Map<string, SessionBaseline>()
|
||||
private readonly recentMessageKeys = new Map<string, number>()
|
||||
private readonly groupNicknameCache = new Map<string, { nicknames: Record<string, string>; updatedAt: number }>()
|
||||
private readonly pushAvatarCacheDir: string
|
||||
private readonly pushAvatarDataCache = new Map<string, string>()
|
||||
private readonly debounceMs = 350
|
||||
private readonly recentMessageTtlMs = 10 * 60 * 1000
|
||||
private readonly groupNicknameCacheTtlMs = 5 * 60 * 1000
|
||||
@@ -45,6 +51,7 @@ class MessagePushService {
|
||||
|
||||
constructor() {
|
||||
this.configService = ConfigService.getInstance()
|
||||
this.pushAvatarCacheDir = path.join(this.configService.getCacheBasePath(), 'push-avatar-files')
|
||||
}
|
||||
|
||||
start(): void {
|
||||
@@ -310,12 +317,13 @@ class MessagePushService {
|
||||
const groupInfo = await chatService.getContactAvatar(sessionId)
|
||||
const groupName = session.displayName || groupInfo?.displayName || sessionId
|
||||
const sourceName = await this.resolveGroupSourceName(sessionId, message, session)
|
||||
const avatarUrl = await this.normalizePushAvatarUrl(session.avatarUrl || groupInfo?.avatarUrl)
|
||||
return {
|
||||
event: 'message.new',
|
||||
sessionId,
|
||||
sessionType,
|
||||
messageKey,
|
||||
avatarUrl: session.avatarUrl || groupInfo?.avatarUrl,
|
||||
avatarUrl,
|
||||
groupName,
|
||||
sourceName,
|
||||
content
|
||||
@@ -323,17 +331,63 @@ class MessagePushService {
|
||||
}
|
||||
|
||||
const contactInfo = await chatService.getContactAvatar(sessionId)
|
||||
const avatarUrl = await this.normalizePushAvatarUrl(session.avatarUrl || contactInfo?.avatarUrl)
|
||||
return {
|
||||
event: 'message.new',
|
||||
sessionId,
|
||||
sessionType,
|
||||
messageKey,
|
||||
avatarUrl: session.avatarUrl || contactInfo?.avatarUrl,
|
||||
avatarUrl,
|
||||
sourceName: session.displayName || contactInfo?.displayName || sessionId,
|
||||
content
|
||||
}
|
||||
}
|
||||
|
||||
private async normalizePushAvatarUrl(avatarUrl?: string): Promise<string | undefined> {
|
||||
const normalized = String(avatarUrl || '').trim()
|
||||
if (!normalized) return undefined
|
||||
if (!normalized.startsWith('data:image/')) {
|
||||
return normalized
|
||||
}
|
||||
|
||||
const cached = this.pushAvatarDataCache.get(normalized)
|
||||
if (cached) return cached
|
||||
|
||||
const match = /^data:(image\/[a-zA-Z0-9.+-]+);base64,(.+)$/i.exec(normalized)
|
||||
if (!match) return undefined
|
||||
|
||||
try {
|
||||
const mimeType = match[1].toLowerCase()
|
||||
const base64Data = match[2]
|
||||
const imageBuffer = Buffer.from(base64Data, 'base64')
|
||||
if (!imageBuffer.length) return undefined
|
||||
|
||||
const ext = this.getImageExtFromMime(mimeType)
|
||||
const hash = createHash('sha1').update(normalized).digest('hex')
|
||||
const filePath = path.join(this.pushAvatarCacheDir, `avatar_${hash}.${ext}`)
|
||||
|
||||
await fs.mkdir(this.pushAvatarCacheDir, { recursive: true })
|
||||
try {
|
||||
await fs.access(filePath)
|
||||
} catch {
|
||||
await fs.writeFile(filePath, imageBuffer)
|
||||
}
|
||||
|
||||
const fileUrl = pathToFileURL(filePath).toString()
|
||||
this.pushAvatarDataCache.set(normalized, fileUrl)
|
||||
return fileUrl
|
||||
} catch {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
private getImageExtFromMime(mimeType: string): string {
|
||||
if (mimeType === 'image/png') return 'png'
|
||||
if (mimeType === 'image/gif') return 'gif'
|
||||
if (mimeType === 'image/webp') return 'webp'
|
||||
return 'jpg'
|
||||
}
|
||||
|
||||
private getSessionType(sessionId: string, session: ChatSession): MessagePushPayload['sessionType'] {
|
||||
if (sessionId.endsWith('@chatroom')) {
|
||||
return 'group'
|
||||
|
||||
Reference in New Issue
Block a user