"""求助域(support)通知模板 —— IT 服务台工单的全生命周期。 覆盖工单创建 / 回复 / 认领 / 解决 / 重新打开五个流程。 ``support.ticket_reply`` 与 ``support.ticket_reopened`` 在这里各拆成三个 key(``.to_requester`` / ``.to_agent`` / ``.to_it``),因为同一事件对三类 收件人的说法完全不同 —— 求助人看到的是「IT 回复了你的工单」,承接工程师 看到的是「求助人回复了工单」,未认领时 IT 群发看到的是「未认领工单有新 回复」。一个 key 只能注册一份文案,合并会让工程师收到张冠李戴的标题,所以 按收件人分 key 而不是按事件分 key。裸 key(``support.ticket_reply`` / ``support.ticket_reopened``)刻意不注册:历史 outbox 行仍按写入时的标题 回落,不会被新文案改写成写给另一类人的说法。 Placeholder 全部来自 ``app/domains/support/service.py`` 的 ``_notify`` / ``_notify_it`` —— 两者都把 ``ticket_number`` 等塞进 envelope ``context``。 用户手写内容(回复正文、解决说明、工单标题)原样透传,不翻译。 """ from __future__ import annotations TEMPLATES: dict[str, dict[str, str]] = { # ── 创建:群发给 IT(global_admin) ──────────────────────────── # context: ticket_number, requester_name, ticket_title "support.ticket_created": { "subject": "新求助工单 · {ticket_number}", "subject_en": "New support ticket · {ticket_number}", "subject_ja": "新しいサポート依頼 · {ticket_number}", "body_text": ( "{requester_name} 提交了一条求助:\n" "{ticket_title}\n\n" "{cta_line}" ), "body_text_en": ( "{requester_name} submitted a support request:\n" "{ticket_title}\n\n" "{cta_line}" ), "body_text_ja": ( "{requester_name} さんからサポート依頼が届きました:\n" "{ticket_title}\n\n" "{cta_line}" ), "card_button_label": "处理工单", "card_button_label_en": "Handle ticket", "card_button_label_ja": "対応する", }, # ── 回复:IT 回复求助人 ─────────────────────────────────────── # context: ticket_number, reply_body "support.ticket_reply.to_requester": { "subject": "IT 回复了你的工单 · {ticket_number}", "subject_en": "IT replied to your ticket · {ticket_number}", "subject_ja": "IT があなたの依頼に返信しました · {ticket_number}", "body_text": "{reply_body}\n\n{cta_line}", "body_text_en": "{reply_body}\n\n{cta_line}", "body_text_ja": "{reply_body}\n\n{cta_line}", "card_button_label": "查看并回复", "card_button_label_en": "View and reply", "card_button_label_ja": "確認して返信", }, # ── 回复:求助人回复给已认领的工程师 ────────────────────────── # context: ticket_number, reply_body "support.ticket_reply.to_agent": { "subject": "求助人回复了工单 · {ticket_number}", "subject_en": "The requester replied to ticket {ticket_number}", "subject_ja": "依頼者から返信がありました · {ticket_number}", "body_text": "{reply_body}\n\n{cta_line}", "body_text_en": "{reply_body}\n\n{cta_line}", "body_text_ja": "{reply_body}\n\n{cta_line}", "card_button_label": "处理工单", "card_button_label_en": "Handle ticket", "card_button_label_ja": "対応する", }, # ── 回复:工单还没人认领,群发给 IT ─────────────────────────── # context: ticket_number, reply_body "support.ticket_reply.to_it": { "subject": "未认领工单有新回复 · {ticket_number}", "subject_en": "New reply on an unclaimed ticket · {ticket_number}", "subject_ja": "未対応の依頼に新しい返信があります · {ticket_number}", "body_text": "{reply_body}\n\n{cta_line}", "body_text_en": "{reply_body}\n\n{cta_line}", "body_text_ja": "{reply_body}\n\n{cta_line}", "card_button_label": "处理工单", "card_button_label_en": "Handle ticket", "card_button_label_ja": "対応する", }, # ── 认领:通知求助人 ────────────────────────────────────────── # context: ticket_number, agent_name, ticket_title "support.ticket_claimed": { "subject": "IT 已受理你的工单 · {ticket_number}", "subject_en": "IT has picked up your ticket · {ticket_number}", "subject_ja": "IT が依頼を受け付けました · {ticket_number}", "body_text": ( "{agent_name} 正在处理你的求助:{ticket_title}\n\n" "{cta_line}" ), "body_text_en": ( "{agent_name} is now working on your request: {ticket_title}\n\n" "{cta_line}" ), "body_text_ja": ( "{agent_name} さんが対応を開始しました:{ticket_title}\n\n" "{cta_line}" ), "card_button_label": "查看", "card_button_label_en": "View ticket", "card_button_label_ja": "確認する", }, # ── 解决:通知求助人确认或重开 ──────────────────────────────── # context: ticket_number, resolution "support.ticket_resolved": { "subject": "你的工单已解决 · {ticket_number}", "subject_en": "Your ticket has been resolved · {ticket_number}", "subject_ja": "依頼が解決済みになりました · {ticket_number}", "body_text": ( "IT 标记为已解决:\n" "{resolution}\n\n" "若问题已处理可关闭,否则可重新打开。\n\n" "{cta_line}" ), "body_text_en": ( "IT marked this as resolved:\n" "{resolution}\n\n" "If the problem is gone you can close the ticket; otherwise " "reopen it.\n\n" "{cta_line}" ), "body_text_ja": ( "IT が解決済みとしてマークしました:\n" "{resolution}\n\n" "問題が解消していればクローズしてください。解消していない場合は" "再オープンできます。\n\n" "{cta_line}" ), "card_button_label": "确认 / 重新打开", "card_button_label_en": "Confirm / reopen", "card_button_label_ja": "確認 / 再オープン", }, # ── 重新打开:IT 重开,通知求助人 ───────────────────────────── # context: ticket_number, ticket_title "support.ticket_reopened.to_requester": { "subject": "工单已重新打开 · {ticket_number}", "subject_en": "Your ticket was reopened · {ticket_number}", "subject_ja": "依頼が再オープンされました · {ticket_number}", "body_text": "{ticket_title}\n\n{cta_line}", "body_text_en": "{ticket_title}\n\n{cta_line}", "body_text_ja": "{ticket_title}\n\n{cta_line}", "card_button_label": "查看", "card_button_label_en": "View ticket", "card_button_label_ja": "確認する", }, # ── 重新打开:求助人重开,通知承接工程师 ────────────────────── # context: ticket_number, ticket_title "support.ticket_reopened.to_agent": { "subject": "求助人重新打开了工单 · {ticket_number}", "subject_en": "The requester reopened ticket {ticket_number}", "subject_ja": "依頼者が依頼を再オープンしました · {ticket_number}", "body_text": "{ticket_title}\n\n{cta_line}", "body_text_en": "{ticket_title}\n\n{cta_line}", "body_text_ja": "{ticket_title}\n\n{cta_line}", "card_button_label": "处理工单", "card_button_label_en": "Handle ticket", "card_button_label_ja": "対応する", }, # ── 重新打开:求助人重开且无人认领,群发给 IT ───────────────── # context: ticket_number, ticket_title "support.ticket_reopened.to_it": { "subject": "工单被重新打开 · {ticket_number}", "subject_en": "A ticket was reopened · {ticket_number}", "subject_ja": "依頼が再オープンされました · {ticket_number}", "body_text": "{ticket_title}\n\n{cta_line}", "body_text_en": "{ticket_title}\n\n{cta_line}", "body_text_ja": "{ticket_title}\n\n{cta_line}", "card_button_label": "处理工单", "card_button_label_en": "Handle ticket", "card_button_label_ja": "対応する", }, # ── SLA / 当前责任方催办 ───────────────────────────────────── # context: ticket_number, ticket_title, reason "support.ticket_sla_reminder.to_agent": { "subject": "工单催办 · {ticket_number}", "subject_en": "Ticket follow-up · {ticket_number}", "subject_ja": "チケット対応依頼 · {ticket_number}", "body_text": "{reason}:{ticket_title}\n\n请进入 IT 支持台处理。\n\n{cta_line}", "body_text_en": "{reason}: {ticket_title}\n\nPlease handle it in the IT Support Desk.\n\n{cta_line}", "body_text_ja": "{reason}:{ticket_title}\n\nIT サポートデスクで対応してください。\n\n{cta_line}", "card_button_label": "处理工单", "card_button_label_en": "Handle ticket", "card_button_label_ja": "対応する", }, "support.ticket_sla_reminder.to_requester": { "subject": "你的 IT 工单需要处理 · {ticket_number}", "subject_en": "Your IT ticket needs you · {ticket_number}", "subject_ja": "IT チケットの確認が必要です · {ticket_number}", "body_text": "{reason}:{ticket_title}\n\n{cta_line}", "body_text_en": "{reason}: {ticket_title}\n\n{cta_line}", "body_text_ja": "{reason}:{ticket_title}\n\n{cta_line}", "card_button_label": "查看并处理", "card_button_label_en": "View and respond", "card_button_label_ja": "確認して対応", }, # ── 知识库缺口周报(IT-only,cron support.kb_gap_digest)──────── # context: window_days, gap_count, cluster_count, gap_lines "support.kb_gap_digest": { "subject": "知识库缺口周报 · {gap_count} 个未命中问题", "subject_en": "Weekly KB gap digest · {gap_count} unanswered questions", "subject_ja": "ナレッジベース ギャップ週報 · 未回答 {gap_count} 件", "body_text": ( "过去 {window_days} 天,以下自助求助问题在知识库(含飞书文档镜像)" "中零命中,员工最终提单或放弃——这就是「该补的文档清单」" "(聚类后 {cluster_count} 组):\n\n{gap_lines}\n\n{cta_line}" ), "body_text_en": ( "In the past {window_days} days these self-service questions got " "ZERO knowledge-base hits (Feishu doc mirror included) and the " "employee ended up filing a ticket or walking away — the " "docs-to-write list ({cluster_count} clusters):\n\n{gap_lines}\n\n{cta_line}" ), "body_text_ja": ( "過去 {window_days} 日間、以下のセルフサービス質問はナレッジベース" "(Feishu ドキュメントミラー含む)でヒット 0 件のまま、従業員は" "起票または離脱しました——「書くべきドキュメント」リストです" "({cluster_count} クラスタ):\n\n{gap_lines}\n\n{cta_line}" ), "card_button_label": "打开知识库管理", "card_button_label_en": "Open KB admin", "card_button_label_ja": "ナレッジ管理を開く", }, } __all__ = ["TEMPLATES"]