Data Persistence Issue: File and URL Lost Between Telegram Inline Button Clicks

Describe the problem/error/question

What is the error message (if any)?

Please share your workflow

(Select the nodes on your canvas and use the keyboard shortcuts CMD+C/CTRL+C and CMD+V/CTRL+V to copy and paste the workflow.)

Share the output returned by the last node

Information on your n8n setup

  • n8n version:
  • Database (default: SQLite):
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app):
  • Operating system:
1 Like

Hi @abd2001 ,

Welcome to the community,

If you still need with the data persistence issue, please reply to this with more information on the issue.

GL

Hi @abd2001 Can you share your workflow with us?

Hi JohnHalex, I have more details. The workflow has two stages:

  1. In the first stage (first click), the file is sent to Google Sheets and stored in Google Drive successfully.
  2. In the second stage (second click/trigger), when I request to ‘Analyze the file’, the workflow fails because it cannot access or reference the file/data from the previous step anymore.
    It seems the binary data or the File ID is not being carried over to the second trigger. How can I make the file data ‘persistent’ so it can be reused in the analysis step?
1 Like

@abd2001 In n8n each workflow run is independent, so by default binary data or file IDs from one trigger are not kept automatically for the next trigger run. The data you get in the first stage lives only in that execution and is cleared later.

How to make the file usable in the second trigger

  1. Save the file ID externally
    After uploading to Google Drive, store the fileId somewhere persistent (Google Sheets, database, Redis, etc). In the second trigger fetch that fileId and use it to download or reference the file again.

  2. Store the actual file persistently
    If you need the binary later, write it to disk or external storage using nodes like Write Binary File. Then read it back on the next trigger.

  3. Static data
    n8n has static data features, but they are limited and not reliable for binary between runs. It’s better to use external storage for file persistence.

Why your current flow fails
The second trigger run starts fresh and does not automatically have the file or ID from the first run, so the analysis step finds nothing unless you saved and reloaded that data. Hope this helps

Hi Anshul_Namdev, thank you for the explanation.

To clarify further: during the second click (the analysis stage), a new row is actually being created in the Google Sheet, but the file link or ID is missing from it. It seems the workflow is starting a fresh process instead of referencing the data from the first stage.

I will share my workflow JSON with you tomorrow when I am back at the office so you can see exactly how the nodes are configured.

1 Like

Hi JohnHalex and Anshul_Namdev,

To clarify my environment: I am using the n8n Desktop App installed locally on my computer (Windows 11), not the cloud version.

Here is the exact workflow sequence and where it fails:

  1. Trigger: The process starts with a “Telegram Trigger”.
  2. Processing: It then goes to a “Code Node” (Java-based) and then to a “Switch Node”.
  3. First Stage (Split): The Switch node has two active outputs:
    • Output 1: Sends a Telegram message to the user with interactive inline buttons.
    • Output 2: Uploads the file to Google Drive storage and records the details in Google Sheets.
  4. Second Stage (Interaction): The user then clicks one of the buttons in Telegram to choose the recipient.
  5. The Issue: After the button click, the workflow triggers the “Analysis” part, but it proceeds without the original PDF file or the data from the first stage. The file data seems to be lost once the second interaction (button click) happens.

I am currently at home. Tomorrow, I will share the full workflow JSON so you can see the node configurations.

{
“nodes”: [
{
“parameters”: {
“updates”: [
“message”,
“callback_query”
],
“additionalFields”: {
“download”: true
}
},
“type”: “n8n-nodes-base.telegramTrigger”,
“typeVersion”: 1.2,
“position”: [
-160,
96
],
“id”: “cf70be02-61e3-443b-a9eb-94242b43bc00”,
“name”: “Telegram Trigger”,
“webhookId”: “bb3a35de-bb14-41c5-b0aa-f851ebd51efc”,
“credentials”: {
“telegramApi”: {
“id”: “NGDDFquFgRUmHn6S”,
“name”: “Telegram account 5”
}
}
},
{
“parameters”: {
“jsCode”: “// 1. جلب البيانات من كل النودات المتوفرة (نظام البحث الشامل)\nconst allInputs = $input.all();\nlet geminiText = “”;\n\n// محاولة جلب النص من أي نود “مُفعل” قبلي مباشرة\ntry {\n if (allInputs.length > 0) {\n const data = allInputs[0].json;\n geminiText = data.output || data.text || (data.candidates && data.candidates[0].content.parts[0].text) || “”;\n }\n} catch (e) { geminiText = “”; }\n\n// إذا لسه فاضي، بننادي النودات بأسمائها (with answer أو without answer)\nif (!geminiText || geminiText.trim().length === 0) {\n try {\n const node1 = $(“with answer”).first().json;\n geminiText = node1.output || node1.text || “”;\n } catch (e) {\n try {\n const node2 = $(“without answer”).first().json;\n geminiText = node2.output || node2.text || “”;\n } catch (e) { geminiText = “”; }\n }\n}\n\n// 2. جلب معلومات التايجر (سمسم سمسم)\nlet chatId = “”;\nlet fileNameToUse = “”;\ntry {\n const tg = $(“Telegram Trigger”).first().json;\n const msg = tg.message || tg.callback_query.message;\n chatId = msg.chat.id;\n if (msg.document && msg.document.file_name) {\n fileNameToUse = msg.document.file_name.split(‘.’).slice(0, -1).join(‘.’) + “.doc”;\n } else {\n fileNameToUse = “تحليل_أبو_إبراهيم.doc”;\n }\n} catch (e) { \n chatId = allInputs[0].json.chat_id || “”; \n fileNameToUse = “document.doc”;\n}\n\n// 3. الحل النهائي: إذا النص لسه فاضي، بنكتب رسالة تنبيه واضحة داخل الملف\nconst finalBody = (geminiText && geminiText.trim().length > 0) \n ? geminiText \n : “تنبيه فني: الملف وصل لنود الكود فارغاً. يرجى التأكد من إغلاق خيار Simplify Output في نودات Gemini وتوصيل سلك الـ Output بنود الكود.”;\n\n// 4. بناء الملف وتنسيقه\nconst isArabic = /[\u0600-\u06FF]/.test(finalBody);\nconst htmlContent = \n<html><head><meta charset=\"utf-8\"></head>\n<body style=\"direction: ${isArabic ? 'rtl' : 'ltr'}; font-family: Arial; padding: 40px; line-height: 1.6;\">\n <div style=\"font-size: 14pt; white-space: pre-wrap; text-align: ${isArabic ? 'right' : 'left'};\">\n ${finalBody}\n </div>\n <br><br>\n <div style=\"margin-top: 50px; border-top: 2px solid #333; padding-top: 10px; display: inline-block; min-width: 250px; text-align: right; float: left;\">\n <p style=\"font-weight: bold; font-size: 16pt; margin: 0;\">السلام عليكم،</p>\n <p style=\"font-weight: bold; font-size: 16pt; margin: 0;\">هذا طلبكم،</p>\n <p style=\"font-weight: bold; font-size: 16pt; margin: 0;\">أخوكم عبد الله إبراهيم طرخان</p>\n </div>\n</body></html>;\n\nreturn [{\n json: { chat_id: chatId, file_name: fileNameToUse },\n binary: {\n data: {\n data: Buffer.from(htmlContent, ‘utf-8’).toString(‘base64’),\n fileName: fileNameToUse,\n fileExtension: “doc”,\n mimeType: “application/msword”\n }\n }\n}];”
},
“type”: “n8n-nodes-base.code”,
“typeVersion”: 2,
“position”: [
1312,
64
],
“id”: “689db839-3337-46c4-bd72-ccdced507556”,
“name”: “Code in JavaScript”
},
{
“parameters”: {
“resource”: “document”,
“modelId”: {
“__rl”: true,
“value”: “models/gemini-2.5-flash”,
“mode”: “list”,
“cachedResultName”: “models/gemini-2.5-flash”
},
“text”: “أنت مساعد ذكي خبير. المطلوب منك استخراج النص من الملف المرفق كاملاً “دون حل الأسئلة”، والالتزام التام بالتنسيق التالي:\n\n1. الأسئلة الاختيارية: اكتب رقم السؤال وبجانبه داش (مثال: 1-)، ثم نص السؤال. الاختيارات تبدأ بحروف (أ، ب، ج، د) متبوعة بقوس.\n2. الأسئلة المقالية: تكتب (س) ثم رقم السؤال ثم (:)، وينقل نص السؤال، ويكون أسفل منه فراغ للإجابة مكون من أربع شرطات ( ---- ).\n3. القوائم والنقاط: تكتب العنوان ثم (:slight_smile: ثم سطر جديد لكل نقطة بصيغة (الرقم - فراغ - النص).\n4. 3. \n4. أبيات الشعر: الشطر الأول في سطر يسبقه مسافتان وقبله علامة (آآ). الشطر الثاني في سطر جديد لا يسبقه شيء. في القصيدة الكاملة، نضع (آآ) في البيت الأول فقط.\n5. علامات الترقيم: تكون ملتصقة بالكلمة التي قبلها، ويتبعها فراغ.\n6. الرياضيات: العمليات الحسابية يسبقها فراغ وتلتصق بالرقم الذي بعدها. الأس يسبقه علامة (^). البسط والمقام يحول لصيغة السطر الواحد. الجذر (√) يوضع قبل الرقم، وإذا كانت معادلة توضع بين قوسين. الأرقام بالإشارات (الموجب والسالب) توضع مع إشارتها بين قوسين.\n7. الكيمياء: السهم في المعادلات يكتب (→)، سهم الغاز (↑)، وسهم الراسب (↓).\n8. الصور: إذا كانت مرقمة وليس بها كتابة، اكتب رقمها ثم بين قوسين شرحها، ثم سطر جديد وضع الشرح بين قوسين، ثم سطر جديد لتكملة الفقرة.\n9. بداية الفقرات: كل فقرة جديدة يجب أن تبدأ بفراغين.\n10- إذا لاحظت وجود ترويسة (Header) أو تذييل (Footer) متكرر في كل صفحة (مثل اسم المدرسة أو التاريخ أو أرقام الصفحات)، فقم بالإبقاء عليها مرة واحدة فقط في بداية النص، واحذفها من باقي الأجزاء لضمان استمرارية النص .\n11. الجداول: يتم تحويل الجدول إلى نصوص متتالية، يكتب اسم العمود ثم نقطتان (:slight_smile: ثم القيمة، ويفصل بين كل صف والآخر سطر فارغ.\n12. المراجعة النهائية: التأكد من عدم دمج نصين مختلفين في سطر واحد، والحفاظ على تسلسل الأرقام كما ورد في الأصل.”,
“inputType”: “binary”,
“simplify”: false,
“options”: {
“maxOutputTokens”: 300000
}
},
“type”: “@n8n/n8n-nodes-langchain.googleGemini”,
“typeVersion”: 1.1,
“position”: [
816,
288
],
“id”: “f5be4cd8-17a3-4f92-86e4-8ef09d2673b9”,
“name”: “without answer”,
“retryOnFail”: true,
“maxTries”: 5,
“credentials”: {
“googlePalmApi”: {
“id”: “NoXjUSXgvQMxzlqb”,
“name”: “Google Gemini(PaLM) Api account”
}
},
“onError”: “continueErrorOutput”
},
{
“parameters”: {
“operation”: “sendDocument”,
“chatId”: “={{ $json.chat_id }}”,
“binaryData”: true,
“additionalFields”: {}
},
“type”: “n8n-nodes-base.telegram”,
“typeVersion”: 1.2,
“position”: [
1488,
0
],
“id”: “bf0c6b5b-4247-4fd7-8844-6d0a46d84c7c”,
“name”: “Send a document”,
“webhookId”: “fe8a785a-8409-4973-bdcf-8b75297e0a48”,
“credentials”: {
“telegramApi”: {
“id”: “NGDDFquFgRUmHn6S”,
“name”: “Telegram account 5”
}
}
},
{
“parameters”: {
“rules”: {
“values”: [
{
“conditions”: {
“options”: {
“caseSensitive”: true,
“leftValue”: “”,
“typeValidation”: “strict”,
“version”: 3
},
“conditions”: [
{
“leftValue”: “={{$json.my_type}}”,
“rightValue”: “new_file”,
“operator”: {
“type”: “string”,
“operation”: “equals”
},
“id”: “48ffc394-eefa-403d-a5c0-e512bded97a1”
}
],
“combinator”: “and”
},
“renameOutput”: true,
“outputKey”: “new file”
},
{
“conditions”: {
“options”: {
“caseSensitive”: true,
“leftValue”: “”,
“typeValidation”: “strict”,
“version”: 3
},
“conditions”: [
{
“id”: “4125f46a-f4f9-484a-b115-f3f484bc88ed”,
“leftValue”: “={{$json.my_type}}”,
“rightValue”: “type_1”,
“operator”: {
“type”: “string”,
“operation”: “equals”
}
}
],
“combinator”: “and”
},
“renameOutput”: true,
“outputKey”: “with answer”
},
{
“conditions”: {
“options”: {
“caseSensitive”: true,
“leftValue”: “”,
“typeValidation”: “strict”,
“version”: 3
},
“conditions”: [
{
“id”: “8bb4fb67-b418-430d-8a7e-d756db8f6527”,
“leftValue”: “={{$json.my_type}}”,
“rightValue”: “type_2”,
“operator”: {
“type”: “string”,
“operation”: “equals”,
“name”: “filter.operator.equals”
}
}
],
“combinator”: “and”
},
“renameOutput”: true,
“outputKey”: “without answer”
},
{
“conditions”: {
“options”: {
“caseSensitive”: true,
“leftValue”: “”,
“typeValidation”: “strict”,
“version”: 3
},
“conditions”: [
{
“id”: “51fc5572-e7b2-490a-a455-fa6ef17295db”,
“leftValue”: “={{$json.my_type}}”,
“rightValue”: “type_3”,
“operator”: {
“type”: “string”,
“operation”: “equals”,
“name”: “filter.operator.equals”
}
}
],
“combinator”: “and”
},
“renameOutput”: true,
“outputKey”: “google drive”
},
{
“conditions”: {
“options”: {
“caseSensitive”: true,
“leftValue”: “”,
“typeValidation”: “strict”,
“version”: 3
},
“conditions”: [
{
“id”: “1927180e-aa9d-4b28-a920-8d7cadd5c5de”,
“leftValue”: “={{$json.my_type}}”,
“rightValue”: “type_4”,
“operator”: {
“type”: “string”,
“operation”: “equals”,
“name”: “filter.operator.equals”
}
}
],
“combinator”: “and”
},
“renameOutput”: true,
“outputKey”: “analysis file”
},
{
“conditions”: {
“options”: {
“caseSensitive”: true,
“leftValue”: “”,
“typeValidation”: “strict”,
“version”: 3
},
“conditions”: [
{
“id”: “d6651bcc-241e-4b05-80f6-4aabf2b39f18”,
“leftValue”: “={{$json.my_type}}”,
“rightValue”: “type_5”,
“operator”: {
“type”: “string”,
“operation”: “equals”,
“name”: “filter.operator.equals”
}
}
],
“combinator”: “and”
},
“renameOutput”: true,
“outputKey”: “analysis picture”
},
{
“conditions”: {
“options”: {
“caseSensitive”: true,
“leftValue”: “”,
“typeValidation”: “strict”,
“version”: 3
},
“conditions”: [
{
“id”: “c8598dc3-e2c2-4deb-8b15-cae935c5083a”,
“leftValue”: “={{$json.my_type}}”,
“rightValue”: “type_6”,
“operator”: {
“type”: “string”,
“operation”: “equals”,
“name”: “filter.operator.equals”
}
}
],
“combinator”: “and”
},
“renameOutput”: true,
“outputKey”: “sheet”
}
]
},
“options”: {}
},
“type”: “n8n-nodes-base.switch”,
“typeVersion”: 3.4,
“position”: [
432,
32
],
“id”: “b56a91c1-11dc-4e7b-832a-1be6d87c12f9”,
“name”: “Switch”,
“alwaysOutputData”: false
},
{
“parameters”: {
“mode”: “combine”,
“combineBy”: “combineByPosition”,
“options”: {
“includeUnpaired”: false
}
},
“type”: “n8n-nodes-base.merge”,
“typeVersion”: 3.2,
“position”: [
1088,
-176
],
“id”: “a29337b2-00e9-4b08-b606-527056acf12c”,
“name”: “Merge”
},
{
“parameters”: {
“chatId”: “=146893252”,
“text”: “تم استلام الملف كيف تريد تنسيقه”,
“replyMarkup”: “inlineKeyboard”,
“inlineKeyboard”: {
“rows”: [
{
“row”: {
“buttons”: [
{
“text”: “مع الإجابات (answer)”,
“additionalFields”: {
“callback_data”: “btn_1”
}
},
{
“text”: “بدون الإجابات (without answer)”,
“additionalFields”: {
“callback_data”: “btn_2”
}
}
]
}
}
]
},
“additionalFields”: {}
},
“type”: “n8n-nodes-base.telegram”,
“typeVersion”: 1.2,
“position”: [
496,
-368
],
“id”: “d329acdc-d95e-42df-a268-219d16248e25”,
“name”: “Send a text message”,
“webhookId”: “fcd36e6d-e1a6-45ed-8751-1fb0f654bc7f”,
“alwaysOutputData”: false,
“credentials”: {
“telegramApi”: {
“id”: “NGDDFquFgRUmHn6S”,
“name”: “Telegram account 5”
}
}
},
{
“parameters”: {
“modelId”: {
“__rl”: true,
“value”: “models/gemini-2.5-flash”,
“mode”: “list”,
“cachedResultName”: “models/gemini-2.5-flash”
},
“messages”: {
“values”: [
{
“content”: “=أنت “ماجد”، الموظف المسؤول في قسم الدمج بمركز النور.\nوصلتك رسالة من أحد المستفيدين أو العملاء نصها: ({{ $json.message.text }}).\n\nمهمتك:\n1. رحب بالشخص بلهجة محترمة وودودة جداً تليق بمركز النور.\n2. عرّف بنفسك: “معك أخوك ماجد من قسم الدمج”.\n3. أخبره أنك هنا لخدمته وتسهيل أموره ضمن مشروع الدمج.\n4. اطلب منه بكل لطف اختيار الخدمة التي يحتاجها من الخيارات الموجودة بالأسفل.\n٥.”
}
]
},
“builtInTools”: {},
“options”: {}
},
“type”: “@n8n/n8n-nodes-langchain.googleGemini”,
“typeVersion”: 1.1,
“position”: [
-96,
-480
],
“id”: “0cf4b03d-5ae7-4c60-8b78-6caffa214416”,
“name”: “Message a model”,
“credentials”: {
“googlePalmApi”: {
“id”: “NoXjUSXgvQMxzlqb”,
“name”: “Google Gemini(PaLM) Api account”
}
}
},
{
“parameters”: {
“chatId”: “={{ $json.callback_query.message.chat.id }}”,
“text”: "انا اخوك ماجد تفضل ضع ملفك هنا ",
“additionalFields”: {}
},
“type”: “n8n-nodes-base.telegram”,
“typeVersion”: 1.2,
“position”: [
1120,
-496
],
“id”: “c527253e-1f31-4e12-9ee6-9633e30c2062”,
“name”: “Send a text message1”,
“webhookId”: “890dd3db-48df-4976-a343-79ca3f9ca510”,
“credentials”: {
“telegramApi”: {
“id”: “NGDDFquFgRUmHn6S”,
“name”: “Telegram account 5”
}
}
},
{
“parameters”: {
“jsCode”: “// كود المطور أبا إبراهيم - نسخة استعادة الملف المفقود\nlet my_type = “unknown”;\nconst input = items[0].json;\n\n// البحث عن الملف في الذاكرة السابقة للبرنامج\nlet persistentBinary = null;\ntry {\n // محاولة جلب الملف من التايجر الأصلي\n const mainTrigger = $(“Telegram Trigger”).first();\n if (mainTrigger.binary && mainTrigger.binary.data) {\n persistentBinary = mainTrigger.binary.data;\n }\n} catch (e) {\n // إذا لم يجده، يحاول البحث في نود الرفع\n try {\n const uploadNode = $(“Upload file”).first();\n if (uploadNode.binary && uploadNode.binary.data) {\n persistentBinary = uploadNode.binary.data;\n }\n } catch (err) { }\n}\n\nif (items[0].binary && !input.callback_query) {\n // الحالة الأولى: استلام ملف جديد (يرسله للمسارين)\n return [\n { json: { …input, my_type: “new_file” }, binary: items[0].binary },\n { json: { …input, my_type: “type_3” }, binary: items[0].binary }\n ];\n} else if (input.callback_query) {\n // الحالة الثانية: ضغط الزر (هنا نقوم بلصق الملف المفقود)\n const data = input.callback_query.data;\n if (data === ‘btn_1’) my_type = “type_1”;\n if (data === ‘btn_2’) my_type = “type_2”;\n\n let output = {\n json: { …input, my_type: my_type }\n };\n\n // إعادة إحياء الملف داخل الجلسة الجديدة\n if (persistentBinary) {\n output.binary = {\n data: persistentBinary,\n mimeType: ‘application/pdf’,\n fileName: ‘document.pdf’\n };\n }\n\n return [output];\n}\n\nreturn [{ json: { …input, my_type: my_type }, binary: items[0].binary }];”
},
“type”: “n8n-nodes-base.code”,
“typeVersion”: 2,
“position”: [
128,
112
],
“id”: “a751422d-a698-4c2b-a982-dc2e4aec60b7”,
“name”: “Code in JavaScript1”,
“notesInFlow”: false
},
{
“parameters”: {
“assignments”: {
“assignments”: [
{
“id”: “6cc5b6fb-025a-4936-9b91-ab26646017cd”,
“name”: “data”,
“value”: “={{ $binary.data }}”,
“type”: “binary”
}
]
},
“includeOtherFields”: true,
“options”: {}
},
“type”: “n8n-nodes-base.set”,
“typeVersion”: 3.4,
“position”: [
256,
-512
],
“id”: “c1598843-1f73-49c0-bce0-48cf5b38e805”,
“name”: “Edit Fields”
},
{
“parameters”: {
“assignments”: {
“assignments”: [
{
“id”: “db3eb290-0a30-42b8-8acd-f5e32da8e22e”,
“name”: “data”,
“value”: “={{ $binary.data }}”,
“type”: “string”
}
]
},
“includeOtherFields”: true,
“options”: {}
},
“type”: “n8n-nodes-base.set”,
“typeVersion”: 3.4,
“position”: [
240,
-208
],
“id”: “2f1a4500-19d3-4bf9-b087-7ac1b23a7a57”,
“name”: “Edit Fields1”
},
{
“parameters”: {
“name”: “={{ $json.my_time }}_{{ $json.fileName || ‘document’ }}”,
“driveId”: {
“__rl”: true,
“mode”: “list”,
“value”: “My Drive”
},
“folderId”: {
“__rl”: true,
“value”: “1-wguWQA92Nm_eap3gHsUmxFhhWlKmaLy”,
“mode”: “list”,
“cachedResultName”: “alnoor damj”,
“cachedResultUrl”: “https://drive.google.com/drive/folders/1-wguWQA92Nm_eap3gHsUmxFhhWlKmaLy”
},
“options”: {}
},
“type”: “n8n-nodes-base.googleDrive”,
“typeVersion”: 3,
“position”: [
688,
-304
],
“id”: “dc4fae9a-4564-4c8c-89e9-d45f5a343a7b”,
“name”: “Upload file”,
“credentials”: {
“googleDriveOAuth2Api”: {
“id”: “5mNgPKrt8wq7Ypmg”,
“name”: “Google Drive account”
}
}
},
{
“parameters”: {
“operation”: “append”,
“documentId”: {
“__rl”: true,
“value”: “1_zZ1c0fPxYvzMbZaZVWn1lfnJrKwP65Qfp4e-C5cyzs”,
“mode”: “list”,
“cachedResultName”: “alnoor sheet”,
“cachedResultUrl”: “https://docs.google.com/spreadsheets/d/1_zZ1c0fPxYvzMbZaZVWn1lfnJrKwP65Qfp4e-C5cyzs/edit?usp=drivesdk”
},
“sheetName”: {
“__rl”: true,
“value”: “gid=0”,
“mode”: “list”,
“cachedResultName”: “Sheet1”,
“cachedResultUrl”: “https://docs.google.com/spreadsheets/d/1_zZ1c0fPxYvzMbZaZVWn1lfnJrKwP65Qfp4e-C5cyzs/edit#gid=0”
},
“columns”: {
“mappingMode”: “defineBelow”,
“value”: {
“اسم الملف”: “={{ $binary.data.fileName }}”,
“رابط الملف”: “={{ $json.webViewLink }}”,
“التاريخ”: “={{ $today.format(‘yyyy-MM-dd’) }}”,
“الوقت”: “={{ $now.format(‘HH:mm’) }}”
},
“matchingColumns”: ,
“schema”: [
{
“id”: “اسم الملف”,
“displayName”: “اسم الملف”,
“required”: false,
“defaultMatch”: false,
“display”: true,
“type”: “string”,
“canBeUsedToMatch”: true
},
{
“id”: “رابط الملف”,
“displayName”: “رابط الملف”,
“required”: false,
“defaultMatch”: false,
“display”: true,
“type”: “string”,
“canBeUsedToMatch”: true
},
{
“id”: “التاريخ”,
“displayName”: “التاريخ”,
“required”: false,
“defaultMatch”: false,
“display”: true,
“type”: “string”,
“canBeUsedToMatch”: true
},
{
“id”: “الوقت”,
“displayName”: “الوقت”,
“required”: false,
“defaultMatch”: false,
“display”: true,
“type”: “string”,
“canBeUsedToMatch”: true
}
],
“attemptToConvertTypes”: false,
“convertFieldsToString”: false
},
“options”: {}
},
“type”: “n8n-nodes-base.googleSheets”,
“typeVersion”: 4.7,
“position”: [
864,
-416
],
“id”: “d1a4ec72-a135-428a-9dfc-946f85e81031”,
“name”: “Append row in sheet”,
“credentials”: {
“googleSheetsOAuth2Api”: {
“id”: “w1bKQtksrpIkCnUt”,
“name”: “Google Sheets account”
}
}
},
{
“parameters”: {
“resource”: “document”,
“modelId”: {
“__rl”: true,
“value”: “models/gemini-2.5-flash”,
“mode”: “list”,
“cachedResultName”: “models/gemini-2.5-flash”
},
“text”: “أنت مساعد ذكي خبير. المطلوب منك استخراج النص من الملف المرفق كاملاً مع “الإجابة على جميع الأسئلة” الموجودة فيه، والالتزام التام بالتنسيق التالي:\n\n1. حل الأسئلة الاختيارية: اكتب رقم السؤال وبجانبه داش (مثال: 1-)، ثم نص السؤال. الاختيارات تبدأ بحروف (أ، ب، ج، د) متبوعة بقوس. الإجابة الصحيحة التي تختارها تبعد عنها ثلاث فراغات وتكتب بجانبها كلمة (صح) بين قوسين.\n2. حل الأسئلة المقالية: تكتب (س) ثم رقم السؤال ثم (:)، والجواب يكون أسفل منه بكلمة (الجواب:) ثم الإجابة النموذجية.\n3. الإجابات المتعددة (النقاط): تكتب الإجابة ثم (:slight_smile: ثم سطر جديد لكل نقطة بصيغة (الرقم - فراغ - الإجابة).\n4. أبيات الشعر: الشطر الأول في سطر يسبقه مسافتان وقبله علامة (آآ). الشطر الثاني في سطر جديد لا يسبقه شيء. في القصيدة الكاملة، نضع (آآ) في البيت الأول فقط.\n5. علامات الترقيم: تكون ملتصقة بالكلمة التي قبلها، ويتبعها فراغ.\n6. الرياضيات: العمليات الحسابية يسبقها فراغ وتلتصق بالرقم الذي بعدها. الأس يسبقه علامة (^). البسط والمقام يحول لصيغة السطر الواحد. الجذر (√) يوضع قبل الرقم، وإذا كانت معادلة توضع بين قوسين. الأرقام بالإشارات (الموجب والسالب) توضع مع إشارتها بين قوسين.\n7. الكيمياء: السهم في المعادلات يكتب (→)، سهم الغاز (↑)، وسهم الراسب (↓).\n8. الصور: إذا كانت مرقمة وليس بها كتابة، اكتب رقمها ثم بين قوسين شرحها، ثم سطر جديد وضع الشرح بين قوسين، ثم سطر جديد لتكملة الفقرة.\n9. بداية الفقرات: كل فقرة جديدة يجب أن تبدأ بفراغين.\n10- إذا لاحظت وجود ترويسة (Header) أو تذييل (Footer) متكرر في كل صفحة (مثل اسم المدرسة أو التاريخ أو أرقام الصفحات)، فقم بالإبقاء عليها مرة واحدة فقط في بداية النص، واحذفها من باقي الأجزاء لضمان استمرارية النص .\n10. الجداول: يتم تحويل الجدول إلى نصوص متتالية، يكتب اسم العمود ثم نقطتان (:slight_smile: ثم القيمة، ويفصل بين كل صف والآخر سطر فارغ.\n١١. المراجعة النهائية: التأكد من عدم دمج نصين مختلفين في سطر واحد، والحفاظ على تسلسل الأرقام كما ورد في الأصل.”,
“inputType”: “binary”,
“simplify”: false,
“options”: {
“maxOutputTokens”: 300000
}
},
“type”: “@n8n/n8n-nodes-langchain.googleGemini”,
“typeVersion”: 1.1,
“position”: [
1136,
-16
],
“id”: “6f0d681b-a6ef-42b0-9571-78d0486776e2”,
“name”: “with answer”,
“retryOnFail”: false,
“maxTries”: 5,
“executeOnce”: true,
“credentials”: {
“googlePalmApi”: {
“id”: “NoXjUSXgvQMxzlqb”,
“name”: “Google Gemini(PaLM) Api account”
}
},
“onError”: “continueErrorOutput”
},
{
“parameters”: {
“jsCode”: “// الكود الصحيح بناءً على اسم العمود في شيت النور\nconst sheetUrl = $node[“Append row in sheet”].json[“رابط الملف”]; \n\nif (!sheetUrl) return ; // حماية إذا كانت الخلية فارغة\n\nreturn [{\n json: {\n clean_url: sheetUrl.trim()\n }\n}];”
},
“type”: “n8n-nodes-base.code”,
“typeVersion”: 2,
“position”: [
1152,
-352
],
“id”: “5fb64a86-4ec6-48d0-80b3-7f2a25237ca9”,
“name”: “Code in JavaScript2”
},
{
“parameters”: {
“url”: “={{ $json.clean_url }}”,
“options”: {
“response”: {
“response”: {
“responseFormat”: “file”
}
}
}
},
“type”: “n8n-nodes-base.httpRequest”,
“typeVersion”: 4.3,
“position”: [
1312,
-256
],
“id”: “0487808c-5492-41fc-9865-4a4ec761339f”,
“name”: “HTTP Request”
},
{
“parameters”: {
“jsCode”: “// 1. مناداة نود الرفع بالاسم الظاهر في صورتك\nconst driveData = $(‘Upload file’).first().json; \n\n// 2. إرجاع النتيجة في كائن جديد تماماً\nreturn {\n url: driveData.webViewLink, // الرابط اللي كان ضايع\n fileName: driveData.name, // اسم الملف\n timestamp: $now.format(‘HH:mm’) // وقت الكبشة الثانية\n};”
},
“type”: “n8n-nodes-base.code”,
“typeVersion”: 2,
“position”: [
672,
-528
],
“id”: “2087e6b8-f356-4c2c-a70b-8e1abd00ceb8”,
“name”: “Code in JavaScript3”
},
{
“parameters”: {
“operation”: “download”,
“fileId”: {
“__rl”: true,
“value”: “={{ $json[“رابط الملف”] }}”,
“mode”: “id”
},
“options”: {}
},
“type”: “n8n-nodes-base.googleDrive”,
“typeVersion”: 3,
“position”: [
960,
-32
],
“id”: “f38ad1da-f887-44eb-9872-920fccc8bac5”,
“name”: “Download file”,
“credentials”: {
“googleDriveOAuth2Api”: {
“id”: “5mNgPKrt8wq7Ypmg”,
“name”: “Google Drive account”
}
}
},
{
“parameters”: {
“documentId”: {
“__rl”: true,
“value”: “1_zZ1c0fPxYvzMbZaZVWn1lfnJrKwP65Qfp4e-C5cyzs”,
“mode”: “list”,
“cachedResultName”: “alnoor sheet”,
“cachedResultUrl”: “https://docs.google.com/spreadsheets/d/1_zZ1c0fPxYvzMbZaZVWn1lfnJrKwP65Qfp4e-C5cyzs/edit?usp=drivesdk”
},
“sheetName”: {
“__rl”: true,
“value”: “gid=0”,
“mode”: “list”,
“cachedResultName”: “Sheet1”,
“cachedResultUrl”: “https://docs.google.com/spreadsheets/d/1_zZ1c0fPxYvzMbZaZVWn1lfnJrKwP65Qfp4e-C5cyzs/edit#gid=0”
},
“options”: {
“returnFirstMatch”: true
}
},
“type”: “n8n-nodes-base.googleSheets”,
“typeVersion”: 4.7,
“position”: [
688,
-32
],
“id”: “89776a91-9837-47c7-855b-25e71c1642b2”,
“name”: “Get row(s) in sheet”,
“credentials”: {
“googleSheetsOAuth2Api”: {
“id”: “w1bKQtksrpIkCnUt”,
“name”: “Google Sheets account”
}
}
}
],
“connections”: {
“Telegram Trigger”: {
“main”: [
[
{
“node”: “Code in JavaScript1”,
“type”: “main”,
“index”: 0
}
]
]
},
“Code in JavaScript”: {
“main”: [
[
{
“node”: “Send a document”,
“type”: “main”,
“index”: 0
}
]
]
},
“without answer”: {
“main”: [
[
{
“node”: “Code in JavaScript”,
“type”: “main”,
“index”: 0
}
],
[
{
“node”: “Code in JavaScript”,
“type”: “main”,
“index”: 0
}
]
]
},
“Send a document”: {
“main”: [

]
},
“Switch”: {
“main”: [
[
{
“node”: “Send a text message”,
“type”: “main”,
“index”: 0
}
],
[
{
“node”: “Get row(s) in sheet”,
“type”: “main”,
“index”: 0
}
],
[
{
“node”: “without answer”,
“type”: “main”,
“index”: 0
}
],
[
{
“node”: “Upload file”,
“type”: “main”,
“index”: 0
}
],
,
,

]
},
“Merge”: {
“main”: [

]
},
“Send a text message”: {
“main”: [

]
},
“Message a model”: {
“main”: [

]
},
“Send a text message1”: {
“main”: [

]
},
“Code in JavaScript1”: {
“main”: [
[
{
“node”: “Switch”,
“type”: “main”,
“index”: 0
}
]
]
},
“Edit Fields”: {
“main”: [

]
},
“Edit Fields1”: {
“main”: [

]
},
“Upload file”: {
“main”: [
[
{
“node”: “Append row in sheet”,
“type”: “main”,
“index”: 0
}
]
]
},
“Append row in sheet”: {
“main”: [

]
},
“with answer”: {
“main”: [
[
{
“node”: “Code in JavaScript”,
“type”: “main”,
“index”: 0
}
],
[
{
“node”: “Code in JavaScript”,
“type”: “main”,
“index”: 0
}
]
]
},
“Code in JavaScript2”: {
“main”: [
[
{
“node”: “HTTP Request”,
“type”: “main”,
“index”: 0
}
]
]
},
“HTTP Request”: {
“main”: [

]
},
“Code in JavaScript3”: {
“main”: [

]
},
“Download file”: {
“main”: [
[
{
“node”: “with answer”,
“type”: “main”,
“index”: 0
}
]
]
},
“Get row(s) in sheet”: {
“main”: [
[
{
“node”: “Download file”,
“type”: “main”,
“index”: 0
}
]
]
}
},
“pinData”: {},
“meta”: {
“templateCredsSetupCompleted”: true,
“instanceId”: “e229359abd80efa7adb88247227cd4ad491f569da41c65dfba2fd6be3e821c43”
}
}

Hi @abd2001,

Excellent specifics. n8n is processing each click of the Q&A buttons in Telegram as a separate and independent run. By default, data (like the Google Drive fileId) from the first run is not available in the second run.

To rectify the situation, the fileId from the initial stage must be stored externally for accessibility by the second stage. One way you can do that is by simply using a Google Sheet as a simple database, since you are already using Google services.

Here is how to change your workflow

  1. Within Your Initial Step Post “Upload To Google Drive”

Insert a node named “Google Sheets: Append Row.” Set it up so that it creates a new row in a dedicated spreadsheet with at least two columns.

Use the Telegram trigger node’s chatId. This makes the user distinct.

Use the fileId from the output of the Google Drive: Upload File node.

As a result, it creates a permanent user-file link.

  1. During your second stage (in the “analyze” branch)

To begin with, add a Google Sheets: Lookup Row node.

Set it to look up the same spreadsheet for a row where the chatId column matches the incoming chatId from the new click of the telegram button.

The fileId stored earlier will be issued by this node.

After that, you can pass that fileId into a “Google Drive: Download File” node which will get you the file for your analysis step.

To Succeed, Focus on This

Your chatId is your key. The bot retrieves the specific file that belongs to the specific user.

Save the fileId or URL in the sheet, not file binary data.

When making a production bot, you might want to add a step to clean up the old entries from the sheet later.

This pattern consistently closes the gap between any two independent triggers. Let me know if this helps

​**“Hi there, regarding the logic of using Google Sheets as a database to store (chatId & fileId) to bridge the gap between n8n triggers. Is this a proven production method to avoid the 404 errors during callback queries? Have you personally implemented this and found it stable for multi-user bots? Thanks!”**

@abd2001 Indeed, for that exact purpose, using a Google Sheet as a lightweight database is a pattern that is both proven and stable in n8n, and I’ve successfully used it with multi-user bots. It is a great method for solving the 404 error when the second trigger can’t find the fileId. This method is quite reliable for low to medium traffic as the native Google Sheets nodes in n8n handle any connection or query problems. If your bot is a high-traffic, public-facing bot with thousands of users, you might eventually want to get your own dedicated database like PostgreSQL for improved performance. But the Google Sheets bridge is good enough for most use cases and is production-ready.