# M2 Inbox与渠道管理 功能梳理文档 > 参照仓库:chatwoot-reference > 产出日期:2026-05-22 > 版本基准:Chatwoot v3.x --- ## 目录 1. [Inbox CRUD + 设置 + 品牌](#1-inbox-crud--设置--品牌) 2. [InboxMember绑定](#2-inboxmember绑定) 3. [Channelable多渠道模式](#3-channelable多渠道模式) 4. [WebWidget渠道](#4-webwidget渠道) 5. [Telegram渠道](#5-telegram渠道) 6. [Facebook / Instagram渠道](#6-facebook--instagram渠道) 7. [WhatsApp渠道](#7-whatsapp渠道) 8. [Email渠道](#8-email渠道) 9. [Twilio SMS / WhatsApp渠道](#9-twilio-sms--whatsapp渠道) 10. [其他渠道(SMS、Line、Twitter、TikTok、API)](#10-其他渠道smsline-twitter-tiktok-api) 11. [Webhook回调(外部事件推送)](#11-webhook回调外部事件推送) 12. [OAuth刷新 / Reauthorizable](#12-oauth刷新--reauthorizable) 13. [企业版InboxCapacity](#13-企业版inboxcapacity) --- ## 1. Inbox CRUD + 设置 + 品牌 ### 功能描述 Inbox(收件箱)是 Chatwoot 的核心聚合单元,代表一个对外沟通渠道的入口。每个 Inbox 绑定一个多态 Channel 对象(`channel_type` + `channel_id`),并拥有独立的设置:自动分配、工作时间、CSAT 调查、欢迎语、离线消息、品牌名等。 ### 用户操作流程 1. **创建 Inbox**:管理员进入 Settings → Inboxes → 点击 "Add Inbox",选择渠道类型(WebWidget/Telegram/WhatsApp等),填写渠道配置,系统自动创建 Channel + Inbox 2. **查看 Inbox 列表**:按账户加载所有 Inbox(含 channel、portal、working_hours、avatar) 3. **更新 Inbox 设置**:修改名称、欢迎语、工作时间、CSAT、自动分配、品牌名、时区等;同时可更新底层 Channel 的属性 4. **删除 Inbox**:级联删除 Channel、InboxMember、Conversation、ContactInbox、Campaign 等 5. **查看可分配 Agent**:获取 Inbox 的 assignable_agents(成员 + 管理员) 6. **设置/移除 Agent Bot**:为 Inbox 关联一个 AgentBot(AI/自动回复机器人) 7. **上传/移除 Avatar**:Inbox 支持头像(ActiveStorage attachment) ### 涉及的API端点 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/v1/accounts/{account_id}/inboxes` | 列出所有 Inbox | | POST | `/api/v1/accounts/{account_id}/inboxes` | 创建 Inbox(含 channel 参数) | | GET | `/api/v1/accounts/{account_id}/inboxes/{id}` | 查看单个 Inbox | | PATCH/PUT | `/api/v1/accounts/{account_id}/inboxes/{id}` | 更新 Inbox 设置 + Channel 属性 | | DELETE | `/api/v1/accounts/{account_id}/inboxes/{id}` | 删除 Inbox | | GET | `/api/v1/accounts/{account_id}/inboxes/{id}/assignable_agents` | (已废弃) 可分配 Agent | | GET | `/api/v1/accounts/{account_id}/inboxes/{id}/campaigns` | Inbox 下的 Campaign | | POST | `/api/v1/accounts/{account_id}/inboxes/{id}/avatar` | 移除头像 | | POST | `/api/v1/accounts/{account_id}/inboxes/{id}/set_agent_bot` | 设置 Agent Bot | ### 涉及的数据模型 + 关键字段 - **Inbox** (`inboxes` 表) - `id`, `name` (必填), `account_id` (必填), `channel_type` (多态类型), `channel_id` (多态ID) - `enable_auto_assignment` (默认 true), `enable_email_collect` (默认 true) - `greeting_enabled`, `greeting_message`, `out_of_office_message` - `working_hours_enabled` (默认 false), `timezone` (默认 "UTC") - `csat_survey_enabled` (默认 false), `csat_config` (jsonb: display_type/message/button_text/language/survey_rules) - `allow_messages_after_resolved` (默认 true) - `lock_to_single_conversation` (默认 false) - `sender_name_type` (enum: friendly=0 / professional=1) - `business_name`, `email_address`, `auto_assignment_config` (jsonb) - `portal_id` (关联帮助中心 Portal) - 关联: `has_many :inbox_members`, `has_many :contact_inboxes`, `has_many :conversations`, `has_many :campaigns`, `has_one :agent_bot_inbox`, `has_one :inbox_assignment_policy`, `has_many :webhooks`, `has_many :working_hours`, `belongs_to :channel` (多态, dependent: :destroy) - **WorkingHour** (`working_hours` 表) - `inbox_id`, `day_of_week`, `open_hour`, `open_minutes`, `close_hour`, `close_minutes` - `closed_all_day`, `open_all_day` - **AgentBotInbox** (`agent_bot_inboxes` 表) - `inbox_id`, `agent_bot_id`, `account_id`, `status` (active/inactive) ### 涉及的业务逻辑(service层) - `InboxesController#create` → 事务中先创建 Channel 再创建 Inbox - `InboxesController#update` → 更新 Inbox 参数 + `update_inbox_working_hours` + `update_channel`(如果 channel 参数存在) - `InboxesHelper#validate_email_channel` → 验证 IMAP/SMTP 连接 - `OutOfOffisable` concern → `out_of_office?` / `working_now?` / `create_default_working_hours` / `update_working_hours` - `InboxAgentAvailability` concern → `available_agents`(基于 OnlineStatusTracker 筛选在线成员) ### 涉及的自动化/规则/事件 - `after_create_commit :dispatch_create_event` → 发布 `INBOX_CREATED` 事件 - `after_update_commit :dispatch_update_event` → 发布 `INBOX_UPDATED` 事件 - `after_destroy :delete_round_robin_agents` → 清除 Redis Round Robin 队列 - `validate_limit` → 创建前检查账户 Inbox 数量上限(企业版有更细粒度限制) ### Chatwoot原实现关键代码文件路径 - `app/models/inbox.rb` - `app/models/concerns/out_of_offisable.rb` - `app/models/concerns/inbox_agent_availability.rb` - `app/models/working_hour.rb` - `app/models/agent_bot_inbox.rb` - `app/controllers/api/v1/accounts/inboxes_controller.rb` - `app/helpers/api/v1/inboxes_helper.rb` - `app/views/api/v1/accounts/inboxes/*.json.jbuilder` ### 版本标注:社区版 / 企业版 - **社区版**:Inbox CRUD、工作时间、CSAT、AgentBot、Avatar、基本数量限制 - **企业版**:Inbox数量精确限制(PlanUsageAndLimits)、InboxCapacityLimits、Captain Assistant绑定、CSAT模板 --- ## 2. InboxMember绑定 ### 功能描述 InboxMember 将 User(客服/Agent)绑定到 Inbox,形成「哪些Agent可以处理该收件箱的对话」的关系。创建/删除 InboxMember 会自动维护 Round Robin 队列。 ### 用户操作流程 1. **查看 Inbox 成员**:进入 Inbox Settings → 查看已绑定的 Agent 列表 2. **添加成员**:选择 Agent 添加到 Inbox,触发 Round Robin 入队 3. **批量更新成员**:传入完整 user_ids 列表,自动计算增量(新增/移除) 4. **移除成员**:从 Inbox 中移除 Agent,触发 Round Robin 出队 5. **Widget端查看成员**:前端 Widget 可查询 Inbox 的在线成员列表 ### 涉及的API端点 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/v1/accounts/{account_id}/inbox_members/{inbox_id}` | 查看成员列表 | | POST | `/api/v1/accounts/{account_id}/inbox_members/{inbox_id}` | 添加成员 | | PATCH/PUT | `/api/v1/accounts/{account_id}/inbox_members/{inbox_id}` | 批量更新成员 | | DELETE | `/api/v1/accounts/{account_id}/inbox_members/{inbox_id}` | 移除成员 | | GET | `/api/v1/widget/inbox_members` | Widget端查看成员(公开) | ### 涉及的数据模型 + 关键字段 - **InboxMember** (`inbox_members` 表) - `id`, `inbox_id` (必填), `user_id` (必填) - 联合唯一索引: `(inbox_id, user_id)` - `belongs_to :inbox`, `belongs_to :user` ### 涉及的业务逻辑(service层) - `InboxMembersController` → 调用 `@inbox.add_members(user_ids)` / `@inbox.remove_members(user_ids)` - `Inbox#add_members` → 批量创建 `inbox_members` + `update_account_cache` - `Inbox#remove_members` → 批量删除 + `update_account_cache` ### 涉及的自动化/规则/事件 - `InboxMember after_create :add_agent_to_round_robin` → 调用 `AutoAssignment::InboxRoundRobinService#add_agent_to_queue` - `InboxMember after_destroy :remove_agent_from_round_robin` → 调用 `AutoAssignment::InboxRoundRobinService#remove_agent_from_queue` - `Audit::InboxMember` mod → 审计日志记录 ### Chatwoot原实现关键代码文件路径 - `app/models/inbox_member.rb` - `app/models/inbox.rb` (add_members/remove_members) - `app/controllers/api/v1/accounts/inbox_members_controller.rb` - `app/controllers/api/v1/widget/inbox_members_controller.rb` - `app/services/auto_assignment/inbox_round_robin_service.rb` ### 版本标注:社区版 --- ## 3. Channelable多渠道模式 ### 功能描述 Chatwoot 采用多态 + Concern 的设计模式实现多渠道。每个渠道类型(WebWidget/Telegram/Facebook/WhatsApp/Email 等)都是独立的 Channel 模型,通过 `Channelable` concern 统一接入 Inbox。Inbox 通过 `belongs_to :channel, polymorphic: true, dependent: :destroy` 关联,`channel_type` 字段存储类名(如 `'Channel::WebWidget'`),`channel_id` 存储对应表的 PK。 ### 用户操作流程 1. 创建 Inbox 时选择渠道类型 → Controller 根据类型动态创建对应 Channel 模型 2. 更新 Inbox 时可选更新 Channel 属性 → 每个 Channel 模型定义 `EDITABLE_ATTRS` 常量控制可修改字段 3. 删除 Inbox → 级联删除 Channel 记录(`dependent: :destroy_async`) ### 涉及的数据模型 + 关键字段 - **Channelable concern** 核心逻辑: - `validates :account_id, presence: true` - `belongs_to :account` - `has_one :inbox, as: :channel, dependent: :destroy_async, touch: true` - `after_update :create_audit_log_entry` - **Inbox 多态关联**: - `belongs_to :channel, polymorphic: true, dependent: :destroy` - `channel_type` 存储类名如 `'Channel::WebWidget'` - `channel_id` 存储对应表的 PK ### 涉及的业务逻辑(service层) - `InboxesController#channel_type_from_params` → 映射参数类型名到 Channel 类: ```ruby { 'web_widget' => Channel::WebWidget, 'api' => Channel::Api, 'email' => Channel::Email, 'line' => Channel::Line, 'telegram' => Channel::Telegram, 'whatsapp' => Channel::Whatsapp, 'sms' => Channel::Sms } ``` - `InboxesController#create_channel` → 根据 `EDITABLE_ATTRS` 创建 Channel 实例 - `InboxesController#update_channel` → 读取 `EDITABLE_ATTRS`,验证/更新 Channel 属性 - `InboxesController#allowed_channel_types` → 仅允许 `web_widget/api/email/line/telegram/whatsapp/sms` 七种通过此 Controller 创建(Facebook/Twilio/Instagram/TikTok/Twitter 有独立的创建流程) ### Chatwoot原实现关键代码文件路径 - `app/models/concerns/channelable.rb` - `app/models/inbox.rb` (多态 belongs_to) - `app/controllers/api/v1/accounts/inboxes_controller.rb` (create_channel / update_channel) - `app/models/channel/web_widget.rb`, `telegram.rb`, `whatsapp.rb`, `email.rb`, `api.rb`, `sms.rb`, `line.rb`, `facebook_page.rb`, `instagram.rb`, `twilio_sms.rb`, `twitter_profile.rb`, `tiktok.rb` ### 版本标注:社区版(所有渠道模型均在社区版) --- ## 4. WebWidget渠道 ### 功能描述 WebWidget 是 Chatwoot 的核心内置渠道,为网站提供嵌入式聊天窗口。支持自定义外观(颜色/欢迎语/回复时间)、预聊天表单、HMAC验证、域名白名单、邮件回访等。 ### 用户操作流程 1. **创建 WebWidget Inbox**:选择 "Website" 渠道 → 输入网站URL、Widget颜色、欢迎标题/标语 → 生成 `website_token` 2. **配置 Widget**:设置预聊天表单(字段类型/必填/占位符)、HMAC强制验证、允许域名列表、邮件回访 3. **嵌入网站**:将生成的 JS SDK + `website_token` 嵌入目标网站 4. **Portal 关联**:WebWidget 可关联到 Portal(帮助中心),`portals.channel_web_widget_id` ### 涉及的API端点 - 创建/更新通过 InboxesController(channel.type = 'web_widget') - Widget 前端通过 `website_token` 发起对话(`/api/v1/widget/conversations`) ### 涉及的数据模型 + 关键字段 - **Channel::WebWidget** (`channel_web_widgets` 表) - `id`, `account_id` - `website_url` (网站URL), `website_token` (唯一,用于前端SDK标识) - `widget_color` (默认 "#1f93ff"), `welcome_title`, `welcome_tagline` - `reply_time` (enum: in_a_few_minutes / in_a_few_hours / in_a_day) - `pre_chat_form_enabled` (默认 false), `pre_chat_form_options` (jsonb) - `hmac_mandatory` (默认 false), `hmac_token` (唯一,用于身份验证) - `allowed_domains` (域名白名单) - `continuity_via_email` (默认 true,关闭对话后邮件通知) - `feature_flags` (FlagShihTzu 位标志,控制 Widget 功能) ### 涉及的业务逻辑(service层) - Widget SDK 加载 → 通过 `website_token` 定位 Channel → 创建 ContactInbox + Conversation - HMAC 验证 → `hmac_mandatory` 强制前端传递 HMAC 签名 - 预聊天表单 → `pre_chat_form_options` 定义表单字段 ### 涉及的自动化/规则/事件 - 创建时自动生成 `website_token` + `hmac_token`(`has_secure_token`) - Portal 关联 → `portals.channel_web_widget_id` 外键 ### Chatwoot原实现关键代码文件路径 - `app/models/channel/web_widget.rb` - `app/javascript/widget/` (前端SDK) - `app/controllers/api/v1/widget/` (Widget API) - `db/migrate/20240415210313_add_channel_web_widget_to_portals.rb` ### 版本标注:社区版 --- ## 5. Telegram渠道 ### 功能描述 通过 Telegram Bot API 接入,将 Telegram Bot 的消息同步到 Chatwoot Inbox。支持文本、附件发送,支持获取用户头像。 ### 用户操作流程 1. **创建 Telegram Inbox**:输入 Bot Token → 系统验证 Token 有效性 → 自动注册 Webhook 2. **收发消息**:用户在 Telegram 发消息 → Webhook 推送到 Chatwoot → 创建 Conversation → Agent 回复通过 Bot API 发回 Telegram 3. **更新**:可修改 Bot Token(重新验证 + 重设 Webhook) ### 涉及的API端点 - 创建/更新通过 InboxesController(channel.type = 'telegram') - Telegram Webhook: `/webhooks/telegram/{bot_token}` → `Webhooks::TelegramController#process_payload` ### 涉及的数据模型 + 关键字段 - **Channel::Telegram** (`channel_telegram` 表) - `id`, `account_id` - `bot_token` (必填, 唯一, 可加密), `bot_name` - `EDITABLE_ATTRS = [:bot_token]` ### 涉及的业务逻辑(service层) - `Telegram::IncomingMessageService` → 解析 Telegram Webhook payload → 创建/更新 Conversation + Message - `Telegram::SendOnTelegramService` → Agent 回复通过 Bot API 发送 - `Telegram::SendAttachmentsService` → 处理附件发送 - `Telegram::UpdateMessageService` → 更新已发送消息 ### 涉及的自动化/规则/事件 - `before_validation :ensure_valid_bot_token` → 创建时验证 Bot Token 有效(调用 `getMe` API) - `before_save :setup_telegram_webhook` → 自动注册 Telegram Webhook URL ### Chatwoot原实现关键代码文件路径 - `app/models/channel/telegram.rb` - `app/controllers/webhooks/telegram_controller.rb` - `app/services/telegram/incoming_message_service.rb` - `app/services/telegram/send_on_telegram_service.rb` - `app/services/telegram/send_attachments_service.rb` - `app/jobs/webhooks/telegram_events_job.rb` ### 版本标注:社区版 --- ## 6. Facebook / Instagram渠道 ### 功能描述 通过 Facebook Graph API 接入 Facebook Page 消息(Messenger)和 Instagram DM。需要 OAuth 授权获取 Page Access Token,支持 Webhook 接收消息,支持 Reauthorization 机制。 ### 用户操作流程 1. **Facebook 创建**:通过 OAuth 流程 → 选择 Page → 获取 Page Access Token → 自动订阅 Webhook 2. **Instagram 创建**:类似 Facebook OAuth → 获取 Instagram Business Account ID + Access Token 3. **收发消息**:Facebook/Instagram Webhook 推送 → 创建 Conversation → Agent 回复通过 Graph API 发回 4. **Reauthorization**:Token 失效后提示重新授权(Reauthorizable concern) ### 涉及的API端点 - Facebook OAuth: `/api/v1/accounts/{id}/facebook/authorize` - Instagram OAuth: `/api/v1/accounts/{id}/instagram/authorizations` - Facebook Webhook: `/webhooks/facebook` (全局) - Instagram Webhook: `/webhooks/instagram/{instagram_id}` → `Webhooks::InstagramController` - InboxesController 创建 Facebook/Instagram Inbox(通过 OAuth 回调后) ### 涉及的数据模型 + 关键字段 - **Channel::FacebookPage** (`channel_facebook_pages` 表) - `id`, `account_id`, `page_id` (必填, scope唯一), `page_access_token` (加密), `user_access_token` (加密) - `instagram_id` (可选,关联 Instagram Business Account) - `include Reauthorizable` - **Channel::Instagram** (`channel_instagram` 表) - `id`, `account_id`, `instagram_id` (必填, 唯一), `access_token` (加密), `expires_at` - `include Reauthorizable`, `AUTHORIZATION_ERROR_THRESHOLD = 1` ### 涉及的业务逻辑(service层) - `Facebook::SendOnFacebookService` → 通过 Graph API 发送 Messenger 消息 - `Instagram::SendOnInstagramService` / `Instagram::Messenger::SendOnInstagramService` → 发送 Instagram DM - `Instagram::RefreshOauthTokenService` → 刷新 Instagram Access Token - `Channel::FacebookPage#subscribe` / `unsubscribe` → 注册/注销 Facebook Webhook - `Channel::Instagram#subscribe` / `unsubscribe` → 注册/注销 Instagram Webhook ### 涉及的自动化/规则/事件 - `after_create_commit :subscribe` → 自动订阅 Facebook/Instagram Webhook - `before_destroy :unsubscribe` → 删除时注销 Webhook - `Reauthorizable` → Token 失效计数 + 邮件通知 + UI 提示重新授权 ### Chatwoot原实现关键代码文件路径 - `app/models/channel/facebook_page.rb` - `app/models/channel/instagram.rb` - `app/models/concerns/reauthorizable.rb` - `app/controllers/webhooks/instagram_controller.rb` - `app/controllers/api/v1/accounts/instagram/authorizations_controller.rb` - `app/services/facebook/send_on_facebook_service.rb` - `app/services/instagram/send_on_instagram_service.rb` - `app/services/instagram/refresh_oauth_token_service.rb` ### 版本标注:社区版 --- ## 7. WhatsApp渠道 ### 功能描述 支持两种 WhatsApp 提供商:360dialog(默认)和 WhatsApp Cloud API(Meta官方)。创建时需要手机号 + provider配置,自动同步消息模板,自动设置 Webhook。 ### 用户操作流程 1. **创建 WhatsApp Inbox**:选择 Provider → 输入手机号 → 配置 API Key / Webhook Verify Token 2. **Embedded Signup(企业版)**:通过 Meta Embedded Signup 流程一键创建 3. **模板管理**:自动同步 WhatsApp 消息模板 → 用于 Campaign 发送 4. **收发消息**:WhatsApp Webhook 推送 → 创建 Conversation → Agent 回复通过 Provider API 发回 ### 涟及的API端点 - 创建/更新通过 InboxesController(channel.type = 'whatsapp') - WhatsApp Webhook: `/webhooks/whatsapp/{phone_number}` → `Webhooks::WhatsappController` - WhatsApp Health: `/api/v1/accounts/{id}/inboxes/{id}/whatsapp_health` (企业版 WhatsappHealthManagement) ### 涉及的数据模型 + 关键字段 - **Channel::Whatsapp** (`channel_whatsapp` 表) - `id`, `account_id`, `phone_number` (必填, 唯一) - `provider` (enum: default / whatsapp_cloud) - `provider_config` (jsonb: webhook_verify_token, api_key, source 等) - `message_templates` (jsonb), `message_templates_last_updated` - `include Reauthorizable` ### 涉及的业务逻辑(service层) - `Whatsapp::IncomingMessageWhatsappCloudService` / `Whatsapp::IncomingMessageBaseService` → 处理 WhatsApp Webhook payload - `Whatsapp::SendOnWhatsappService` → 通过 Provider API 发送消息 - `Whatsapp::ChannelCreationService` → 创建 WhatsApp Channel - `Whatsapp::WebhookSetupService` / `Whatsapp::WebhookTeardownService` → 设置/注销 Webhook - `Whatsapp::TokenExchangeService` / `Whatsapp::TokenValidationService` → Token 管理 - `Whatsapp::TemplateProcessorService` / `Whatsapp::SyncTemplatesJob` → 模板同步 - `Whatsapp::EmbeddedSignupService` → Meta Embedded Signup 流程 - `Whatsapp::ReauthorizationService` → 360dialog Token 重新授权 - `Whatsapp::PhoneNumberNormalizationService` → 手机号规范化 ### 涉及的自动化/规则/事件 - `after_create :sync_templates` → 创建时同步消息模板 - `after_commit :setup_webhooks, on: :create` → 自动设置 Webhook(条件: `should_auto_setup_webhooks?`) - `before_destroy :teardown_webhooks` → 删除时注销 Webhook - Webhook 签名验证 → `MetaTokenVerifyConcern` (WhatsApp Cloud) - `Reauthorizable` → Token 失效处理 ### Chatwoot原实现关键代码文件路径 - `app/models/channel/whatsapp.rb` - `app/controllers/webhooks/whatsapp_controller.rb` - `app/services/whatsapp/incoming_message_whatsapp_cloud_service.rb` - `app/services/whatsapp/incoming_message_base_service.rb` - `app/services/whatsapp/send_on_whatsapp_service.rb` - `app/services/whatsapp/webhook_setup_service.rb` - `app/services/whatsapp/channel_creation_service.rb` - `app/services/whatsapp/embedded_signup_service.rb` - `app/services/whatsapp/reauthorization_service.rb` - `app/controllers/api/v1/accounts/concerns/whatsapp_health_management.rb` ### 版本标注:社区版(核心功能)/ 企业版(Embedded Signup、WhatsApp Health Dashboard) --- ## 8. Email渠道 ### 功能描述 通过 IMAP + SMTP 接入邮件,将客户邮件同步到 Chatwoot Inbox。支持 IMAP 收件(拉取邮件)和 SMTP 发件(Agent回复通过邮件发出),也支持邮件转发(forward_to_email)。 ### 用户操作流程 1. **创建 Email Inbox**:输入邮箱地址 → 系统生成 `forward_to_email` → 可选配置 IMAP/SMTP 2. **配置 IMAP**:设置 IMAP 地址/端口/SSL/认证/登录凭据 → 验证连接 → 启用 IMAP 收件 3. **配置 SMTP**:设置 SMTP 地址/端口/SSL/认证/域名/登录凭据 → 验证连接 → 启用 SMTP 发件 4. **收发邮件**:IMAP 拉取 → 创建 Conversation → Agent 回复通过 SMTP 发出 ### 涉及的API端点 - 创建/更新通过 InboxesController(channel.type = 'email') - 更新时额外验证 IMAP/SMTP 连接(`InboxesHelper#validate_email_channel`) ### 涉及的数据模型 + 关键字段 - **Channel::Email** (`channel_email` 表) - `id`, `account_id`, `email` (唯一), `forward_to_email` (唯一) - IMAP: `imap_enabled`, `imap_address`, `imap_port`, `imap_login`, `imap_password`, `imap_enable_ssl`, `imap_authentication` - SMTP: `smtp_enabled`, `smtp_address`, `smtp_port`, `smtp_login`, `smtp_password`, `smtp_domain`, `smtp_enable_ssl_tls`, `smtp_enable_starttls_auto`, `smtp_authentication`, `smtp_openssl_verify_mode` - `provider`, `provider_config` (jsonb) - `verified_for_sending` (默认 false) - `EDITABLE_ATTRS` 包含所有 IMAP/SMTP 字段 ### 涉及的业务逻辑(service层) - `Email::SendOnEmailService` → Agent 回复通过 SMTP 发送邮件 - `Imap::FetchService` → 定期通过 IMAP 拉取新邮件 → 创建 Conversation/Message - `InboxesHelper#validate_email_channel` → 创建/更新时验证 IMAP/SMTP 连接 ### 涉及的自动化/规则/事件 - IMAP 拉取 → 定时任务(Scheduler)定期调用 `Imap::FetchService` - SMTP 发件 → Agent 回复触发 `Email::SendOnEmailService` - 验证 → 创建/更新 Email Inbox 时必须验证 IMAP/SMTP 连接 ### Chatwoot原实现关键代码文件路径 - `app/models/channel/email.rb` - `app/services/email/send_on_email_service.rb` - `app/services/imap/fetch_service.rb` - `app/helpers/api/v1/inboxes_helper.rb` - `app/services/imap/` (IMAP 相关) ### 版本标注:社区版 / 企业版(Email Channel Migration - Platform API) --- ## 9. Twilio SMS / WhatsApp渠道 ### 功能描述 通过 Twilio API 接入 SMS 和 WhatsApp 消息。Twilio 渠道有独立的创建流程(不通过 InboxesController),支持 API Key 认证、Messaging Service、语音通话(企业版)。 ### 用户操作流程 1. **创建 Twilio Inbox**:输入 Account SID + Auth Token / API Key → 选择 medium (sms/whatsapp) → 输入手机号或 Messaging Service SID → 系统验证 Twilio 凭据 → 自动设置 Webhook 2. **收发消息**:Twilio Webhook 推送 → 创建 Conversation → Agent 回复通过 Twilio API 发回 3. **模板同步**:WhatsApp 模板可通过 Twilio Content API 同步 ### 涉及的API端点 | 方法 | 路径 | 说明 | |------|------|------| | POST | `/api/v1/accounts/{id}/channels/twilio_channel` | 创建 Twilio Inbox(独立 Controller) | | POST | `/webhooks/twilio/callback` | Twilio 回调 Webhook | ### 涉及的数据模型 + 关键字段 - **Channel::TwilioSms** (`channel_twilio_sms` 表) - `id`, `account_id`, `account_sid` (必填), `auth_token` (必填, 加密), `api_key_sid`, `api_key_secret` - `phone_number`, `messaging_service_sid` - `medium` (enum: sms=0 / whatsapp=1) - `voice_enabled` (默认 false, 企业版语音通话) - `content_templates` (jsonb), `content_templates_last_updated` - `twiml_app_sid` ### 涉及的业务逻辑(service层) - `Twilio::IncomingMessageService` → 处理 Twilio Webhook payload - `Twilio::SendOnTwilioService` → 通过 Twilio API 发送消息 - `Twilio::WebhookSetupService` → 设置 Twilio Webhook URL - `Twilio::DeliveryStatusService` → 处理消息送达状态回调 - `Twilio::TemplateSyncService` → 同步 WhatsApp Content Templates - `Twilio::OneoffSmsCampaignService` → SMS 短信营销 ### 涉及的自动化/规则/事件 - 创建时验证 Twilio 凭据(`authenticate_twilio` → `client.messages.list(limit: 1)`) - 创建 SMS 时自动设置 Webhook(`setup_webhooks` → `Twilio::WebhookSetupService`) ### Chatwoot原实现关键代码文件路径 - `app/models/channel/twilio_sms.rb` - `app/controllers/api/v1/accounts/channels/twilio_channels_controller.rb` - `app/controllers/webhooks/twilio_controller.rb` - `app/services/twilio/incoming_message_service.rb` - `app/services/twilio/send_on_twilio_service.rb` - `app/services/twilio/webhook_setup_service.rb` - `app/services/twilio/template_sync_service.rb` ### 版本标注:社区版(SMS/WhatsApp)/ 企业版(Voice 通话、Twilio CSAT 模板) --- ## 10. 其他渠道(SMS、Line、Twitter、TikTok、API) ### SMS(Bandwidth) - **Channel::Sms** (`channel_sms` 表) - `phone_number` (唯一), `provider` (default), `provider_config` (jsonb: application_id 等) - 通过 Bandwidth API 发送 SMS - Webhook: `/webhooks/sms/{phone_number}` → `Webhooks::SmsController` - **关键文件**: `app/models/channel/sms.rb`, `app/services/sms/` ### Line - **Channel::Line** (`channel_line` 表) - `line_channel_id` (唯一), `line_channel_secret`, `line_channel_token` (加密) - 使用 `line-bot-api` gem - Webhook: `/webhooks/line/{line_channel_id}` → `Webhooks::LineController` - **关键文件**: `app/models/channel/line.rb`, `app/services/line/incoming_message_service.rb`, `app/services/line/send_on_line_service.rb` ### Twitter - **Channel::TwitterProfile** (`channel_twitter_profiles` 表) - `profile_id` (scope唯一), `twitter_access_token` (加密), `twitter_access_token_secret` (加密) - `tweets_enabled` (默认 true) - `before_destroy :unsubscribe` - 注:Twitter API v1.1 已停用,此渠道功能受限 - **关键文件**: `app/models/channel/twitter_profile.rb` ### TikTok - **Channel::Tiktok** (`channel_tiktok` 表) - `business_id` (唯一), `access_token` (加密), `refresh_token` (加密) - `expires_at`, `refresh_token_expires_at` - `include Reauthorizable` - OAuth 授权: `/api/v1/accounts/{id}/tiktok/authorizations` - **关键文件**: `app/models/channel/tiktok.rb`, `app/services/tiktok/`, `app/controllers/webhooks/tiktok_controller.rb` ### API Channel - **Channel::Api** (`channel_api` 表) - `identifier` (唯一, auto token), `hmac_token` (唯一, auto token), `webhook_url` - `hmac_mandatory`, `additional_attributes` (jsonb: agent_reply_time_window 等) - `secret` (auto token, `WebhookSecretable`) - 适合第三方系统通过 API + Webhook 集成 - **关键文件**: `app/models/channel/api.rb`, `app/controllers/api/v1/accounts/inboxes_controller.rb` ### 版本标注 - SMS/Line/Twitter/API: 社区版 - TikTok: 社区版(OAuth + Webhook) --- ## 11. Webhook回调(外部事件推送) ### 功能描述 Chatwoot 支持两类 Webhook: 1. **渠道 Webhook**:外部平台(Telegram/WhatsApp/Facebook等)向 Chatwoot 推送消息事件的回调入口 2. **用户自定义 Webhook**:Chatwoot 向外部系统推送内部事件(对话创建/更新/消息等)的出站 Webhook ### 用户操作流程 1. **渠道 Webhook**:创建渠道时自动注册 → 外部平台推送消息 → WebhookController 接收 → 异步 Job 处理 2. **自定义 Webhook**:管理员创建 Webhook → 选择订阅事件 → 事件触发时 Chatwoot POST 到指定 URL ### 涉及的API端点 **渠道 Webhook(入站)**: | 路径 | 说明 | |------|------| | `/webhooks/telegram/{bot_token}` | Telegram 消息回调 | | `/webhooks/whatsapp/{phone_number}` | WhatsApp 消息回调 | | `/webhooks/line/{line_channel_id}` | Line 消息回调 | | `/webhooks/sms/{phone_number}` | SMS 消息回调 | | `/webhooks/instagram/{instagram_id}` | Instagram 消息回调 | | `/webhooks/tiktok` | TikTok 消息回调 | | `/webhooks/facebook` | Facebook 消息回调 | | `/twilio/callback` | Twilio 回调 | **自定义 Webhook(出站)**: | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/v1/accounts/{id}/webhooks` | 列出 Webhook | | POST | `/api/v1/accounts/{id}/webhooks` | 创建 Webhook | | PATCH | `/api/v1/accounts/{id}/webhooks/{wid}` | 更新 Webhook | | DELETE | `/api/v1/accounts/{id}/webhooks/{wid}` | 删除 Webhook | ### 涉及的数据模型 + 关键字段 - **Webhook** (`webhooks` 表) - `id`, `account_id`, `inbox_id` (可选), `url`, `name`, `secret` (WebhookSecretable) - `subscriptions` (jsonb: 允许的事件列表) - `webhook_type` (enum: account_type=0 / inbox_type=1) - 联合唯一索引: `(account_id, url)` ### 允许的订阅事件 ```ruby ALLOWED_WEBHOOK_EVENTS = %w[ conversation_status_changed conversation_updated conversation_created contact_created contact_updated message_created message_updated webwidget_triggered inbox_created inbox_updated conversation_typing_on conversation_typing_off ] ``` ### 涉及的业务逻辑(service层) - 各渠道 WebhookController → 接收 payload → 异步 Job 处理(如 `Webhooks::TelegramEventsJob`, `Webhooks::WhatsappEventsJob`) - 自定义 Webhook → 事件触发时 `WebhookJob` POST 到用户指定 URL(带 HMAC 签名) - `WebhookSecretable` → 生成/验证 Webhook Secret ### 涉及的自动化/规则/事件 - 渠道创建时自动注册 Webhook(Telegram/WhatsApp/Facebook/Instagram/Twilio) - 渠道删除时自动注销 Webhook - WhatsApp Webhook 签名验证 → `MetaTokenVerifyConcern` ### Chatwoot原实现关键代码文件路径 - `app/controllers/webhooks/` (各渠道 Webhook Controller) - `app/models/webhook.rb` - `app/controllers/api/v1/accounts/webhooks_controller.rb` - `app/models/concerns/webhook_secretable.rb` - `app/jobs/webhooks/` (各渠道异步 Job) ### 版本标注:社区版 --- ## 12. OAuth刷新 / Reauthorizable ### 功能描述 部分渠道(Facebook、Instagram、WhatsApp、TikTok)依赖外部 OAuth Token,Token 可能过期或失效。`Reauthorizable` concern 提供统一机制:计数授权错误 → 达到阈值后标记需要重新授权 → 发邮件通知 → UI 提示重新授权流程。 ### 用户操作流程 1. **正常使用**:Token 有效,消息正常收发 2. **Token 失效**:外部 API 返回授权错误 → `authorization_error!` 计数 +1 3. **达到阈值**:标记 `reauthorization_required?` → 发邮件通知管理员 → UI 显示"需要重新授权"提示 4. **重新授权**:管理员点击重新授权 → 通过 OAuth 流程获取新 Token → `reauthorized!` 清除标记 5. **自动刷新**:Instagram/Google/Microsoft 有 `RefreshOauthTokenService` 自动刷新 Token ### 涉及的数据模型 + 关键字段 - **Reauthorizable concern**: - `reauthorization_required?` → Redis 键检查 - `authorization_error_count` → Redis 计数 - `authorization_error!` → 计数递增 + 阈值判断 - `prompt_reauthorization!` → 设置 Redis 标记 + 发邮件 - `reauthorized!` → 清除 Redis 标记 + 计数 - 使用此 concern 的模型: - `Channel::FacebookPage` (阈值=2) - `Channel::Instagram` (阈值=1) - `Channel::Whatsapp` (阈值=2) - `Channel::Tiktok` (阈值=1) ### 涉及的业务逻辑(service层) - `Instagram::RefreshOauthTokenService` → 自动刷新 Instagram Token - `Google::RefreshOauthTokenService` → 自动刷新 Google Token - `Microsoft::RefreshOauthTokenService` → 自动刷新 Microsoft Token - `Whatsapp::ReauthorizationService` → 360dialog Token 重新授权 - `Tiktok::TokenService` → TikTok Token 管理 ### 涉及的自动化/规则/事件 - `Inbox#dispatch_reauthorization_event` → 发布 `INBOX_UPDATED` 事件(包含 reauthorization_required 变化) - 邮件通知 → `Reauthorizable` 阈值触发时发送邮件给管理员 - `after_update :create_audit_log_entry` (Channelable) → Channel 更新时创建审计日志 ### Chatwoot原实现关键代码文件路径 - `app/models/concerns/reauthorizable.rb` - `app/models/inbox.rb` (dispatch_reauthorization_event) - `app/services/instagram/refresh_oauth_token_service.rb` - `app/services/google/refresh_oauth_token_service.rb` - `app/services/microsoft/refresh_oauth_token_service.rb` - `app/services/whatsapp/reauthorization_service.rb` - `app/services/tiktok/token_service.rb` ### 版本标注:社区版 --- ## 13. 企业版InboxCapacity ### 功能描述 企业版的 Agent Capacity Policy 机制允许为每个 Inbox + Agent 组合设定对话数量上限(`conversation_limit`)。当 Agent 在某 Inbox 的活跃对话数达到上限时,自动分配系统不再将新对话分配给该 Agent。 ### 用户操作流程 1. **创建 Agent Capacity Policy**:定义全局分配容量策略 2. **设置 Inbox 容量限制**:为 Policy 下的每个 Inbox 设定 `conversation_limit` 3. **分配生效**:自动分配时检查 Agent 在该 Inbox 的容量是否已满 ### 涉及的API端点 | 方法 | 路径 | 说明 | |------|------|------| | POST | `/api/v1/accounts/{id}/agent_capacity_policies/{policy_id}/inbox_limits` | 创建 Inbox 容量限制 | | PATCH | `/api/v1/accounts/{id}/agent_capacity_policies/{policy_id}/inbox_limits/{limit_id}` | 更新限制 | | DELETE | `/api/v1/accounts/{id}/agent_capacity_policies/{policy_id}/inbox_limits/{limit_id}` | 删除限制 | ### 涉及的数据模型 + 关键字段 - **InboxCapacityLimit** (`inbox_capacity_limits` 表) - `id`, `agent_capacity_policy_id` (必填), `inbox_id` (必填) - `conversation_limit` (必填, >=0) - 联合唯一索引: `(agent_capacity_policy_id, inbox_id)` - **Enterprise::Concerns::Inbox** → `has_many :inbox_capacity_limits` - **AgentCapacityPolicy** → `has_many :inbox_capacity_limits` - **Inbox#member_ids_with_assignment_capacity** → 企业版覆写,返回有剩余容量的成员 ID ### 涉及的业务逻辑(service层) - `Api::V1::Accounts::AgentCapacityPolicies::InboxLimitsController` → CRUD InboxCapacityLimit - `Inbox#member_ids_with_assignment_capacity` → 社区版返回所有 member_ids,企业版根据容量筛选 - `Enterprise::Account::PlanUsageAndLimits` → `usage_limits` 包含 `inboxes` 数量限制 ### 涉及的自动化/规则/事件 - 创建 InboxCapacityLimit 时验证无重复(同一 Policy + Inbox 只能有一条) - 自动分配时 `member_ids_with_assignment_capacity` 筛选有容量的 Agent - `validate_limit` → 创建 Inbox 时检查账户 Inbox 数量上限 ### Chatwoot原实现关键代码文件路径 - `enterprise/app/models/inbox_capacity_limit.rb` - `enterprise/app/models/enterprise/concerns/inbox.rb` - `enterprise/app/models/enterprise/account/plan_usage_and_limits.rb` - `enterprise/app/controllers/api/v1/accounts/agent_capacity_policies/inbox_limits_controller.rb` - `app/models/concerns/inbox_agent_availability.rb` (社区版 member_ids_with_assignment_capacity) ### 版本标注:**企业版** --- ## 附录:渠道模型对照表 | 渠道 | 模型类 | 表名 | 关键标识字段 | 创建方式 | Reauthorizable | 加密字段 | |------|--------|------|------------|---------|---------------|---------| | WebWidget | Channel::WebWidget | channel_web_widgets | website_token | InboxesController | ❌ | ❌ | | Telegram | Channel::Telegram | channel_telegram | bot_token | InboxesController | ❌ | bot_token | | Facebook | Channel::FacebookPage | channel_facebook_pages | page_id | OAuth回调 | ✅ (阈值2) | page_access_token, user_access_token | | Instagram | Channel::Instagram | channel_instagram | instagram_id | OAuth回调 | ✅ (阈值1) | access_token | | WhatsApp | Channel::Whatsapp | channel_whatsapp | phone_number | InboxesController | ✅ (阈值2) | ❌ (provider_config含API key) | | Email | Channel::Email | channel_email | email | InboxesController | ❌ | imap_password, smtp_password | | Twilio | Channel::TwilioSms | channel_twilio_sms | account_sid+phone_number | TwilioChannelsController | ❌ | auth_token | | SMS | Channel::Sms | channel_sms | phone_number | InboxesController | ❌ | ❌ | | Line | Channel::Line | channel_line | line_channel_id | InboxesController | ❌ | line_channel_secret, line_channel_token | | Twitter | Channel::TwitterProfile | channel_twitter_profiles | account_id+profile_id | OAuth | ❌ | twitter_access_token, twitter_access_token_secret | | TikTok | Channel::Tiktok | channel_tiktok | business_id | OAuth回调 | ✅ (阈值1) | access_token, refresh_token | | API | Channel::Api | channel_api | identifier | InboxesController | ❌ | ❌ | --- ## 附录:Inbox多态类型判断方法 ```ruby # Inbox 模型中的渠道类型判断方法 inbox.web_widget? # Channel::WebWidget inbox.telegram? # Channel::Telegram inbox.facebook? # Channel::FacebookPage inbox.instagram? # Facebook? + channel.instagram_id.present? || Channel::Instagram inbox.whatsapp? # Channel::Whatsapp inbox.email? # Channel::Email inbox.twilio? # Channel::TwilioSms inbox.twilio_whatsapp? # Channel::TwilioSms && medium == 'whatsapp' inbox.sms? # Channel::Sms inbox.twitter? # Channel::TwitterProfile inbox.tiktok? # Channel::Tiktok inbox.api? # Channel::Api # Inbox 通用类型名 inbox.inbox_type # channel.name (如 'WebWidget', 'Telegram', 'Whatsapp' 等) ``` --- ## 附录:Inbox回调Webhook URL生成 ```ruby # Inbox#callback_webhook_url 根据渠道类型生成 Channel::TwilioSms → "#{FRONTEND_URL}/twilio/callback" Channel::Sms → "#{FRONTEND_URL}/webhooks/sms/#{phone_number}" Channel::Line → "#{FRONTEND_URL}/webhooks/line/#{line_channel_id}" Channel::Whatsapp → "#{FRONTEND_URL}/webhooks/whatsapp/#{phone_number}" ```