import type { DatabaseClient } from "./database"; import { addTaskJoinWay, deleteJoinWay, getJoinWayQrCode, updateTaskJoinWay, type WecomConfig, } from "./wecom-client"; type FetchLike = typeof fetch; function text(value: unknown) { return String(value ?? "").trim(); } export type BindTaskCustomerChatResult = { customerChatId: string; customerChatName: string; joinConfigId: string; joinQrCode: string; qrError?: string; }; export async function bindTaskCustomerChat( db: DatabaseClient, params: { taskId: string; chatId: string; chatName: string }, config: WecomConfig, fetchImpl: FetchLike = fetch, ): Promise { const taskId = text(params.taskId); const chatId = text(params.chatId); const chatName = text(params.chatName).slice(0, 255); if (!taskId) throw new Error("缺少 taskId"); if (!chatId) throw new Error("请选择要绑定的客户群"); const task = await db .prepare("SELECT id, name, join_config_id FROM tasks WHERE id = ?") .bind(taskId) .first<{ id: string; name: string; join_config_id: string | null }>(); if (!task) throw new Error("任务不存在"); const joinInput = { chatIdList: [chatId], roomBaseName: task.name, state: `task-${taskId}`, }; let configId = text(task.join_config_id); if (configId) { try { await updateTaskJoinWay(config, { ...joinInput, configId }, fetchImpl); } catch { // 活码配置可能已被企微侧清理,降级为重新创建 configId = (await addTaskJoinWay(config, joinInput, fetchImpl)).configId; } } else { configId = (await addTaskJoinWay(config, joinInput, fetchImpl)).configId; } let joinQrCode = ""; let qrError: string | undefined; try { joinQrCode = (await getJoinWayQrCode(config, configId, fetchImpl)).qrCode; } catch (error) { qrError = `活码二维码获取失败:${error instanceof Error ? error.message : String(error)}`; } await db .prepare( `UPDATE tasks SET customer_chat_id = ?, customer_chat_name = ?, join_config_id = ?, join_qr_code = ? WHERE id = ?`, ) .bind(chatId, chatName, configId, joinQrCode, taskId) .run(); return { customerChatId: chatId, customerChatName: chatName, joinConfigId: configId, joinQrCode, qrError, }; } export async function unbindTaskCustomerChat( db: DatabaseClient, taskId: string, config: WecomConfig, fetchImpl: FetchLike = fetch, ): Promise { const id = text(taskId); if (!id) throw new Error("缺少 taskId"); const task = await db .prepare("SELECT join_config_id FROM tasks WHERE id = ?") .bind(id) .first<{ join_config_id: string | null }>(); if (!task) throw new Error("任务不存在"); const configId = text(task.join_config_id); if (configId) { await deleteJoinWay(config, configId, fetchImpl); } await db .prepare( `UPDATE tasks SET customer_chat_id = '', customer_chat_name = '', join_config_id = '', join_qr_code = '' WHERE id = ?`, ) .bind(id) .run(); }