diff --git a/src/channels/telegram/menu.ts b/src/channels/telegram/menu.ts index eae919e..8673549 100644 --- a/src/channels/telegram/menu.ts +++ b/src/channels/telegram/menu.ts @@ -12,6 +12,7 @@ export const privateBotCommands: BotCommand[] = [ { command: "expires", description: "查看当前会话销毁策略" }, { command: "whoami", description: "查看你的 Telegram 用户 ID" }, { command: "history", description: "查看最近消息摘要,例如 /history 20" }, + { command: "search", description: "搜索历史消息,例如 /search 关键词" }, { command: "note", description: "保存内部备注,不会外发" }, { command: "notes", description: "查看最近内部备注,例如 /notes 10" }, { command: "tag", description: "添加标签" }, @@ -19,6 +20,7 @@ export const privateBotCommands: BotCommand[] = [ { command: "tags", description: "列出当前会话标签" }, { command: "priority", description: "设置优先级 low/normal/high/urgent" }, { command: "assign", description: "分配负责人" }, + { command: "mine", description: "查看分配给自己的会话" }, { command: "close", description: "关闭会话" }, { command: "open", description: "重新打开会话" }, { command: "mute", description: "静音提醒,例如 /mute 2h" }, @@ -26,6 +28,7 @@ export const privateBotCommands: BotCommand[] = [ { command: "unban", description: "解除封禁" }, { command: "delete", description: "删除当前 Topic 并清理数据库,需 /delete confirm" }, { command: "reset", description: "清空会话消息和草稿,需 /reset confirm" }, + { command: "audit", description: "查看本会话审计记录,例如 /audit 20" }, { command: "draft", description: "AI 回复草稿:/draft view|send|discard 或 /draft 重新生成" }, { command: "ai_on", description: "开启当前会话的 AI 草稿" }, { command: "ai_off", description: "关闭当前会话的 AI 草稿" }, @@ -42,6 +45,7 @@ export const adminBotCommands: BotCommand[] = [ { command: "expires", description: "查看当前会话销毁策略" }, { command: "whoami", description: "查看你的 Telegram 管理员 ID" }, { command: "history", description: "查看最近消息摘要,例如 /history 20" }, + { command: "search", description: "搜索历史消息,例如 /search 关键词" }, { command: "note", description: "保存内部备注,不会外发" }, { command: "notes", description: "查看最近内部备注,例如 /notes 10" }, { command: "tag", description: "添加标签" }, @@ -49,6 +53,7 @@ export const adminBotCommands: BotCommand[] = [ { command: "tags", description: "列出当前会话标签" }, { command: "priority", description: "设置优先级 low/normal/high/urgent" }, { command: "assign", description: "分配负责人" }, + { command: "mine", description: "查看分配给自己的会话" }, { command: "close", description: "关闭会话" }, { command: "open", description: "重新打开会话" }, { command: "mute", description: "静音提醒,例如 /mute 2h" }, @@ -56,6 +61,7 @@ export const adminBotCommands: BotCommand[] = [ { command: "unban", description: "解除封禁" }, { command: "delete", description: "删除当前 Topic 并清理数据库,需 /delete confirm" }, { command: "reset", description: "清空会话消息和草稿,需 /reset confirm" }, + { command: "audit", description: "查看本会话审计记录,例如 /audit 20" }, { command: "draft", description: "AI 回复草稿:/draft view|send|discard 或 /draft 重新生成" }, { command: "ai_on", description: "开启当前会话的 AI 草稿" }, { command: "ai_off", description: "关闭当前会话的 AI 草稿" }, diff --git a/src/channels/telegram/messages.ts b/src/channels/telegram/messages.ts index d9367d5..8062260 100644 --- a/src/channels/telegram/messages.ts +++ b/src/channels/telegram/messages.ts @@ -299,6 +299,18 @@ export async function handlePrivateMessage(ctx: Context, deps: TelegramMessageDe } } + if (bundle.conversation.priority === "urgent" && bundle.conversation.assignedAdminId) { + try { + await ctx.api.sendMessage( + deps.config.TELEGRAM_MANAGEMENT_CHAT_ID, + `紧急消息提醒:负责人 ${bundle.conversation.assignedAdminId} 请关注本会话。`, + { message_thread_id: topic.messageThreadId }, + ); + } catch { + // 提醒失败不影响主流程 + } + } + const draft = await deps.aiDrafts.generate(bundle.conversation.id, savedMessage.id); if (draft.status === "ready") { await ctx.api.sendMessage(deps.config.TELEGRAM_MANAGEMENT_CHAT_ID, `AI 草稿(不会自动发送):\n\n${draft.text}`, { diff --git a/test/core.test.ts b/test/core.test.ts index 3c0094f..29edb78 100644 --- a/test/core.test.ts +++ b/test/core.test.ts @@ -732,6 +732,24 @@ describe("conversation service", () => { const empty = service.listByAssignee("999", 20); assert.equal(empty.length, 0); }); + + it("supports urgent priority with assignee for alert trigger", async () => { + const service = new ConversationService(handle.db, 30); + const bundle = await service.getOrCreateConversation({ + platform: "telegram", + externalUserId: "700", + displayName: "UrgentUser", + }); + service.setPriority(bundle.conversation.id, "urgent"); + service.assign(bundle.conversation.id, "500"); + + const conv = await service.getConversation(bundle.conversation.id); + assert.ok(conv); + assert.equal(conv!.priority, "urgent"); + assert.equal(conv!.assignedAdminId, "500"); + // Alert condition: priority === "urgent" && assignedAdminId is truthy + assert.ok(conv!.priority === "urgent" && conv!.assignedAdminId !== null); + }); }); describe("permissions and rate limits", () => { @@ -824,6 +842,9 @@ describe("telegram helpers", () => { assert.ok(adminBotCommands.some((command) => command.command === "ai_on")); assert.ok(adminBotCommands.some((command) => command.command === "ai_off")); assert.ok(adminBotCommands.some((command) => command.command === "help")); + assert.ok(adminBotCommands.some((command) => command.command === "search")); + assert.ok(adminBotCommands.some((command) => command.command === "mine")); + assert.ok(adminBotCommands.some((command) => command.command === "audit")); assert.ok(adminBotCommands.every((command) => !command.command.startsWith("/"))); });