计划执行与检查节点
executing-plans
按既定实施计划完成工作,保持过程检查和反馈。
intercom【效率与协作】Adds customer messaging and support to a product with Intercom: the Messenger chat widget, user identification, product tours, help center, and the REST API for contacts and messages. Use when a user asks to add in-app chat, install Intercom in a React or Next.js app, secure the Messenger with JWTs, track events for targeting, sync users to Intercom …
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Intercom is a customer messaging platform: live chat, a shared inbox, help center, product tours, in-app messages and the Fin AI agent. Two integration surfaces matter to developers. The Messenger runs in the browser (or iOS/Android) and shows the chat widget for a visitor or logged-in user. The REST API (https://api.intercom.io) runs on your server to manage contacts, conversations and messages with an access token.
Checked against the Intercom developer docs in October 2026. Two older practices are outdated: the HMAC user_hash identity verification is deprecated in favour of JWTs (intercom_user_jwt), and a hand-pasted loader snippet is no longer needed in React apps because the @intercom/messenger-js-sdk package loads the widget.
Your workspace ID (app_id) is in the Intercom URL after apps/. It is public, so a NEXT_PUBLIC_ variable is fine.
npm install @intercom/messenger-js-sdk
// components/IntercomProvider.tsx
'use client'
import { useEffect } from 'react'
import Intercom, { shutdown } from '@intercom/messenger-js-sdk'
type Props = {
user?: { id: string; email: string; name: string; createdAt: number; intercomJwt: string }
}
export function IntercomProvider({ user }: Props) {
useEffect(() => {
Intercom({
app_id: process.env.NEXT_PUBLIC_INTERCOM_APP_ID!,
// api_base: 'https://api-iam.eu.intercom.io', // EU-hosted workspaces; AU: api-iam.au.intercom.io
...(user && {
user_id: user.id,
name: user.name,
email: user.email,
created_at: user.createdAt, // Unix seconds
intercom_user_jwt: user.intercomJwt, // signed on your server, see Step 2
}),
})
return () => shutdown() // clears the session; also call on logout
}, [user?.id])
return null
}
Other exports of the package: update, trackEvent, show, hide, showNewMessage, startTour, showArticle. The plain window.Intercom('boot' | 'update' | 'trackEvent' | 'shutdown', ...) API works the same if you use the JavaScript snippet instead. Anonymous visitors: boot with only app_id.
Without verification anyone can impersonate a user by changing user_id in the browser. Take the Messenger secret key from Settings, Messenger, Security, keep it as INTERCOM_MESSENGER_SECRET, and sign a token on the server for the logged-in user.
// app/api/intercom-jwt/route.ts — server only
import jwt from 'jsonwebtoken'
export function signIntercomJwt(user: { id: string; email: string; name: string }) {
return jwt.sign(
{ user_id: user.id, email: user.email, name: user.name }, // user_id is required
process.env.INTERCOM_MESSENGER_SECRET!,
{ algorithm: 'HS256', expiresIn: '1h' },
)
}
Send exactly one of intercom_user_jwt or user_hash; both together returns HTTP 400. After tests pass, enforce verification in the Messenger security settings.
import { trackEvent, update } from '@intercom/messenger-js-sdk'
update() // after a client-side route change
trackEvent('completed-onboarding', { plan: 'pro', team_size: 5 }) // targets tours, messages, workflows
Create a token under Developer Hub, then use a version header so behaviour does not change under you. Regional workspaces use api.eu.intercom.io or api.au.intercom.io.
const headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.INTERCOM_ACCESS_TOKEN}`,
'Intercom-Version': '2.16',
}
// Create a contact (a user needs an email or an external_id)
const contact = await fetch('https://api.intercom.io/contacts', {
method: 'POST',
headers,
body: JSON.stringify({
role: 'user',
external_id: 'usr_8f31c2',
email: 'maria.keller@brightdesk.io',
name: 'Maria Keller',
custom_attributes: { plan: 'pro', mrr: 49, company_size: 10 },
}),
}).then((r) => r.json())
// Send an in-app message from an admin to that contact
await fetch('https://api.intercom.io/messages', {
method: 'POST',
headers,
body: JSON.stringify({
message_type: 'inapp',
from: { type: 'admin', id: '394051' },
to: { type: 'user', id: contact.id },
body: 'Hi Maria, how are you finding the new dashboard?',
}),
})
Creating a contact and messaging it immediately can return 404 for a moment; retry after a short delay. The official Node client is intercom-client (new IntercomClient({ token })), which has typed methods for the same endpoints. Custom attributes must exist as data attributes in the workspace to be used for segmentation.
Request: "Put the Intercom chat widget in our Next.js app and make sure users can't spoof each other."
Install @intercom/messenger-js-sdk, add IntercomProvider to the root layout inside the authenticated area, add the server function signIntercomJwt, pass its output as intercomJwt, then turn on "Enforce identity verification" in Messenger settings.
Result: the widget appears bottom-right; the user's name and email show in the Intercom inbox, and a request without a valid intercom_user_jwt is rejected.
Request: "When someone upgrades to Pro, update their Intercom contact and record an event."
On the Stripe webhook handler, call the Contacts API (PUT /contacts/{id} with custom_attributes: { plan: 'pro' }) and fire trackEvent('upgraded-to-pro', { seats: 5 }) from the client after checkout. Build a segment on plan = pro.
Result: the contact shows plan: pro in Intercom and the tour or message targeted at that segment starts for the next session.
INTERCOM_ACCESS_TOKEN or the Messenger secret in client code; only app_id is public.shutdown() on logout so the next person on a shared browser does not see the previous conversation.