Claude-code-plugins intercom-deploy-integration
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/intercom-pack/skills/intercom-deploy-integration" ~/.claude/skills/jeremylongshore-claude-code-plugins-intercom-deploy-integration && rm -rf "$T"
manifest:
plugins/saas-packs/intercom-pack/skills/intercom-deploy-integration/SKILL.mdsource content
Intercom Deploy Integration
Overview
Deploy Intercom-powered applications to Vercel, Fly.io, or Google Cloud Run with proper secret management, webhook endpoint configuration, and health checks.
Prerequisites
- Intercom production access token
- Platform CLI installed (
,vercel
, orflyctl
)gcloud - Application with Intercom integration ready for deployment
Instructions
Step 1: Vercel Deployment
# Add Intercom secrets to Vercel vercel env add INTERCOM_ACCESS_TOKEN production vercel env add INTERCOM_WEBHOOK_SECRET production # Deploy to production vercel --prod
API Route for Webhooks (Vercel Serverless):
// api/webhooks/intercom.ts (Vercel serverless function) import crypto from "crypto"; export const config = { api: { bodyParser: false } }; export default async function handler(req: any, res: any) { if (req.method !== "POST") return res.status(405).end(); const chunks: Buffer[] = []; for await (const chunk of req) chunks.push(chunk); const body = Buffer.concat(chunks); // Verify signature const signature = req.headers["x-hub-signature"] as string; const expected = "sha1=" + crypto .createHmac("sha1", process.env.INTERCOM_WEBHOOK_SECRET!) .update(body) .digest("hex"); if (!crypto.timingSafeEqual(Buffer.from(signature || ""), Buffer.from(expected))) { return res.status(401).json({ error: "Invalid signature" }); } const event = JSON.parse(body.toString()); console.log(`Intercom webhook: ${event.topic}`); // Process within 5s (Intercom timeout) // For long processing, queue the event and return immediately res.status(200).json({ received: true }); }
vercel.json:
{ "functions": { "api/webhooks/intercom.ts": { "maxDuration": 10 } } }
Step 2: Fly.io Deployment
# fly.toml app = "my-intercom-app" primary_region = "iad" [env] NODE_ENV = "production" [http_service] internal_port = 3000 force_https = true auto_stop_machines = false # Keep running for webhooks auto_start_machines = true [[http_service.checks]] grace_period = "10s" interval = "30s" method = "GET" path = "/health" timeout = "5s"
# Set secrets fly secrets set INTERCOM_ACCESS_TOKEN="dG9rOi4uLg==" fly secrets set INTERCOM_WEBHOOK_SECRET="your-secret" # Deploy fly deploy # Verify health fly status curl https://my-intercom-app.fly.dev/health
Step 3: Google Cloud Run
#!/bin/bash PROJECT_ID="${GOOGLE_CLOUD_PROJECT}" SERVICE="intercom-service" REGION="us-central1" # Store secrets in Secret Manager echo -n "$INTERCOM_ACCESS_TOKEN" | \ gcloud secrets create intercom-token --data-file=- --replication-policy=automatic echo -n "$INTERCOM_WEBHOOK_SECRET" | \ gcloud secrets create intercom-webhook-secret --data-file=- --replication-policy=automatic # Build and deploy gcloud builds submit --tag gcr.io/$PROJECT_ID/$SERVICE gcloud run deploy $SERVICE \ --image gcr.io/$PROJECT_ID/$SERVICE \ --region $REGION \ --platform managed \ --allow-unauthenticated \ --set-secrets="INTERCOM_ACCESS_TOKEN=intercom-token:latest,INTERCOM_WEBHOOK_SECRET=intercom-webhook-secret:latest" \ --min-instances=1 \ --timeout=60
Step 4: Health Check Endpoint
// src/routes/health.ts import { IntercomClient, IntercomError } from "intercom-client"; const client = new IntercomClient({ token: process.env.INTERCOM_ACCESS_TOKEN!, }); export async function healthCheck(): Promise<{ status: string; services: { intercom: { connected: boolean; latencyMs: number; error?: string } }; }> { const start = Date.now(); try { await client.admins.list(); return { status: "healthy", services: { intercom: { connected: true, latencyMs: Date.now() - start }, }, }; } catch (err) { const latencyMs = Date.now() - start; const error = err instanceof IntercomError ? `${err.statusCode}: ${err.message}` : (err as Error).message; return { status: "degraded", services: { intercom: { connected: false, latencyMs, error }, }, }; } }
Step 5: Register Webhook URL
After deploying, configure the webhook URL in Intercom:
- Go to Developer Hub > Webhooks
- Set endpoint URL:
https://your-domain.com/api/webhooks/intercom - Select topics:
,conversation.user.created
, etc.contact.created - Copy the webhook signing secret to your platform secrets
- Send a test notification to verify
Webhook Topics Reference
| Topic | Fires When |
|---|---|
| New conversation from contact |
| Contact replies |
| Admin replies |
| Conversation closed |
| New contact created |
| Lead converts to user |
| Tag applied to contact |
| New user (legacy topic) |
Error Handling
| 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 |
Resources
Next Steps
For webhook handling patterns, see
intercom-webhooks-events.