This workflow corresponds to n8n.io template #11048 — we link there as the canonical source.
This workflow follows the Gmail → 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "3f6579ee-2b84-4fea-ae12-2200fb0ed677",
"name": "Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"position": [
-576,
464
],
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"notesInFlow": true,
"typeVersion": 1.2
},
{
"id": "2c0ad9d1-8b46-4967-a191-0a2da2d0efaa",
"name": "Report Generated",
"type": "n8n-nodes-base.if",
"position": [
224,
64
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0ef7f8ca-c09f-4ea8-a440-044f6c6dec7c",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.report_bool }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "315b7f24-1e54-4ec6-992a-8b01c2029362",
"name": "Load Report Infos",
"type": "n8n-nodes-base.code",
"position": [
1088,
-48
],
"parameters": {
"jsCode": "let workflowData = $getWorkflowStaticData('global');\n\nreturn [\n {\n json: {\n report_bool: workflowData.report_bool || false,\n report: workflowData.report || \"Not available\",\n barcode: workflowData.barcode || \"Not available\",\n }\n }\n];"
},
"typeVersion": 2
},
{
"id": "dcc75e5a-b805-4021-87ed-19f916d5fd77",
"name": "Reinitialise State Variables",
"type": "n8n-nodes-base.code",
"notes": "You only need to run the initialization step once per workflow, regardless of the number of Telegram chat IDs. The initialization creates the telegramStates object within the global static data of the workflow. Once that object exists, the workflow will use it to store the state for any chat ID.",
"position": [
1552,
128
],
"parameters": {
"jsCode": "let workflowStaticData = $getWorkflowStaticData('global');\n\nworkflowStaticData.report_bool = false;\nworkflowStaticData.report = \"Not available\";\n\nreturn workflowStaticData;"
},
"notesInFlow": false,
"typeVersion": 2
},
{
"id": "5b8aa6dc-c124-41c2-8bac-08e2172f9448",
"name": "Image Received ?",
"type": "n8n-nodes-base.if",
"position": [
-288,
464
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "fb92074d-ea25-44df-b26d-1ef2f8b54bed",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.message.photo[0].file_id }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "5b0a24a0-688d-41bf-96e4-04acd2392e97",
"name": "Instructions to Operator",
"type": "n8n-nodes-base.telegram",
"position": [
144,
480
],
"parameters": {
"text": "=\ud83e\udd16 *LogiGreen AI Damage Inspector*\n\n\ud83d\udcf8 Step 1 \u2014 Upload a clear picture of the damaged pallet \nThis allows me to analyze the damage and generate a structured report.\n\n\ud83c\udff7\ufe0f Step 2 \u2014 Send a photo of the pallet barcode \nThis identifies the pallet and links it to your warehouse records.\n\n\ud83d\udce4 Once both images are received, I will automatically create and send the full damage report.",
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"forceReply": {
"selective": true
},
"replyMarkup": "forceReply",
"additionalFields": {
"appendAttribution": false
}
},
"notesInFlow": true,
"typeVersion": 1.2
},
{
"id": "80c065fe-7563-4ca0-9110-1b34947090f0",
"name": "Request Barcode Photo",
"type": "n8n-nodes-base.telegram",
"position": [
816,
464
],
"parameters": {
"text": "=\ud83e\udd16 LogiGreen AI Damage Inspector \n\ud83d\udcf7 Please take a clear photo of the pallet barcode so I can identify the pallet.",
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"forceReply": {
"selective": true
},
"replyMarkup": "forceReply",
"additionalFields": {
"appendAttribution": false
}
},
"notesInFlow": true,
"typeVersion": 1.2
},
{
"id": "6d95a9bd-9807-4c9b-bd16-2382f264733f",
"name": "Download Pallet Image",
"type": "n8n-nodes-base.telegram",
"position": [
464,
368
],
"parameters": {
"fileId": "={{ $('Telegram Trigger').item.json.message.photo[3].file_id }}",
"resource": "file",
"additionalFields": {}
},
"notesInFlow": true,
"typeVersion": 1.2
},
{
"id": "639adc69-5a1a-40b7-bafd-2782cb79e420",
"name": "Download Barcode Image",
"type": "n8n-nodes-base.telegram",
"position": [
448,
-112
],
"parameters": {
"fileId": "={{ $('Telegram Trigger').item.json.message.photo[3].file_id }}",
"resource": "file",
"additionalFields": {}
},
"notesInFlow": true,
"typeVersion": 1.2
},
{
"id": "186941ff-b64f-49d7-8274-61877860c422",
"name": "AI Damage Analysis (GPT-4o)",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
640,
368
],
"parameters": {
"text": "=You are an AI assistant specialized in warehouse operations and damaged-goods reporting.\nAnalyze the image provided and output a clean, structured damage report.\nStay factual and describe only what you can see.\n\nYour output MUST follow this exact structure:\n\nDamage Summary:\n- [1\u20132 sentence high-level description]\n\nObserved Damage:\n- Packaging condition: [...]\n- Pallet condition: [...]\n- Product condition: [...]\n- Stability: [...]\n\nSeverity: [Minor / Moderate / Severe]\n\nRecommended Actions:\n- [...]\n- [...]\n\nGuidelines:\n- Do NOT hallucinate information not visible in the image.\n- If something is unclear, write: \"Not visible\".\n- Severity must be one of: Minor, Moderate, Severe.\n- Recommended actions should be short and actionable.",
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o",
"cachedResultName": "GPT-4O"
},
"options": {},
"resource": "image",
"simplify": false,
"inputType": "base64",
"operation": "analyze"
},
"notesInFlow": true,
"typeVersion": 2
},
{
"id": "75d5a5d5-a4ce-4d51-8685-c1a632e64892",
"name": "AI Barcode Reader (GPT-4o Mini)",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
640,
-112
],
"parameters": {
"text": "Read the barcode, just output the value, nothing else.",
"modelId": {
"__rl": true,
"mode": "list",
"value": "chatgpt-4o-latest",
"cachedResultName": "CHATGPT-4O-LATEST"
},
"options": {},
"resource": "image",
"inputType": "base64",
"operation": "analyze"
},
"notesInFlow": true,
"typeVersion": 2
},
{
"id": "8e023dca-dbe1-42a8-a7aa-9a16e7ea6861",
"name": "Store Report",
"type": "n8n-nodes-base.code",
"position": [
816,
288
],
"parameters": {
"jsCode": "let workflowStaticData = $getWorkflowStaticData('global');\n\nworkflowStaticData.report_bool = true;\nworkflowStaticData.report = $input.first().json.output[0].content[0].text;\n \nreturn {\n 'report_bool': workflowStaticData.report_bool,\n 'report': workflowStaticData.report\n}"
},
"typeVersion": 2
},
{
"id": "d514813c-7c75-495b-935e-1d3e7090de70",
"name": "Extract Barcode Value",
"type": "n8n-nodes-base.set",
"position": [
832,
-112
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "bc1db010-3424-4f4b-b434-cf9367280e56",
"name": "['0'].content[0].text",
"type": "string",
"value": "={{ $json['0'].content[0].text }}"
}
]
}
},
"notesInFlow": true,
"typeVersion": 3.4
},
{
"id": "d1f5882d-4185-43b5-8014-a2d60ab4c9f2",
"name": "Store Barcode",
"type": "n8n-nodes-base.code",
"position": [
1088,
-176
],
"parameters": {
"jsCode": "let workflowStaticData = $getWorkflowStaticData('global');\nworkflowStaticData.barcode = $input.first().json['0'].content[0].text;\n\n \nreturn {\n 'barcode': workflowStaticData.barcode\n}"
},
"typeVersion": 2
},
{
"id": "d2e01a64-0ee9-4e23-9414-8026afb96c62",
"name": "Send Report by Email",
"type": "n8n-nodes-base.gmail",
"position": [
1552,
-192
],
"parameters": {
"sendTo": "<ADD_EMAIL_QUALITY_TEAM>",
"message": "={{ $json.email_html }}",
"options": {
"appendAttribution": false
},
"subject": "={{ $json.email_title }}"
},
"notesInFlow": true,
"typeVersion": 2.1
},
{
"id": "0c49eafd-cf08-4dbc-9292-3d7765bea612",
"name": "Confirm Report Sent to Operator",
"type": "n8n-nodes-base.telegram",
"position": [
1552,
-48
],
"parameters": {
"text": "=\u2705 Your damage report has been generated and sent successfully. \n\ud83e\udd16 *LogiGreen AI Damage Inspector*",
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"notesInFlow": true,
"typeVersion": 1.2
},
{
"id": "5a5b1b91-7b5e-43d2-8b7f-10e8f09052c3",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-640,
-304
],
"parameters": {
"width": 608,
"height": 640,
"content": "## AI Damage Report Generator for Warehouse Operations\n\nThis workflow is designed to help warehouse operators generate a complete damage report without needing to write anything manually.\n\n### How it Works\n1. **Telegram Trigger** receives the operator\u2019s first image (damaged pallet)\n2. The workflow runs **AI Damage Analysis (GPT-4o)** to generate a structured report.\n3. The bot then asks the operator to **send a photo of the pallet barcode**.\n4. **AI Barcode Reader (GPT-4o Mini)** extracts the pallet ID from it\n5. Both results (damage report + pallet number) are stored temporarily.\n6. The workflow generates an **HTML report**.\n7. The report is emailed automatically to the quality team.\n\n### Setup\n- [ ] Connect your **Telegram Bot API** to receive images.\n- [ ] Add your **OpenAI API Key** to the Vision nodes.\n- [ ] Connect your **Gmail** credentials.\n- [ ] Update the **recipient email address** in the \u201cSend Report by Email\u201d node. \n\n### Customize\n- **Branding:** update logo, colors and bot name\n- **Damage Analysis**: enrich the report generated by the AI node\n\n"
},
"typeVersion": 1
},
{
"id": "94651a43-9726-46b0-a8f3-a325cea7c7e3",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-640,
352
],
"parameters": {
"color": 7,
"width": 620,
"height": 268,
"content": "## 1. Telegram Trigger and message format check"
},
"typeVersion": 1
},
{
"id": "dc87f0e2-3498-4f5e-8123-b35a8dbd7d65",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
352
],
"parameters": {
"color": 7,
"width": 396,
"height": 268,
"content": "## 2. If the message is not an image, send instructions "
},
"typeVersion": 1
},
{
"id": "cd18543f-e716-450a-8e68-0ed4bc17528d",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
-304
],
"parameters": {
"color": 7,
"width": 396,
"height": 636,
"content": "## 3. Load state variables and check whether a report was already generated"
},
"typeVersion": 1
},
{
"id": "d2f4c719-e49c-45e6-84a1-26f7542908ef",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
224
],
"parameters": {
"color": 7,
"width": 540,
"height": 396,
"content": "## 5. Download the image, generate the report , store it, and request the barcode"
},
"typeVersion": 1
},
{
"id": "e4ab215e-1f5d-44ad-b404-29321b35ced0",
"name": "Sticky Note13",
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
-304
],
"parameters": {
"color": 7,
"width": 540,
"height": 492,
"content": "## 4. Download the photo to extract the bar code"
},
"typeVersion": 1
},
{
"id": "8c1d7943-f835-4479-944f-20464f0e9c7e",
"name": "Sticky Note14",
"type": "n8n-nodes-base.stickyNote",
"position": [
1328,
-304
],
"parameters": {
"color": 7,
"width": 364,
"height": 604,
"content": "## 7. Generate the final report, send it by email, and confirm to the operator"
},
"typeVersion": 1
},
{
"id": "b15415cb-2a1e-4632-a097-e2c8572b57cd",
"name": "Sticky Note15",
"type": "n8n-nodes-base.stickyNote",
"position": [
976,
-304
],
"parameters": {
"color": 7,
"width": 332,
"height": 604,
"content": "## 6. Load the state variables used for the report"
},
"typeVersion": 1
},
{
"id": "6c6eed41-369c-4d2a-9817-cfa58365213c",
"name": "Generate Report",
"type": "n8n-nodes-base.code",
"position": [
1360,
-48
],
"parameters": {
"jsCode": "const { report_bool, report, barcode } = $json;\n\n// Email title\nconst emailTitle = `Damage Report \u2013 Pallet ${barcode}`;\n\n// Prettify text: replace newlines with <br>\nconst formattedReport = report.replace(/\\n/g, \"<br>\");\n\nconst emailHtml = `\n<html>\n<head>\n<style>\n body {\n font-family: Arial, sans-serif;\n background: #f7f7f7;\n padding: 20px;\n }\n .card {\n background: #ffffff;\n border-radius: 12px;\n padding: 24px;\n border: 1px solid #e4e4e4;\n box-shadow: 0px 2px 6px rgba(0,0,0,0.08);\n max-width: 700px;\n margin: auto;\n }\n .header {\n display: flex;\n align-items: center;\n border-bottom: 2px solid #6BB64A;\n padding-bottom: 12px;\n margin-bottom: 24px;\n }\n .header img {\n height: 60px;\n margin-right: 16px;\n }\n .header h1 {\n font-size: 22px;\n margin: 0;\n color: #6BB64A;\n }\n .section-title {\n font-size: 18px;\n font-weight: bold;\n color: #6BB64A;\n margin-top: 20px;\n }\n .barcode-box {\n background: #eef8e9;\n padding: 12px;\n border-radius: 8px;\n font-size: 16px;\n border-left: 4px solid #6BB64A;\n margin-bottom: 20px;\n }\n .footer {\n margin-top: 30px;\n font-size: 12px;\n color: #999;\n text-align: center;\n }\n a {\n color: #6BB64A;\n }\n</style>\n</head>\n\n<body>\n <div class=\"card\">\n <div class=\"header\">\n <img src=\"https://logigreenconsulting.odoo.com/web/image/website/1/logo?unique=6cd9ddb\" alt=\"LogiGreen Logo\">\n <h1>LogiGreen AI Damage Inspector</h1>\n </div>\n\n <div class=\"section-title\">Pallet Information</div>\n <div class=\"barcode-box\">\n <strong>Pallet Number:</strong> ${barcode}<br>\n <strong>Report Valid:</strong> ${report_bool ? \"Yes\" : \"No\"}\n </div>\n\n <div class=\"section-title\">Damage Report</div>\n <p>${formattedReport}</p>\n\n <div class=\"footer\">\n Generated automatically by the <strong>LogiGreen AI Damage Inspector</strong><br>\n LogiGreen Consulting \u2013 <a href=\"https://logi-green.com\" target=\"_blank\">https://logi-green.com</a>\n </div>\n </div>\n</body>\n</html>\n`;\n\nreturn [\n {\n json: {\n email_title: emailTitle,\n email_html: emailHtml\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "3bcc7430-05f2-4e58-b96d-8305d0e0dda7",
"name": "Load Report State",
"type": "n8n-nodes-base.code",
"position": [
64,
64
],
"parameters": {
"jsCode": "let workflowData = $getWorkflowStaticData('global');\n\nreturn [\n {\n json: {\n report_bool: workflowData.report_bool || false,\n report: workflowData.report || \"Not available\"\n }\n }\n];"
},
"typeVersion": 2
},
{
"id": "5dac07d5-c0e8-4d5f-b2e6-1ecf6e53bf04",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1216,
320
],
"parameters": {
"width": 480,
"height": 304,
"content": "## [Tutorial](https://www.youtube.com/watch?v=3Xdo1pzd8rw)\n@[youtube](3Xdo1pzd8rw)"
},
"typeVersion": 1
}
],
"connections": {
"Generate Report": {
"main": [
[
{
"node": "Send Report by Email",
"type": "main",
"index": 0
},
{
"node": "Confirm Report Sent to Operator",
"type": "main",
"index": 0
},
{
"node": "Reinitialise State Variables",
"type": "main",
"index": 0
}
]
]
},
"Image Received ?": {
"main": [
[
{
"node": "Load Report State",
"type": "main",
"index": 0
}
],
[
{
"node": "Instructions to Operator",
"type": "main",
"index": 0
}
]
]
},
"Report Generated": {
"main": [
[
{
"node": "Download Barcode Image",
"type": "main",
"index": 0
}
],
[
{
"node": "Download Pallet Image",
"type": "main",
"index": 0
}
]
]
},
"Telegram Trigger": {
"main": [
[
{
"node": "Image Received ?",
"type": "main",
"index": 0
}
]
]
},
"Load Report Infos": {
"main": [
[
{
"node": "Generate Report",
"type": "main",
"index": 0
}
]
]
},
"Load Report State": {
"main": [
[
{
"node": "Report Generated",
"type": "main",
"index": 0
}
]
]
},
"Download Pallet Image": {
"main": [
[
{
"node": "AI Damage Analysis (GPT-4o)",
"type": "main",
"index": 0
}
]
]
},
"Extract Barcode Value": {
"main": [
[
{
"node": "Store Barcode",
"type": "main",
"index": 0
},
{
"node": "Load Report Infos",
"type": "main",
"index": 0
}
]
]
},
"Download Barcode Image": {
"main": [
[
{
"node": "AI Barcode Reader (GPT-4o Mini)",
"type": "main",
"index": 0
}
]
]
},
"AI Damage Analysis (GPT-4o)": {
"main": [
[
{
"node": "Request Barcode Photo",
"type": "main",
"index": 0
},
{
"node": "Store Report",
"type": "main",
"index": 0
}
]
]
},
"AI Barcode Reader (GPT-4o Mini)": {
"main": [
[
{
"node": "Extract Barcode Value",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Tags: Logistics, Supply Chain, Warehouse Operations, Paperless processes, Quality Management
Source: https://n8n.io/workflows/11048/ — 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.
Send a target niche and location via Telegram message Workflow discovers businesses via Google Maps API AI enriches contacts with email and LinkedIn data via Serper GPT-4o scores and qualifies each le
💥 Automate YouTube thumbnail creation from video links -vide. Uses telegramTrigger, httpRequest, googleDrive, gmail. Event-driven trigger; 25 nodes.
💥 Automate YouTube thumbnail creation from video links -vide. Uses telegramTrigger, httpRequest, googleDrive, gmail. Event-driven trigger; 25 nodes.
This n8n template demonstrates how to capture Telegram voice messages, transcribe them into text using AssemblyAI, analyze the transcript with AI for summary and sentiment insights, and finally delive
Send a number to your Telegram bot (e.g., 2) and get a neatly formatted digest of all Gmail newsletters received since that date. Each email is summarized by an LLM into concise topics, merged into a