- Facebook/Instagram/TikTok 渠道 OAuth 授权流程改进 - 新增 oauth/credentialstore 包 - 集成应用 OpenAI 重命名为 OpenAI 兼容 (migration 061) - 消息生命周期与 AI 流程架构文档 - inbox 管理界面 i18n 更新
524 lines
27 KiB
Markdown
524 lines
27 KiB
Markdown
# GoChat 消息生命周期与 AI 自动回复流程
|
||
|
||
> 本文档描述从渠道消息入站、人工/AI 回复、消息打标签到 AI 自动触发的完整运行流程。
|
||
> 所有文件路径相对于仓库根目录,行号截至 2026-07-30。
|
||
|
||
---
|
||
|
||
## 一、整体架构概览
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ 外部渠道 │
|
||
│ Facebook │ Instagram │ TikTok │ Telegram │ LINE │ Email │ Web Widget │ API
|
||
└─────┬──────────┬──────────┬──────────┬─────────┬───────┬──────┬──────┘
|
||
│ │ │ │ │ │ │
|
||
▼ ▼ ▼ ▼ ▼ ▼ ▼
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ Webhook 路由层 (router.go) │
|
||
│ /webhooks/facebook /webhooks/instagram /webhooks/tiktok ... │
|
||
└──────────────────────────────┬──────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ Channel Provider 层 (插件接口) │
|
||
│ FacebookProvider InstagramProvider TikTokProvider TelegramProvider│
|
||
│ IncomingMessage() 解析渠道原始 payload → channel.IncomingMessage │
|
||
└──────────────────────────────┬──────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ IncomingPersister (持久化层) │
|
||
│ 1. resolveOrCreateContactInbox — 查找/创建 Contact + ContactInbox │
|
||
│ 2. resolveOrCreateConversation — 查找/创建 Conversation │
|
||
│ 3. createMessage — 持久化 Message │
|
||
│ 4. dispatchIncomingEvents — 广播 channel events │
|
||
└──────────────────────────────┬──────────────────────────────────────┘
|
||
│ DispatchAsync
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ Dispatcher (事件分发总线) │
|
||
│ channel.Dispatcher → 广播 ChannelEvent 给所有注册的 EventListener │
|
||
│ │
|
||
│ 注册的 Listener: │
|
||
│ ├── AutoReplyListener — AI 自动回复 │
|
||
│ ├── AutomationRuleListener— 自动化规则(标签/分配/状态变更) │
|
||
│ ├── ActionCableListener — WebSocket 推送到前端 │
|
||
│ ├── NotificationListener — 创建通知 │
|
||
│ ├── AgentBotRuleListener — Agent Bot 规则 │
|
||
│ └── AutoAssignmentListener— 自动分配 │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 二、入站消息流(Inbound)
|
||
|
||
### 2.1 Webhook 路由注册
|
||
|
||
路由在 `backend/internal/router/router.go` 中注册:
|
||
|
||
- **Facebook**: `POST /webhooks/facebook` → `FacebookWebhookHandler.HandleWebhook`
|
||
- **Instagram**: `POST /webhooks/instagram` → `InstagramWebhookHandler`
|
||
- **TikTok**: `POST /webhooks/tiktok` → `TikTokWebhookHandler`
|
||
- **Telegram**: `POST /webhooks/telegram/:inbox_id` → `TelegramWebhookHandler`
|
||
- **LINE**: `POST /webhooks/line/:inbox_id` → `LineWebhookHandler`
|
||
- **Email**: IMAP 轮询 + ActionMailbox 端点
|
||
- **Web Widget**: WebSocket 实时消息(不走 webhook)
|
||
- **API Channel**: `POST /webhooks/api/:inbox_id` → 外部系统主动推送
|
||
|
||
### 2.2 Webhook Handler → Provider → IncomingMessage
|
||
|
||
以 Facebook 为例:
|
||
|
||
```
|
||
FacebookWebhookHandler.HandleWebhook (handler/webhook/facebook_webhook.go)
|
||
→ 解析 Facebook webhook payload (entry[].messaging[])
|
||
→ 遍历每条 messaging event
|
||
→ 调用 FacebookProvider.IncomingMessage() (channel/facebook/provider.go)
|
||
→ 解析 sender_id, recipient_id, message text, attachments
|
||
→ 返回 channel.IncomingMessage{
|
||
SourceID: "facebook_msg_xxx",
|
||
ConversationID: senderPSID,
|
||
Content: messageText,
|
||
ContentType: channel.ContentText,
|
||
Attachments: []Attachment{...},
|
||
ChannelType: channel.ChannelFacebook,
|
||
}
|
||
```
|
||
|
||
其他渠道同理,每个 Provider 实现 `IncomingMessage()` 方法将渠道原始数据归一化为 `channel.IncomingMessage` 结构。
|
||
|
||
### 2.3 IncomingPersister 持久化
|
||
|
||
`backend/internal/handler/webhook/incoming_persister.go:74`
|
||
|
||
```
|
||
IncomingPersister.PersistIncoming(ctx, inbox, msg)
|
||
│
|
||
├── 若有 WorkerPool → enqueueIncomingMessagePersist (异步队列)
|
||
│ └── providerIncomingMessagePersistJob (incoming_persister_jobs.go:24)
|
||
│ └── performPersistIncoming (异步执行)
|
||
│
|
||
└── performPersistIncoming(ctx, inbox, msg) — 同步路径
|
||
│
|
||
├── 1. resolveOrCreateContactInbox (L451)
|
||
│ ├── 按 inbox_id + source_id 查找 ContactInbox
|
||
│ ├── 找到 → 返回关联的 Contact(更新 name 等)
|
||
│ └── 未找到 → 创建 Contact + ContactInbox
|
||
│
|
||
├── 2. resolveOrCreateConversation (L504)
|
||
│ ├── 查找 account_id+inbox_id+contact_id+status=open 的最近会话
|
||
│ ├── 找到 → 更新 last_activity_at, last_message_at
|
||
│ └── 未找到 → 创建新 Conversation (status=open)
|
||
│
|
||
├── 3. createMessage (L545)
|
||
│ ├── 构建 model.Message{SenderType:"Contact", MessageType:"incoming"}
|
||
│ ├── 处理 in_reply_to(按 source_id 查找被回复的消息)
|
||
│ ├── 处理 attachments
|
||
│ └── messageRepo.Create() 持久化到 messages 表
|
||
│
|
||
└── 4. dispatchIncomingEvents (L383)
|
||
├── EventContactCreated (仅新联系人)
|
||
├── EventConversationCreated + EventConversationOpened (仅新会话)
|
||
├── EventConversationUpdated (已有会话)
|
||
├── EventMessageCreated
|
||
└── EventMessageIncoming
|
||
└── dispatcher.DispatchAsync() → 广播给所有 Listener
|
||
```
|
||
|
||
### 2.4 WebSocket 实时推送
|
||
|
||
```
|
||
ActionCableListener.OnEvent (internal/wsevent/bridge_listener.go:51)
|
||
├── 接收 EventMessageCreated / EventMessageIncoming
|
||
├── 构建 WebSocket payload (message JSON + conversation meta)
|
||
└── wsHub.Broadcast() → 推送到该 account 所有在线 agent 前端
|
||
└── 前端 Vue SPA WebSocket 连接接收 → Vuex/Pinia store 更新 → UI 刷新
|
||
```
|
||
|
||
### 2.5 通知创建
|
||
|
||
```
|
||
NotificationListener.OnEvent
|
||
├── 接收 EventMessageIncoming
|
||
├── 检查 inbox 的通知设置
|
||
├── 创建 Notification 记录 (notification 表)
|
||
├── 推送 Push notification (PushDeliveryService)
|
||
│ └── SendPushNotification (push_delivery_service.go:63)
|
||
└── 发送邮件通知(如配置)
|
||
```
|
||
|
||
---
|
||
|
||
## 三、出站回复流(Outbound)
|
||
|
||
### 3.1 前端发起
|
||
|
||
```
|
||
Agent 在 ReplyBox 输入消息 → 点击发送
|
||
│
|
||
├── frontend/app/javascript/dashboard/api/inbox/message.js:56
|
||
│ MessageApi.create({ conversationId, message, ... })
|
||
│ → POST /api/v1/accounts/:id/conversations/:conversation_id/messages
|
||
│
|
||
└── 前端 Vuex store: conversations/actions.js
|
||
createPendingMessageAndSend → MessageApi.create()
|
||
```
|
||
|
||
### 3.2 后端处理
|
||
|
||
```
|
||
MessageHandler.Create (handler/api/v1/message_handler.go)
|
||
→ 解析请求 body (content, private, files, echo_id, ...)
|
||
→ 调用 MessageService.Create()
|
||
│
|
||
│ backend/internal/service/message_service.go
|
||
│
|
||
├── 构建 model.Message{MessageType:"outgoing", SenderType:"User"}
|
||
├── messageRepo.Create() — 持久化消息
|
||
├── 更新 conversation.last_activity_at, last_message_at
|
||
├── dispatchMessageEvent(EventMessageCreated + EventMessageOutgoing)
|
||
│ └── dispatcher.Dispatch() → 广播给 Listener
|
||
│ ├── ActionCableListener → WebSocket 推送 (agent 端即时看到)
|
||
│ ├── AutomationRuleListener → 触发自动化规则
|
||
│ └── 其他 Listener
|
||
│
|
||
└── 投递到渠道 (MessageDeliveryWorker)
|
||
│
|
||
├── 若有 WorkerPool → EnqueueSendReply (异步队列)
|
||
│ └── message_delivery_worker.go: CreateOutgoing → SendReply
|
||
│
|
||
└── SendReply(messageID)
|
||
├── 加载 message + conversation + inbox + contact
|
||
├── 根据 inbox.ChannelType 获取对应 Provider
|
||
├── 调用 Provider.SendMessage(ctx, inbox, message, contact)
|
||
│ ├── Facebook: POST graph.facebook.com/me/messages
|
||
│ ├── Instagram: POST graph.facebook.com/me/messages (IGID)
|
||
│ ├── TikTok: POST business-api.tiktok.com/...
|
||
│ ├── Telegram: POST api.telegram.org/bot.../sendMessage
|
||
│ ├── Email: SMTP 发送
|
||
│ ├── Web Widget: WebSocket 推送到 widget 端
|
||
│ └── API: POST 到 inbox.webhook_url
|
||
├── 更新 message.Status = "sent" / "delivered" / "failed"
|
||
└── dispatchMessageEvent(EventMessageStatusUpdated)
|
||
```
|
||
|
||
### 3.3 消息状态回执
|
||
|
||
渠道 webhook 回调消息已读/已送达状态:
|
||
```
|
||
FacebookWebhookHandler → 解析 delivery/read event
|
||
→ IncomingPersister.dispatchMessageStatusEvent()
|
||
→ 更新 message.Status
|
||
→ dispatcher.Dispatch(EventMessageStatusUpdated)
|
||
→ ActionCableListener → WebSocket 推送状态更新到前端
|
||
```
|
||
|
||
---
|
||
|
||
## 四、标签系统
|
||
|
||
### 4.1 数据模型(双路径并存)
|
||
|
||
GoChat 标签系统存在两条并行路径:
|
||
|
||
**路径 A — Tag 关联表(结构化)**
|
||
- **Tag** (`backend/internal/model/tag.go:12`): 表名 `tags`,字段 `ID, AccountID, Name(账号内唯一), Color, Description, ShowOnSidebar`
|
||
- 唯一索引:`idx_tag_account_name`(AccountID + Name)
|
||
- **ConversationLabel** (`backend/internal/model/conversation_label.go:11`): 表名 `conversation_labels`,字段 `ID, ConversationID, TagID, AccountID`
|
||
- 唯一索引:`idx_conv_label_tag`(ConversationID + TagID),防止重复关联
|
||
- Repository: `TagRepo` (`repository/tag_repo.go`) — `DeleteWithAssociations` 删除 Tag 时同步清理关联行和 `conversations.labels` 文本字段
|
||
|
||
**路径 B — Conversation.Labels 文本字段(遗留)**
|
||
- `Conversation.Labels string` (`model/conversation.go:30`) — 逗号分隔字符串,如 `"billing,urgent"`
|
||
- 辅助函数: `mergeConversationLabels()` / `splitConversationLabels()` (`conversation_maintenance_worker.go:726,755`)
|
||
- `TagRepo.RenameConversationLabelText` (`repository/tag_repo.go:70`) — Tag 重命名时同步更新 `conversations.labels` 中的文本
|
||
|
||
两条路径在自动化规则和手动操作中同时维护。
|
||
|
||
### 4.2 标签 CRUD API
|
||
|
||
```
|
||
LabelHandler (handler/api/v1/label_handler.go)
|
||
├── GET /api/v1/accounts/:id/labels — 列出标签
|
||
├── POST /api/v1/accounts/:id/labels — 创建标签
|
||
├── PATCH /api/v1/accounts/:id/labels/:id — 更新标签
|
||
└── DELETE /api/v1/accounts/:id/labels/:id — 删除标签
|
||
│
|
||
└── LabelService (service/label_service.go)
|
||
└── LabelRepo (repository/label_repo.go)
|
||
```
|
||
|
||
### 4.3 会话标签操作
|
||
|
||
```
|
||
ConversationHandler (handler/api/v1/conversation_handler.go)
|
||
├── POST /conversations/:id/labels — 给会话打标签
|
||
└── POST /conversations/:id/labels — 移除标签
|
||
│
|
||
└── ConversationService.ToggleLabels()
|
||
├── 更新 conversation.labels 字段 (mergeConversationLabels)
|
||
├── dispatchConversationEventWithData(EventConversationLabelsUpdated)
|
||
└── ActionCableListener → WebSocket 推送标签变更到前端
|
||
```
|
||
|
||
### 4.4 自动化规则中的标签
|
||
|
||
```
|
||
AutomationRule (model/automation_rule.go)
|
||
└── AutomationAction.ActionType = "add_label"
|
||
└── ActionParams = {"labels": ["billing", "urgent"]}
|
||
|
||
AutomationRuleListener.OnEvent (automation/listener.go)
|
||
├── 接收 EventMessageCreated / EventConversationCreated
|
||
├── ConditionsFilterService 检查规则条件是否匹配
|
||
├── 匹配 → ActionService 执行动作
|
||
│ └── add_label → 更新 conversation.labels
|
||
└── dispatch EventConversationLabelsUpdated
|
||
```
|
||
|
||
### 4.5 前端标签管理
|
||
|
||
```
|
||
LabelBox.vue (dashboard/routes/dashboard/conversation/labels/LabelBox.vue)
|
||
├── 显示当前会话所有标签
|
||
├── 添加/移除标签 → API 调用
|
||
└── useConversationLabels composable
|
||
```
|
||
|
||
---
|
||
|
||
## 五、AI 自动回复
|
||
|
||
### 5.1 架构概览
|
||
|
||
```
|
||
入站消息 EventMessageCreated
|
||
│
|
||
▼
|
||
┌────────────────────────────────┐
|
||
│ AutoReplyListener │
|
||
│ (service/auto_reply_listener.go)│
|
||
└───────────────┬────────────────┘
|
||
│
|
||
┌─────────▼──────────┐
|
||
│ EvaluateRules() │
|
||
│ (auto_reply_rule │
|
||
│ _service.go) │
|
||
└─────────┬──────────┘
|
||
│
|
||
┌───────────────┼───────────────┐
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
Static Mode LLM Mode Mixed Mode
|
||
(固定文本回复) (LLM 生成回复) (LLM + 固定文本)
|
||
│ │ │
|
||
│ ┌──────▼──────┐ │
|
||
│ │ LLM Provider │ │
|
||
│ │ (RAG 知识库) │ │
|
||
│ └──────┬──────┘ │
|
||
│ │ │
|
||
└───────────────┼───────────────┘
|
||
▼
|
||
MessageService.Create()
|
||
(outgoing message)
|
||
│
|
||
▼
|
||
MessageDeliveryWorker
|
||
→ 渠道发送
|
||
```
|
||
|
||
### 5.2 AutoReplyListener 触发链路
|
||
|
||
`backend/internal/service/auto_reply_listener.go`
|
||
|
||
```
|
||
AutoReplyListener.OnEvent(ctx, event) (L62)
|
||
│
|
||
├── 过滤:仅处理 EventMessageCreated / EventMessageIncoming
|
||
├── 过滤:仅处理 sender_type = "Contact" 的入站消息
|
||
├── 加载 Conversation(检查是否已 resolved → 跳过)
|
||
├── fetchRecentMessages — 取最近 10 条消息作为上下文 (L205)
|
||
│
|
||
├── 构建 AutoReplyEvaluationContext {
|
||
│ AccountID, InboxID, ConversationID,
|
||
│ MessageContent, PreviousMessages,
|
||
│ ConversationStatus, Language
|
||
│ }
|
||
│
|
||
├── AutoReplyRuleService.EvaluateRules(ctx, evalCtx) (auto_reply_rule_service.go)
|
||
│ ├── 按 inbox_id 查找 active 状态的 auto-reply rules
|
||
│ ├── 逐条评估 conditions(关键词匹配 / 正则 / 消息长度 / 时间窗口)
|
||
│ ├── 按 priority 排序,返回第一个匹配的 rule
|
||
│ └── 根据 rule.Mode 生成回复内容:
|
||
│ ├── Static: 直接返回 rule.ResponseText
|
||
│ ├── LLM: 调用 LLM Provider 生成回复(可带 RAG 检索)
|
||
│ └── Mixed: LLM 生成 + 固定文本拼接
|
||
│
|
||
├── 检查 OneTimeOnly — 该规则是否已对此会话触发过 (L225)
|
||
│
|
||
├── 若有 DelaySeconds → 异步 goroutine 延迟发送 (L137)
|
||
│
|
||
└── sendAutoReply(ctx, event, conversation, result) (L151)
|
||
├── 解析 inbox 关联的 AgentBot 作为 sender
|
||
├── 构建 CreateMessageRequest{
|
||
│ Content: replyContent,
|
||
│ MessageType: "outgoing",
|
||
│ SenderType: "agent_bot",
|
||
│ }
|
||
└── MessageService.Create() → 消息持久化 + 事件分发
|
||
└── → MessageDeliveryWorker → 渠道发送
|
||
```
|
||
|
||
### 5.3 Auto-Reply Rule 数据模型
|
||
|
||
`backend/internal/model/captain_auto_reply_rule.go`
|
||
|
||
```
|
||
CaptainAutoReplyRule {
|
||
AccountID
|
||
AssistantID — 关联 Captain Assistant
|
||
InboxID — 绑定到特定 inbox
|
||
Name, Description
|
||
Status — draft / active / archived
|
||
Mode — static / llm / mixed
|
||
Priority — 数字越小优先级越高
|
||
Conditions — JSON: 关键词/正则/消息属性条件
|
||
ResponseText — static/mixed 模式的固定回复文本
|
||
LLMPromptOverride — LLM 模式的自定义 prompt
|
||
DelaySeconds — 延迟发送秒数
|
||
OneTimeOnly — 是否只触发一次
|
||
}
|
||
```
|
||
|
||
### 5.4 Captain Assistant
|
||
|
||
Captain 是 GoChat 的 AI 助手框架,提供 LLM 能力:
|
||
|
||
```
|
||
CaptainAssistant (model/captain_assistant.go)
|
||
├── 关联一个 LLM Provider (OpenAI / DeepSeek / 自定义)
|
||
├── 关联 RAG 文档库 (CaptainDocument)
|
||
├── 关联 Scenario(场景化 prompt 模板)
|
||
└── 关联 Auto-Reply Rules
|
||
|
||
CaptainAssistantHandler (handler/api/v1/captain_assistant_handler.go)
|
||
├── CRUD assistant
|
||
├── 测试 assistant (发送测试消息)
|
||
└── 生成回复 (直接调用 LLM)
|
||
|
||
CaptainConversationHandler (handler/api/v1/captain_conversation_handler.go)
|
||
├── AI 参与会话 — Captain 读取会话上下文 + RAG 检索 → 生成建议回复
|
||
└── 也可直接发送 AI 回复到会话
|
||
```
|
||
|
||
### 5.5 Copilot(Agent 辅助)
|
||
|
||
Copilot 是给人工 agent 用的 AI 辅助工具,不会自动发送回复:
|
||
|
||
```
|
||
CopilotHandler (handler/api/v1/copilot_handler.go)
|
||
├── POST /copilot/suggest — 根据会话上下文生成建议回复
|
||
├── POST /copilot/rephrase — 改写 agent 输入的文本
|
||
└── POST /copilot/summarize — 总结会话
|
||
|
||
CopilotContainer.vue (前端侧边栏)
|
||
├── Agent 在侧边栏与 Copilot 交互
|
||
├── Copilot 调用 LLM + RAG 生成建议
|
||
└── Agent 确认后手动发送(不自动发送)
|
||
```
|
||
|
||
### 5.6 RAG 知识检索
|
||
|
||
```
|
||
RAGHandler (handler/api/v1/rag_handler.go)
|
||
├── 上传文档 → 向量化 → 存入 pgvector
|
||
├── 检索:query 向量化 → pgvector 相似度搜索 → 返回 top-k 文档片段
|
||
└── 在 LLM 调用时注入检索到的上下文
|
||
|
||
流程:
|
||
用户消息 → 向量化 → pgvector 检索相关文档 → 注入 LLM prompt → 生成回复
|
||
```
|
||
|
||
---
|
||
|
||
## 六、完整消息生命周期
|
||
|
||
```
|
||
客户 GoChat 后端 Agent 前端
|
||
│ │ │
|
||
│ 1. 发送消息 │ │
|
||
│ ──────────────────────► │ │
|
||
│ 2. Webhook 接收 │
|
||
│ 3. Provider 解析 │
|
||
│ 4. IncomingPersister 持久化 │
|
||
│ 5. Dispatcher 广播事件 │
|
||
│ │ 6. WebSocket 推送 │
|
||
│ │ ────────────────────────────► │
|
||
│ │ 7. Agent 看到消息 │
|
||
│ │ │
|
||
│ 8. AutoReplyListener 检查 │
|
||
│ 9. 匹配规则 → AI 生成回复 │
|
||
│ 10. MessageService.Create() │
|
||
│ 11. MessageDeliveryWorker │
|
||
│ 12. 渠道发送回复 │ │
|
||
│ ◄────────────────────── │ │
|
||
│ │ 13. WebSocket 推送 AI 回复 │
|
||
│ │ ────────────────────────────► │
|
||
│ │ 14. Agent 看到 AI 回复 │
|
||
│ │ │
|
||
│ │ 15. (可选) Agent 手动回复 │
|
||
│ │ ◄──────────────────────────── │
|
||
│ 16. MessageService.Create() │
|
||
│ 17. Provider.SendMessage() │
|
||
│ 18. 渠道发送回复 │ │
|
||
│ ◄────────────────────── │ │
|
||
│ │ │
|
||
│ │ 19. AutomationRuleListener │
|
||
│ │ → 匹配规则 → 自动打标签 │
|
||
│ │ → 自动分配 agent │
|
||
│ │ → 自动变更状态 │
|
||
```
|
||
|
||
---
|
||
|
||
## 七、关键文件索引
|
||
|
||
| 组件 | 文件路径 | 关键函数/行号 |
|
||
|---|---|---|
|
||
| Webhook 路由 | `backend/internal/router/router.go` | webhook 路由注册 |
|
||
| Facebook Webhook | `backend/internal/handler/webhook/facebook_webhook.go` | `HandleWebhook` |
|
||
| TikTok Webhook | `backend/internal/handler/webhook/tiktok_webhook.go` | `HandleWebhook` |
|
||
| LINE Webhook | `backend/internal/handler/webhook/line_webhook.go` | `HandleWebhook` |
|
||
| IncomingPersister | `backend/internal/handler/webhook/incoming_persister.go` | `PersistIncoming` L74 |
|
||
| 持久化 Job | `backend/internal/handler/webhook/incoming_persister_jobs.go` | `providerIncomingMessagePersistJob` L24 |
|
||
| Dispatcher | `backend/internal/channel/dispatcher.go` | `Dispatch` L85, `DispatchAsync` L110 |
|
||
| Channel Event | `backend/internal/channel/event.go` | `ChannelEvent` 结构体, EventType 常量 |
|
||
| Facebook Provider | `backend/internal/channel/facebook/provider.go` | `IncomingMessage`, `SendMessage` L352 |
|
||
| Instagram Provider | `backend/internal/channel/facebook/instagram_provider.go` | `IncomingMessage`, `SendMessage` L364 |
|
||
| Message Service | `backend/internal/service/message_service.go` | `Create`, `dispatchMessageEvent` L68 |
|
||
| Message Handler | `backend/internal/handler/api/v1/message_handler.go` | `Create` |
|
||
| Message Delivery Worker | `backend/internal/service/message_delivery_worker.go` | `EnqueueSendReply`, `SendReply` |
|
||
| AutoReply Listener | `backend/internal/service/auto_reply_listener.go` | `OnEvent` L62, `sendAutoReply` L151 |
|
||
| AutoReply Rule Service | `backend/internal/service/auto_reply_rule_service.go` | `EvaluateRules` |
|
||
| AutoReply Rule Model | `backend/internal/model/captain_auto_reply_rule.go` | `CaptainAutoReplyRule` |
|
||
| Captain Assistant Handler | `backend/internal/handler/api/v1/captain_assistant_handler.go` | CRUD + 测试 |
|
||
| Captain Conversation Handler | `backend/internal/handler/api/v1/captain_conversation_handler.go` | AI 会话参与 |
|
||
| Copilot Handler | `backend/internal/handler/api/v1/copilot_handler.go` | suggest/rephrase/summarize |
|
||
| RAG Handler | `backend/internal/handler/api/v1/rag_handler.go` | 文档上传/检索 |
|
||
| Automation Rule Listener | `backend/internal/automation/listener.go` | `OnEvent` |
|
||
| Automation Action | `backend/internal/model/automation_action.go` | `AutomationAction` L10 |
|
||
| Tag Model | `backend/internal/model/tag.go` | `Tag` L12 |
|
||
| ConversationLabel Model | `backend/internal/model/conversation_label.go` | `ConversationLabel` L11 |
|
||
| Tag Repo | `backend/internal/repository/tag_repo.go` | `DeleteWithAssociations` L54, `RenameConversationLabelText` L70 |
|
||
| ConversationLabel Repo | `backend/internal/repository/conversation_label_repo.go` | CRUD |
|
||
| WebSocket Hub | `backend/internal/ws/hub.go` | `Broadcast` |
|
||
| WS Event Bridge | `backend/internal/wsevent/bridge_listener.go` | `ActionCableListener.OnEvent` L51 |
|
||
| Inbox Serializer | `backend/internal/handler/api/v1/inbox_serializer.go` | `serializeInbox` L21 |
|
||
| Notification Service | `backend/internal/service/notification_delivery_service.go` | 通知投递 |
|
||
| Push Delivery | `backend/internal/service/push_delivery_service.go` | `SendPushNotification` L63 |
|
||
| 前端 Message API | `frontend/app/javascript/dashboard/api/inbox/message.js` | `create` L56 |
|
||
| 前端 ReplyBox | `frontend/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue` | 消息输入框 |
|
||
| 前端 Copilot | `frontend/app/javascript/dashboard/components/copilot/CopilotContainer.vue` | Copilot 侧边栏 |
|