export type WecomCallbackFields = Record; export type WecomCallbackEventResult = { recognized: boolean; action: string; taskId: string; btnKey: string; operator: string; }; export function parseWecomCallbackXml(xml: string): WecomCallbackFields { const fields: WecomCallbackFields = {}; const source = String(xml ?? ""); const pattern = /<([A-Za-z][A-Za-z0-9_]*)>(?:|([^<]*))<\/\1>/g; let match: RegExpExecArray | null; while ((match = pattern.exec(source)) !== null) { const tag = match[1]; const value = match[2] ?? match[3] ?? ""; if (!(tag in fields)) fields[tag] = value.trim(); } return fields; } export function extractWecomEncryptField(body: string): string { const fields = parseWecomCallbackXml(body); return fields.Encrypt ?? ""; } export function handleWecomCallbackEvent( fields: WecomCallbackFields, ): WecomCallbackEventResult { const event = fields.Event ?? ""; const taskId = fields.TaskId ?? ""; const btnKey = fields.BtnKey ?? ""; const operator = fields.FromUserName ?? ""; if (fields.MsgType === "event" && event === "template_card_event") { if (btnKey === "mark_handled") { console.info( "[KOC LOOP] wecom card ack", { taskId, operator }, ); return { recognized: true, action: "card_ack", taskId, btnKey, operator }; } return { recognized: true, action: "ignored", taskId, btnKey, operator }; } console.info("[KOC LOOP] wecom callback event ignored", { msgType: fields.MsgType ?? "", event, }); return { recognized: false, action: "ignored", taskId, btnKey, operator }; }