From figma-pack
Deploys Figma webhook receivers and design token APIs to Vercel, Cloud Run, and Fly.io with secret management, verification, and health checks.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin figma-packThis skill is limited to using the following tools:
Deploy Figma webhook receivers and design API services to production platforms with proper secret management and health checks.
Provides production reference architecture for Figma REST API integrations: design token extraction, asset exports, webhook handlers, with TypeScript project structure and CLI scripts.
Deploys Framer Server API integrations like CMS sync and webhook handlers to Vercel, Fly.io, and Cloud Run. Configures secrets and production pipelines.
Deploys Canva Connect API integrations to Vercel, Fly.io, and Cloud Run. Manages OAuth secrets, configures platform files, and sets up server-side token exchange.
Share bugs, ideas, or general feedback.
Deploy Figma webhook receivers and design API services to production platforms with proper secret management and health checks.
# Store Figma secrets
vercel env add FIGMA_PAT production
vercel env add FIGMA_WEBHOOK_PASSCODE production
# Deploy
vercel --prod
// api/webhooks/figma.ts (Vercel serverless function)
import { NextRequest, NextResponse } from 'next/server';
import crypto from 'crypto';
export async function POST(req: NextRequest) {
const payload = await req.json();
// Verify passcode
const expected = process.env.FIGMA_WEBHOOK_PASSCODE!;
const received = payload.passcode || '';
if (!crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected))) {
return NextResponse.json({ error: 'Invalid passcode' }, { status: 401 });
}
// Process webhook event
switch (payload.event_type) {
case 'FILE_UPDATE':
console.log(`File updated: ${payload.file_name} (${payload.file_key})`);
// Trigger token re-sync, invalidate cache, etc.
break;
case 'FILE_COMMENT':
console.log(`New comment on ${payload.file_name}`);
break;
case 'LIBRARY_PUBLISH':
console.log(`Library published: ${payload.file_name}`);
break;
}
return NextResponse.json({ received: true });
}
export const config = { maxDuration: 10 };
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY dist/ ./dist/
ENV PORT=8080
CMD ["node", "dist/server.js"]
PROJECT_ID="${GOOGLE_CLOUD_PROJECT}"
SERVICE="figma-token-api"
REGION="us-central1"
# Store PAT in Secret Manager
echo -n "${FIGMA_PAT}" | gcloud secrets create figma-pat --data-file=-
# 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 \
--set-secrets="FIGMA_PAT=figma-pat:latest" \
--allow-unauthenticated \
--max-instances=5 \
--timeout=30s
# fly.toml
app = "figma-webhook-service"
primary_region = "iad"
[env]
NODE_ENV = "production"
[http_service]
internal_port = 3000
force_https = true
auto_stop_machines = "suspend"
auto_start_machines = true
min_machines_running = 1
[[http_service.checks]]
grace_period = "10s"
interval = "30s"
method = "GET"
path = "/health"
timeout = "5s"
fly secrets set FIGMA_PAT=figd_your-token
fly secrets set FIGMA_WEBHOOK_PASSCODE=your-passcode
fly deploy
// src/health.ts -- works on any platform
import { figmaFetch } from './figma-client';
export async function healthHandler(req: Request): Promise<Response> {
const start = Date.now();
try {
const res = await fetch('https://api.figma.com/v1/me', {
headers: { 'X-Figma-Token': process.env.FIGMA_PAT! },
signal: AbortSignal.timeout(5000),
});
return Response.json({
status: res.ok ? 'healthy' : 'degraded',
figma: {
authenticated: res.ok,
latencyMs: Date.now() - start,
},
timestamp: new Date().toISOString(),
});
} catch {
return Response.json({
status: 'unhealthy',
figma: { authenticated: false, latencyMs: Date.now() - start },
}, { status: 503 });
}
}
| Issue | Cause | Solution |
|---|---|---|
| Secret not found in runtime | Wrong env name | Verify with platform CLI (vercel env ls) |
| Webhook timeout | Processing too slow | Return 200 immediately, process async |
| Cold start latency | Serverless cold boot | Use Fly.io min_machines_running: 1 or Cloud Run min instances |
| Health check fails | PAT expired | Rotate token via platform secret management |
For webhook handling, see figma-webhooks-events.