flag92 flag92
博客
发布于 Sun Feb 01 2026 08:00:00 GMT+0800 (中国标准时间)
迁移ChatwootIntercom

从 Intercom 迁移到 Chatwoot 的完整路径

数据导出、字段映射、并行运营、切流时机——本文给出 Intercom 到 Chatwoot 的实战迁移路径,含脚本与陷阱。

为什么迁移#

最常见的三个原因:

  1. Intercom AI seat 价格 $79-$129/座,年付突破 $20k 后老板叫停
  2. 想用 LLM 做深度定制,Intercom Fin 不够灵活
  3. 数据合规(GDPR / 个保法)要求自部署

迁移总览#

导出阶段
1-3 天

映射阶段
3-5 天

并行阶段
2-4 周

切流阶段
1 天

收尾
1 周

Intercom Export API
历史对话

联系人 / 公司 / 标签
自定义字段

知识库 Help Center 文章

字段映射脚本

用户标签 → custom attributes

Macros → canned responses

两边同时跑
分流 10% → 50% → 90%

对比 CSAT / FRT / 自助率

DNS 切换 widget 域名

历史工单全迁回 + 数据校核

导出 Intercom 数据#

1. Conversations#

# 用 Intercom Export API
curl https://api.intercom.io/conversations \
  -H "Authorization: Bearer $INTERCOM_TOKEN" \
  -H "Accept: application/json" \
  > conversations.json

由于 Intercom 的分页是 cursor-based,建议用官方 SDK:

from python_intercom import Client
intercom = Client(personal_access_token=TOKEN)
all_convs = []
for c in intercom.conversations.find_all():
    all_convs.append(c.to_dict())

2. Contacts、Companies、Tags#

逐个 endpoint 拉,存 JSONL。

3. Help Center 文章#

/articles API 返回 Markdown 形式正文,直接保存。

字段映射#

IntercomChatwoot备注
conversation.idsource_id存 Chatwoot 的 additional_attributes
conversation_partsmessagescontent_type 对齐
user.emailcontact.email主键
user.custom_attributescontact.additional_attributesJSON
tagslabels多对多关系
teamsteams手动建对应团队
macroscanned_responses文本相同

导入到 Chatwoot#

Chatwoot 的导入 API 没有 Intercom 那么完善,需要写脚本:

import requests
CW = 'https://support.example.com/api/v1/accounts/1'
H = {'api_access_token': CW_KEY}

def import_contact(c):
    r = requests.post(f'{CW}/contacts', json={
        'name': c['name'],
        'email': c['email'],
        'additional_attributes': c['custom_attributes'],
    }, headers=H)
    return r.json()['payload']['contact']['id']

def import_conversation(conv, contact_id):
    cw_conv = requests.post(f'{CW}/conversations', json={
        'source_id': conv['id'],
        'inbox_id': 1,
        'contact_id': contact_id,
        'status': 'open' if conv['state'] == 'open' else 'resolved',
    }, headers=H).json()
    for part in conv['conversation_parts']['conversation_parts']:
        requests.post(f'{CW}/conversations/{cw_conv["id"]}/messages', json={
            'content': part['body'],
            'message_type': 'incoming' if part['author']['type'] == 'user' else 'outgoing',
        }, headers=H)

注意:导入超过 10 万会话时要批量 + 限速,否则 Chatwoot Postgres 会被拖死。

并行运营策略#

不要直接切。推荐 4 周分流:

分配目标
第 1 周Intercom 90% / Chatwoot 10%发现 Chatwoot 配置问题
第 2 周70% / 30%对比 CSAT
第 3 周40% / 60%做坐席培训
第 4 周0% / 100%切 DNS

实现分流:在网页 Widget 处加 JS:

// 按 user_id hash 决定走哪边
const useNew = parseInt(userId.slice(-2), 16) < 100 * pctNew;
if (useNew) loadChatwootWidget(); else loadIntercomWidget();

切流后的收尾#

  1. 把 Intercom 历史对话标记为「已迁移」并存只读快照
  2. Chatwoot 里给每个迁移的对话加 label「from_intercom」
  3. 一年后再决定是否删除 Intercom 数据(合规留存期)

三个常见坑#

  1. 附件迁移容易漏:Intercom 的图片 URL 有时间签名,过期就 404。迁移时要先下载到 S3
  2. 时区错位:Intercom 用 UTC,Chatwoot 默认按账户时区显示,对话时间戳要做转换
  3. email 大小写:Intercom 严格大小写,Chatwoot 默认小写。导入时统一小写

站内搜索

按 ⌘ K 随时唤起