mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-08-17 11:37:06 +08:00
57 lines
1.7 KiB
TypeScript
57 lines
1.7 KiB
TypeScript
import { createHash } from 'crypto'
|
||
import type {
|
||
KnowledgeNormalizedMessage,
|
||
KnowledgeSourceMessage
|
||
} from '../../shared/knowledge'
|
||
|
||
const compact = (value: string | undefined): string => value?.replace(/\s+/g, ' ').trim() || ''
|
||
|
||
function digest(value: string): string {
|
||
return createHash('sha256').update(value).digest('hex')
|
||
}
|
||
|
||
/**
|
||
* Converts a read-only archive record into text safe for local search. Paths,
|
||
* binary media and raw voice data are deliberately excluded.
|
||
*/
|
||
export function normalizeKnowledgeMessage(
|
||
source: KnowledgeSourceMessage
|
||
): KnowledgeNormalizedMessage {
|
||
const sections: string[] = []
|
||
const messageText = compact(source.text)
|
||
if (messageText) sections.push(messageText)
|
||
|
||
const transcript = compact(source.voiceTranscript)
|
||
if (transcript) sections.push(`语音转写:${transcript}`)
|
||
|
||
const attachmentName = compact(source.attachment?.name)
|
||
if (attachmentName) {
|
||
const label = source.attachment?.kind === 'link' ? '链接' : '附件'
|
||
sections.push(`${label}:${attachmentName}`)
|
||
}
|
||
const url = compact(source.attachment?.url)
|
||
if (url) sections.push(`地址:${url}`)
|
||
|
||
const searchableText = sections.join('\n')
|
||
return {
|
||
...source,
|
||
text: messageText || undefined,
|
||
voiceTranscript: transcript || undefined,
|
||
searchableText,
|
||
contentHash: digest(
|
||
JSON.stringify({
|
||
messageId: source.messageId,
|
||
createTime: source.createTime,
|
||
senderId: source.senderId || '',
|
||
kind: source.kind,
|
||
voiceTranscriptState: source.voiceTranscriptState || '',
|
||
searchableText
|
||
})
|
||
)
|
||
}
|
||
}
|
||
|
||
export function isIndexableKnowledgeMessage(message: KnowledgeNormalizedMessage): boolean {
|
||
return Boolean(message.searchableText.trim())
|
||
}
|