M1 账户与用户管理 — Chatwoot 功能梳理文档
基于 Chatwoot 源码深度阅读 + CodeGraph 上下文梳理
生成日期:2026-05-22
参照仓库:chatwoot-reference
1. 账户 CRUD + 设置 + 品牌
账户创建(注册时自动建账)
- 功能描述:用户注册时同步创建其第一个 Account,Account 与 User 通过 AccountUser 关联。AccountBuilder 事务性地创建 Account + User + AccountUser(角色默认 administrator)。
- 用户操作流程:
- 用户在注册页面填写账户名、用户名、邮箱、密码
- 系统验证邮箱有效性( disposable / blocked domain 检测)
- 如通过 CAPTCHA 校验,事务性地创建 Account 和 User
- 发送确认邮件;API-only 模式下直接返回 auth token
- 已登录用户点击"添加账户"可创建新账户,自动成为该账户 administrator
- 涉及的API端点:
POST /api/v1/accounts — 创建账户(无需认证)
- 请求参数:
{ account_name, user_full_name, email, password, locale }
- 响应(已认证/API-only):
{ data: { id, email, ... }, meta: { access_token, ... } }
- 响应(未确认注册):
{ email: "user@example.com" }
- 涉及的数据模型:
- Account(
accounts 表):id, name, domain, locale, status, feature_flags, settings, custom_attributes, limits, support_email, auto_resolve_duration, internal_attributes
status enum:active(0), suspended(1)
settings jsonb:包含 auto_resolve_after, auto_resolve_message, auto_resolve_ignore_waiting, audio_transcriptions 等大量配置项(参见 AccountSettingsSchema)
feature_flags bigint:位运算存储(FlagShihTzu)
- 涉及的业务逻辑:
- AccountBuilder(
app/builders/account_builder.rb):事务性创建 Account → User → AccountUser
- Account::SignUpEmailValidationService:邮箱验证(valid_email2 + blocked domain)
- Account::BrandingEnrichmentJob:注册后异步从邮箱域名拉取品牌信息(logo/favicon)
- 涉及的自动化/规则/事件:
before_create :enable_default_features — 根据 InstallationConfig 启用默认 feature flags
after_create_commit :notify_creation — ActionCable 通知
Account::BrandingEnrichmentJob.perform_later — 品牌信息异步填充
AccountSettingsSchema — JSON Schema 校验 settings 字段合法性
- CAPTCHA 验证(
validate_captcha before_action)
- 邮件域名黑名单(
SignUpEmailValidationService.blocked_domains)
- Chatwoot原实现关键代码文件路径:
app/controllers/api/v1/accounts_controller.rb
app/builders/account_builder.rb
app/services/account/sign_up_email_validation_service.rb
app/jobs/account/branding_enrichment_job.rb
app/models/account.rb
app/models/concerns/account_settings_schema.rb
app/models/concerns/featurable.rb
- 版本标注:社区版
账户查看(Show)
- 功能描述:返回当前账户详情,包含 feature flags、settings、limits、品牌信息等。
- 用户操作流程:用户切换到某账户后,前端自动请求账户数据以渲染侧边栏和设置页。
- 涉及的API端点:
GET /api/v1/accounts/:id
- 响应:
{ id, name, domain, locale, features, settings, limits, ... }
- 涉及的数据模型:Account 全字段 +
latest_chatwoot_version(Redis::Alfred)
- 涉及的业务逻辑:
AccountsController#show — 查 Redis 获取最新 Chatwoot 版本号用于版本提示
- 涉及的自动化/规则/事件:Pundit 授权(AccountPolicy#show? → administrator || agent)
- Chatwoot原实现关键代码文件路径:
app/controllers/api/v1/accounts_controller.rb
app/policies/account_policy.rb
- 版本标注:社区版
账户更新(Update)
- 功能描述:管理员更新账户名称、域名、语言、支持邮箱、settings(自动解决配置等)、custom_attributes。
- 用户操作流程:
- 管理员进入 Settings → Account Settings
- 编辑账户名称/域名/locale/support_email
- 编辑 auto_resolve_after、auto_resolve_message 等会话自动解决配置
- 保存
- 涉及的API端点:
PUT /api/v1/accounts/:id
- 请求参数:
{ name, locale, domain, support_email, settings: { auto_resolve_after, ... }, custom_attributes: { ... } }
- 涉及的数据模型:Account 的
name, locale, domain, support_email, settings, custom_attributes
- 涉及的业务逻辑:
- 合并
custom_attributes 和 settings(merge! 策略,非覆盖)
- JSON Schema 校验 settings(
AccountSettingsSchema)
- onboarding_step 步进逻辑:account_details → invite_team
- 涉及的自动化/规则/事件:Pundit(AccountPolicy#update? → 仅 administrator)
- Chatwoot原实现关键代码文件路径:
app/controllers/api/v1/accounts_controller.rb
app/models/concerns/account_settings_schema.rb
app/policies/account_policy.rb
- 版本标注:社区版
账户激活时间更新(Update Active At)
- 功能描述:用户切换账户时更新 AccountUser 的
active_at,用于前端判断当前活跃账户。
- 涉及的API端点:
POST /api/v1/accounts/:id/update_active_at
- 涉及的数据模型:AccountUser
active_at
- 涉及的业务逻辑:直接更新
active_at = Time.now.utc
- Chatwoot原实现关键代码文件路径:
app/controllers/api/v1/accounts_controller.rb
- 版本标注:社区版
账户缓存键(Cache Keys)
- 功能描述:前端轮询获取账户级别缓存键,用于判断数据是否需要刷新。
- 涉及的API端点:
GET /api/v1/accounts/:id/cache_keys
- 涉及的业务逻辑:
CacheKeysHelper#cache_keys_for_account 生成多维缓存键
- Chatwoot原实现关键代码文件路径:
app/controllers/api/v1/accounts_controller.rb, app/helpers/cache_keys_helper.rb
- 版本标注:社区版
2. 用户注册 / 登录 / OAuth
用户注册(邮箱+密码)
- 功能描述:通过 AccountBuilder 创建账户时同步注册用户;独立注册仅通过账户创建入口。Devise Confirmable 模块要求邮箱确认后才能登录。
- 用户操作流程:
- 填写邮箱、密码、全名
- 系统调用 AccountBuilder → User.create! + Account.create! + AccountUser.create!
- 发送确认邮件
- 用户点击邮件链接确认邮箱
- 确认后可正常登录
- 涉及的API端点:
POST /api/v1/accounts(注册入口与账户创建合一)
GET /auth/confirmation?confirmation_token=xxx(Devise 确认回调)
POST /api/v1/resend_confirmation(重发确认邮件)
- 涉及的数据模型:
- User(
users 表):id, name, email, display_name, encrypted_password, provider, uid, confirmation_token, confirmed_at, confirmation_sent_at, unconfirmed_email, reset_password_token, reset_password_sent_at, sign_in_count, current_sign_in_at, current_sign_in_ip, last_sign_in_at, last_sign_in_ip, availability, message_signature, custom_attributes, ui_settings, pubsub_token, tokens, type
- Devise 模块:
:database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, :password_has_required_content
- 涉及的业务逻辑:
- Account::SignUpEmailValidationService:邮箱有效性 + disposable + blocked domain
- AccountBuilder:事务创建 User → Account → AccountUser
- Devise Confirmable:确认邮件 → token 校验 → 设置 confirmed_at
- 涉及的自动化/规则/事件:
- 邮箱确认后才能登录(
DeviseOverrides::SessionsController 检查 confirmed?)
- 密码必须包含数字+字母+特殊字符(
:password_has_required_content)
- Chatwoot原实现关键代码文件路径:
app/builders/account_builder.rb
app/services/account/sign_up_email_validation_service.rb
app/controllers/devise_overrides/confirmations_controller.rb
app/controllers/auth/resend_confirmations_controller.rb
app/models/user.rb
- 版本标注:社区版
用户登录(邮箱+密码 + MFA + SSO)
- 功能描述:支持邮箱密码登录、MFA 二次验证、SSO 一次性令牌登录。基于 DeviseTokenAuth 实现 JWT 式 token 认证(多 token 机制,支持并发多设备)。
- 用户操作流程:
- 用户输入邮箱 + 密码 →
POST /auth/sign_in
- 若启用 MFA,返回
mfa_required 错误,前端引导用户输入 OTP/backup code
- 用户输入
mfa_token → 再次 POST /auth/sign_in 完成 MFA 校验
- 若使用 SSO 登录(
sso_auth_token),直接通过令牌认证
- 成功后返回 auth headers(
access-token, client, uid, expiry)
- 涉及的API端点:
POST /auth/sign_in — 登录
- 请求:
{ email, password } 或 { email, password, mfa_token } 或 { email, sso_auth_token }
- 响应成功:auth headers + 用户 JSON
- 响应 MFA:
{ errors: ["mfa_required"], mfa_required: true }
- 响应未确认:
{ errors: ["user_not_confirmed"] }
- 涉及的数据模型:User
email, encrypted_password, otp_required_for_login, otp_secret, confirmed_at, provider
- 涉及的业务逻辑:
- DeviseOverrides::SessionsController:
find_user_for_authentication:邮箱 + 密码校验
handle_mfa_verification:Mfa::AuthenticationService 校验 OTP 或 backup code
handle_mfa_required:返回 MFA 提示
handle_sso_authentication:SsoAuthenticatable#valid_sso_auth_token?
process_sso_auth_token:SSO token 前置处理
- Mfa::AuthenticationService:OTP / backup code 校验
- SsoAuthenticatable:Redis 管理临时 SSO token(5 分钟有效期)
- 涉及的自动化/规则/事件:
- MFA 启用的用户必须经过二次验证
- SSO auth token 5 分钟过期(Redis::Alfred setex)
- DeviseTokenAuth 多 token 机制:每次登录生成新 token 对(access-token + client)
- Chatwoot原实现关键代码文件路径:
app/controllers/devise_overrides/sessions_controller.rb
app/models/concerns/sso_authenticatable.rb
app/services/mfa/management_service.rb
app/services/mfa/authentication_service.rb
- 版本标注:社区版
用户密码重置
- 功能描述:通过邮箱发送重置密码链接,用户点击链接后设置新密码。
- 用户操作流程:
- 用户在登录页点击"忘记密码"
- 输入邮箱 →
POST /auth/password → 发送重置邮件
- 用户点击邮件中的链接
- 输入新密码 + 确认密码 →
PUT /auth/password → 返回 auth headers
- 涉及的API端点:
POST /auth/password — 请求重置邮件
PUT /auth/password — 执行重置({ reset_password_token, password, password_confirmation })
- 涉及的数据模型:User
reset_password_token, reset_password_sent_at, encrypted_password
- 涉及的业务逻辑:DeviseOverrides::PasswordsController — 标准 Devise 流程 + 返回 auth headers
- Chatwoot原实现关键代码文件路径:
app/controllers/devise_overrides/passwords_controller.rb
- 版本标注:社区版
OAuth 登录(Google OAuth2 / SAML)
- 功能描述:支持 Google OAuth2 和 SAML 作为外部认证提供者。OAuth 回调后查找或创建用户,生成 SSO auth token 重定向到前端登录页完成认证。
- 用户操作流程:
- 用户点击"Google 登录"按钮
- 重定向到 Google OAuth 授权页
- 授权后回调到
/auth/google_oauth2/callback
- 系统查找/创建用户,生成 SSO auth token
- 重定向到前端
/app/login?email=xxx&sso_auth_token=xxx
- 前端用 SSO auth token 调用
POST /auth/sign_in 完成认证
- 涉及的API端点:
GET /auth/google_oauth2 — 发起 OAuth
GET /auth/google_oauth2/callback — OAuth 回调
POST /auth/saml_login — SAML 登录入口(企业版)
- 涉及的数据模型:User
provider, uid(OAuth 用户 provider='google_oauth2', uid=Google sub)
- 涉及的业务逻辑:
- DeviseOverrides::OmniauthCallbacksController:
sign_in_user:找到用户 → 生成 SSO auth token → 重定向到登录页
sign_up_user:创建新用户 → 设置随机密码 → 重定向到登录页
sign_in_user_on_mobile:移动端 deeplink 方式
- SsoAuthenticatable:
generate_sso_auth_token(Redis 5分钟有效期)
- 涉及的自动化/规则/事件:
- OAuth 新用户自动确认邮箱(
skip_confirmation!)
- OAuth 新用户设置随机密码
- 移动端通过 deeplink 跳转
- Chatwoot原实现关键代码文件路径:
app/controllers/devise_overrides/omniauth_callbacks_controller.rb
app/models/concerns/sso_authenticatable.rb
enterprise/app/controllers/api/v1/auth_controller.rb
- 版本标注:社区版(Google OAuth2)/ 企业版(SAML)
Token 验证
- 功能描述:验证当前 access-token 是否有效,用于前端刷新时校验 session。
- 涉及的API端点:
GET /auth/validate_token
- 涉及的业务逻辑:DeviseOverrides::TokenValidationsController — DeviseTokenAuth 标准 + 自定义渲染
- Chatwoot原实现关键代码文件路径:
app/controllers/devise_overrides/token_validations_controller.rb
- 版本标注:社区版
3. AccountUser 多账户角色
AccountUser 关联管理
- 功能描述:一个 User 可属于多个 Account(通过 AccountUser 中间表),每个 AccountUser 独立设定 role(administrator/agent)、availability、auto_offline、custom_role_id、agent_capacity_policy_id。
- 用户操作流程:
- 管理员在 Settings → Agents 列表中邀请/删除/编辑成员
- 用户切换账户时前端调用
update_active_at 更新活跃账户
- 用户可在 Profile 中设置各账户的 availability 和 auto_offline
- 涉及的API端点:
POST /api/v1/accounts/:account_id/agents — 邀请成员
PUT /api/v1/accounts/:account_id/agents/:id — 更新成员角色/availability
DELETE /api/v1/accounts/:account_id/agents/:id — 删除成员
POST /api/v1/accounts/:account_id/agents/bulk_create — 批量邀请
GET /api/v1/accounts/:account_id/agents — 列出成员
POST /api/v1/profile/availability — 更新当前用户在某账户的 availability
POST /api/v1/profile/auto_offline — 更新 auto_offline
PUT /api/v1/profile/set_active_account — 切换活跃账户
- 涉及的数据模型:
- AccountUser(
account_users 表):id, account_id, user_id, role, availability, auto_offline, active_at, inviter_id, custom_role_id, agent_capacity_policy_id
role enum:agent(0), administrator(1)
availability enum:online(0), offline(1), busy(2)
- 索引:
uniq_user_id_per_account_id(account_id + user_id 联合唯一)
- 涉及的业务逻辑:
- AgentBuilder(
app/builders/agent_builder.rb):查找或创建 User → 创建 AccountUser → 发送邀请邮件
- AccountsController#update_active_at:更新 active_at
- ProfilesController#availability / #auto_offline / #set_active_account:各账户独立设置
- 删除 Agent 时:
AccountUser.destroy! → 如果用户无其他账户则删除 User 记录
- 涉及的自动化/规则/事件:
after_create_commit :notify_creation, :create_notification_setting — 创建 AccountUser 时自动创建通知设置
after_destroy :notify_deletion, :remove_user_from_account — 删除时清理
after_save :update_presence_in_redis — availability 变更时更新 Redis 在线状态
- AvailabilityStatusable:用户 availability_status 综合判断(DB availability + Redis online presence + auto_offline)
- Chatwoot原实现关键代码文件路径:
app/models/account_user.rb
app/controllers/api/v1/accounts/agents_controller.rb
app/builders/agent_builder.rb
app/controllers/api/v1/profiles_controller.rb
app/models/concerns/availability_statusable.rb
app/policies/user_policy.rb
- 版本标注:社区版(role=agent/administrator)/ 企业版(custom_role_id, agent_capacity_policy_id)
4. Profile 管理
Profile 查看 / 更新
- 功能描述:用户查看和更新自己的个人信息,包括姓名、邮箱、显示名、消息签名、头像、UI 设置等。
- 用户操作流程:
- 用户点击侧边栏头像 → 进入 Profile 页
- 编辑 name / display_name / email / message_signature / custom_attributes
- 更换头像(上传/删除)
- 修改密码(需输入当前密码验证)
- 重置 access token(用于 API 访问)
- 重发邮箱确认
- 涉及的API端点:
GET /api/v1/profile — 查看
PUT /api/v1/profile — 更新(含密码修改需 current_password)
DELETE /api/v1/profile/avatar — 删除头像
POST /api/v1/profile/resend_confirmation — 重发确认邮件
POST /api/v1/profile/reset_access_token — 重置 access token
POST /api/v1/profile/availability — 更新某账户 availability
POST /api/v1/profile/auto_offline — 更新某账户 auto_offline
PUT /api/v1/profile/set_active_account — 设置活跃账户
- 涉及的数据模型:User
name, display_name, email, message_signature, ui_settings, custom_attributes, avatar(ActiveStorage)
- 涉及的业务逻辑:
- ProfilesController:
update:密码修改需验证 current_password;其他字段直接 assign_attributes + merge custom_attributes
avatar:删除 ActiveStorage attachment
reset_access_token:user.access_token.regenerate_token
- 邮箱变更触发 Devise Confirmable reconfirmation 流程
- 涉及的自动化/规则/事件:
- 邮箱变更需重新确认(unconfirmed_email 机制)
- 密码修改必须验证当前密码
- Chatwoot原实现关键代码文件路径:
app/controllers/api/v1/profiles_controller.rb
app/views/api/v1/profiles/show.json.jbuilder
- 版本标注:社区版
MFA(多因子认证)管理
- 功能描述:用户启用/禁用/验证 TOTP 二步认证,支持 OTP code 和 backup code。
- 用户操作流程:
- 用户在 Profile → Security 页点击"启用 MFA"
- 系统生成 otp_secret → 返回 provisioning URI(QR 码)
- 用户用 Authenticator App 扫码绑定
- 输入 OTP code 验证 →
POST /api/v1/profile/mfa/verify
- 验证成功后启用 MFA,返回 10 个 backup codes
- 可随时重新生成 backup codes 或禁用 MFA(需验证 OTP)
- 涉及的API端点:
GET /api/v1/profile/mfa — 查看 MFA 状态
POST /api/v1/profile/mfa — 启用(生成 otp_secret)
POST /api/v1/profile/mfa/verify — 验证并激活
POST /api/v1/profile/mfa/backup_codes — 重新生成 backup codes
DELETE /api/v1/profile/mfa — 禁用 MFA
- 涉及的数据模型:User
otp_secret(encrypted), otp_required_for_login, otp_backup_codes(encrypted)
- 涉及的业务逻辑:
- Mfa::ManagementService:enable/disable/verify/generate_backup_codes
- Mfa::AuthenticationService:authenticate(OTP 或 backup code)
- backup code 消耗机制:验证后标记为 'XXXXXXXX'(不可重用)
- OTP secret 和 backup codes 使用 ActiveRecord encryption
- 涉及的自动化/规则/事件:
- 全局 MFA 开关:
Chatwoot.mfa_enabled?(环境变量控制)
- 禁用 MFA 需验证当前 OTP/backup code
- backup code 常量时间比较(防 timing attack)
- Chatwoot原实现关键代码文件路径:
app/controllers/api/v1/profile/mfa_controller.rb
app/services/mfa/management_service.rb
app/services/mfa/authentication_service.rb
app/services/mfa/token_service.rb
- 版本标注:社区版
5. JWT 认证 + Devise
DeviseTokenAuth 认证机制
- 功能描述:Chatwoot 使用 DeviseTokenAuth 实现 token-based 认证,而非传统 JWT。每次登录生成一对 token(
access-token + client),通过 HTTP headers 传递。支持多设备并发登录(每个 client 一个 token)。
- 用户操作流程:
- 登录成功后响应 headers 包含
access-token, client, uid, expiry, token-type
- 前端存储 headers,后续请求携带这些 headers
- Token 验证:
GET /auth/validate_token
- Token 过期后自动刷新(DeviseTokenAuth 内置机制)
- 涉及的API端点:
POST /auth/sign_in — 登录
DELETE /auth/sign_out — 登出
GET /auth/validate_token — 验证 token
- Auth headers:
access-token, client, uid, expiry, token-type
- 涉及的数据模型:User
tokens(json 列,存储多 client token 信息)
- 涉及的业务逻辑:
- DeviseTokenAuth 管理多 client token 存储/验证/过期
Api::BaseController#authenticate_user! → DeviseTokenAuth set_user_by_token
Api::BaseController#set_current_user → 设置 Current.user
Api::BaseController#set_current_account → 根据 account_id 参数设置 Current.account + Current.account_user
- 涉及的自动化/规则/事件:
- Token 过期时间 configurable(默认 2 周)
- 每次请求可更新 token(change_headers_on_each_request)
- Chatwoot原实现关键代码文件路径:
app/controllers/api/base_controller.rb
app/controllers/devise_overrides/sessions_controller.rb
app/controllers/devise_overrides/token_validations_controller.rb
config/routes.rb(mount_devise_token_auth_for 'User', at: 'auth')
app/models/user.rb(DeviseTokenAuth::Concerns::User)
- 版本标注:社区版
6. RBAC 权限 + CustomRole(企业版)
内置角色 RBAC
- 功能描述:AccountUser 内置两种角色:administrator(1) 和 agent(0)。各 Policy 类基于
@account_user.role 做授权判断。administrator 有全部权限,agent 权限受限。
- 用户操作流程:管理员在邀请成员时选择角色(administrator / agent / custom_role)。
- 涉及的API端点:
POST /api/v1/accounts/:account_id/agents(role 参数)
PUT /api/v1/accounts/:account_id/agents/:id(可更改 role)
- 涉及的数据模型:AccountUser
role enum(agent:0, administrator:1)
- 涉及的业务逻辑:
- ApplicationPolicy:所有 Policy 的基类,接收
user_context[:account_user] 进行角色判断
- AccountPolicy:show/limits → agent+administrator;update/toggle_deletion/subscription → 仅 administrator
- UserPolicy:create/update/destroy/bulk_create → 仅 administrator
- AgentPolicy:通过 Pundit + AccountPolicy 授权
- 涉及的自动化/规则/事件:Pundit 中间件在每次 controller action 前调用
authorize 方法
- Chatwoot原实现关键代码文件路径:
app/policies/application_policy.rb
app/policies/account_policy.rb
app/policies/user_policy.rb
app/controllers/api/base_controller.rb(check_authorization before_action)
- 版本标注:社区版
CustomRole 自定义角色(企业版)
- 功能描述:企业版允许管理员创建自定义角色(CustomRole),定义细粒度权限(conversation_manage, contact_manage 等),并将 CustomRole 关联到 AccountUser,替代内置 agent 角色提供更精细的权限控制。
- 用户操作流程:
- 管理员进入 Settings → Custom Roles
- 创建自定义角色:填写名称、描述、勾选权限列表
- 在邀请/编辑 Agent 时选择自定义角色
- 涉及的API端点:
GET /api/v1/accounts/:account_id/custom_roles — 列出
POST /api/v1/accounts/:account_id/custom_roles — 创建
GET /api/v1/accounts/:account_id/custom_roles/:id — 查看
PUT /api/v1/accounts/:account_id/custom_roles/:id — 更新
DELETE /api/v1/accounts/:account_id/custom_roles/:id — 删除
- 请求:
{ name, description, permissions: ["conversation_manage", "contact_manage", ...] }
- 涉及的数据模型:
- CustomRole(
custom_roles 表):id, name, description, permissions(array), account_id
- 可用权限列表(PERMISSIONS 常量):
conversation_manage — 管理所有会话
conversation_unassigned_manage — 管理未分配会话并自分配
conversation_participating_manage — 管理参与的会话
contact_manage — 管理联系人
report_manage — 管理报告
knowledge_base_manage — 管理知识库
- AccountUser
custom_role_id(FK → custom_roles)
- 涉及的业务逻辑:
- CustomRolesController:CRUD,依赖 EnterpriseAccountsController(企业版校验)
- 删除 CustomRole 时
account_users.custom_role_id 被 nullify
- 涉及的自动化/规则/事件:
- Feature flag
custom_roles 必须启用
- CustomRolePolicy 全部操作仅 administrator
- Chatwoot原实现关键代码文件路径:
enterprise/app/models/custom_role.rb
enterprise/app/controllers/api/v1/accounts/custom_roles_controller.rb
enterprise/app/policies/custom_role_policy.rb
enterprise/app/controllers/api/v1/accounts/enterprise_accounts_controller.rb
- 版本标注:企业版
7. SAML SSO 设置(企业版)
SAML SSO 配置
- 功能描述:管理员为账户配置 SAML IdP 参数(SSO URL、证书、Entity ID),配置后账户内用户的
provider 字段自动更新为 'saml',强制通过 SAML 认证登录。
- 用户操作流程:
- 管理员进入 Settings → SAML SSO
- 填写 IdP SSO URL、X.509 Certificate、IdP Entity ID、SP Entity ID
- 可选配置 role_mappings(SAML 属性 → Chatwoot 角色映射)
- 保存后,账户用户 provider 字段批量更新为 'saml'
- 涉及的API端点:
GET /api/v1/accounts/:account_id/saml_settings — 查看
POST /api/v1/accounts/:account_id/saml_settings — 创建
PUT /api/v1/accounts/:account_id/saml_settings — 更新
DELETE /api/v1/accounts/:account_id/saml_settings — 删除
POST /api/v1/auth/saml_login — 发起 SAML 登录
- 请求:
{ sso_url, certificate, idp_entity_id, sp_entity_id, role_mappings: {} }
- 涉及的数据模型:
- AccountSamlSettings(
account_saml_settings 表):id, account_id, sso_url, certificate, idp_entity_id, sp_entity_id, role_mappings(json)
- Account
saml_settings(has_one 关联)
- User
provider(更新为 'saml')
- 涉及的业务逻辑:
- SamlSettingsController:CRUD + SAML feature flag 校验 + SSO 全局开关校验
- AccountSamlSettings:
after_create_commit :update_account_users_provider — 批量将账户用户 provider 改为 'saml'
after_destroy_commit :reset_account_users_provider — 批量恢复 provider 为 'email'
- 证书 X.509 校验(
certificate_must_be_valid_x509)
- SP Entity ID 自动生成(
set_sp_entity_id)
certificate_fingerprint:计算证书指纹
- Saml::UpdateAccountUsersProviderJob:批量更新 provider,1000条/批
- Api::V1::AuthController#saml_login:根据邮箱查找 SAML 启用的账户,重定向到
/auth/saml?account_id=xxx
- 涉及的自动化/规则/事件:
- Feature flag
saml 必须启用
- 全局配置
ENABLE_SAML_SSO_LOGIN 必须为 true
- SAML 设置创建/删除触发批量 provider 更新 Job
- SAML 回调 → OmniauthCallbacksController → sign_in_user(生成 SSO auth token)
- role_mappings 可将 SAML 属性映射到 Chatwoot 角色
- Chatwoot原实现关键代码文件路径:
enterprise/app/models/account_saml_settings.rb
enterprise/app/controllers/api/v1/accounts/saml_settings_controller.rb
enterprise/app/controllers/api/v1/auth_controller.rb
enterprise/app/jobs/saml/update_account_users_provider_job.rb
enterprise/app/policies/account_saml_settings_policy.rb
app/controllers/devise_overrides/omniauth_callbacks_controller.rb
- 版本标注:企业版
8. Company 组织管理(企业版)
Company CRUD + 品牌
- 功能描述:企业版提供 Company 模型,用于组织/公司级别管理联系人归属。Company 可设置名称、域名、描述、自定义属性,支持自动从域名拉取 favicon 作为 logo。
- 用户操作流程:
- 管理员/用户进入 Contacts → Companies 页面
- 创建公司:填写名称、域名(可选)、描述
- 编辑/删除公司
- 将联系人关联到公司
- 搜索公司(按名称或域名)
- 涉及的API端点:
GET /api/v1/accounts/:account_id/companies — 列出(分页25/页)
GET /api/v1/accounts/:account_id/companies/search?q=xxx — 搜索
POST /api/v1/accounts/:account_id/companies — 创建
GET /api/v1/accounts/:account_id/companies/:id — 查看
PUT /api/v1/accounts/:account_id/companies/:id — 更新
DELETE /api/v1/accounts/:account_id/companies/:id — 删除(仅 administrator)
DELETE /api/v1/accounts/:account_id/companies/:id/destroy_custom_attributes — 删除自定义属性
- 涉及的数据模型:
- Company(
companies 表):id, account_id, name, domain, description, additional_attributes(jsonb), custom_attributes(jsonb), contacts_count, last_activity_at
- 索引:
(account_id, domain) UNIQUE WHERE domain IS NOT NULL
- 关联:
contacts(has_many, dependent: nullify)
Avatarable — 支持 ActiveStorage avatar + 从域名 favicon 自动拉取
- 涉及的业务逻辑:
- CompaniesController:CRUD + 搜索 + 分页 + 排序(Sift gem: name/domain/created_at/last_activity_at/contacts_count)
after_create_commit :fetch_favicon — 从域名自动拉取 favicon 作为 logo
record_activity_at! — 5分钟 rollup 间隔内不重复更新 last_activity_at
- 品名长度限制(COMPANY_NAME_LENGTH_LIMIT)
- 品域名格式校验 + 账户内唯一
- 涉及的自动化/规则/事件:
- Feature flag
companies 必须启用
- CompanyPolicy:所有用户可 index/show/create/update/search;仅 administrator 可 destroy
- favicon 自动拉取(Avatar::AvatarFromFaviconJob)
- last_activity_at 活动汇总(ACTIVITY_ROLLUP_INTERVAL = 5分钟)
- Chatwoot原实现关键代码文件路径:
enterprise/app/models/company.rb
enterprise/app/controllers/api/v1/accounts/companies_controller.rb
enterprise/app/policies/company_policy.rb
- 版本标注:企业版
9. AgentCapacityPolicy 容量策略(企业版)
容量策略 CRUD
- 功能描述:企业版支持定义 Agent 容量策略(AgentCapacityPolicy),限制每个 Agent 在指定 Inbox 中同时处理的会话数量上限。一个策略可关联多个 Inbox 的容量上限(InboxCapacityLimit),并可分配给多个 AccountUser。
- 用户操作流程:
- 管理员进入 Settings → Agent Capacity Policies
- 创建策略:填写名称、描述、排除规则(exclusion_rules)
- 为策略添加 Inbox 容量限制:选择 Inbox + 设置 conversation_limit
- 将策略分配给特定 Agent
- 编辑/删除策略
- 涉及的API端点:
GET /api/v1/accounts/:account_id/agent_capacity_policies — 列出
POST /api/v1/accounts/:account_id/agent_capacity_policies — 创建
GET /api/v1/accounts/:account_id/agent_capacity_policies/:id — 查看
PUT /api/v1/accounts/:account_id/agent_capacity_policies/:id — 更新
DELETE /api/v1/accounts/:account_id/agent_capacity_policies/:id — 删除
- 子资源:
GET /api/v1/accounts/:account_id/agent_capacity_policies/:policy_id/users — 查看分配的 Agent
POST /api/v1/accounts/:account_id/agent_capacity_policies/:policy_id/users — 分配 Agent
DELETE /api/v1/accounts/:account_id/agent_capacity_policies/:policy_id/users/:id — 取消分配
POST /api/v1/accounts/:account_id/agent_capacity_policies/:policy_id/inbox_limits — 创建 Inbox 容量限制
PUT .../inbox_limits/:id — 更新容量限制值
DELETE .../inbox_limits/:id — 删除容量限制
- 涉及的数据模型:
- AgentCapacityPolicy(
agent_capacity_policies 表):id, account_id, name, description, exclusion_rules(jsonb)
exclusion_rules:{ exclude_older_than_hours: int, excluded_labels: [string] }
- 含排除逻辑:超过指定小时数的会话不计入容量;带特定标签的会话不计入容量
- InboxCapacityLimit(
inbox_capacity_limits 表):id, agent_capacity_policy_id, inbox_id, conversation_limit
- 索引:
(agent_capacity_policy_id, inbox_id) UNIQUE
conversation_limit 必须 >= 0
- AccountUser
agent_capacity_policy_id(FK → agent_capacity_policies)
- 涉及的业务逻辑:
- AgentCapacityPoliciesController:CRUD + 企业版校验
- AgentCapacityPolicies::UsersController:分配/取消 Agent → 更新 AccountUser.agent_capacity_policy_id
- AgentCapacityPolicies::InboxLimitsController:管理各 Inbox 的 conversation_limit
- 涉及的自动化/规则/事件:
- 仅 administrator 可操作(AgentCapacityPolicyPolicy 全操作限 administrator)
- 一个 Inbox 在同一策略下只能有一个容量限制(唯一索引)
- AccountUser 删除时
agent_capacity_policy_id 被 nullify
- Chatwoot原实现关键代码文件路径:
enterprise/app/models/agent_capacity_policy.rb
enterprise/app/models/inbox_capacity_limit.rb
enterprise/app/controllers/api/v1/accounts/agent_capacity_policies_controller.rb
enterprise/app/controllers/api/v1/accounts/agent_capacity_policies/users_controller.rb
enterprise/app/controllers/api/v1/accounts/agent_capacity_policies/inbox_limits_controller.rb
enterprise/app/policies/agent_capacity_policy_policy.rb
db/migrate/20250806140004_add_agent_capacity_policy_to_account_users.rb
- 版本标注:企业版
10. FeatureFlags 功能开关
FeatureFlags 管理
- 功能描述:Account 级别功能开关,通过 FlagShihTzu 位运算存储在
feature_flags bigint 列中。支持按 Account 启用/禁用特定功能,前端根据 feature flags 动态显示/隐藏功能入口。
- 用户操作流程:
- 管理员进入 Settings → Account Features
- 切换功能开关(enable/disable)
- 前端实时响应功能可见性变化
- 涉及的API端点:
- 通过 Account show/update 间接管理(settings 返回 enabled_features / disabled_features)
- Super Admin 可通过 InstallationConfig 设置
ACCOUNT_LEVEL_FEATURE_DEFAULTS
- 涉及的数据模型:
- Account
feature_flags(bigint,位运算存储)
- Featurable concern:
enable_features! / disable_features! / feature_enabled? / all_features / enabled_features / disabled_features
- config/features.yml:定义所有功能开关列表(名称 + 显示名 + 默认启用 + premium 标记)
- 涉及的业务逻辑:
- Featurable(
app/models/concerns/featurable.rb):
enable_default_features:创建 Account 时根据 InstallationConfig 设置默认值
feature_enabled?(name) → 位运算检查
- 功能列表(config/features.yml 关键项):
| Feature |
Display Name |
Default |
Premium |
| inbound_emails |
Inbound Emails |
true |
- |
| channel_email |
Email Channel |
true |
- |
| channel_facebook |
Facebook Channel |
true |
- |
| help_center |
Help Center |
true |
- |
| agent_bots |
Agent Bots |
true |
- |
| macros |
Macros |
true |
- |
| agent_management |
Agent Management |
true |
- |
| team_management |
Team Management |
true |
- |
| inbox_management |
Inbox Management |
true |
- |
| labels |
Labels |
true |
- |
| custom_attributes |
Custom Attributes |
true |
- |
| automations |
Automations |
true |
- |
| campaigns |
Campaigns |
true |
- |
| reports |
Reports |
true |
- |
| crm |
CRM |
true |
- |
| auto_resolve_conversations |
Auto Resolve |
true |
- |
| disable_branding |
Disable Branding |
false |
✅ premium |
| custom_roles |
Custom Roles |
false |
✅ premium |
| sla |
SLA |
false |
✅ premium |
| audit_logs |
Audit Logs |
false |
✅ premium |
| saml |
SAML |
false |
✅ premium |
| companies |
Companies |
false |
✅ premium |
| channel_voice |
Voice Channel |
false |
✅ premium |
| advanced_search |
Advanced Search |
false |
✅ premium |
- 涉及的自动化/规则/事件:
before_create :enable_default_features — Account 创建时设置默认 features
- premium 功能需要企业版许可证
- feature flag 变更触发缓存清除(
after_update_commit :clear_unread_conversation_counts_cache 等条件回调)
- Chatwoot原实现关键代码文件路径:
app/models/concerns/featurable.rb
config/features.yml
app/models/account.rb
- 版本标注:社区版(基础功能)/ 企业版(premium 功能需许可证)
附录:关键数据模型汇总
accounts 表
| 字段 |
类型 |
说明 |
| id |
integer PK |
主键 |
| name |
string NOT NULL |
账户名称 |
| domain |
string(100) |
入站邮件域名 |
| locale |
integer default(en) |
账户语言 |
| status |
integer default(active) |
active(0)/suspended(1) |
| feature_flags |
bigint default(0) |
位运算功能开关 |
| settings |
jsonb |
账户设置(自动解决、Captain等) |
| custom_attributes |
jsonb |
自定义属性(含 onboarding_step) |
| limits |
jsonb |
使用限制 |
| support_email |
string(100) |
支持邮箱 |
| auto_resolve_duration |
integer |
自动解决时长 |
| internal_attributes |
jsonb |
内部属性 |
users 表
| 字段 |
类型 |
说明 |
| id |
integer PK |
主键 |
| name |
string NOT NULL |
用户名 |
| email |
string |
邮箱(唯一) |
| display_name |
string |
显示名 |
| encrypted_password |
string NOT NULL |
加密密码 |
| provider |
string default(email) |
认证提供者(email/google_oauth2/saml) |
| uid |
string NOT NULL |
提供者内ID |
| confirmation_token |
string |
确认令牌 |
| confirmed_at |
datetime |
确认时间 |
| otp_secret |
string(encrypted) |
MFA TOTP secret |
| otp_required_for_login |
boolean default(false) |
MFA 启用标志 |
| otp_backup_codes |
text(encrypted) |
MFA 备用码 |
| availability |
integer default(online) |
online(0)/offline(1)/busy(2) |
| message_signature |
text |
消息签名 |
| custom_attributes |
jsonb |
自定义属性 |
| ui_settings |
jsonb |
UI偏好设置 |
| pubsub_token |
string |
ActionCable token |
| tokens |
json |
DeviseTokenAuth 多 token 存储 |
| type |
string |
用户类型(SuperAdmin等STI) |
account_users 表
| 字段 |
类型 |
说明 |
| id |
bigint PK |
主键 |
| account_id |
bigint FK |
所属账户 |
| user_id |
bigint FK |
所属用户 |
| role |
integer default(agent) |
agent(0)/administrator(1) |
| availability |
integer default(online) |
online(0)/offline(1)/busy(2) |
| auto_offline |
boolean default(true) |
自动离线 |
| active_at |
datetime |
活跃时间 |
| inviter_id |
bigint FK |
邀请人 |
| custom_role_id |
bigint FK |
自定义角色(企业版) |
| agent_capacity_policy_id |
bigint FK |
容量策略(企业版) |
custom_roles 表(企业版)
| 字段 |
类型 |
说明 |
| id |
bigint PK |
主键 |
| account_id |
bigint FK NOT NULL |
所属账户 |
| name |
string |
角色名称 |
| description |
string |
角色描述 |
| permissions |
text array |
权限列表 |
account_saml_settings 表(企业版)
| 字段 |
类型 |
说明 |
| id |
bigint PK |
主键 |
| account_id |
bigint FK NOT NULL |
所属账户 |
| sso_url |
string |
IdP SSO URL |
| certificate |
text |
X.509 Certificate |
| idp_entity_id |
string |
IdP Entity ID |
| sp_entity_id |
string |
SP Entity ID |
| role_mappings |
json |
SAML→角色映射 |
companies 表(企业版)
| 字段 |
类型 |
说明 |
| id |
bigint PK |
主键 |
| account_id |
bigint FK NOT NULL |
所属账户 |
| name |
string NOT NULL |
公司名称 |
| domain |
string |
公司域名(账户内唯一) |
| description |
text |
描述 |
| additional_attributes |
jsonb |
额外属性 |
| custom_attributes |
jsonb |
自定义属性 |
| contacts_count |
integer |
联系人数 |
| last_activity_at |
datetime |
最后活动时间 |
agent_capacity_policies 表(企业版)
| 字段 |
类型 |
说明 |
| id |
bigint PK |
主键 |
| account_id |
bigint FK NOT NULL |
所属账户 |
| name |
string(255) NOT NULL |
策略名称 |
| description |
text |
策略描述 |
| exclusion_rules |
jsonb NOT NULL |
排除规则 |
inbox_capacity_limits 表(企业版)
| 字段 |
类型 |
说明 |
| id |
bigint PK |
主键 |
| agent_capacity_policy_id |
bigint FK NOT NULL |
所属策略 |
| inbox_id |
bigint FK NOT NULL |
所属 Inbox |
| conversation_limit |
integer NOT NULL |
会话容量上限 |
附录:路由汇总