技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
intercom-migration-deep-dive【数据与研究】Use when migrating from Zendesk/Freshdesk/HelpScout to Intercom, bulk-importing contacts, or re-platforming to Intercom with the contacts, conversations, and articles APIs. Trigger with phrases like "migrate to intercom", "intercom migration", "import contacts to intercom", "switch to intercom", "zendesk to intercom", "intercom data import".
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
name: intercom-migration-deep-dive description: | Use when migrating from Zendesk/Freshdesk/HelpScout to Intercom, bulk-importing contacts, or re-platforming to Intercom with the contacts, conversations, and articles APIs. Trigger with phrases like "migrate to intercom", "intercom migration", "import contacts to intercom", "switch to intercom", "zendesk to intercom", "intercom data import". allowed-tools: Read, Write, Edit, Bash(npm:), Bash(node:) version: 1.6.0 license: MIT author: Jeremy Longshore jeremy@intentsolutions.io tags:
Comprehensive guide for migrating to Intercom from other platforms (Zendesk, Freshdesk, HelpScout) or bulk-importing data. Covers contact import, company import, tags, Help Center articles, orchestration, and post-migration validation. The full runnable TypeScript for every phase lives in references/implementation.md; this file carries the workflow and the first-phase skeleton so you can follow it end to end, then drill into the reference for depth.
INTERCOM_ACCESS_TOKENintercom-client SDK installed (npm install intercom-client)All scripts read the workspace access token from the environment — never hard-code it. Create the token in the Intercom Developer Hub (Settings → Developers → your app → Authentication), then:
export INTERCOM_ACCESS_TOKEN="your-workspace-access-token"
import { IntercomClient, IntercomError } from "intercom-client";
const client = new IntercomClient({ token: process.env.INTERCOM_ACCESS_TOKEN! });
| Type | Complexity | Duration | Risk |
|---|---|---|---|
| Contact import | Low | Hours | Low |
| Zendesk/Freshdesk migration | Medium | 1-2 weeks | Medium |
| Full re-platform (with history) | High | 2-4 weeks | High |
| Help Center migration | Medium | Days | Low |
Run the phases in dependency order. Each phase is a standalone function in references/implementation.md; the orchestrator in Step 5 chains them.
external_id/email, then
update or create. Stamp migrated_from + migration_date custom attributes
so rollback can find migrated records. Skeleton below.executeMigration(plan) runs companies → contacts
→ tags → articles with per-phase progress logging.validateMigration(expectedCounts) compares live
counts against source counts (95% threshold for contacts/articles).Contact-import skeleton (full body in the reference):
async function importContacts(contacts: SourceContact[]) {
const stats = { created: 0, updated: 0, failed: 0, errors: [] as any[] };
for (const contact of contacts) {
const existing = await client.contacts.search({
query: { operator: "OR", value: [
{ field: "external_id", operator: "=", value: contact.id },
{ field: "email", operator: "=", value: contact.email },
] },
});
if (existing.data.length > 0) {
await client.contacts.update({ contactId: existing.data[0].id, /* ...attrs */ });
stats.updated++;
} else {
await client.contacts.create({ role: "user", externalId: contact.id, /* ...attrs */ });
stats.created++;
}
}
return stats;
}
See references/implementation.md for the complete error handling, rate limiting, company/tag/article functions, orchestrator, and validation code.
{ created, updated, failed, errors[] } — a
reconciliation record where errors[] carries per-contact { contact_id, email, error } for every failure.executeMigration) prints a per-phase progress log and a
final Migration complete in N minutes line plus the first 10 failed contacts.validateMigration) returns { passed, checks[] } where each
check is { name, expected, actual, passed }, and prints a PASSED/FAILED
summary with an OK/FAIL line per resource.| Issue | Cause | Solution |
|---|---|---|
| 409 Conflict | Duplicate external_id/email | Search before create |
| 429 Rate Limited | Too fast | Add delays between batches |
| 422 Validation | Bad email/data format | Validate data before import |
| Partial migration | Script crashed | Use idempotent operations, re-run |
| Missing conversations | API doesn't support bulk import | Contact Intercom support for import |
Rollback: keep the source system active during migration; only decommission
after validation plus a 2-week parallel run. To reverse, search by
custom_attributes.migration_date and delete migrated contacts in batches — see
the Rollback Procedure in
references/implementation.md.
SourceContact[],
run importContacts() (Step 1), then reconcile against the returned
errors[]. Full function: references/implementation.md.MigrationPlan (contacts,
companies, tags, articles) and run executeMigration(plan) (Step 5), then
validateMigration(expectedCounts) (Step 6). Full orchestrator +
validation: references/implementation.md.migrateArticles(articles, authorId) (Step 4):
references/implementation.md.