Intercom webhooks events
425 plugins, 2,810 skills, 200 agents for Claude Code. Open-source marketplace at tonsofskills.com with the ccpi CLI package manager.
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill intercom-webhooks-eventsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
'Implement Intercom webhook handling and data event tracking.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
6.4 KB, as published. Nobody here has run it
Intercom Webhooks & Events
Overview
Handle incoming Intercom webhooks (notifications) with signature verification and implement outbound data event tracking via the Events API. Incoming webhooks push conversation and contact changes to your endpoint; outbound data events push custom activity into Intercom for segmentation and messaging.
The full, copy-ready code lives in references/; this file walks the workflow at a high level so you can follow it start to finish, then drill in for depth.
Prerequisites
- HTTPS endpoint accessible from internet
- Webhook secret from Intercom Developer Hub
- Access token from Intercom Developer Hub (for outbound data events)
intercom-clientSDK installed- Redis or database for idempotency (recommended)
Authentication
Two distinct credentials, both issued from the Intercom Developer Hub and read from environment variables — never hard-code them:
- Incoming webhooks are verified with
INTERCOM_WEBHOOK_SECRET. Intercom signs every delivery with HMAC-SHA1 in theX-Hub-Signatureheader; you recompute the digest over the raw request body and compare withcrypto.timingSafeEqual. Reject any request that fails or is missing the header. - Outbound data events authenticate with a bearer
INTERCOM_ACCESS_TOKENpassed toIntercomClient.
Instructions
Read the relevant reference file, then use Write/Edit to scaffold the handler into the target project.
- Build the signed endpoint. Create an Express route that captures the raw body (
express.raw), verifies theX-Hub-SignatureHMAC-SHA1 digest againstINTERCOM_WEBHOOK_SECRET, and returns200within 5 seconds — Intercom treats a slower response as a failure. Respond first, process after. See incoming webhooks walkthrough Step 1. - Model the payload. Every delivery is a
notification_eventenvelope carryingtopic,id, anddata.item(the changed resource). Type it so the router is safe. See incoming webhooks walkthrough Step 2. - Route by topic. Dispatch on
notification.topicthrough a handler map; log and no-op unknown topics rather than throwing. Pick topics from the topics reference. See incoming webhooks walkthrough Step 3. - Add idempotency. Intercom retries a failed delivery once after ~1 minute. Guard each
notification.idwith a RedisSET NXlock so retries never double-process; release the lock on failure to allow a genuine retry. See incoming webhooks walkthrough Step 4. - Track outbound events. Submit custom activity with
client.dataEvents.createusing a past-tenseverb-nouneventName, a UnixcreatedAt, the contact's externaluserId, and optionalmetadata. See data events walkthrough Step 5. - Submit in bulk when needed. There is no batch events endpoint — throttle individual
dataEvents.createcalls (e.g. a short delay every 50) and tally succeeded/failed. See data events walkthrough Step 6.
Output
A working integration produces:
- A signed
/webhooks/intercomendpoint that returns200 {"received": true}on valid deliveries and401on missing/invalid signatures. - Per-topic handler execution logged as
Processed <topic>: <id>, with unknown topics logged and skipped. - Idempotent processing — duplicate
notification.iddeliveries are skipped withDuplicate webhook skipped: <id>. - Outbound
dataEvents.createcalls that appear on the contact's Intercom timeline; bulk runs return{ succeeded, failed }counts.
Error Handling
| Issue | Cause | Solution |
|---|---|---|
| Invalid signature | Secret mismatch | Verify secret matches Developer Hub |
| Timeout (5s) | Slow processing | Queue events, respond immediately |
| Duplicate events | Retry delivery | Implement idempotency with Redis |
| Missing topic handler | New topic added | Log unhandled topics, add handler |
| Event rejected (422) | Invalid user_id or event_name | Verify contact exists, use verb-noun naming |
Examples
Verify a signature and respond fast (skeleton — full version in incoming webhooks):
const expected = "sha1=" + crypto
.createHmac("sha1", process.env.INTERCOM_WEBHOOK_SECRET!)
.update(req.body) // raw Buffer, not parsed JSON
.digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(401).json({ error: "Invalid signature" });
}
res.status(200).json({ received: true }); // respond within 5s, then process async
Track a custom data event (full version in data events):
await client.dataEvents.create({
eventName: "completed-onboarding", // past-tense verb-noun
createdAt: Math.floor(Date.now() / 1000),
userId: "user-12345", // contact's external ID
metadata: { steps_completed: 5, plan: "pro" },
});
More: incoming webhooks · data events · webhook topics.
Resources
Next Steps
For performance optimization once the webhook endpoint and event pipeline are live, see the intercom-performance-tuning skill to profile throughput and tune rate limits.