This workflow follows the Google Sheets → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "WF3 \u2014 Compat Analytics (Receive + Weekly Report)",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "bih-compat-event",
"responseMode": "onReceived",
"options": {}
},
"id": "webhook-compat",
"name": "Webhook \u2014 Compat Event",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
240,
300
]
},
{
"parameters": {
"operation": "append",
"documentId": {
"__rl": true,
"value": "={{ $vars.COMPAT_SHEET_ID }}",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "BIH Compat Events",
"mode": "name"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"timestamp": "={{ $json.body.ts }}",
"event": "={{ $json.body.event }}",
"brand": "={{ $json.body.brand ?? '' }}",
"model": "={{ $json.body.model ?? '' }}",
"tonnage": "={{ $json.body.tonnage ?? '' }}",
"productCount": "={{ $json.body.productCount ?? '' }}",
"productId": "={{ $json.body.productId ?? '' }}",
"productName": "={{ $json.body.productName ?? '' }}"
}
},
"options": {}
},
"id": "sheets-append",
"name": "Google Sheets \u2014 Append Row",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
480,
180
]
},
{
"parameters": {
"jsCode": "// Transform webhook body \u2192 D1 /ingest/compat field names\nconst body = $json.body || {};\n\n// Required fields\nif (!body.event || !body.ts) return [];\nconst validEvents = ['brand_selected', 'model_selected', 'no_results', 'product_clicked'];\nif (!validEvents.includes(body.event)) return [];\n\nconst out = {\n ts: body.ts,\n event: body.event\n};\n\n// Optional fields \u2014 only include when present\nif (body.brand) out.brand = String(body.brand);\nif (body.model) out.model = String(body.model);\nif (body.tonnage != null && body.tonnage !== '') out.tonnage = Number(body.tonnage);\nif (body.productCount != null) out.product_count = Number(body.productCount);\nif (body.productId) out.product_id = String(body.productId);\nif (body.productName) out.product_name = String(body.productName);\n\nreturn [{ json: out }];"
},
"id": "transform-d1",
"name": "Transform \u2014 D1 Compat Format",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
480,
420
]
},
{
"parameters": {
"method": "POST",
"url": "https://intel-api.freightracing.ca/ingest/compat",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $vars.BIH_API_SECRET }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ $json }}",
"options": {
"timeout": 10000
}
},
"id": "post-d1-compat",
"name": "POST \u2014 D1 Compat",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
720,
420
],
"continueOnFail": true
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"weeksInterval": 1,
"triggerAtDay": [
1
],
"triggerAtHour": 8,
"triggerAtMinute": 0
}
]
}
},
"id": "cron-weekly",
"name": "Cron \u2014 Monday 8AM",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [
240,
660
]
},
{
"parameters": {
"operation": "read",
"documentId": {
"__rl": true,
"value": "={{ $vars.COMPAT_SHEET_ID }}",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "BIH Compat Events",
"mode": "name"
},
"options": {}
},
"id": "sheets-read",
"name": "Google Sheets \u2014 Read All",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
480,
660
]
},
{
"parameters": {
"jsCode": "// Aggregate last 7 days of compat events into a weekly summary\nconst rows = $input.all().map(r => r.json);\nconst cutoff = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();\nconst week = rows.filter(r => r.timestamp && r.timestamp >= cutoff);\n\nif (week.length === 0) {\n return [{ json: { summary: 'No compatibility searches this week.' } }];\n}\n\n// Counts\nconst totalSearches = week.filter(r => r.event === 'model_selected').length;\nconst noResults = week.filter(r => r.event === 'no_results').length;\nconst clicks = week.filter(r => r.event === 'product_clicked').length;\n\n// Top brands\nconst brandCounts = {};\nweek.filter(r => r.event === 'model_selected').forEach(r => {\n brandCounts[r.brand] = (brandCounts[r.brand] || 0) + 1;\n});\nconst topBrands = Object.entries(brandCounts)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([b, n]) => `${b} (${n})`)\n .join(', ');\n\n// Top models\nconst modelCounts = {};\nweek.filter(r => r.event === 'model_selected').forEach(r => {\n const key = `${r.brand} ${r.model}`;\n modelCounts[key] = (modelCounts[key] || 0) + 1;\n});\nconst topModels = Object.entries(modelCounts)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([m, n]) => `${m} (${n})`)\n .join('\\n \u2022 ');\n\n// No-result models\nconst noResultModels = [...new Set(\n week.filter(r => r.event === 'no_results').map(r => `${r.brand} ${r.model} (${r.tonnage}T)`)\n)].join(', ') || 'None';\n\n// Top clicked products\nconst productCounts = {};\nweek.filter(r => r.event === 'product_clicked').forEach(r => {\n productCounts[r.productName] = (productCounts[r.productName] || 0) + 1;\n});\nconst topProducts = Object.entries(productCounts)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 3)\n .map(([p, n]) => `${p} (${n})`)\n .join(', ') || 'None';\n\nconst summary = `\ud83d\udcca BIH Compatibility Finder \u2014 Weekly Report\\n` +\n `Week ending: ${new Date().toLocaleDateString('en-CA')}\\n\\n` +\n `\ud83d\udd0d Total model searches: ${totalSearches}\\n` +\n `\u274c No-result searches: ${noResults}\\n` +\n `\ud83d\udc46 Product clicks: ${clicks}\\n\\n` +\n `\ud83c\udfc6 Top brands:\\n \u2022 ${topBrands || 'None'}\\n\\n` +\n `\ud83d\udd27 Top models:\\n \u2022 ${topModels || 'None'}\\n\\n` +\n `\u26a0\ufe0f No-match models: ${noResultModels}\\n\\n` +\n `\ud83d\udce6 Top clicked: ${topProducts}`;\n\nreturn [{ json: { summary } }];"
},
"id": "code-aggregate",
"name": "Code \u2014 Aggregate Weekly",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
720,
660
]
},
{
"parameters": {
"chatId": "={{ $vars.TELEGRAM_CHAT_ID }}",
"text": "={{ $json.summary }}",
"additionalFields": {}
},
"id": "telegram-report",
"name": "Telegram \u2014 Send Weekly Report",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
960,
580
]
},
{
"parameters": {
"method": "POST",
"url": "http://127.0.0.1:18789/hooks/agent",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer bih-hooks-n8n-7f3a9c2d1e8b"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"message\": \"\u8bf7\u5206\u6790\u4ee5\u4e0b BIH \u517c\u5bb9\u6027\u5468\u62a5\u6570\u636e\uff0c\u7ed9\u51fa\u6df1\u5ea6\u4e1a\u52a1\u6d1e\u5bdf\u548c\u5177\u4f53\u5efa\u8bae\u3002\u91cd\u70b9\u5173\u6ce8\uff1a1) \u54ea\u4e9b\u578b\u53f7\u641c\u7d22\u91cf\u9ad8\u4f46\u65e0\u5339\u914d\u4ea7\u54c1\uff08\u5e93\u5b58\u7f3a\u53e3\u673a\u4f1a\uff09\uff1b2) \u54c1\u724c/\u578b\u53f7\u8d8b\u52bf\u662f\u5426\u8bf4\u660e\u76ee\u6807\u5e02\u573a\u5728\u53d8\u5316\uff1b3) \u7ed9\u51fa 1-3 \u6761\u53ef\u64cd\u4f5c\u7684\u4ea7\u54c1\u6216\u8425\u9500\u5efa\u8bae\u3002\u6570\u636e\u6458\u8981\u5982\u4e0b\uff1a\\n\\n{{ $json.summary }}\",\n \"name\": \"n8n-compat-weekly\",\n \"deliver\": true,\n \"channel\": \"telegram\",\n \"to\": \"{{ $vars.TELEGRAM_CHAT_ID }}\",\n \"model\": \"anyrouter/claude-opus-4-6\",\n \"thinking\": \"medium\",\n \"timeoutSeconds\": 120\n}",
"options": {}
},
"id": "openclaw-ai-analysis",
"name": "OpenClaw \u2014 AI Business Insights",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
960,
740
]
}
],
"connections": {
"Webhook \u2014 Compat Event": {
"main": [
[
{
"node": "Google Sheets \u2014 Append Row",
"type": "main",
"index": 0
},
{
"node": "Transform \u2014 D1 Compat Format",
"type": "main",
"index": 0
}
]
]
},
"Transform \u2014 D1 Compat Format": {
"main": [
[
{
"node": "POST \u2014 D1 Compat",
"type": "main",
"index": 0
}
]
]
},
"Cron \u2014 Monday 8AM": {
"main": [
[
{
"node": "Google Sheets \u2014 Read All",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets \u2014 Read All": {
"main": [
[
{
"node": "Code \u2014 Aggregate Weekly",
"type": "main",
"index": 0
}
]
]
},
"Code \u2014 Aggregate Weekly": {
"main": [
[
{
"node": "Telegram \u2014 Send Weekly Report",
"type": "main",
"index": 0
},
{
"node": "OpenClaw \u2014 AI Business Insights",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": []
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
WF3 — Compat Analytics (Receive + Weekly Report). Uses googleSheets, httpRequest, telegram. Webhook trigger; 9 nodes.
Source: https://github.com/toshskyline996/bih-website/blob/1d735be5dc40099f36852da6867e9e84f52407c7/n8n-workflows/wf3-compat-analytics.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
01_order_processing_tilda. Uses stickyNote, googleSheets, httpRequest, telegram. Webhook trigger; 25 nodes.
This workflow is a complete, production-ready solution for recovering abandoned carts in Shopify stores using a multi-channel, multi-touch approach. It automates personalized follow-ups via Email, SMS
checkProcess(old). Uses googleSheets, httpRequest, telegram, @n-octo-n/n8n-nodes-json-database. Event-driven trigger; 40 nodes.
[](https://www.linkedin.com/in/mosaab-yassir-lafrimi/)[](https://t.me/joevenner)
This template monitors Google Drive folder for new files, extracts text from PDFs, images, text files, CSVs, and Google Docs., reads images with meta/llama-3.2-11b-vision-instruct, structures the resu