Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Deploy Intercom integrations to Vercel, Fly.io, and Cloud Run with proper secrets. Use when deploying Intercom-powered applications to production, configuring platform-specific secrets, or setting up signed webhook endpoints and health checks. Trigger with phrases like "deploy intercom", "intercom Vercel", "intercom production deploy", "intercom Cloud Run", "intercom Fly.io".
.claude/skills/jeremylongshore-intercom-deploy-integration/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 4% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 56% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 58% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 33% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 4% | 0% |
Deploy Intercom-powered applications to Vercel, Fly.io, or Google Cloud Run with proper secret management, signed webhook endpoints, and health checks. The workflow is the same across platforms — provision two secrets, deploy, wire a /health probe, then register the webhook URL — and each platform's copy-ready code lives in references/implementation.md.
vercel, flyctl, or gcloud)Two secrets drive every deployment. INTERCOM_ACCESS_TOKEN authenticates API calls (passed to the SDK as new IntercomClient({ token })); INTERCOM_WEBHOOK_SECRET is the Developer Hub signing secret used to verify inbound webhook payloads (HMAC-SHA1 over the raw body, compared against the X-Hub-Signature header). Store both in the platform's secret store — never hardcode them: vercel env add, fly secrets set, or Cloud Run Secret Manager. A mismatched webhook secret returns 401 Invalid signature; an invalid token surfaces as a degraded health check rather than a hard failure.
Pick the platform that matches your stack. Each step below shows the essential skeleton; open references/implementation.md for the complete webhook handler, vercel.json, fly.toml, Cloud Run deploy script, and shared health-check code.
vercel env add INTERCOM_ACCESS_TOKEN production thenvercel env add INTERCOM_WEBHOOK_SECRET production.
fly secrets set INTERCOM_ACCESS_TOKEN=... INTERCOM_WEBHOOK_SECRET=....--set-secrets.Read the raw request body (disable body parsing), recompute the HMAC-SHA1 signature, and compare with crypto.timingSafeEqual. Return within 5 seconds — queue slower work:
typescriptconst expected = "sha1=" + crypto .createHmac("sha1", process.env.INTERCOM_WEBHOOK_SECRET!) .update(rawBody) .digest("hex"); if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) return res.status(401).end();
Write this to api/webhooks/intercom.ts (Vercel) or the equivalent route. Full handler, including the raw-body read and the Vercel config export, is in the Vercel section of references/implementation.md.
Expose a /health route that calls client.admins.list() and reports healthy / degraded with latency. Edit your platform config to wire it as the liveness probe (fly.toml checks block, or Cloud Run's default). Full code is in the Health Check section of references/implementation.md.
Run the platform deploy command: vercel --prod, fly deploy, or the gcloud run deploy script. Verify with curl https://your-domain.com/health.
In Developer Hub > Webhooks, set the endpoint to https://your-domain.com/api/webhooks/intercom, select topics (see the reference table below), copy the signing secret into your platform secrets, and send a test notification to confirm a 200.
| Topic | Fires When | |-------|-----------| | conversation.user.created | New conversation from contact | | conversation.user.replied | Contact replies | | conversation.admin.replied | Admin replies | | conversation.admin.closed | Conversation closed | | contact.created | New contact created | | contact.signed_up | Lead converts to user | | contact.tag.created | Tag applied to contact | | user.created | New user (legacy topic) |
A successful run produces a deployed service reachable over HTTPS with:
INTERCOM_ACCESS_TOKEN and INTERCOM_WEBHOOK_SECRET stored in the platform'ssecret store (never in source).
200 { "received": true } for validpayloads and 401 for bad signatures.
/health endpoint returning {"status":"healthy","services":{"intercom":{"connected":true,"latencyMs":142}}}.| Issue | Cause | Solution | |-------|-------|----------| | Webhook 401 | Signature mismatch | Verify secret matches Developer Hub | | Cold start timeout | Serverless spin-up | Set min instances > 0 | | Secret not found | Missing config | Verify secrets with platform CLI | | Health check failing | Token invalid in prod | Verify production token | | Webhook delivery fails | 5s timeout exceeded | Queue events, process async |
Start from the Vercel skeleton, then drill into the platform you're shipping to:
bashvercel env add INTERCOM_ACCESS_TOKEN production vercel env add INTERCOM_WEBHOOK_SECRET production vercel --prod
Full end-to-end walkthroughs for Vercel, Fly.io, and Cloud Run — including expected output and how to read a failing test notification — are in references/examples.md.
For webhook payload handling and event-processing patterns after deployment, see the intercom-webhooks-events skill in this pack.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-04 | pass→pass | 11,998 | 10,672 | -11% | 1 | 1 | 0% | 2,054 | 2,565 | +25% | 0 | 0 | — |
case-01 | fail→pass | 23,113 | 23,117 | +0% | 1 | 1 | 0% | 4,914 | 5,124 | +4% | 0 | 0 | — |
case-02 | fail→pass | 22,532 | 26,070 | +16% | 1 | 1 | 0% | 3,564 | 5,559 | +56% | 0 | 0 | — |
case-03 | fail→pass | 20,334 | 26,216 | +29% | 1 | 1 | 0% | 3,960 | 6,244 | +58% | 0 | 0 | — |
case-05 | pass→pass | 11,905 | 8,238 | -31% | 1 | 1 | 0% | 1,312 | 2,157 | +64% | 0 | 0 | — |
case-06 | pass→pass | 14,825 | 15,164 | +2% | 1 | 1 | 0% | 2,732 | 3,311 | +21% | 0 | 0 | — |
case-07 | fail→pass | 15,839 | 17,757 | +12% | 1 | 1 | 0% | 2,857 | 3,812 | +33% | 0 | 0 | — |
case-08 | pass→pass | 17,654 | 17,156 | -3% | 1 | 1 | 0% | 2,135 | 3,208 | +50% | 0 | 0 | — |
case-09 | pass→pass | 12,708 | 8,169 | -36% | 1 | 1 | 0% | 1,206 | 1,849 | +53% | 0 | 0 | — |
case-10 | fail→pass | 70,163 | 2,260 | -97% | 1 | 1 | 0% | 1,798 | 1,864 | +4% | 0 | 0 | — |
case-11 | pass→pass | 24,527 | 7,403 | -70% | 1 | 1 | 0% | 1,047 | 1,766 | +69% | 0 | 0 | — |
case-12 | pass→pass | 5,606 | 8,538 | +52% | 1 | 1 | 0% | 1,032 | 2,085 | +102% | 0 | 0 | — |
case-13 | fail→pass | 7,445 | 8,152 | +9% | 1 | 1 | 0% | 1,405 | 2,001 | +42% | 0 | 0 | — |
case-14 | pass→pass | 6,706 | 7,965 | +19% | 1 | 1 | 0% | 1,149 | 2,036 | +77% | 0 | 0 | — |
case-15 | pass→pass | 12,618 | 1,947 | -85% | 1 | 1 | 0% | 1,392 | 1,743 | +25% | 0 | 0 | — |
case-16 | fail→pass | 12,054 | 16,768 | +39% | 1 | 1 | 0% | 2,024 | 3,479 | +72% | 0 | 0 | — |
case-17 | pass→pass | 8,702 | 9,649 | +11% | 1 | 1 | 0% | 1,578 | 2,379 | +51% | 0 | 0 | — |
case-18 | fail→fail | 25,808 | 18,076 | -30% | 1 | 1 | 0% | 2,956 | 4,752 | +61% | 0 | 0 | — |
case-19 | fail→pass | 8,419 | 7,921 | -6% | 1 | 1 | 0% | 1,376 | 1,989 | +45% | 0 | 0 | — |
case-20 | fail→fail | 18,486 | 29,638 | +60% | 1 | 1 | 0% | 3,636 | 5,534 | +52% | 0 | 0 | — |
case-21 | fail→fail | 22,420 | 20,284 | -10% | 1 | 1 | 0% | 3,390 | 5,641 | +66% | 0 | 0 | — |
case-22 | fail→fail | 18,768 | 16,754 | -11% | 1 | 1 | 0% | 3,762 | 5,035 | +34% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +36 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.