1. 准备开源客服系统我是用的Chatwoot 可以选择以下开源客服系统作为基础Chatwoot: 开源多语言跟踪和分析支持多渠道客户对接自动化和工作流等。源码Zammad: 现代的开源工单系统。FreeScout: 免费且轻量化的 Help Desk 系统。Chatwoot 移动应用项目常见问题解决方案。2. 创建 Docker 配置文件创建chatwoot目录mkdir chatwoot cd chatwoot # 新建docker挂载的子目录 mkdir -p ./{postgres,redis,app/log,app/tmp,app/storage} # 给chatwoot目录授权 chmod -R 777 chatwoot在chatwoot目录下创建一个docker-compose.yml文件来定义服务version: 3 services: base: base image: chatwoot/chatwoot:latest #container_name: chatwoot-base env_file: env.txt ## Change this file for customized env variables volumes: - ./app/storage:/app/storage - ./app/tmp:/app/tmp - ./app/log:/app/log rails: : *base depends_on: - postgres - redis ports: - 3000:3000 environment: - NODE_ENVproduction - RAILS_ENVproduction - INSTALLATION_ENVdocker entrypoint: docker/entrypoints/rails.sh command: [bundle, exec, rails, s, -p, 3000, -b, 0.0.0.0] sidekiq: : *base depends_on: - postgres - redis environment: - NODE_ENVproduction - RAILS_ENVproduction - INSTALLATION_ENVdocker command: [bundle, exec, sidekiq, -C, config/sidekiq.yml] postgres: image: postgres:14 container_name: chatwoot-postgres restart: always #ports: # - 5432:5432 volumes: - ./postgres:/var/lib/postgresql/data environment: - POSTGRES_DBchatwoot - POSTGRES_USERpostgres # Please provide your own password. - POSTGRES_PASSWORD数据库密码 redis: image: redis:6.2-alpine container_name: chatwoot-redis restart: always command: [sh, -c, redis-server --requirepass \$REDIS_PASSWORD\] env_file: env.txt volumes: - ./redis:/data #ports: # - 6379:6379 # middleware: # build: ./middleware # restart: always # ports: # - 4000:4000 # environment: # - CHATWOOT_BOT_TOKEN你的CHATWOOT机器人token # - CHATWOOT_URLhttp://CHATWOOT的ip:3000 # - RASA_URLhttp://RASA的ip:5005在chatwoot目录下创建一个 env.txt文件来定义服务配置# Learn about the various environment variables at # https://www.chatwoot.com/docs/self-hosted/configuration/environment-variables/#rails-production-variables # Used to verify the integrity of signed cookies. so ensure a secure value is set # SECRET_KEY_BASE should be alphanumeric. Avoid special characters or symbols. # Use rake secret to generate this variable # 用于验证签名cookie的完整性。因此请确保设置了一个安全值 SECRET_KEY_BASE6eONF6WVhCjbsPMOawORdTF0MccxXgheFvklSzH5ud0 # Replace with the URL you are planning to use for your app # 替换你运行的域名或者IP地址 FRONTEND_URLhttps://你的ip:3000 # To use a dedicated URL for help center pages # HELPCENTER_URLhttp://0.0.0.0:3000 # If the variable is set, all non-authenticated pages would fallback to the default locale. # Whenever a new account is created, the default language will be DEFAULT_LOCALE instead of en # DEFAULT_LOCALEen # If you plan to use CDN for your assets, set Asset CDN Host ASSET_CDN_HOST # Force all access to the app over SSL, default is set to false FORCE_SSLfalse # This lets you control new sign ups on your chatwoot installation # true : default option, allows sign ups # false : disables all the end points related to sign ups # api_only: disables the UI for signup, but you can create sign ups via the account apis # 注册选项 # true : 允许注册 # false : 关闭注册 # api_only: 关闭UI上的注册但可以通过API注册 ENABLE_ACCOUNT_SIGNUPfalse # Redis config # Redis 配置 # specify the configs via single URL or individual variables # ref: https://www.iana.org/assignments/uri-schemes/prov/redis # You can also use the following format for the URL: redis://:passwordhost:port/db_number REDIS_URLredis://redis:6379 # If you are using docker-compose, set this variables value to be any string, # which will be the password for the redis service running inside the docker-compose # to make it secure # 设置REDIS的密码建议复杂一点 REDIS_PASSWORD # Redis Sentinel can be used by passing list of sentinel host and ports e,g. sentinel_host1:port1,sentinel_host2:port2 REDIS_SENTINELS # Redis sentinel master name is required when using sentinel, default value is mymaster. # You can find list of master using SENTINEL masters command REDIS_SENTINEL_MASTER_NAME # By default Chatwoot will pass REDIS_PASSWORD as the password value for sentinels # Use the following environment variable to customize passwords for sentinels. # Use empty string if sentinels are configured with out passwords # REDIS_SENTINEL_PASSWORD # Redis premium breakage in heroku fix # enable the following configuration # ref: https://github.com/chatwoot/chatwoot/issues/2420 # REDIS_OPENSSL_VERIFY_MODEnone # Postgres Database config variables # Postgres Database 配置密码复杂一点 # You can leave POSTGRES_DATABASE blank. The default name of # the database in the production environment is chatwoot_production # POSTGRES_DATABASE POSTGRES_HOSTpostgres POSTGRES_USERNAMEpostgres POSTGRES_PASSWORDpostgres RAILS_ENVdevelopment # Changes the Postgres query timeout limit. The default is 14 seconds. Modify only when required. # POSTGRES_STATEMENT_TIMEOUT14s RAILS_MAX_THREADS5 # The email from which all outgoing emails are sent # 下面时SMTP配置可以用来配置邮件通知。具体配置信息建议到你的邮箱服务商那里查看。 # could user either emailyourdomain.com or BrandName emailyourdomain.com MAILER_SENDER_EMAILChatwoot chatwootqq.com SMTP_DOMAINqq.com # Set the value to mailhog if using docker-compose for development environments, # Set the value as localhost or your SMTP address in other environments # If SMTP_ADDRESS is empty, Chatwoot would try to use sendmail(postfix) SMTP_ADDRESS SMTP_PORT SMTP_USERNAME SMTP_PASSWORD # plain,login,cram_md5 SMTP_AUTHENTICATIONlogin SMTP_ENABLE_STARTTLS_AUTOtrue SMTP_DEBUG_OUTPUTtrue # Can be: none, peer, client_once, fail_if_no_peer_cert, see http://api.rubyonrails.org/classes/ActionMailer/Base.html SMTP_OPENSSL_VERIFY_MODEnone RAILS_MAILER_TIMEOUT60 # Comment out the following environment variables if required by your SMTP server # 如果您的SMTP服务器需要请注释掉以下环境变量。 #SMTP_TLSfalse #SMTP_SSLfalse # SMTP_OPEN_TIMEOUT # SMTP_READ_TIMEOUT # Mail Incoming # 下面是连续会话使用的邮箱 # This is the domain set for the reply emails when conversation continuity is enabled MAILER_INBOUND_EMAIL_DOMAIN # Set this to the appropriate ingress channel with regards to incoming emails # 将此设置为适当的接收渠道以接收到电子邮件 # 支持的邮箱 : # Possible values are : # relay for Exim, Postfix, Qmail # mailgun for Mailgun # mandrill for Mandrill # postmark for Postmark # sendgrid for Sendgrid RAILS_INBOUND_EMAIL_SERVICE # Use one of the following based on the email ingress service # Ref: https://edgeguides.rubyonrails.org/action_mailbox_basics.html # Set this to a password of your choice and use it in the Inbound webhook # 根据电子邮件入口服务使用以下其中一个 # 参考: https://edgeguides.rubyonrails.org/action_mailbox_basics.html # 将其设置为您选择的密码并在入站webhook中使用它 RAILS_INBOUND_EMAIL_PASSWORD MAILGUN_INGRESS_SIGNING_KEY MANDRILL_INGRESS_API_KEY # Creating Your Inbound Webhook Instructions for Postmark and Sendgrid: # Inbound webhook URL format: # https://actionmailbox:[YOUR_RAILS_INBOUND_EMAIL_PASSWORD][YOUR_CHATWOOT_DOMAIN.COM]/rails/action_mailbox/[RAILS_INBOUND_EMAIL_SERVICE]/inbound_emails # Note: Replace the values inside the brackets; do not include the brackets themselves. # Example: https://actionmailbox:mYRandomPassword3chatwoot.example.com/rails/action_mailbox/postmark/inbound_emails # For Postmark # Ensure the Include raw email content in JSON payload checkbox is selected in the inbound webhook section. # Storage # 存储信息的形式默认本地 ACTIVE_STORAGE_SERVICElocal # Amazon S3 # documentation参考文档: https://www.chatwoot.com/docs/configuring-s3-bucket-as-cloud-storage S3_BUCKET_NAME AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_REGION # Log settings日志设置 # Disable if you want to write logs to a file RAILS_LOG_TO_STDOUTtrue LOG_LEVELinfo LOG_SIZE500 # Configure this environment variable if you want to use lograge instead of rails logger #LOGRAGE_ENABLEDtrue ### This environment variables are only required if you are setting up social media channels # Facebook # documentation: https://www.chatwoot.com/docs/facebook-setup FB_VERIFY_TOKEN FB_APP_SECRET FB_APP_ID # https://developers.facebook.com/docs/messenger-platform/instagram/get-started#app-dashboard IG_VERIFY_TOKEN # Twitter # documentation: https://www.chatwoot.com/docs/twitter-app-setup TWITTER_APP_ID TWITTER_CONSUMER_KEY TWITTER_CONSUMER_SECRET TWITTER_ENVIRONMENT #slack integration SLACK_CLIENT_ID SLACK_CLIENT_SECRET # Google OAuth GOOGLE_OAUTH_CLIENT_ID GOOGLE_OAUTH_CLIENT_SECRET GOOGLE_OAUTH_CALLBACK_URL ### Change this env variable only if you are using a custom build mobile app ## Mobile app env variables IOS_APP_IDL7YLMN4634.com.chatwoot.app ANDROID_BUNDLE_IDcom.chatwoot.app # https://developers.google.com/android/guides/client-auth (use keytool to print the fingerprint in the first section) ANDROID_SHA256_CERT_FINGERPRINTAC:73:8E:DE:EB:56:EA:CC:10:87:02:A7:65:37:7B:38:D4:5D:D4:53:F8:3B:FB:D3:C6:28:64:1D:AA:08:1E:D8 ### Smart App Banner # https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html # You can find your app-id in https://itunesconnect.apple.com #IOS_APP_IDENTIFIER1495796682 ## Push Notification ## generate a new key value here : https://d3v.one/vapid-key-generator/ # VAPID_PUBLIC_KEY # VAPID_PRIVATE_KEY # # for mobile apps # FCM_SERVER_KEY ### APM and Error Monitoring configurations ## Elastic APM ## https://www.elastic.co/guide/en/apm/agent/ruby/current/getting-started-rails.html # ELASTIC_APM_SERVER_URL # ELASTIC_APM_SECRET_TOKEN ## Sentry # SENTRY_DSN ## Scout ## https://scoutapm.com/docs/ruby/configuration # SCOUT_KEYYOURKEY # SCOUT_NAMEYOURAPPNAME (Production) # SCOUT_MONITORtrue ## NewRelic # https://docs.newrelic.com/docs/agents/ruby-agent/configuration/ruby-agent-configuration/ # NEW_RELIC_LICENSE_KEY # Set this to true to allow newrelic apm to send logs. # This is turned off by default. # NEW_RELIC_APPLICATION_LOGGING_ENABLED ## Datadog ## https://github.com/DataDog/dd-trace-rb/blob/master/docs/GettingStarted.md#environment-variables # DD_TRACE_AGENT_URL # MaxMindDB API key to download GeoLite2 City database # IP_LOOKUP_API_KEY ## Rack Attack configuration ## To prevent and throttle abusive requests # ENABLE_RACK_ATTACKtrue # RACK_ATTACK_LIMIT300 # ENABLE_RACK_ATTACK_WIDGET_APItrue ## Running chatwoot as an API only server ## setting this value to true will disable the frontend dashboard endpoints # CW_API_ONLY_SERVERfalse ## Development Only Config # if you want to use letter_opener for local emails # LETTER_OPENERtrue # meant to be used in github codespaces # WEBPACKER_DEV_SERVER_PUBLIC # If you want to use official mobile app, # the notifications would be relayed via a Chatwoot server ENABLE_PUSH_RELAY_SERVERtrue # Stripe API key STRIPE_SECRET_KEY STRIPE_WEBHOOK_SECRET # Set to true if you want to upload files to cloud storage using the signed url # Make sure to follow https://edgeguides.rubyonrails.org/active_storage_overview.html#cross-origin-resource-sharing-cors-configuration on the cloud storage after setting this to true. DIRECT_UPLOADS_ENABLED #MS OAUTH creds AZURE_APP_ID AZURE_APP_SECRET ## Advanced configurations ## Change these values to fine tune performance # control the concurrency setting of sidekiq # SIDEKIQ_CONCURRENCY10 # AI powered features ## OpenAI key # OPENAI_API_KEY # Housekeeping/Performance related configurations # Set to true if you want to remove stale contact inboxes # contact_inboxes with no conversation older than 90 days will be removed # REMOVE_STALE_CONTACT_INBOX_JOB_STATUSfalse在env.txt文件中配置好以下参数SECRET_KEY_BASE你的系统令牌ley 可以用命令 openssl rand -base64 32 来生成 FRONTEND_URLhttps://你的ip:3000 前端地址,根据实际情况填写 HELPCENTER_URLhttps://你的ip:3000 帮助中心地址,可以和FRONTEND_URL一样 REDIS_URLredis://passwordredis:6379/1 redis://:passwordhost:port/db_number REDIS_PASSWORDredis密码 POSTGRES_HOSTpostgres POSTGRES_USERNAMEpostgres POSTGRES_PASSWORD(数据库密码,需与docker-compose.yaml中的postgres数据库密码保持一致)3. 启动服务通过运行迁移来准备数据库# docker compose 是新版 cli 命令,如果执行不了,就换成 docker-compose# 即 docker-compose run --rm rails bundle exec rails db:chatwoot_preparedocker compose run --rm rails bundle exec rails db:chatwoot_prepareubuntuubuntu:~/chatwoot$ docker compose run --rm rails bundle exec rails db:chatwoot_prepare [] Creating 2/2 ✔ Container chatwoot-postgres-1 Recreated 0.1s ..... fatal: not a git repository (or any of the parent directories): .git Created database chatwoot_production ubuntuubuntu:~/chatwoot$当看到Created database chatwoot_production即表示创建成功,继续执行下面的命令docker-compose down docker-compose up -d备注chatwoot-base-1不会运行显示的是exit状态不影响使用。使用浏览器管理后台访问http://你的ip:3000/注意事项第一次进来先要初始化账号信息设置好系统语言超级管理员后台http://你的ip:3000/super_admin​设置中文:Settings -- Account Setting -- Site language ,下拉找到简体中文创建web收件箱按照步骤正确填写信息后创建创建收件箱最后一步生成 script 代码将生成的js代码放到你的html中最后效果​4. 扩展功能对接邮箱功能在env.txt文件中配置好以下参数# 发送者格式“好日子 123456789qq.com” 或 123456789qq.com MAILER_SENDER_EMAIL好日子 123456789qq.com # SMTP 邮件服务器域名例qq.comgmail.com SMTP_DOMAINcannmax.vip # SMTP 邮件服务器地址例qq邮箱smtp.qq.com谷歌smtp.gmail.com SMTP_ADDRESS # 587TLS或 465SSL SMTP_PORT # 邮箱账号 SMTP_USERNAME # 邮箱密码或授权码根据邮箱服务器规则去填例qq邮箱为邮箱授权码 SMTP_PASSWORD # 邮箱服务器SMTP 认证方式通常为 plain参数有plain,login,cram_md5 SMTP_AUTHENTICATIONlogin # 是否使用TLS协议发送邮件 SMTP_ENABLE_STARTTLS_AUTOtrue # 开启debug调式有些邮箱必须在debug情况下才能使用 SMTP_DEBUG_OUTPUTtrue # 是否有ssl校验 Can be: none, peer, client_once, fail_if_no_peer_cert, see SMTP_OPENSSL_VERIFY_MODEnone #发送等待时长 RAILS_MAILER_TIMEOUT60 # 如果SMTP服务器需要则注释掉以下环境变量 #SMTP_TLSfalse #SMTP_SSLfalse注意如果使用 Gmail 或 QQ 邮箱需要启用“允许低安全性应用访问”或使用授权码而非直接密码。配置中邮箱和密码需与 SMTP 服务一致。自定义机器人1.生成chatwoot机器人token方式一通过超级管理员后台http://你的ip:3000/super_admin生成机器人token方式二通过 Rails控制台创建代理机器人进入rails容器docker exec -it chatwoot-rails-1 sh启动 rails 控制台bundle exec rails c在 Rails 控制台中输入以下命令来创建代理机器人并获取其访问令牌。保存检索到的令牌token因为在调用 chatwoot API 时需要使用它。# 在驻留bot逻辑时指定url # 如果传参了account_id属性来创建帐户bot而不是全局bot bot AgentBot.create!(name: 机器人名, outgoing_url: http://localhost:8000) bot.access_token.token为您的机器人添加头像可选avatar_file Down.download(image url 你的头像图片链接) bot.avatar.attach(io: avatar_file, filename: avatar_file.original_filename, content_type: avatar_file.content_type)通过运行以下命令将 Agent Bot 连接到您的收件箱# 取代的收件箱。首先使用Inbox.findinbox_id查找特定的收件箱 AgentBotInbox.create!(inbox: Inbox.first, agent_bot: bot)2.创建智能机器人对话服务系统我用的是rasa部署文件我已经全部压缩直接运行即可下面是部署文件下载地址https://download.csdn.net/download/ko_10086/90192098注意想更多了解rasa请百度我这里就不细讲了。我的对话模型仅为测试模型如需替换成其它模型将模型下载地址替换重新运行即可​4.测试 rasa服务API使用postman或者Apifox测试curl -X POST http://你的rasa的Ip:5005/webhooks/rest/webhook \ -H Content-Type: application/json \ -d {sender: test_user, message: hello}预期响应[ { recipient_id: test_user, text: Hey! How are you? } ]3.rasa与 chatwoot整合对接在chatwoot目录下创建middleware在middleware目录下创建一个app.py来执行rasa与 chatwoot的交互# middleware/app.py from flask import Flask, request,jsonify import requests import os app Flask(__name__) CHATWOOT_BOT_TOKEN os.getenv(CHATWOOT_BOT_TOKEN) CHATWOOT_URL os.getenv(CHATWOOT_URL) RASA_URL os.getenv(RASA_URL) app.route(/rasa, methods[POST]) def rasa(): data request.get_json() event data.get(event) if message_created event: message_type data[message_type] message data[content] conversation data[conversation][id] contact data[sender][id] account data[account][id] if (message_type incoming): bot_response send_to_bot(contact, message) create_message send_to_chatwoot(account, conversation, bot_response) print(create_message) if automation_event.message_created event: message data[messages][0][content] conversation data[messages][0][conversation_id] contact data[messages][0][sender][id] account data[messages][0][account_id] message_type data[messages][0][message_type] if (message_type 0): bot_response send_to_bot(contact, message) create_message send_to_chatwoot(account, conversation, bot_response) print(create_message) return jsonify({status: success}), 200 def send_to_bot(sender, message): data { sender: sender, message: message } headers {Content-Type: application/json, Accept: application/json} r requests.post(f{RASA_URL}/webhooks/rest/webhook, jsondata, headersheaders) return r.json()[0][text] def send_to_chatwoot(account, conversation, message): data { content: message } url f{CHATWOOT_URL}/api/v1/accounts/{account}/conversations/{conversation}/messages headers {Content-Type: application/json, Accept: application/json, api_access_token: f{CHATWOOT_BOT_TOKEN}} r requests.post(url, jsondata, headersheaders) return r.json() if __name__ __main__: app.run(host0.0.0.0, port4000)在middleware目录下创建一个requirements.txt文件来导入app.py相关工具Flask requests在middleware目录下创建一个Dockerfile文件来构建服务# middleware/Dockerfile FROM python:3.8-slim WORKDIR /app COPY requirements.txt requirements.txt RUN pip install --no-cache-dir -r requirements.txt RUN pip install --upgrade Jinja2 Flask COPY app.py . CMD [python, app.py]在chatwoot目录下的docker-compose.yml文件里加上middleware服务上面已经加上了取消注释即可然后运行如果运行不了就单写一个docker-compose.yml文件来运行middleware服务运行命令docker-compose down docker-compose up -d --build4.测试智能机器人chatwoot的收件箱绑定好上面配置好的机器人​在集成方式里面配置rasa与chatwoot交互的api并选中对应交互事件​​然后去客户端发送消息测试即可如以下这样​还有一种配置rasa与chatwoot交互的api的方式即在Automation配置规则​两种方式都是一样的队列分析和监控http://你chatwoot的ip:3000/monitoring/sidekiq5. 修改前端最新的代码环境node.js 23.11.1 或者以上 npm 10.9.2 或者以上pnpm v10.2.0在package.json文件中添加scripts: { build: vite build },修改vite.config.ts文件build: { rollupOptions: { output: { // [NOTE] when not in library mode, no new keys will be addedd or overwritten // setting dir: isLibraryMode ? public/packs : undefined will not work ...(isLibraryMode ? { dir: public/packs, entryFileNames: chunkInfo { if (chunkInfo.name sdk) { return js/sdk.js; } return [name].js; }, } : { // 这里是添加的打包内容从下面的resolve复制过来即可 vue: vue/dist/vue.esm-bundler.js, components: path.resolve(./app/javascript/dashboard/components), next: path.resolve(./app/javascript/dashboard/components-next), v3: path.resolve(./app/javascript/v3), dashboard: path.resolve(./app/javascript/dashboard), helpers: path.resolve(./app/javascript/shared/helpers), shared: path.resolve(./app/javascript/shared), survey: path.resolve(./app/javascript/survey), widget: path.resolve(./app/javascript/widget), assets: path.resolve(./app/javascript/dashboard/assets), }), inlineDynamicImports: isLibraryMode, // Disable code-splitting for SDK }, }, lib: isLibraryMode ? { entry: path.resolve(__dirname, ./app/javascript/entrypoints/sdk.js), formats: [iife], // IIFE format for single file name: sdk, } : undefined, },安装依赖命令pnpm install打包命令pnpm run build打包后的前端目录./public/vitedocker-compose.yml修改为version: 3 services: base: base image: chatwoot/chatwoot:latest #container_name: chatwoot-base env_file: env.txt ## Change this file for customized env variables volumes: #前端运行目录 - ./app/app/public/vite:/app/public/vite - ./app/storage:/app/storage - ./app/tmp:/app/tmp - ./app/log:/app/log rails: 以下不做修改。。。。。重启docker-compose down docker-compose up -d6. 基于官方二开后的基于chatwoot-4.4.0该版本之后的理应都可以覆盖运行仓库地址GitHub - HZ-PRE/chatwoot: 由chatwoot二开而来 · GitHub准备新增一下字段ALTER TABLE inboxes ADD COLUMN additional_attributes jsonb;二开内容在默认轮询基础上加了另外两种分配规则