@intentsolutionsio/vercel-pack 1.0.0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +67 -44
  3. package/package.json +4 -4
  4. package/skills/vercel-advanced-troubleshooting/SKILL.md +185 -195
  5. package/skills/vercel-advanced-troubleshooting/references/errors.md +11 -0
  6. package/skills/vercel-advanced-troubleshooting/references/evidence-collection-framework.md +34 -0
  7. package/skills/vercel-advanced-troubleshooting/references/examples.md +11 -0
  8. package/skills/vercel-advanced-troubleshooting/references/systematic-isolation.md +56 -0
  9. package/skills/vercel-advanced-troubleshooting/references/timing-analysis.md +35 -0
  10. package/skills/vercel-architecture-variants/SKILL.md +227 -216
  11. package/skills/vercel-architecture-variants/references/errors.md +11 -0
  12. package/skills/vercel-architecture-variants/references/examples.md +12 -0
  13. package/skills/vercel-architecture-variants/references/variant-a-monolith-(simple).md +44 -0
  14. package/skills/vercel-architecture-variants/references/variant-b-service-layer-(moderate).md +72 -0
  15. package/skills/vercel-architecture-variants/references/variant-c-microservice-(complex).md +81 -0
  16. package/skills/vercel-ci-integration/SKILL.md +183 -73
  17. package/skills/vercel-ci-integration/references/errors.md +10 -0
  18. package/skills/vercel-ci-integration/references/examples.md +36 -0
  19. package/skills/vercel-ci-integration/references/implementation.md +54 -0
  20. package/skills/vercel-common-errors/SKILL.md +164 -60
  21. package/skills/vercel-common-errors/references/errors.md +53 -0
  22. package/skills/vercel-common-errors/references/examples.md +23 -0
  23. package/skills/vercel-cost-tuning/SKILL.md +158 -145
  24. package/skills/vercel-cost-tuning/references/cost-estimation.md +34 -0
  25. package/skills/vercel-cost-tuning/references/cost-reduction-strategies.md +40 -0
  26. package/skills/vercel-cost-tuning/references/errors.md +11 -0
  27. package/skills/vercel-cost-tuning/references/examples.md +15 -0
  28. package/skills/vercel-data-handling/SKILL.md +202 -155
  29. package/skills/vercel-data-handling/references/errors.md +11 -0
  30. package/skills/vercel-data-handling/references/examples.md +27 -0
  31. package/skills/vercel-data-handling/references/implementation.md +223 -0
  32. package/skills/vercel-debug-bundle/SKILL.md +163 -67
  33. package/skills/vercel-debug-bundle/references/errors.md +12 -0
  34. package/skills/vercel-debug-bundle/references/examples.md +24 -0
  35. package/skills/vercel-debug-bundle/references/implementation.md +54 -0
  36. package/skills/vercel-deploy-integration/SKILL.md +163 -156
  37. package/skills/vercel-deploy-integration/references/errors.md +11 -0
  38. package/skills/vercel-deploy-integration/references/examples.md +21 -0
  39. package/skills/vercel-deploy-integration/references/google-cloud-run.md +36 -0
  40. package/skills/vercel-deploy-integration/references/vercel-deployment.md +35 -0
  41. package/skills/vercel-deploy-preview/SKILL.md +164 -39
  42. package/skills/vercel-edge-functions/SKILL.md +185 -37
  43. package/skills/vercel-enterprise-rbac/SKILL.md +185 -170
  44. package/skills/vercel-enterprise-rbac/references/errors.md +11 -0
  45. package/skills/vercel-enterprise-rbac/references/examples.md +12 -0
  46. package/skills/vercel-enterprise-rbac/references/role-implementation.md +33 -0
  47. package/skills/vercel-enterprise-rbac/references/sso-integration.md +35 -0
  48. package/skills/vercel-hello-world/SKILL.md +141 -55
  49. package/skills/vercel-incident-runbook/SKILL.md +186 -138
  50. package/skills/vercel-incident-runbook/references/errors.md +11 -0
  51. package/skills/vercel-incident-runbook/references/examples.md +10 -0
  52. package/skills/vercel-incident-runbook/references/immediate-actions-by-error-type.md +41 -0
  53. package/skills/vercel-install-auth/SKILL.md +130 -53
  54. package/skills/vercel-known-pitfalls/SKILL.md +235 -233
  55. package/skills/vercel-known-pitfalls/references/errors.md +11 -0
  56. package/skills/vercel-known-pitfalls/references/examples.md +12 -0
  57. package/skills/vercel-load-scale/SKILL.md +197 -204
  58. package/skills/vercel-load-scale/references/capacity-planning.md +47 -0
  59. package/skills/vercel-load-scale/references/errors.md +11 -0
  60. package/skills/vercel-load-scale/references/examples.md +26 -0
  61. package/skills/vercel-load-scale/references/load-testing-with-k6.md +59 -0
  62. package/skills/vercel-load-scale/references/scaling-patterns.md +65 -0
  63. package/skills/vercel-local-dev-loop/SKILL.md +159 -71
  64. package/skills/vercel-local-dev-loop/references/errors.md +11 -0
  65. package/skills/vercel-local-dev-loop/references/examples.md +21 -0
  66. package/skills/vercel-local-dev-loop/references/implementation.md +60 -0
  67. package/skills/vercel-migration-deep-dive/SKILL.md +202 -187
  68. package/skills/vercel-migration-deep-dive/references/errors.md +11 -0
  69. package/skills/vercel-migration-deep-dive/references/examples.md +12 -0
  70. package/skills/vercel-migration-deep-dive/references/implementation-plan.md +80 -0
  71. package/skills/vercel-migration-deep-dive/references/pre-migration-assessment.md +39 -0
  72. package/skills/vercel-multi-env-setup/SKILL.md +167 -164
  73. package/skills/vercel-multi-env-setup/references/configuration-structure.md +59 -0
  74. package/skills/vercel-multi-env-setup/references/errors.md +11 -0
  75. package/skills/vercel-multi-env-setup/references/examples.md +11 -0
  76. package/skills/vercel-observability/SKILL.md +205 -195
  77. package/skills/vercel-observability/references/alert-configuration.md +40 -0
  78. package/skills/vercel-observability/references/errors.md +11 -0
  79. package/skills/vercel-observability/references/examples.md +13 -0
  80. package/skills/vercel-observability/references/metrics-collection.md +65 -0
  81. package/skills/vercel-performance-tuning/SKILL.md +212 -156
  82. package/skills/vercel-performance-tuning/references/caching-strategy.md +49 -0
  83. package/skills/vercel-performance-tuning/references/errors.md +11 -0
  84. package/skills/vercel-performance-tuning/references/examples.md +13 -0
  85. package/skills/vercel-policy-guardrails/SKILL.md +276 -193
  86. package/skills/vercel-policy-guardrails/references/errors.md +11 -0
  87. package/skills/vercel-policy-guardrails/references/eslint-rules.md +46 -0
  88. package/skills/vercel-policy-guardrails/references/examples.md +10 -0
  89. package/skills/vercel-prod-checklist/SKILL.md +219 -94
  90. package/skills/vercel-prod-checklist/references/errors.md +11 -0
  91. package/skills/vercel-prod-checklist/references/examples.md +25 -0
  92. package/skills/vercel-prod-checklist/references/implementation.md +60 -0
  93. package/skills/vercel-rate-limits/SKILL.md +187 -100
  94. package/skills/vercel-rate-limits/references/errors.md +11 -0
  95. package/skills/vercel-rate-limits/references/examples.md +46 -0
  96. package/skills/vercel-rate-limits/references/implementation.md +66 -0
  97. package/skills/vercel-reference-architecture/SKILL.md +226 -180
  98. package/skills/vercel-reference-architecture/references/errors.md +11 -0
  99. package/skills/vercel-reference-architecture/references/examples.md +13 -0
  100. package/skills/vercel-reference-architecture/references/key-components.md +65 -0
  101. package/skills/vercel-reference-architecture/references/project-structure.md +40 -0
  102. package/skills/vercel-reliability-patterns/SKILL.md +272 -211
  103. package/skills/vercel-reliability-patterns/references/circuit-breaker.md +36 -0
  104. package/skills/vercel-reliability-patterns/references/dead-letter-queue.md +48 -0
  105. package/skills/vercel-reliability-patterns/references/errors.md +11 -0
  106. package/skills/vercel-reliability-patterns/references/examples.md +11 -0
  107. package/skills/vercel-reliability-patterns/references/idempotency-keys.md +36 -0
  108. package/skills/vercel-sdk-patterns/SKILL.md +264 -92
  109. package/skills/vercel-sdk-patterns/references/errors.md +11 -0
  110. package/skills/vercel-sdk-patterns/references/examples.md +45 -0
  111. package/skills/vercel-sdk-patterns/references/implementation.md +67 -0
  112. package/skills/vercel-security-basics/SKILL.md +186 -96
  113. package/skills/vercel-security-basics/references/errors.md +10 -0
  114. package/skills/vercel-security-basics/references/examples.md +70 -0
  115. package/skills/vercel-security-basics/references/implementation.md +39 -0
  116. package/skills/vercel-upgrade-migration/SKILL.md +167 -67
  117. package/skills/vercel-upgrade-migration/references/errors.md +10 -0
  118. package/skills/vercel-upgrade-migration/references/examples.md +51 -0
  119. package/skills/vercel-upgrade-migration/references/implementation.md +29 -0
  120. package/skills/vercel-webhooks-events/SKILL.md +208 -132
  121. package/skills/vercel-webhooks-events/references/errors.md +11 -0
  122. package/skills/vercel-webhooks-events/references/event-handler-pattern.md +37 -0
  123. package/skills/vercel-webhooks-events/references/examples.md +16 -0
  124. package/skills/vercel-webhooks-events/references/signature-verification.md +33 -0
@@ -1,199 +1,275 @@
1
1
  ---
2
2
  name: vercel-webhooks-events
3
- description: |
4
- Implement Vercel webhook signature validation and event handling.
5
- Use when setting up webhook endpoints, implementing signature verification,
6
- or handling Vercel event notifications securely.
3
+ description: 'Implement Vercel webhook handling with signature verification and event
4
+ processing.
5
+
6
+ Use when setting up webhook endpoints, processing deployment events,
7
+
8
+ or building integrations that react to Vercel deployment lifecycle.
9
+
7
10
  Trigger with phrases like "vercel webhook", "vercel events",
8
- "vercel webhook signature", "handle vercel events", "vercel notifications".
11
+
12
+ "vercel deployment.ready", "handle vercel events", "vercel webhook signature".
13
+
14
+ '
9
15
  allowed-tools: Read, Write, Edit, Bash(curl:*)
10
16
  version: 1.0.0
11
17
  license: MIT
12
18
  author: Jeremy Longshore <jeremy@intentsolutions.io>
19
+ tags:
20
+ - saas
21
+ - vercel
22
+ - webhooks
23
+ - events
24
+ - integration
25
+ compatibility: Designed for Claude Code, also compatible with Codex and OpenClaw
13
26
  ---
14
-
15
27
  # Vercel Webhooks & Events
16
28
 
17
29
  ## Overview
18
- Securely handle Vercel webhooks with signature validation and replay protection.
19
30
 
20
- ## Prerequisites
21
- - Vercel webhook secret configured
22
- - HTTPS endpoint accessible from internet
23
- - Understanding of cryptographic signatures
24
- - Redis or database for idempotency (optional)
31
+ Handle Vercel webhook events (deployment.created, deployment.ready, deployment.error) with HMAC signature verification. Covers both integration webhooks (Vercel Marketplace) and project-level deploy hooks.
25
32
 
26
- ## Webhook Endpoint Setup
33
+ ## Prerequisites
27
34
 
28
- ### Express.js
29
- ```typescript
30
- import express from 'express';
31
- import crypto from 'crypto';
35
+ - HTTPS endpoint accessible from the internet
36
+ - Webhook secret from Vercel dashboard or integration settings
37
+ - `crypto` module for HMAC signature verification
32
38
 
33
- const app = express();
39
+ ## Instructions
34
40
 
35
- // IMPORTANT: Raw body needed for signature verification
36
- app.post('/webhooks/vercel',
37
- express.raw({ type: 'application/json' }),
38
- async (req, res) => {
39
- const signature = req.headers['x-vercel-signature'] as string;
40
- const timestamp = req.headers['x-vercel-timestamp'] as string;
41
+ ### Step 1: Register a Webhook
41
42
 
42
- if (!verifyVercelSignature(req.body, signature, timestamp)) {
43
- return res.status(401).json({ error: 'Invalid signature' });
44
- }
43
+ In the Vercel dashboard:
45
44
 
46
- const event = JSON.parse(req.body.toString());
47
- await handleVercelEvent(event);
45
+ 1. Go to **Settings > Webhooks**
46
+ 2. Add your endpoint URL (must be HTTPS)
47
+ 3. Select events to subscribe to
48
+ 4. Copy the webhook secret for signature verification
48
49
 
49
- res.status(200).json({ received: true });
50
- }
51
- );
52
- ```
50
+ Or for Integration webhooks, configure in the Integration Console at `vercel.com/dashboard/integrations`.
53
51
 
54
- ## Signature Verification
52
+ ### Step 2: Verify Webhook Signature
55
53
 
56
54
  ```typescript
57
- function verifyVercelSignature(
58
- payload: Buffer,
59
- signature: string,
60
- timestamp: string
61
- ): boolean {
62
- const secret = process.env.VERCEL_WEBHOOK_SECRET!;
63
-
64
- // Reject old timestamps (replay attack protection)
65
- const timestampAge = Date.now() - parseInt(timestamp) * 1000;
66
- if (timestampAge > 300000) { // 5 minutes
67
- console.error('Webhook timestamp too old');
68
- return false;
69
- }
55
+ // api/webhooks/vercel.ts
56
+ import type { VercelRequest, VercelResponse } from '@vercel/node';
57
+ import crypto from 'crypto';
70
58
 
71
- // Compute expected signature
72
- const signedPayload = `${timestamp}.${payload.toString()}`;
59
+ const WEBHOOK_SECRET = process.env.VERCEL_WEBHOOK_SECRET!;
60
+
61
+ function verifySignature(body: string, signature: string): boolean {
73
62
  const expectedSignature = crypto
74
- .createHmac('sha256', secret)
75
- .update(signedPayload)
63
+ .createHmac('sha1', WEBHOOK_SECRET)
64
+ .update(body)
76
65
  .digest('hex');
77
-
78
- // Timing-safe comparison
79
66
  return crypto.timingSafeEqual(
80
67
  Buffer.from(signature),
81
68
  Buffer.from(expectedSignature)
82
69
  );
83
70
  }
71
+
72
+ export default async function handler(req: VercelRequest, res: VercelResponse) {
73
+ if (req.method !== 'POST') {
74
+ return res.status(405).json({ error: 'Method not allowed' });
75
+ }
76
+
77
+ // Get raw body for signature verification
78
+ const rawBody = JSON.stringify(req.body);
79
+ const signature = req.headers['x-vercel-signature'] as string;
80
+
81
+ if (!signature || !verifySignature(rawBody, signature)) {
82
+ return res.status(401).json({ error: 'Invalid signature' });
83
+ }
84
+
85
+ // Process the event
86
+ const event = req.body;
87
+ await handleEvent(event);
88
+
89
+ res.status(200).json({ received: true });
90
+ }
84
91
  ```
85
92
 
86
- ## Event Handler Pattern
93
+ ### Step 3: Handle Deployment Events
87
94
 
88
95
  ```typescript
89
- type VercelEventType = 'resource.created' | 'resource.updated' | 'resource.deleted';
90
-
91
- interface VercelEvent {
96
+ // lib/webhook-handlers.ts
97
+ interface VercelWebhookEvent {
92
98
  id: string;
93
- type: VercelEventType;
94
- data: Record<string, any>;
95
- created: string;
99
+ type: string;
100
+ createdAt: number;
101
+ payload: {
102
+ deployment: {
103
+ id: string;
104
+ name: string;
105
+ url: string;
106
+ meta: Record<string, string>;
107
+ };
108
+ project: {
109
+ id: string;
110
+ name: string;
111
+ };
112
+ target: 'production' | 'preview' | null;
113
+ user: { id: string; email: string; username: string };
114
+ };
96
115
  }
97
116
 
98
- const eventHandlers: Record<VercelEventType, (data: any) => Promise<void>> = {
99
- 'resource.created': async (data) => { /* handle */ },
100
- 'resource.updated': async (data) => { /* handle */ },
101
- 'resource.deleted': async (data) => { /* handle */ }
102
- };
117
+ async function handleEvent(event: VercelWebhookEvent): Promise<void> {
118
+ switch (event.type) {
119
+ case 'deployment.created':
120
+ console.log(`Deployment started: ${event.payload.deployment.url}`);
121
+ // Notify Slack, update status board, etc.
122
+ break;
123
+
124
+ case 'deployment.ready':
125
+ console.log(`Deployment ready: ${event.payload.deployment.url}`);
126
+ // Run smoke tests against the deployment URL
127
+ // Notify team of successful deploy
128
+ if (event.payload.target === 'production') {
129
+ await notifyProductionDeploy(event);
130
+ }
131
+ break;
132
+
133
+ case 'deployment.error':
134
+ console.error(`Deployment failed: ${event.payload.deployment.id}`);
135
+ // Alert on-call engineer
136
+ // Create incident ticket
137
+ await notifyDeploymentError(event);
138
+ break;
139
+
140
+ case 'deployment.canceled':
141
+ console.log(`Deployment canceled: ${event.payload.deployment.id}`);
142
+ break;
143
+
144
+ case 'project.created':
145
+ console.log(`New project: ${event.payload.project.name}`);
146
+ break;
147
+
148
+ case 'project.removed':
149
+ console.log(`Project removed: ${event.payload.project.name}`);
150
+ break;
151
+
152
+ default:
153
+ console.log(`Unhandled event type: ${event.type}`);
154
+ }
155
+ }
156
+ ```
103
157
 
104
- async function handleVercelEvent(event: VercelEvent): Promise<void> {
105
- const handler = eventHandlers[event.type];
158
+ ### Step 4: Idempotency Prevent Duplicate Processing
106
159
 
107
- if (!handler) {
108
- console.log(`Unhandled event type: ${event.type}`);
109
- return;
160
+ ```typescript
161
+ // lib/idempotency.ts
162
+ // Vercel may retry webhook delivery — track processed event IDs
163
+ const processedEvents = new Set<string>(); // Use Redis in production
164
+
165
+ async function processWebhookIdempotent(
166
+ event: VercelWebhookEvent,
167
+ handler: (e: VercelWebhookEvent) => Promise<void>
168
+ ): Promise<boolean> {
169
+ if (processedEvents.has(event.id)) {
170
+ console.log(`Skipping duplicate event: ${event.id}`);
171
+ return false;
110
172
  }
111
173
 
112
- try {
113
- await handler(event.data);
114
- console.log(`Processed ${event.type}: ${event.id}`);
115
- } catch (error) {
116
- console.error(`Failed to process ${event.type}: ${event.id}`, error);
117
- throw error; // Rethrow to trigger retry
118
- }
174
+ await handler(event);
175
+ processedEvents.add(event.id);
176
+ return true;
119
177
  }
120
178
  ```
121
179
 
122
- ## Idempotency Handling
180
+ ### Step 5: Slack Notification Example
123
181
 
124
182
  ```typescript
125
- import { Redis } from 'ioredis';
126
-
127
- const redis = new Redis(process.env.REDIS_URL);
128
-
129
- async function isEventProcessed(eventId: string): Promise<boolean> {
130
- const key = `vercel:event:${eventId}`;
131
- const exists = await redis.exists(key);
132
- return exists === 1;
183
+ // lib/notifications.ts
184
+ async function notifyProductionDeploy(event: VercelWebhookEvent): Promise<void> {
185
+ const { deployment, project, user } = event.payload;
186
+
187
+ await fetch(process.env.SLACK_WEBHOOK_URL!, {
188
+ method: 'POST',
189
+ headers: { 'Content-Type': 'application/json' },
190
+ body: JSON.stringify({
191
+ text: `Production deploy complete`,
192
+ blocks: [
193
+ {
194
+ type: 'section',
195
+ text: {
196
+ type: 'mrkdwn',
197
+ text: [
198
+ `*${project.name}* deployed to production`,
199
+ `By: ${user.username}`,
200
+ `URL: https://${deployment.url}`,
201
+ `Commit: ${deployment.meta?.githubCommitMessage ?? 'N/A'}`,
202
+ ].join('\n'),
203
+ },
204
+ },
205
+ ],
206
+ }),
207
+ });
133
208
  }
134
209
 
135
- async function markEventProcessed(eventId: string): Promise<void> {
136
- const key = `vercel:event:${eventId}`;
137
- await redis.set(key, '1', 'EX', 86400 * 7); // 7 days TTL
210
+ async function notifyDeploymentError(event: VercelWebhookEvent): Promise<void> {
211
+ await fetch(process.env.SLACK_WEBHOOK_URL!, {
212
+ method: 'POST',
213
+ headers: { 'Content-Type': 'application/json' },
214
+ body: JSON.stringify({
215
+ text: `Deployment FAILED for ${event.payload.project.name} — ${event.payload.deployment.id}`,
216
+ }),
217
+ });
138
218
  }
139
219
  ```
140
220
 
141
- ## Webhook Testing
221
+ ### Step 6: Test Webhooks Locally
142
222
 
143
223
  ```bash
144
- # Use Vercel CLI to send test events
145
- vercel dev
224
+ # Use the Vercel CLI to test webhook signatures
225
+ # Or use a tunnel service for local testing
226
+ npx localtunnel --port 3000
227
+ # Gives you a public URL like https://xxx.loca.lt
146
228
 
147
- # Or use webhook.site for debugging
148
- curl -X POST https://webhook.site/your-uuid \
229
+ # Send a test webhook payload
230
+ curl -X POST http://localhost:3000/api/webhooks/vercel \
149
231
  -H "Content-Type: application/json" \
150
- -d '{"type": "resource.created", "data": {}}'
232
+ -H "x-vercel-signature: $(echo -n '{"type":"deployment.ready","id":"test"}' | openssl dgst -sha1 -hmac 'your-secret' | awk '{print $2}')" \
233
+ -d '{"type":"deployment.ready","id":"test"}'
151
234
  ```
152
235
 
153
- ## Instructions
154
-
155
- ### Step 1: Register Webhook Endpoint
156
- Configure your webhook URL in the Vercel dashboard.
236
+ ## Webhook Event Types
157
237
 
158
- ### Step 2: Implement Signature Verification
159
- Use the signature verification code to validate incoming webhooks.
160
-
161
- ### Step 3: Handle Events
162
- Implement handlers for each event type your application needs.
163
-
164
- ### Step 4: Add Idempotency
165
- Prevent duplicate processing with event ID tracking.
238
+ | Event | Trigger |
239
+ |-------|---------|
240
+ | `deployment.created` | New deployment started building |
241
+ | `deployment.ready` | Deployment build completed successfully |
242
+ | `deployment.error` | Deployment build failed |
243
+ | `deployment.canceled` | Deployment was canceled |
244
+ | `project.created` | New project created |
245
+ | `project.removed` | Project deleted |
246
+ | `domain.created` | Domain added to project |
247
+ | `integration.configuration.removed` | Integration uninstalled |
166
248
 
167
249
  ## Output
168
- - Secure webhook endpoint
169
- - Signature validation enabled
170
- - Event handlers implemented
171
- - Replay attack protection active
172
-
173
- ## Error Handling
174
- | Issue | Cause | Solution |
175
- |-------|-------|----------|
176
- | Invalid signature | Wrong secret | Verify webhook secret |
177
- | Timestamp rejected | Clock drift | Check server time sync |
178
- | Duplicate events | Missing idempotency | Implement event ID tracking |
179
- | Handler timeout | Slow processing | Use async queue |
180
250
 
181
- ## Examples
251
+ - Webhook endpoint with HMAC signature verification
252
+ - Event handlers for deployment lifecycle events
253
+ - Idempotent processing preventing duplicates
254
+ - Slack notifications for production deploys and failures
182
255
 
183
- ### Testing Webhooks Locally
184
- ```bash
185
- # Use ngrok to expose local server
186
- ngrok http 3000
256
+ ## Error Handling
187
257
 
188
- # Send test webhook
189
- curl -X POST https://your-ngrok-url/webhooks/vercel \
190
- -H "Content-Type: application/json" \
191
- -d '{"type": "test", "data": {}}'
192
- ```
258
+ | Error | Cause | Solution |
259
+ |-------|-------|----------|
260
+ | `401 Invalid signature` | Wrong webhook secret or body mismatch | Verify secret matches dashboard, use raw body for HMAC |
261
+ | Webhook not received | Endpoint not publicly accessible | Ensure HTTPS, check firewall rules |
262
+ | Duplicate processing | Webhook retried by Vercel | Implement idempotency with event ID tracking |
263
+ | `504 timeout` on webhook endpoint | Handler takes too long | Return 200 immediately, process async in background |
264
+ | Missing `x-vercel-signature` | Not a real Vercel webhook | Reject requests without the signature header |
193
265
 
194
266
  ## Resources
195
- - [Vercel Webhooks Guide](https://vercel.com/docs/webhooks)
196
- - [Webhook Security Best Practices](https://vercel.com/docs/webhooks/security)
267
+
268
+ - [Vercel Webhooks API](https://vercel.com/docs/webhooks/webhooks-api)
269
+ - [Setting Up Webhooks](https://vercel.com/docs/webhooks)
270
+ - [Deploy Hooks](https://vercel.com/docs/deploy-hooks)
271
+ - [Integration Webhooks](https://vercel.com/docs/integrations/create-integration)
197
272
 
198
273
  ## Next Steps
199
- For performance optimization, see `vercel-performance-tuning`.
274
+
275
+ For performance optimization, see `vercel-performance-tuning`.
@@ -0,0 +1,11 @@
1
+ # Error Handling Reference
2
+
3
+ | Issue | Cause | Solution |
4
+ |-------|-------|----------|
5
+ | Invalid signature | Wrong secret | Verify webhook secret |
6
+ | Timestamp rejected | Clock drift | Check server time sync |
7
+ | Duplicate events | Missing idempotency | Implement event ID tracking |
8
+ | Handler timeout | Slow processing | Use async queue |
9
+
10
+ ---
11
+ *[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
@@ -0,0 +1,37 @@
1
+ # Event Handler Pattern
2
+
3
+ ## Event Handler Pattern
4
+
5
+ ```typescript
6
+ type VercelEventType = 'resource.created' | 'resource.updated' | 'resource.deleted';
7
+
8
+ interface VercelEvent {
9
+ id: string;
10
+ type: VercelEventType;
11
+ data: Record<string, any>;
12
+ created: string;
13
+ }
14
+
15
+ const eventHandlers: Record<VercelEventType, (data: any) => Promise<void>> = {
16
+ 'resource.created': async (data) => { /* handle */ },
17
+ 'resource.updated': async (data) => { /* handle */ },
18
+ 'resource.deleted': async (data) => { /* handle */ }
19
+ };
20
+
21
+ async function handleVercelEvent(event: VercelEvent): Promise<void> {
22
+ const handler = eventHandlers[event.type];
23
+
24
+ if (!handler) {
25
+ console.log(`Unhandled event type: ${event.type}`);
26
+ return;
27
+ }
28
+
29
+ try {
30
+ await handler(event.data);
31
+ console.log(`Processed ${event.type}: ${event.id}`);
32
+ } catch (error) {
33
+ console.error(`Failed to process ${event.type}: ${event.id}`, error);
34
+ throw error; // Rethrow to trigger retry
35
+ }
36
+ }
37
+ ```
@@ -0,0 +1,16 @@
1
+ ## Examples
2
+
3
+ ### Testing Webhooks Locally
4
+
5
+ ```bash
6
+ # Use ngrok to expose local server
7
+ ngrok http 3000
8
+
9
+ # Send test webhook
10
+ curl -X POST https://your-ngrok-url/webhooks/vercel \
11
+ -H "Content-Type: application/json" \
12
+ -d '{"type": "test", "data": {}}'
13
+ ```
14
+
15
+ ---
16
+ *[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
@@ -0,0 +1,33 @@
1
+ # Signature Verification
2
+
3
+ ## Signature Verification
4
+
5
+ ```typescript
6
+ function verifyVercelSignature(
7
+ payload: Buffer,
8
+ signature: string,
9
+ timestamp: string
10
+ ): boolean {
11
+ const secret = process.env.VERCEL_WEBHOOK_SECRET!;
12
+
13
+ // Reject old timestamps (replay attack protection)
14
+ const timestampAge = Date.now() - parseInt(timestamp) * 1000;
15
+ if (timestampAge > 300000) { // 5 minutes
16
+ console.error('Webhook timestamp too old');
17
+ return false;
18
+ }
19
+
20
+ // Compute expected signature
21
+ const signedPayload = `${timestamp}.${payload.toString()}`;
22
+ const expectedSignature = crypto
23
+ .createHmac('sha256', secret)
24
+ .update(signedPayload)
25
+ .digest('hex');
26
+
27
+ // Timing-safe comparison
28
+ return crypto.timingSafeEqual(
29
+ Buffer.from(signature),
30
+ Buffer.from(expectedSignature)
31
+ );
32
+ }
33
+ ```