From intercom-pack
Manages Intercom contacts: create users/leads, search/filter by attributes, update custom data, merge leads into users. For CRM syncing and segmentation.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin intercom-packThis skill is limited to using the following tools:
Primary workflow for managing Intercom contacts. Covers creating users and leads, searching with filters, updating custom attributes, merging leads into users, and managing tags and segments.
Automates Intercom tasks like listing/searching/managing conversations, contacts, companies, segments, admins via Rube MCP and Composio tools.
Automates Intercom tasks like managing conversations, contacts, companies, segments, admins via Rube MCP and Composio toolkit. Useful for support workflows after OAuth setup.
Creates minimal TypeScript examples for Intercom contacts, conversations, and messages. For starting integrations, testing setups, or learning core API data model.
Share bugs, ideas, or general feedback.
Primary workflow for managing Intercom contacts. Covers creating users and leads, searching with filters, updating custom attributes, merging leads into users, and managing tags and segments.
intercom-install-auth setupimport { IntercomClient } from "intercom-client";
const client = new IntercomClient({
token: process.env.INTERCOM_ACCESS_TOKEN!,
});
// Create an identified user (has external_id)
const user = await client.contacts.create({
role: "user",
externalId: "customer-9001",
email: "alice@acme.com",
name: "Alice Johnson",
phone: "+1-555-0100",
customAttributes: {
plan: "enterprise",
company_size: 500,
signed_up_at: Math.floor(Date.now() / 1000),
},
});
// Response: { type: "contact", id: "6657add46abd...", role: "user", ... }
// Create an anonymous lead (no external_id required)
const lead = await client.contacts.create({
role: "lead",
email: "visitor@example.com",
name: "Website Visitor",
customAttributes: {
landing_page: "/pricing",
utm_source: "google",
},
});
POST to https://api.intercom.io/contacts/search with query filters.
// Simple search by email
const byEmail = await client.contacts.search({
query: {
field: "email",
operator: "=",
value: "alice@acme.com",
},
});
// Compound search: users on enterprise plan who signed up recently
const filtered = await client.contacts.search({
query: {
operator: "AND",
value: [
{ field: "role", operator: "=", value: "user" },
{ field: "custom_attributes.plan", operator: "=", value: "enterprise" },
{ field: "signed_up_at", operator: ">", value: Math.floor(Date.now() / 1000) - 86400 * 30 },
],
},
pagination: { per_page: 50 },
sort: { field: "created_at", order: "descending" },
});
console.log(`Found ${filtered.totalCount} contacts`);
for (const contact of filtered.data) {
console.log(` ${contact.name} (${contact.email}) - plan: ${contact.customAttributes?.plan}`);
}
const updated = await client.contacts.update({
contactId: user.id,
name: "Alice Johnson-Smith",
customAttributes: {
plan: "enterprise_plus",
upgraded_at: Math.floor(Date.now() / 1000),
},
});
When an anonymous lead is identified, merge them into a user contact. The lead's conversation history transfers to the user.
// Lead must have role "lead", user must have role "user"
const merged = await client.contacts.merge({
from: lead.id, // Lead ID (will be deleted)
into: user.id, // User ID (will absorb lead data)
});
console.log(`Merged lead into user: ${merged.id}`);
// The lead's conversations, events, and tags are now on the user
const segments = await client.contacts.listSegments({
contactId: user.id,
});
for (const segment of segments.data) {
console.log(`Segment: ${segment.name} (${segment.id})`);
}
async function* allContacts(client: IntercomClient) {
let startingAfter: string | undefined;
do {
const page = await client.contacts.list({
perPage: 50,
startingAfter,
});
for (const contact of page.data) {
yield contact;
}
startingAfter = page.pages?.next?.startingAfter ?? undefined;
} while (startingAfter);
}
// Stream all contacts
let count = 0;
for await (const contact of allContacts(client)) {
count++;
if (count % 100 === 0) console.log(`Processed ${count} contacts`);
}
| Field | Type | Description |
|---|---|---|
id | string | Intercom-generated unique ID |
external_id | string | Your system's user ID |
role | "user" or "lead" | Contact type |
email | string | Email address |
name | string | Full name |
phone | string | Phone number |
custom_attributes | object | Custom key-value data |
created_at | number | Unix timestamp |
last_seen_at | number | Last activity timestamp |
signed_up_at | number | Signup timestamp |
tags | object | Applied tags list |
companies | object | Associated companies |
location | object | GeoIP location data |
| Error | HTTP Code | Cause | Solution |
|---|---|---|---|
not_found | 404 | Contact ID doesn't exist | Verify with search first |
conflict | 409 | Duplicate external_id or email | Search before creating |
parameter_invalid | 422 | Bad field value or missing required field | Check field types and names |
rate_limit_exceeded | 429 | Over 10,000 req/min (private apps) | Add backoff, batch operations |
merge_not_possible | 400 | Merging user into lead (reversed) | from must be lead, into must be user |
For conversation management, see intercom-core-workflow-b.