bps-kit 1.2.2 → 1.3.1
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.
- package/.bps-kit.json +4 -4
- package/README.md +3 -0
- package/implementation_plan.md.resolved +37 -0
- package/package.json +2 -2
- package/templates/agents-template/ARCHITECTURE.md +21 -9
- package/templates/agents-template/agents/automation-specialist.md +157 -0
- package/templates/agents-template/rules/GEMINI.md +2 -10
- package/templates/agents-template/workflows/automate.md +153 -0
- package/templates/skills_normal/n8n-code-javascript/BUILTIN_FUNCTIONS.md +764 -0
- package/templates/skills_normal/n8n-code-javascript/COMMON_PATTERNS.md +1110 -0
- package/templates/skills_normal/n8n-code-javascript/DATA_ACCESS.md +782 -0
- package/templates/skills_normal/n8n-code-javascript/ERROR_PATTERNS.md +763 -0
- package/templates/skills_normal/n8n-code-javascript/README.md +350 -0
- package/templates/skills_normal/n8n-code-javascript/SKILL.md +699 -0
- package/templates/skills_normal/n8n-code-python/COMMON_PATTERNS.md +794 -0
- package/templates/skills_normal/n8n-code-python/DATA_ACCESS.md +702 -0
- package/templates/skills_normal/n8n-code-python/ERROR_PATTERNS.md +601 -0
- package/templates/skills_normal/n8n-code-python/README.md +386 -0
- package/templates/skills_normal/n8n-code-python/SKILL.md +748 -0
- package/templates/skills_normal/n8n-code-python/STANDARD_LIBRARY.md +974 -0
- package/templates/skills_normal/n8n-expression-syntax/COMMON_MISTAKES.md +393 -0
- package/templates/skills_normal/n8n-expression-syntax/EXAMPLES.md +483 -0
- package/templates/skills_normal/n8n-expression-syntax/README.md +93 -0
- package/templates/skills_normal/n8n-expression-syntax/SKILL.md +516 -0
- package/templates/skills_normal/n8n-mcp-tools-expert/README.md +99 -0
- package/templates/skills_normal/n8n-mcp-tools-expert/SEARCH_GUIDE.md +374 -0
- package/templates/skills_normal/n8n-mcp-tools-expert/SKILL.md +642 -0
- package/templates/skills_normal/n8n-mcp-tools-expert/VALIDATION_GUIDE.md +442 -0
- package/templates/skills_normal/n8n-mcp-tools-expert/WORKFLOW_GUIDE.md +618 -0
- package/templates/skills_normal/n8n-node-configuration/DEPENDENCIES.md +789 -0
- package/templates/skills_normal/n8n-node-configuration/OPERATION_PATTERNS.md +913 -0
- package/templates/skills_normal/n8n-node-configuration/README.md +364 -0
- package/templates/skills_normal/n8n-node-configuration/SKILL.md +785 -0
- package/templates/skills_normal/n8n-validation-expert/ERROR_CATALOG.md +943 -0
- package/templates/skills_normal/n8n-validation-expert/FALSE_POSITIVES.md +720 -0
- package/templates/skills_normal/n8n-validation-expert/README.md +290 -0
- package/templates/skills_normal/n8n-validation-expert/SKILL.md +689 -0
- package/templates/skills_normal/n8n-workflow-patterns/README.md +251 -0
- package/templates/skills_normal/n8n-workflow-patterns/SKILL.md +411 -0
- package/templates/skills_normal/n8n-workflow-patterns/ai_agent_workflow.md +784 -0
- package/templates/skills_normal/n8n-workflow-patterns/database_operations.md +785 -0
- package/templates/skills_normal/n8n-workflow-patterns/http_api_integration.md +734 -0
- package/templates/skills_normal/n8n-workflow-patterns/scheduled_tasks.md +773 -0
- package/templates/skills_normal/n8n-workflow-patterns/webhook_processing.md +545 -0
- package/templates/vault/n8n-code-javascript/SKILL.md +10 -10
- package/templates/vault/n8n-code-python/SKILL.md +11 -11
- package/templates/vault/n8n-expression-syntax/SKILL.md +4 -4
- package/templates/vault/n8n-mcp-tools-expert/SKILL.md +9 -9
- package/templates/vault/n8n-node-configuration/SKILL.md +2 -2
- package/templates/vault/n8n-validation-expert/SKILL.md +3 -3
- package/templates/vault/n8n-workflow-patterns/SKILL.md +11 -11
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
# Webhook Processing Pattern
|
|
2
|
+
|
|
3
|
+
**Use Case**: Receive HTTP requests from external systems and process them instantly.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Pattern Structure
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Webhook → [Validate] → [Transform] → [Action] → [Response/Notify]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Key Characteristic**: Instant event-driven processing
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Core Components
|
|
18
|
+
|
|
19
|
+
### 1. Webhook Node (Trigger)
|
|
20
|
+
**Purpose**: Create HTTP endpoint to receive data
|
|
21
|
+
|
|
22
|
+
**Configuration**:
|
|
23
|
+
```javascript
|
|
24
|
+
{
|
|
25
|
+
path: "form-submit", // URL path: https://n8n.example.com/webhook/form-submit
|
|
26
|
+
httpMethod: "POST", // GET, POST, PUT, DELETE
|
|
27
|
+
responseMode: "onReceived", // or "lastNode" for custom response
|
|
28
|
+
responseData: "allEntries" // or "firstEntryJson"
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Critical Gotcha**: Data is nested under `$json.body`
|
|
33
|
+
```javascript
|
|
34
|
+
❌ {{$json.email}}
|
|
35
|
+
✅ {{$json.body.email}}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2. Validation (Optional but Recommended)
|
|
39
|
+
**Purpose**: Verify incoming data before processing
|
|
40
|
+
|
|
41
|
+
**Options**:
|
|
42
|
+
- **IF node** - Check required fields exist
|
|
43
|
+
- **Code node** - Custom validation logic
|
|
44
|
+
- **Stop and Error** - Fail gracefully with message
|
|
45
|
+
|
|
46
|
+
**Example**:
|
|
47
|
+
```javascript
|
|
48
|
+
// IF node condition
|
|
49
|
+
{{$json.body.email}} is not empty AND
|
|
50
|
+
{{$json.body.name}} is not empty
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 3. Transformation
|
|
54
|
+
**Purpose**: Map webhook data to desired format
|
|
55
|
+
|
|
56
|
+
**Typical nodes**:
|
|
57
|
+
- **Set** - Field mapping
|
|
58
|
+
- **Code** - Complex transformations
|
|
59
|
+
|
|
60
|
+
**Example** (Set node):
|
|
61
|
+
```javascript
|
|
62
|
+
{
|
|
63
|
+
"user_email": "={{$json.body.email}}",
|
|
64
|
+
"user_name": "={{$json.body.name}}",
|
|
65
|
+
"timestamp": "={{$now}}"
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 4. Action
|
|
70
|
+
**Purpose**: Do something with the data
|
|
71
|
+
|
|
72
|
+
**Common actions**:
|
|
73
|
+
- Store in database (Postgres, MySQL, MongoDB)
|
|
74
|
+
- Send notification (Slack, Email, Discord)
|
|
75
|
+
- Call another API (HTTP Request)
|
|
76
|
+
- Update external system (CRM, support ticket)
|
|
77
|
+
|
|
78
|
+
### 5. Response (If responseMode: "lastNode")
|
|
79
|
+
**Purpose**: Send custom HTTP response
|
|
80
|
+
|
|
81
|
+
**Webhook Response Node**:
|
|
82
|
+
```javascript
|
|
83
|
+
{
|
|
84
|
+
statusCode: 200,
|
|
85
|
+
headers: {
|
|
86
|
+
"Content-Type": "application/json"
|
|
87
|
+
},
|
|
88
|
+
body: {
|
|
89
|
+
"status": "success",
|
|
90
|
+
"message": "Form received"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Common Use Cases
|
|
98
|
+
|
|
99
|
+
### 1. Form Submissions
|
|
100
|
+
**Flow**: Form → Webhook → Validate → Database → Email Confirmation
|
|
101
|
+
|
|
102
|
+
**Example**:
|
|
103
|
+
```
|
|
104
|
+
1. Webhook (path: "contact-form", POST)
|
|
105
|
+
2. IF (check email & message not empty)
|
|
106
|
+
3. Postgres (insert into contacts table)
|
|
107
|
+
4. Email (send confirmation to user)
|
|
108
|
+
5. Slack (notify team in #leads)
|
|
109
|
+
6. Webhook Response ({"status": "success"})
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Real Data Access**:
|
|
113
|
+
```javascript
|
|
114
|
+
Name: {{$json.body.name}}
|
|
115
|
+
Email: {{$json.body.email}}
|
|
116
|
+
Message: {{$json.body.message}}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### 2. Payment Webhooks (Stripe, PayPal)
|
|
120
|
+
**Flow**: Payment Provider → Webhook → Verify → Update Database → Send Receipt
|
|
121
|
+
|
|
122
|
+
**Security**: Verify webhook signatures
|
|
123
|
+
```javascript
|
|
124
|
+
// Code node - verify Stripe signature
|
|
125
|
+
const crypto = require('crypto');
|
|
126
|
+
const signature = $input.item.headers['stripe-signature'];
|
|
127
|
+
const secret = $credentials.stripeWebhookSecret;
|
|
128
|
+
|
|
129
|
+
// Verify signature matches
|
|
130
|
+
const expectedSig = crypto
|
|
131
|
+
.createHmac('sha256', secret)
|
|
132
|
+
.update($input.item.body)
|
|
133
|
+
.digest('hex');
|
|
134
|
+
|
|
135
|
+
if (signature !== expectedSig) {
|
|
136
|
+
throw new Error('Invalid webhook signature');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return $input.item.body; // Return validated body
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 3. Chat Platform Integrations (Slack, Discord, Teams)
|
|
143
|
+
**Flow**: Chat Command → Webhook → Process → Respond
|
|
144
|
+
|
|
145
|
+
**Example** (Slack slash command):
|
|
146
|
+
```
|
|
147
|
+
1. Webhook (path: "slack-command", POST)
|
|
148
|
+
2. Code (parse Slack payload: $json.body.text, $json.body.user_id)
|
|
149
|
+
3. HTTP Request (fetch data from API)
|
|
150
|
+
4. Set (format Slack message)
|
|
151
|
+
5. Webhook Response (immediate Slack response)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Slack Data Access**:
|
|
155
|
+
```javascript
|
|
156
|
+
Command: {{$json.body.command}}
|
|
157
|
+
Text: {{$json.body.text}}
|
|
158
|
+
User ID: {{$json.body.user_id}}
|
|
159
|
+
Channel ID: {{$json.body.channel_id}}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 4. GitHub/GitLab Webhooks
|
|
163
|
+
**Flow**: Git Event → Webhook → Parse → Notify/Deploy
|
|
164
|
+
|
|
165
|
+
**Example** (new PR notification):
|
|
166
|
+
```
|
|
167
|
+
1. Webhook (path: "github", POST)
|
|
168
|
+
2. IF (check $json.body.action equals "opened")
|
|
169
|
+
3. Set (extract PR details: title, author, url)
|
|
170
|
+
4. Slack (notify #dev-team)
|
|
171
|
+
5. Webhook Response (200 OK)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**GitHub Data Access**:
|
|
175
|
+
```javascript
|
|
176
|
+
Event Type: {{$json.headers['x-github-event']}}
|
|
177
|
+
Action: {{$json.body.action}}
|
|
178
|
+
PR Title: {{$json.body.pull_request.title}}
|
|
179
|
+
Author: {{$json.body.pull_request.user.login}}
|
|
180
|
+
URL: {{$json.body.pull_request.html_url}}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 5. IoT Device Data
|
|
184
|
+
**Flow**: Device → Webhook → Validate → Store → Alert (if threshold)
|
|
185
|
+
|
|
186
|
+
**Example** (temperature sensor):
|
|
187
|
+
```
|
|
188
|
+
1. Webhook (path: "sensor-data", POST)
|
|
189
|
+
2. Set (extract sensor readings)
|
|
190
|
+
3. Postgres (insert into sensor_readings)
|
|
191
|
+
4. IF (temperature > 80)
|
|
192
|
+
5. Email (alert admin)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Webhook Data Structure
|
|
198
|
+
|
|
199
|
+
### Standard Structure
|
|
200
|
+
```json
|
|
201
|
+
{
|
|
202
|
+
"headers": {
|
|
203
|
+
"content-type": "application/json",
|
|
204
|
+
"user-agent": "...",
|
|
205
|
+
"x-custom-header": "..."
|
|
206
|
+
},
|
|
207
|
+
"params": {
|
|
208
|
+
"id": "123" // From URL: /webhook/form/:id
|
|
209
|
+
},
|
|
210
|
+
"query": {
|
|
211
|
+
"token": "abc" // From URL: /webhook/form?token=abc
|
|
212
|
+
},
|
|
213
|
+
"body": {
|
|
214
|
+
// ⚠️ YOUR DATA IS HERE!
|
|
215
|
+
"name": "John",
|
|
216
|
+
"email": "john@example.com"
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Accessing Different Parts
|
|
222
|
+
```javascript
|
|
223
|
+
// Headers
|
|
224
|
+
{{$json.headers['content-type']}}
|
|
225
|
+
{{$json.headers['x-api-key']}}
|
|
226
|
+
|
|
227
|
+
// URL Parameters
|
|
228
|
+
{{$json.params.id}}
|
|
229
|
+
|
|
230
|
+
// Query Parameters
|
|
231
|
+
{{$json.query.token}}
|
|
232
|
+
{{$json.query.page}}
|
|
233
|
+
|
|
234
|
+
// Body (MOST COMMON)
|
|
235
|
+
{{$json.body.email}}
|
|
236
|
+
{{$json.body.user.name}}
|
|
237
|
+
{{$json.body.items[0].price}}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Authentication & Security
|
|
243
|
+
|
|
244
|
+
### 1. Query Parameter Token
|
|
245
|
+
**Simple but less secure**
|
|
246
|
+
```javascript
|
|
247
|
+
// IF node - validate token
|
|
248
|
+
{{$json.query.token}} equals "your-secret-token"
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### 2. Header-Based Auth
|
|
252
|
+
**Better security**
|
|
253
|
+
```javascript
|
|
254
|
+
// IF node - check header
|
|
255
|
+
{{$json.headers['x-api-key']}} equals "your-api-key"
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### 3. Signature Verification
|
|
259
|
+
**Best security** (for webhooks from services like Stripe, GitHub)
|
|
260
|
+
```javascript
|
|
261
|
+
// Code node
|
|
262
|
+
const crypto = require('crypto');
|
|
263
|
+
const signature = $input.item.headers['x-signature'];
|
|
264
|
+
const secret = $credentials.webhookSecret;
|
|
265
|
+
|
|
266
|
+
const calculatedSig = crypto
|
|
267
|
+
.createHmac('sha256', secret)
|
|
268
|
+
.update(JSON.stringify($input.item.body))
|
|
269
|
+
.digest('hex');
|
|
270
|
+
|
|
271
|
+
if (signature !== `sha256=${calculatedSig}`) {
|
|
272
|
+
throw new Error('Invalid signature');
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return $input.item.body;
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### 4. IP Whitelist
|
|
279
|
+
**Restrict access by IP** (n8n workflow settings)
|
|
280
|
+
- Configure in workflow settings
|
|
281
|
+
- Only allow specific IP ranges
|
|
282
|
+
- Use for internal systems
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Response Modes
|
|
287
|
+
|
|
288
|
+
### onReceived (Default)
|
|
289
|
+
**Behavior**: Immediate 200 OK response, workflow continues in background
|
|
290
|
+
|
|
291
|
+
**Use when**:
|
|
292
|
+
- Long-running workflows
|
|
293
|
+
- Response doesn't depend on workflow result
|
|
294
|
+
- Fire-and-forget processing
|
|
295
|
+
|
|
296
|
+
**Configuration**:
|
|
297
|
+
```javascript
|
|
298
|
+
{
|
|
299
|
+
responseMode: "onReceived",
|
|
300
|
+
responseCode: 200
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### lastNode (Custom Response)
|
|
305
|
+
**Behavior**: Wait for workflow completion, send custom response
|
|
306
|
+
|
|
307
|
+
**Use when**:
|
|
308
|
+
- Need to return data to caller
|
|
309
|
+
- Synchronous processing required
|
|
310
|
+
- Form submissions with confirmation
|
|
311
|
+
|
|
312
|
+
**Configuration**:
|
|
313
|
+
```javascript
|
|
314
|
+
{
|
|
315
|
+
responseMode: "lastNode"
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**Then add Webhook Response node**:
|
|
320
|
+
```javascript
|
|
321
|
+
{
|
|
322
|
+
statusCode: 200,
|
|
323
|
+
headers: {
|
|
324
|
+
"Content-Type": "application/json"
|
|
325
|
+
},
|
|
326
|
+
body: {
|
|
327
|
+
"id": "={{$json.record_id}}",
|
|
328
|
+
"status": "success"
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Error Handling
|
|
336
|
+
|
|
337
|
+
### Pattern 1: Try-Catch with Error Trigger
|
|
338
|
+
```
|
|
339
|
+
Main Flow:
|
|
340
|
+
Webhook → [nodes...] → Success Response
|
|
341
|
+
|
|
342
|
+
Error Flow:
|
|
343
|
+
Error Trigger → Log Error → Slack Alert → Error Response
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Error Trigger Configuration**:
|
|
347
|
+
```javascript
|
|
348
|
+
{
|
|
349
|
+
workflowId: "current-workflow-id"
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**Error Response** (if responseMode: "lastNode"):
|
|
354
|
+
```javascript
|
|
355
|
+
{
|
|
356
|
+
statusCode: 500,
|
|
357
|
+
body: {
|
|
358
|
+
"status": "error",
|
|
359
|
+
"message": "Processing failed"
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Pattern 2: Validation Early Exit
|
|
365
|
+
```
|
|
366
|
+
Webhook → IF (validate) → [True: Process]
|
|
367
|
+
└→ [False: Error Response]
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
**False Branch Response**:
|
|
371
|
+
```javascript
|
|
372
|
+
{
|
|
373
|
+
statusCode: 400,
|
|
374
|
+
body: {
|
|
375
|
+
"status": "error",
|
|
376
|
+
"message": "Invalid data: missing email"
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Pattern 3: Continue On Fail
|
|
382
|
+
**Per-node setting**: Continue even if node fails
|
|
383
|
+
|
|
384
|
+
**Use case**: Non-critical notifications
|
|
385
|
+
```
|
|
386
|
+
Webhook → Database (critical) → Slack (continueOnFail: true)
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
## Testing Webhooks
|
|
392
|
+
|
|
393
|
+
### 1. Use Manual Trigger
|
|
394
|
+
Replace Webhook with Manual Trigger for testing:
|
|
395
|
+
```
|
|
396
|
+
Manual Trigger → [set test data] → rest of workflow
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### 2. Use curl
|
|
400
|
+
```bash
|
|
401
|
+
curl -X POST https://n8n.example.com/webhook/form-submit \
|
|
402
|
+
-H "Content-Type: application/json" \
|
|
403
|
+
-d '{"email": "test@example.com", "name": "Test User"}'
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### 3. Use Postman/Insomnia
|
|
407
|
+
- Create request collection
|
|
408
|
+
- Test different payloads
|
|
409
|
+
- Verify responses
|
|
410
|
+
|
|
411
|
+
### 4. Webhook.site
|
|
412
|
+
- Use webhook.site for testing
|
|
413
|
+
- Copy webhook.site URL to your service
|
|
414
|
+
- View requests and debug
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
## Performance Considerations
|
|
419
|
+
|
|
420
|
+
### Large Payloads
|
|
421
|
+
- Webhook timeout: 120 seconds (default)
|
|
422
|
+
- For large data, consider async processing:
|
|
423
|
+
```
|
|
424
|
+
Webhook → Queue (Redis/DB) → Response (immediate)
|
|
425
|
+
|
|
426
|
+
Separate Workflow:
|
|
427
|
+
Schedule → Check Queue → Process
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### High Volume
|
|
431
|
+
- Use "Execute Once" mode if processing all items together
|
|
432
|
+
- Consider rate limiting
|
|
433
|
+
- Monitor execution times
|
|
434
|
+
- Scale n8n instance if needed
|
|
435
|
+
|
|
436
|
+
### Retries
|
|
437
|
+
- Webhook calls typically don't retry automatically
|
|
438
|
+
- Implement retry logic on caller side
|
|
439
|
+
- Or use queue pattern for guaranteed processing
|
|
440
|
+
|
|
441
|
+
---
|
|
442
|
+
|
|
443
|
+
## Common Gotchas
|
|
444
|
+
|
|
445
|
+
### 1. ❌ Wrong: Accessing webhook data
|
|
446
|
+
```javascript
|
|
447
|
+
{{$json.email}} // Empty or undefined
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### ✅ Correct
|
|
451
|
+
```javascript
|
|
452
|
+
{{$json.body.email}} // Data is under .body
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### 2. ❌ Wrong: Response mode confusion
|
|
456
|
+
Using Webhook Response node with responseMode: "onReceived" (ignored)
|
|
457
|
+
|
|
458
|
+
### ✅ Correct
|
|
459
|
+
Set responseMode: "lastNode" to use Webhook Response node
|
|
460
|
+
|
|
461
|
+
### 3. ❌ Wrong: No validation
|
|
462
|
+
Assuming data is always present and valid
|
|
463
|
+
|
|
464
|
+
### ✅ Correct
|
|
465
|
+
Validate data early with IF node or Code node
|
|
466
|
+
|
|
467
|
+
### 4. ❌ Wrong: Hardcoded paths
|
|
468
|
+
Using same path for dev/prod
|
|
469
|
+
|
|
470
|
+
### ✅ Correct
|
|
471
|
+
Use environment variables: `{{$env.WEBHOOK_PATH_PREFIX}}/form-submit`
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
## Real Template Examples
|
|
476
|
+
|
|
477
|
+
From n8n template library (1,085 webhook templates):
|
|
478
|
+
|
|
479
|
+
**Simple Form to Slack**:
|
|
480
|
+
```
|
|
481
|
+
Webhook → Set → Slack
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
**Payment Processing**:
|
|
485
|
+
```
|
|
486
|
+
Webhook → Verify Signature → Update Database → Send Receipt → Notify Admin
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
**Chat Bot**:
|
|
490
|
+
```
|
|
491
|
+
Webhook → Parse Command → AI Agent → Format Response → Webhook Response
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
Use `search_templates({query: "webhook"})` to find more!
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
## Checklist for Webhook Workflows
|
|
499
|
+
|
|
500
|
+
### Setup
|
|
501
|
+
- [ ] Choose descriptive webhook path
|
|
502
|
+
- [ ] Configure HTTP method (POST most common)
|
|
503
|
+
- [ ] Choose response mode (onReceived vs lastNode)
|
|
504
|
+
- [ ] Test webhook URL before connecting services
|
|
505
|
+
|
|
506
|
+
### Security
|
|
507
|
+
- [ ] Add authentication (token, signature, IP whitelist)
|
|
508
|
+
- [ ] Validate incoming data
|
|
509
|
+
- [ ] Sanitize user input (if storing/displaying)
|
|
510
|
+
- [ ] Use HTTPS (always)
|
|
511
|
+
|
|
512
|
+
### Data Handling
|
|
513
|
+
- [ ] Remember data is under $json.body
|
|
514
|
+
- [ ] Handle missing fields gracefully
|
|
515
|
+
- [ ] Transform data to desired format
|
|
516
|
+
- [ ] Log important data (for debugging)
|
|
517
|
+
|
|
518
|
+
### Error Handling
|
|
519
|
+
- [ ] Add Error Trigger workflow
|
|
520
|
+
- [ ] Validate required fields
|
|
521
|
+
- [ ] Return appropriate error responses
|
|
522
|
+
- [ ] Alert team on failures
|
|
523
|
+
|
|
524
|
+
### Testing
|
|
525
|
+
- [ ] Test with curl/Postman
|
|
526
|
+
- [ ] Test error scenarios
|
|
527
|
+
- [ ] Verify response format
|
|
528
|
+
- [ ] Monitor first executions
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
## Summary
|
|
533
|
+
|
|
534
|
+
**Key Points**:
|
|
535
|
+
1. **Data under $json.body** (most common mistake!)
|
|
536
|
+
2. **Validate early** to catch bad data
|
|
537
|
+
3. **Choose response mode** based on use case
|
|
538
|
+
4. **Secure webhooks** with auth
|
|
539
|
+
5. **Handle errors** gracefully
|
|
540
|
+
|
|
541
|
+
**Pattern**: Webhook → Validate → Transform → Action → Response
|
|
542
|
+
|
|
543
|
+
**Related**:
|
|
544
|
+
- [n8n Expression Syntax](../../n8n-expression-syntax/SKILL.md) - Accessing webhook data correctly
|
|
545
|
+
- [http_api_integration.md](http_api_integration.md) - Making HTTP requests in response
|
|
@@ -181,7 +181,7 @@ return [{
|
|
|
181
181
|
}];
|
|
182
182
|
```
|
|
183
183
|
|
|
184
|
-
**See**: DATA_ACCESS.md for comprehensive guide
|
|
184
|
+
**See**: [DATA_ACCESS.md](DATA_ACCESS.md) for comprehensive guide
|
|
185
185
|
|
|
186
186
|
---
|
|
187
187
|
|
|
@@ -205,7 +205,7 @@ const name = webhookData.name;
|
|
|
205
205
|
|
|
206
206
|
**Why**: Webhook node wraps all request data under `body` property. This includes POST data, query parameters, and JSON payloads.
|
|
207
207
|
|
|
208
|
-
**See**: DATA_ACCESS.md for full webhook structure details
|
|
208
|
+
**See**: [DATA_ACCESS.md](DATA_ACCESS.md) for full webhook structure details
|
|
209
209
|
|
|
210
210
|
---
|
|
211
211
|
|
|
@@ -275,7 +275,7 @@ return [{data: value}]; // Should be {json: value}
|
|
|
275
275
|
|
|
276
276
|
**Why it matters**: Next nodes expect array format. Incorrect format causes workflow execution to fail.
|
|
277
277
|
|
|
278
|
-
**See**: ERROR_PATTERNS.md #3 for detailed error solutions
|
|
278
|
+
**See**: [ERROR_PATTERNS.md](ERROR_PATTERNS.md) #3 for detailed error solutions
|
|
279
279
|
|
|
280
280
|
---
|
|
281
281
|
|
|
@@ -378,7 +378,7 @@ return [{
|
|
|
378
378
|
}];
|
|
379
379
|
```
|
|
380
380
|
|
|
381
|
-
**See**: COMMON_PATTERNS.md for 10 detailed production patterns
|
|
381
|
+
**See**: [COMMON_PATTERNS.md](COMMON_PATTERNS.md) for 10 detailed production patterns
|
|
382
382
|
|
|
383
383
|
---
|
|
384
384
|
|
|
@@ -447,7 +447,7 @@ const email = $json.email;
|
|
|
447
447
|
const email = $json.body.email;
|
|
448
448
|
```
|
|
449
449
|
|
|
450
|
-
**See**: ERROR_PATTERNS.md for comprehensive error guide
|
|
450
|
+
**See**: [ERROR_PATTERNS.md](ERROR_PATTERNS.md) for comprehensive error guide
|
|
451
451
|
|
|
452
452
|
---
|
|
453
453
|
|
|
@@ -510,7 +510,7 @@ const names = $jmespath(data, 'users[*].name');
|
|
|
510
510
|
return [{json: {adults, names}}];
|
|
511
511
|
```
|
|
512
512
|
|
|
513
|
-
**See**: BUILTIN_FUNCTIONS.md for complete reference
|
|
513
|
+
**See**: [BUILTIN_FUNCTIONS.md](BUILTIN_FUNCTIONS.md) for complete reference
|
|
514
514
|
|
|
515
515
|
---
|
|
516
516
|
|
|
@@ -684,10 +684,10 @@ Before deploying Code nodes, verify:
|
|
|
684
684
|
## Additional Resources
|
|
685
685
|
|
|
686
686
|
### Related Files
|
|
687
|
-
- DATA_ACCESS.md - Comprehensive data access patterns
|
|
688
|
-
- COMMON_PATTERNS.md - 10 production-tested patterns
|
|
689
|
-
- ERROR_PATTERNS.md - Top 5 errors and solutions
|
|
690
|
-
- BUILTIN_FUNCTIONS.md - Complete built-in reference
|
|
687
|
+
- [DATA_ACCESS.md](DATA_ACCESS.md) - Comprehensive data access patterns
|
|
688
|
+
- [COMMON_PATTERNS.md](COMMON_PATTERNS.md) - 10 production-tested patterns
|
|
689
|
+
- [ERROR_PATTERNS.md](ERROR_PATTERNS.md) - Top 5 errors and solutions
|
|
690
|
+
- [BUILTIN_FUNCTIONS.md](BUILTIN_FUNCTIONS.md) - Complete built-in reference
|
|
691
691
|
|
|
692
692
|
### n8n Documentation
|
|
693
693
|
- Code Node Guide: https://docs.n8n.io/code/code-node/
|
|
@@ -231,7 +231,7 @@ return [{
|
|
|
231
231
|
}]
|
|
232
232
|
```
|
|
233
233
|
|
|
234
|
-
**See**: DATA_ACCESS.md for comprehensive guide
|
|
234
|
+
**See**: [DATA_ACCESS.md](DATA_ACCESS.md) for comprehensive guide
|
|
235
235
|
|
|
236
236
|
---
|
|
237
237
|
|
|
@@ -255,7 +255,7 @@ name = webhook_data.get("name")
|
|
|
255
255
|
|
|
256
256
|
**Why**: Webhook node wraps all request data under `body` property. This includes POST data, query parameters, and JSON payloads.
|
|
257
257
|
|
|
258
|
-
**See**: DATA_ACCESS.md for full webhook structure details
|
|
258
|
+
**See**: [DATA_ACCESS.md](DATA_ACCESS.md) for full webhook structure details
|
|
259
259
|
|
|
260
260
|
---
|
|
261
261
|
|
|
@@ -318,7 +318,7 @@ return [{"data": value}] # Should be {"json": value}
|
|
|
318
318
|
|
|
319
319
|
**Why it matters**: Next nodes expect list format. Incorrect format causes workflow execution to fail.
|
|
320
320
|
|
|
321
|
-
**See**: ERROR_PATTERNS.md #2 for detailed error solutions
|
|
321
|
+
**See**: [ERROR_PATTERNS.md](ERROR_PATTERNS.md) #2 for detailed error solutions
|
|
322
322
|
|
|
323
323
|
---
|
|
324
324
|
|
|
@@ -368,7 +368,7 @@ import statistics # ✅ Statistical functions
|
|
|
368
368
|
- ✅ Use **HTTP Request node** + **HTML Extract node**
|
|
369
369
|
- ✅ Or switch to **JavaScript** with regex/string methods
|
|
370
370
|
|
|
371
|
-
**See**: STANDARD_LIBRARY.md for complete reference
|
|
371
|
+
**See**: [STANDARD_LIBRARY.md](STANDARD_LIBRARY.md) for complete reference
|
|
372
372
|
|
|
373
373
|
---
|
|
374
374
|
|
|
@@ -488,7 +488,7 @@ else:
|
|
|
488
488
|
return [{"json": {"error": "No values found"}}]
|
|
489
489
|
```
|
|
490
490
|
|
|
491
|
-
**See**: COMMON_PATTERNS.md for 10 detailed Python patterns
|
|
491
|
+
**See**: [COMMON_PATTERNS.md](COMMON_PATTERNS.md) for 10 detailed Python patterns
|
|
492
492
|
|
|
493
493
|
---
|
|
494
494
|
|
|
@@ -552,7 +552,7 @@ email = _json["body"]["email"]
|
|
|
552
552
|
email = _json.get("body", {}).get("email", "no-email")
|
|
553
553
|
```
|
|
554
554
|
|
|
555
|
-
**See**: ERROR_PATTERNS.md for comprehensive error guide
|
|
555
|
+
**See**: [ERROR_PATTERNS.md](ERROR_PATTERNS.md) for comprehensive error guide
|
|
556
556
|
|
|
557
557
|
---
|
|
558
558
|
|
|
@@ -596,7 +596,7 @@ from statistics import mean, median, stdev
|
|
|
596
596
|
average = mean([1, 2, 3, 4, 5])
|
|
597
597
|
```
|
|
598
598
|
|
|
599
|
-
**See**: STANDARD_LIBRARY.md for complete reference
|
|
599
|
+
**See**: [STANDARD_LIBRARY.md](STANDARD_LIBRARY.md) for complete reference
|
|
600
600
|
|
|
601
601
|
---
|
|
602
602
|
|
|
@@ -734,10 +734,10 @@ Before deploying Python Code nodes, verify:
|
|
|
734
734
|
## Additional Resources
|
|
735
735
|
|
|
736
736
|
### Related Files
|
|
737
|
-
- DATA_ACCESS.md - Comprehensive Python data access patterns
|
|
738
|
-
- COMMON_PATTERNS.md - 10 Python patterns for n8n
|
|
739
|
-
- ERROR_PATTERNS.md - Top 5 errors and solutions
|
|
740
|
-
- STANDARD_LIBRARY.md - Complete standard library reference
|
|
737
|
+
- [DATA_ACCESS.md](DATA_ACCESS.md) - Comprehensive Python data access patterns
|
|
738
|
+
- [COMMON_PATTERNS.md](COMMON_PATTERNS.md) - 10 Python patterns for n8n
|
|
739
|
+
- [ERROR_PATTERNS.md](ERROR_PATTERNS.md) - Top 5 errors and solutions
|
|
740
|
+
- [STANDARD_LIBRARY.md](STANDARD_LIBRARY.md) - Complete standard library reference
|
|
741
741
|
|
|
742
742
|
### n8n Documentation
|
|
743
743
|
- Code Node Guide: https://docs.n8n.io/code/code-node/
|
|
@@ -249,7 +249,7 @@ Don't double-wrap expressions:
|
|
|
249
249
|
|
|
250
250
|
## Common Mistakes
|
|
251
251
|
|
|
252
|
-
For complete error catalog with fixes, see COMMON_MISTAKES.md
|
|
252
|
+
For complete error catalog with fixes, see [COMMON_MISTAKES.md](COMMON_MISTAKES.md)
|
|
253
253
|
|
|
254
254
|
### Quick Fixes
|
|
255
255
|
|
|
@@ -266,7 +266,7 @@ For complete error catalog with fixes, see COMMON_MISTAKES.md
|
|
|
266
266
|
|
|
267
267
|
## Working Examples
|
|
268
268
|
|
|
269
|
-
For real workflow examples, see EXAMPLES.md
|
|
269
|
+
For real workflow examples, see [EXAMPLES.md](EXAMPLES.md)
|
|
270
270
|
|
|
271
271
|
### Example 1: Webhook to Slack
|
|
272
272
|
|
|
@@ -508,8 +508,8 @@ Hello {{$json.name}}!
|
|
|
508
508
|
- `{{$node.HTTP Request}}` → Use `{{$node["HTTP Request"]}}`
|
|
509
509
|
|
|
510
510
|
For more details, see:
|
|
511
|
-
- COMMON_MISTAKES.md - Complete error catalog
|
|
512
|
-
- EXAMPLES.md - Real workflow examples
|
|
511
|
+
- [COMMON_MISTAKES.md](COMMON_MISTAKES.md) - Complete error catalog
|
|
512
|
+
- [EXAMPLES.md](EXAMPLES.md) - Real workflow examples
|
|
513
513
|
|
|
514
514
|
---
|
|
515
515
|
|