This workflow follows the HTTP Request → OpenAI 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 →
{
"updatedAt": "2026-01-16T05:19:00.458Z",
"createdAt": "2026-01-16T05:18:21.484Z",
"id": "jOqm2QFbEBCBTn0Hvem5k",
"name": "Social DM Reply Agent",
"description": null,
"active": false,
"isArchived": false,
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "meta-webhook",
"options": {}
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Webhook - Incoming Messages",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
-144,
208
]
},
{
"parameters": {
"path": "meta-webhook",
"responseMode": "responseNode",
"options": {}
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Webhook - Verification",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
-144,
-112
]
},
{
"parameters": {
"respondWith": "text",
"responseBody": "={{ $json.query['hub.challenge'] }}",
"options": {}
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Respond to Verification",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
80,
-112
]
},
{
"parameters": {
"jsCode": "// Extract message data from Meta webhook payload\nconst entry = $input.first().json.entry?.[0];\nconst messaging = entry?.messaging?.[0] || entry?.changes?.[0]?.value;\n\nif (!messaging) {\n return [{ json: { error: 'No messaging data found' } }];\n}\n\n// Determine platform (Instagram or Facebook)\nlet platform = 'facebook';\nlet senderId = '';\nlet messageText = '';\nlet messageId = '';\nlet timestamp = '';\n\nif (messaging.sender) {\n // Facebook Messenger format\n senderId = messaging.sender.id;\n messageText = messaging.message?.text || '';\n messageId = messaging.message?.mid || '';\n timestamp = messaging.timestamp;\n} else if (messaging.from) {\n // Instagram DM format\n platform = 'instagram';\n senderId = messaging.from.id;\n messageText = messaging.message?.text || '';\n messageId = messaging.message?.id || '';\n timestamp = messaging.timestamp;\n}\n\n// Check for Instagram by looking at page ID pattern or other indicators\nif (entry?.id?.startsWith('17')) {\n platform = 'instagram';\n}\n\nreturn [{\n json: {\n platform,\n senderId,\n messageText,\n messageId,\n timestamp: timestamp || new Date().toISOString(),\n rawEntry: entry\n }\n}];"
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Extract Message Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
80,
208
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "condition-has-message",
"leftValue": "={{ $json.messageText }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "notEmpty"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Has Message Text?",
"type": "n8n-nodes-base.filter",
"typeVersion": 2,
"position": [
304,
208
]
},
{
"parameters": {
"operation": "select"
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Supabase - Get Account",
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
528,
208
]
},
{
"parameters": {
"jsCode": "// Prepare data for reply generation\nconst messageData = $('Extract Message Data').first().json;\nconst accountData = $input.first().json;\n\nconst hasAccount = accountData && Object.keys(accountData).length > 0;\n\nreturn [{\n json: {\n ...messageData,\n accountFound: hasAccount,\n accountId: accountData?.id || null,\n displayName: accountData?.display_name || 'there',\n customContext: accountData?.custom_context || '',\n replyContext: hasAccount \n ? `Customer: ${accountData.display_name || 'Unknown'}. Context: ${accountData.custom_context || 'No specific context available.'}`\n : 'New contact - no prior context available.'\n }\n}];"
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Prepare Reply Context",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
752,
208
]
},
{
"parameters": {
"jsCode": "// Format the reply for sending\nconst context = $('Prepare Reply Context').first().json;\nconst aiResponse = $input.first().json;\n\nconst replyText = aiResponse.message?.content || aiResponse.text || 'Thank you for your message! A team member will get back to you shortly.';\n\nreturn [{\n json: {\n platform: context.platform,\n senderId: context.senderId,\n originalMessage: context.messageText,\n replyText: replyText.trim(),\n accountId: context.accountId,\n timestamp: new Date().toISOString()\n }\n}];"
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Format Reply",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1328,
208
]
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"leftValue": "={{ $json.platform }}",
"rightValue": "instagram",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "Instagram"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"leftValue": "={{ $json.platform }}",
"rightValue": "facebook",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "Facebook"
}
]
},
"options": {}
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Switch - Platform",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
1552,
208
]
},
{
"parameters": {
"method": "POST",
"url": "https://graph.facebook.com/v18.0/me/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpQueryAuth",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "access_token",
"value": "={{ $credentials.pageAccessToken }}"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "recipient",
"value": "={\"id\":\"{{ $json.senderId }}\"}"
},
{
"name": "message",
"value": "={\"text\":\"{{ $json.replyText }}\"}"
}
]
},
"options": {}
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Send Instagram Reply",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1776,
112
]
},
{
"parameters": {
"method": "POST",
"url": "https://graph.facebook.com/v18.0/me/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpQueryAuth",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "access_token",
"value": "={{ $credentials.pageAccessToken }}"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "recipient",
"value": "={\"id\":\"{{ $json.senderId }}\"}"
},
{
"name": "message",
"value": "={\"text\":\"{{ $json.replyText }}\"}"
}
]
},
"options": {}
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Send Facebook Reply",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1776,
304
]
},
{
"parameters": {
"tableId": "message_logs",
"fieldsUi": {
"fieldValues": [
{
"fieldValue": "={{ $('Format Reply').first().json.accountId }}"
},
{
"fieldValue": "incoming"
},
{
"fieldValue": "={{ $('Format Reply').first().json.originalMessage }}"
},
{
"fieldValue": "={{ $('Format Reply').first().json.platform }}"
},
{
"fieldValue": "={{ $('Format Reply').first().json.senderId }}"
}
]
}
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Log Incoming Message",
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2000,
112
]
},
{
"parameters": {
"tableId": "message_logs",
"fieldsUi": {
"fieldValues": [
{
"fieldValue": "={{ $('Format Reply').first().json.accountId }}"
},
{
"fieldValue": "outgoing"
},
{
"fieldValue": "={{ $('Format Reply').first().json.replyText }}"
},
{
"fieldValue": "={{ $('Format Reply').first().json.platform }}"
},
{
"fieldValue": "={{ $('Format Reply').first().json.senderId }}"
}
]
}
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Log Outgoing Reply",
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2224,
112
]
},
{
"parameters": {
"tableId": "message_logs",
"fieldsUi": {
"fieldValues": [
{
"fieldValue": "={{ $('Format Reply').first().json.accountId }}"
},
{
"fieldValue": "incoming"
},
{
"fieldValue": "={{ $('Format Reply').first().json.originalMessage }}"
},
{
"fieldValue": "={{ $('Format Reply').first().json.platform }}"
},
{
"fieldValue": "={{ $('Format Reply').first().json.senderId }}"
}
]
}
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Log Incoming (FB)",
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2000,
304
]
},
{
"parameters": {
"tableId": "message_logs",
"fieldsUi": {
"fieldValues": [
{
"fieldValue": "={{ $('Format Reply').first().json.accountId }}"
},
{
"fieldValue": "outgoing"
},
{
"fieldValue": "={{ $('Format Reply').first().json.replyText }}"
},
{
"fieldValue": "={{ $('Format Reply').first().json.platform }}"
},
{
"fieldValue": "={{ $('Format Reply').first().json.senderId }}"
}
]
}
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "Log Outgoing (FB)",
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2224,
304
]
},
{
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": ""
},
"messages": {
"values": [
{
"content": "You are a helpful customer support assistant. Generate friendly, concise replies to customer messages.\n\nContext about this customer:\n{{ $json.replyContext }}\n\nRules:\n- Keep responses under 160 characters when possible\n- Be warm and professional\n- If you don't know something, offer to connect them with a human\n- Never make up information about products or services",
"role": "system"
},
{
"content": "Customer message: {{ $json.messageText }}\n\nGenerate a helpful reply:"
}
]
},
"options": {
"maxTokens": 150,
"temperature": 0.7
}
},
"id": "{{YOUR_NOTION_PAGE_ID}}",
"name": "OpenAI - Generate Reply",
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1.8,
"position": [
976,
208
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Webhook - Verification": {
"main": [
[
{
"node": "Respond to Verification",
"type": "main",
"index": 0
}
]
]
},
"Webhook - Incoming Messages": {
"main": [
[
{
"node": "Extract Message Data",
"type": "main",
"index": 0
}
]
]
},
"Extract Message Data": {
"main": [
[
{
"node": "Has Message Text?",
"type": "main",
"index": 0
}
]
]
},
"Has Message Text?": {
"main": [
[
{
"node": "Supabase - Get Account",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Get Account": {
"main": [
[
{
"node": "Prepare Reply Context",
"type": "main",
"index": 0
}
]
]
},
"Prepare Reply Context": {
"main": [
[
{
"node": "OpenAI - Generate Reply",
"type": "main",
"index": 0
}
]
]
},
"Format Reply": {
"main": [
[
{
"node": "Switch - Platform",
"type": "main",
"index": 0
}
]
]
},
"Switch - Platform": {
"main": [
[
{
"node": "Send Instagram Reply",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Facebook Reply",
"type": "main",
"index": 0
}
]
]
},
"Send Instagram Reply": {
"main": [
[
{
"node": "Log Incoming Message",
"type": "main",
"index": 0
}
]
]
},
"Log Incoming Message": {
"main": [
[
{
"node": "Log Outgoing Reply",
"type": "main",
"index": 0
}
]
]
},
"Send Facebook Reply": {
"main": [
[
{
"node": "Log Incoming (FB)",
"type": "main",
"index": 0
}
]
]
},
"Log Incoming (FB)": {
"main": [
[
{
"node": "Log Outgoing (FB)",
"type": "main",
"index": 0
}
]
]
},
"OpenAI - Generate Reply": {
"main": [
[
{
"node": "Format Reply",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"availableInMCP": false
},
"staticData": null,
"meta": null,
"versionId": "{{YOUR_NOTION_PAGE_ID}}",
"activeVersionId": null,
"versionCounter": 2,
"triggerCount": 0,
"shared": [
{
"updatedAt": "2026-01-16T05:18:21.484Z",
"createdAt": "2026-01-16T05:18:21.484Z",
"role": "workflow:owner",
"workflowId": "jOqm2QFbEBCBTn0Hvem5k",
"projectId": "7NOiDJlVGtj6HHEb",
"project": {
"updatedAt": "2025-01-26T16:28:33.630Z",
"createdAt": "2025-01-26T11:37:02.698Z",
"id": "7NOiDJlVGtj6HHEb",
"name": "Rayan Ratego <rayanratego@gmail.com>",
"type": "personal",
"icon": null,
"description": null,
"creatorId": "{{YOUR_NOTION_PAGE_ID}}",
"projectRelations": [
{
"updatedAt": "2025-01-26T11:37:02.698Z",
"createdAt": "2025-01-26T11:37:02.698Z",
"userId": "{{YOUR_NOTION_PAGE_ID}}",
"projectId": "7NOiDJlVGtj6HHEb",
"user": {
"updatedAt": "2026-05-06T14:08:54.748Z",
"createdAt": "2025-01-26T11:36:47.660Z",
"id": "{{YOUR_NOTION_PAGE_ID}}",
"email": "rayanratego@gmail.com",
"firstName": "Rayan",
"lastName": "Ratego",
"personalizationAnswers": {
"version": "v4",
"personalization_survey_submitted_at": "2025-01-26T16:29:57.338Z",
"personalization_survey_n8n_version": "1.75.2",
"companyIndustryExtended": [
"it-industry",
"healthcare",
"marketing-industry",
"media-industry"
],
"companySize": "<20",
"companyType": "other",
"role": "business-owner",
"reportedSource": "youtube"
},
"settings": {
"userActivated": true,
"easyAIWorkflowOnboarded": true,
"firstSuccessfulWorkflowId": "qyOU7EgejsL50BFL",
"userActivatedAt": 1757343922037,
"npsSurvey": {
"responded": true,
"lastShownAt": 1771221135008
}
},
"disabled": false,
"mfaEnabled": false,
"lastActiveAt": "2026-05-06",
"isPending": false
}
}
]
}
}
],
"tags": [],
"activeVersion": null
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
openAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Social DM Reply Agent. Uses supabase, httpRequest, openAi. Webhook trigger; 16 nodes.
Source: https://gist.github.com/Rategor/ca598aa7a32e96d9ff65eaa8274ebea0 — 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.
leads. Uses supabase, gmail, formTrigger, httpRequest. Webhook trigger; 62 nodes.
Agent: IPTV (instance_e2165d22_1762376395079). Uses openAi, redis, supabase, httpRequest. Webhook trigger; 56 nodes.
'Elena AI' is a powerful n8n workflow that transforms your automation platform into a full-fledged, multi-agent AI hub. 🤖✨ By combining Redis state management with specialized “tool” sub-workflows, yo
Ai Agent For Realtime Insights On Meetings. Uses openAi, postgres, postgresTool, httpRequest. Webhook trigger; 19 nodes.
I prepared a detailed guide explaining how to build an AI-powered meeting assistant that provides real-time transcription and insights during virtual meetings.