This workflow corresponds to n8n.io template #17904 — we link there as the canonical source.
This workflow follows the Agent → Facebookgraphapi 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 →
{
"id": "WxNDmriGQmXYuW4O",
"meta": {
"builderVariant": "mcp",
"aiBuilderAssisted": true
},
"name": "Answer Facebook Messenger product questions with AI and Google Sheets inventory",
"tags": [],
"nodes": [
{
"id": "24b20d58-be53-468f-bb4d-e778f760080b",
"name": "Trigger \u2013 New Facebook Messenger Message",
"type": "n8n-nodes-base.facebookTrigger",
"position": [
-1984,
192
],
"parameters": {
"appId": "<__PLACEHOLDER_VALUE__Your Facebook App ID (developers.facebook.com)__>",
"fields": [
"messages"
],
"object": "page",
"options": {}
},
"typeVersion": 1
},
{
"id": "4d40178e-5e33-4ebc-aa5b-9026d5d5f052",
"name": "Split Out Facebook Page Entries",
"type": "n8n-nodes-base.splitOut",
"position": [
-1728,
192
],
"parameters": {
"options": {},
"fieldToSplitOut": "entry"
},
"typeVersion": 1
},
{
"id": "5c5aaa3d-3f49-4ad6-a81a-4eca3c28cb86",
"name": "Split Out Messenger Events",
"type": "n8n-nodes-base.splitOut",
"position": [
-1472,
192
],
"parameters": {
"options": {},
"fieldToSplitOut": "messaging"
},
"typeVersion": 1
},
{
"id": "19916a4f-c67b-44c7-88b8-9674ef7d2b12",
"name": "Check Valid Customer Message",
"type": "n8n-nodes-base.if",
"position": [
-1248,
192
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "notEmpty"
},
"leftValue": "={{ $json.message?.text }}",
"rightValue": ""
},
{
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ !!$json.message?.is_echo }}",
"rightValue": false
}
]
}
},
"typeVersion": 2.3
},
{
"id": "b10cd7b6-4bf7-4c1e-805b-b92f3c6b45cd",
"name": "Configuration",
"type": "n8n-nodes-base.set",
"position": [
-1056,
160
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "cfg-1",
"name": "openai_model",
"type": "string",
"value": "gpt-5-mini"
},
{
"id": "cfg-2",
"name": "model_temperature",
"type": "number",
"value": 0.2
},
{
"id": "cfg-3",
"name": "match_confidence_threshold",
"type": "number",
"value": 60
},
{
"id": "cfg-4",
"name": "not_found_reply_template",
"type": "string",
"value": "Hi! Thanks for reaching out \ud83d\ude4f We don't currently have that item in stock, but our team will follow up as soon as it's available."
},
{
"id": "cfg-5",
"name": "customer_message",
"type": "string",
"value": "={{ $json.message.text }}"
},
{
"id": "cfg-6",
"name": "customer_psid",
"type": "string",
"value": "={{ $json.sender.id }}"
},
{
"id": "cfg-7",
"name": "page_id",
"type": "string",
"value": "={{ $json.recipient.id }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "f79c960f-e680-4ce7-9fb1-94d9767858a9",
"name": "AI \u2013 Extract Product & Customer Intent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-800,
416
],
"parameters": {
"text": "=Customer message:\n\"{{ $json.customer_message }}\"\n\nExtract the product name, the customer's intent, and your reasoning.",
"options": {
"systemMessage": "You are an AI assistant for a Facebook Messenger shop assistant. You read one customer message and extract structured information.\n\nRules:\n1. Identify the product name mentioned \u2014 be flexible with typos, plural/singular, and casual wording. Return a clean, lowercase product name only.\n2. Detect the customer's intent: one of 'availability', 'price', 'general_question', or 'other'.\n3. Add a short one-sentence reasoning explaining your extraction (for debugging).\n4. Always return clean JSON only \u2014 no explanation text outside the JSON."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 3.1
},
{
"id": "d56ef31c-cc2c-4a77-a97d-887b7b27fbd3",
"name": "OpenAI Model \u2014 Intent Extraction",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
-800,
656
],
"parameters": {
"model": {
"__rl": true,
"mode": "id",
"value": "={{ $('Configuration').item.json.openai_model }}"
},
"options": {
"temperature": "={{ $('Configuration').item.json.model_temperature }}"
},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "e3d7b884-a3c7-4170-b988-b0e89828fca2",
"name": "Structured Output Parser \u2014 Intent",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-640,
640
],
"parameters": {
"jsonSchemaExample": "{ \"product_name\": \"red backpack\", \"intent\": \"availability\", \"reasoning\": \"Customer explicitly asked if the red backpack is in stock\" }"
},
"typeVersion": 1.3
},
{
"id": "757b2626-c7c2-4da5-91bb-e47bb243a769",
"name": "Combine Intent + Inventory Data",
"type": "n8n-nodes-base.merge",
"position": [
-384,
416
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "6aaf76a1-bdff-4a59-b9b0-9cb0e41d1910",
"name": "Log Skipped Event to Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1072,
352
],
"parameters": {
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": "skipped_events"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": "Facebook Messenger Assistant \u2014 Skipped Events"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "d59ae44d-c57c-4d07-bff9-15588fdab646",
"name": "Fetch Inventory Records from Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
-864,
160
],
"parameters": {
"sheetName": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": "inventory"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": "Facebook Messenger Assistant \u2014 Inventory"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "032aa391-0211-4496-aaf8-e1d3967ea6b7",
"name": "Aggregate Inventory Into Single List",
"type": "n8n-nodes-base.aggregate",
"position": [
-592,
192
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData",
"destinationFieldName": "inventory"
},
"typeVersion": 1
},
{
"id": "e2880ef2-ab55-4570-b2f2-01ccb8ca2186",
"name": "Prepare Product Matching Payload",
"type": "n8n-nodes-base.set",
"position": [
-176,
416
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "pm-1",
"name": "product_query",
"type": "string",
"value": "={{ $json.output.product_name }}"
},
{
"id": "pm-2",
"name": "customer_intent",
"type": "string",
"value": "={{ $json.output.intent }}"
},
{
"id": "pm-3",
"name": "inventory_list",
"type": "string",
"value": "={{ JSON.stringify($json.inventory) }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "06634c97-141e-4de2-914c-2f8547ce3369",
"name": "AI \u2013 Match Requested Product in Inventory",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-256,
672
],
"parameters": {
"text": "=Customer product request:\n- Product: \"{{ $json.product_query }}\"\n- Intent: \"{{ $json.customer_intent }}\"\n\nCurrent inventory (JSON):\n{{ $json.inventory_list }}\n\nDetermine whether this product exists in the inventory and prepare a reply.",
"options": {
"systemMessage": "You are an AI product-lookup assistant for a Facebook Messenger shop.\n\nRules:\n1. Match the requested product against the inventory list. Accept close/fuzzy matches (typos, synonyms), but never invent a product that isn't in the list.\n2. If found, return the matching inventory item and a confidence score 0-100.\n3. If not found, return found: false, matched_item: {}, and a confidence score 0-100 for how sure you are it's really absent.\n4. Write a short, friendly, ready-to-send reply in the same language the customer wrote in. If found, mention the product name and price when available.\n5. Add a one-sentence reasoning field for debugging.\n6. Always return clean JSON only."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 3.1
},
{
"id": "2be0f26d-ed80-43ba-aeb9-a2d369fc80d0",
"name": "OpenAI Model \u2014 Product Matching",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
-256,
928
],
"parameters": {
"model": {
"__rl": true,
"mode": "id",
"value": "={{ $('Configuration').item.json.openai_model }}"
},
"options": {
"temperature": "={{ $('Configuration').item.json.model_temperature }}"
},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "07aface6-5ae2-45d7-9ace-f4dfc22e7b35",
"name": "Structured Output Parser \u2014 Product Match",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-112,
912
],
"parameters": {
"jsonSchemaExample": "{ \"product_name\": \"red backpack\", \"found\": true, \"matched_item\": { \"name\": \"Red Backpack\", \"price\": \"49.99\", \"stock\": \"in stock\" }, \"reply\": \"Yes! Our Red Backpack is in stock for $49.99.\", \"confidence\": 92, \"reasoning\": \"Exact name match found in inventory row 4\" }"
},
"typeVersion": 1.3
},
{
"id": "5e444eb0-9769-4a96-a8a4-1ae24aab3f07",
"name": "Check If Product Exists",
"type": "n8n-nodes-base.if",
"position": [
80,
0
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $json.output.found }}",
"rightValue": true
},
{
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.output.confidence }}",
"rightValue": "={{ $('Configuration').item.json.match_confidence_threshold }}"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "3e3946eb-f2c4-4e0a-81ee-c99271df559b",
"name": "Send Facebook Reply \u2014 Product Found",
"type": "n8n-nodes-base.facebookGraphApi",
"position": [
320,
-128
],
"parameters": {
"edge": "messages",
"node": "me",
"options": {
"queryParametersJson": "={{ { \"recipient\": { \"id\": $(\"Configuration\").item.json.customer_psid }, \"messaging_type\": \"RESPONSE\", \"message\": { \"text\": $json.output.reply } } }}"
},
"graphApiVersion": "v23.0",
"httpRequestMethod": "POST"
},
"typeVersion": 1
},
{
"id": "204c4150-0249-41ed-9c2d-8a242bf64ee5",
"name": "Log Conversation to Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
560,
0
],
"parameters": {
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": "conversations"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": "Facebook Messenger Assistant \u2014 Conversations"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "78043a5f-9b66-4c61-bea8-cf8e2985c3e4",
"name": "Send Facebook Reply \u2014 Product Not Found",
"type": "n8n-nodes-base.facebookGraphApi",
"position": [
320,
144
],
"parameters": {
"edge": "messages",
"node": "me",
"options": {
"queryParametersJson": "={{ { \"recipient\": { \"id\": $(\"Configuration\").item.json.customer_psid }, \"messaging_type\": \"RESPONSE\", \"message\": { \"text\": $(\"Configuration\").item.json.not_found_reply_template } } }}"
},
"graphApiVersion": "v23.0",
"httpRequestMethod": "POST"
},
"typeVersion": 1
},
{
"id": "90340c70-2f09-4419-a73e-5846e5623081",
"name": "Sticky Note 56a0e62c",
"type": "n8n-nodes-base.stickyNote",
"position": [
880,
-432
],
"parameters": {
"color": 4,
"width": 720,
"height": 1604,
"content": "# Answer Facebook Messenger product questions with AI and Google Sheets inventory\n# \ud83d\udce5 [Open full documentation on Notion](https://automatisation.notion.site/Course-Answer-Facebook-Messenger-product-questions-with-AI-and-Google-Sheets-inventory-3a03d6550fd98190a9eed6f95b947879)\n\n## How it works\nA Facebook Messenger message comes in through a real-time webhook. AI reads the customer's message, identifies the product they're asking about, checks it against your Google Sheets inventory, then sends an instant, on-brand reply \u2014 found or not found \u2014 and logs every conversation for review.\n\n## Setup\n1. Create a Facebook App at developers.facebook.com and connect a Page.\n2. Create the 'Facebook Graph App API' credential (App ID + App Secret) and select it on the trigger.\n3. Create the 'Facebook Graph API' credential (Page Access Token) and select it on both 'Send Facebook Reply' nodes.\n4. Pick your Google Sheets inventory + logging spreadsheets on the 3 Google Sheets nodes.\n5. Adjust the 'Configuration' node, activate the workflow.\n\n## Requirements\n- Facebook Page + Facebook App with the Messenger product enabled\n- OpenAI account\n- Google Sheets (inventory + logging)\n\n## Customization\n- Adjust the AI model, temperature and confidence threshold in Configuration\n- Edit the not-found reply template to match your brand voice\n- Add more Switch branches for price questions vs availability questions\n\nNeed help customizing?\nContact me for consulting and support : [Linkedin](https://www.linkedin.com/in/doctor-firass/)\n\n# MY NEW YOUTUBE CHANNEL\n\ud83d\udc49 [Subscribe to my new YouTube channel](https://www.youtube.com/@DrFiras_AI). Here I'll share videos and Shorts with practical tutorials and FREE templates for n8n.\n\n[](https://www.youtube.com/@DrFiras_AI)"
},
"typeVersion": 1
},
{
"id": "1fd02afa-8c38-4840-947e-f27fbba0704e",
"name": "Sticky Note 7af1111b",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2048,
-48
],
"parameters": {
"color": 7,
"width": 780,
"height": 200,
"content": "## Intake \u2014 Real-Time Messenger Webhook\nFacebook pushes each message the instant it arrives (no polling). We flatten the payload natively and drop anything that is not a real customer text message (delivery receipts, read receipts, bot echoes)."
},
"typeVersion": 1
},
{
"id": "5e1f6579-fec2-41a0-9f1c-abfc4a7ca357",
"name": "Sticky Note 6e995673",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1248,
-48
],
"parameters": {
"color": 7,
"width": 300,
"height": 200,
"content": "## Configuration\nOne place to adjust the AI model, temperature, confidence threshold and the not-found reply text."
},
"typeVersion": 1
},
{
"id": "7e601baa-0691-41a2-9b49-9a33d64a960b",
"name": "Sticky Note b1dd5c77",
"type": "n8n-nodes-base.stickyNote",
"position": [
-816,
848
],
"parameters": {
"color": 7,
"width": 300,
"height": 200,
"content": "## AI Intent Understanding\nGPT-5 mini reads the message and extracts the product name + intent as clean structured JSON."
},
"typeVersion": 1
},
{
"id": "e502e524-4718-4428-83db-6f7eccf68ba2",
"name": "Sticky Note ece6c899",
"type": "n8n-nodes-base.stickyNote",
"position": [
-928,
-48
],
"parameters": {
"color": 7,
"width": 940,
"height": 196,
"content": "## Inventory Matching\nPulls the full Google Sheets inventory, combines it with the AI-interpreted request, and asks a second AI agent to decide if the product exists \u2014 with a confidence score."
},
"typeVersion": 1
},
{
"id": "2dd4c427-732b-44b4-96c6-3d4c4b060280",
"name": "Sticky Note 52a8d167",
"type": "n8n-nodes-base.stickyNote",
"position": [
32,
-256
],
"parameters": {
"color": 7,
"width": 780,
"height": 604,
"content": "## Reply Delivery & Logging\nSends a personalized reply when the product is found (confidence-gated), or a consistent on-brand template when not. Every conversation is logged to Google Sheets for review."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"availableInMCP": true,
"executionOrder": "v1"
},
"versionId": "d5c66339-81b9-4de1-8572-10c11c24263a",
"nodeGroups": [],
"connections": {
"Configuration": {
"main": [
[
{
"node": "AI \u2013 Extract Product & Customer Intent",
"type": "main",
"index": 0
},
{
"node": "Fetch Inventory Records from Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Check If Product Exists": {
"main": [
[
{
"node": "Send Facebook Reply \u2014 Product Found",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Facebook Reply \u2014 Product Not Found",
"type": "main",
"index": 0
}
]
]
},
"Split Out Messenger Events": {
"main": [
[
{
"node": "Check Valid Customer Message",
"type": "main",
"index": 0
}
]
]
},
"Check Valid Customer Message": {
"main": [
[
{
"node": "Configuration",
"type": "main",
"index": 0
}
],
[
{
"node": "Log Skipped Event to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Combine Intent + Inventory Data": {
"main": [
[
{
"node": "Prepare Product Matching Payload",
"type": "main",
"index": 0
}
]
]
},
"Split Out Facebook Page Entries": {
"main": [
[
{
"node": "Split Out Messenger Events",
"type": "main",
"index": 0
}
]
]
},
"Prepare Product Matching Payload": {
"main": [
[
{
"node": "AI \u2013 Match Requested Product in Inventory",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Model \u2014 Product Matching": {
"ai_languageModel": [
[
{
"node": "AI \u2013 Match Requested Product in Inventory",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"OpenAI Model \u2014 Intent Extraction": {
"ai_languageModel": [
[
{
"node": "AI \u2013 Extract Product & Customer Intent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Structured Output Parser \u2014 Intent": {
"ai_outputParser": [
[
{
"node": "AI \u2013 Extract Product & Customer Intent",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Aggregate Inventory Into Single List": {
"main": [
[
{
"node": "Combine Intent + Inventory Data",
"type": "main",
"index": 1
}
]
]
},
"Send Facebook Reply \u2014 Product Found": {
"main": [
[
{
"node": "Log Conversation to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"AI \u2013 Extract Product & Customer Intent": {
"main": [
[
{
"node": "Combine Intent + Inventory Data",
"type": "main",
"index": 0
}
]
]
},
"Send Facebook Reply \u2014 Product Not Found": {
"main": [
[
{
"node": "Log Conversation to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Fetch Inventory Records from Google Sheets": {
"main": [
[
{
"node": "Aggregate Inventory Into Single List",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser \u2014 Product Match": {
"ai_outputParser": [
[
{
"node": "AI \u2013 Match Requested Product in Inventory",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Trigger \u2013 New Facebook Messenger Message": {
"main": [
[
{
"node": "Split Out Facebook Page Entries",
"type": "main",
"index": 0
}
]
]
},
"AI \u2013 Match Requested Product in Inventory": {
"main": [
[
{
"node": "Check If Product Exists",
"type": "main",
"index": 0
}
]
]
}
}
}
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.
googleSheetsOAuth2ApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow listens for new Facebook Messenger messages, uses OpenAI to extract the requested product and intent, checks the request against an inventory stored in Google Sheets, replies via the Facebook Graph API, and logs skipped events and conversations back to Google…
Source: https://n8n.io/workflows/17904/ — 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.
This comprehensive n8n workflow automates the entire Meta (Facebook/Instagram) advertising process, from asset analysis to ad creation. It combines AI-powered content analysis with automated ad deploy
This workflow is designed for marketers, content creators, agencies, and solo founders who want to publish long‑form posts with visuals on autopilot using n8n and AI agents.
This workflow automates Facebook posting and appointment booking directly from a Telegram bot, making it especially useful for pet grooming businesses that want to keep their social media active while
Streamline Facebook Messenger inbox management with an AI-powered categorization and response system. 💬⚙️ This workflow automatically classifies new messages as Lead, Query, or Spam using GPT-4, route
Automatically analyze the sentiment of Facebook posts and their audience comments using GPT-4 to identify trends and potential PR risks. 🧠💬 This workflow fetches recent posts via the Facebook Graph AP