AutomationFlowsAI & RAG › Provide Academic OCR and RAG Answers on Telegram with Gemini, Gpt-4 Mini and…

Provide Academic OCR and RAG Answers on Telegram with Gemini, Gpt-4 Mini and…

Original n8n title: Provide Academic OCR and RAG Answers on Telegram with Gemini, Gpt-4 Mini and Supabase

ByRayan Koemi Karuby @rynkoemi on n8n.io

🛠️ How It Works: System Architecture Workflow ini bekerja melalui empat lapisan proses utama yang terintegrasi secara otomatis: Input Processing & Routing Telegram Trigger: Menangkap setiap pesan masuk dari mahasiswa.

Event trigger★★★★★ complexityAI-powered38 nodesTelegram TriggerHTTP RequestTelegramGoogle SheetsOpenAI ChatAgentGoogle Sheets ToolGoogle Drive Trigger
AI & RAG Trigger: Event Nodes: 38 Complexity: ★★★★★ AI nodes: yes Added:

This workflow corresponds to n8n.io template #15564 — we link there as the canonical source.

This workflow follows the Agent → Documentdefaultdataloader 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 →

Download .json
{
  "id": "zzkoWBHt4jUdt82V",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Workflow Utama",
  "tags": [],
  "nodes": [
    {
      "id": "d2ba99b1-454c-4a40-94ee-cbab20d44359",
      "name": "Telegram Trigger",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -544,
        1760
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {
          "download": true
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "14a65c1f-9f0f-4ad6-bb58-8ab1c797cf27",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        -320,
        1728
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "91d9cd60-3987-4aeb-8add-b15b23601087",
                    "operator": {
                      "type": "string",
                      "operation": "exists",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.message.text }}",
                    "rightValue": ""
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "ad99e257-bcaf-42a2-b068-53e0c96729db",
                    "operator": {
                      "type": "object",
                      "operation": "exists",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.message.photo[2] }}",
                    "rightValue": ""
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "4f8d9425-641e-4044-a54a-d73444ea28e0",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $json.message.text }}",
                    "rightValue": "/help"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "69cae014-32a5-44e4-abb1-bd8324df9b65",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $json.message.text }}",
                    "rightValue": "=/cekstatus"
                  }
                ]
              }
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "4c6d0bdd-4c69-4c43-a214-f5a852bbae5c",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        176,
        1728
      ],
      "parameters": {
        "options": {
          "ignoreCase": true
        },
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "23f4316d-5a77-45ae-81e7-18ee4cacb995",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.candidates[0].content.parts[0].text }}",
              "rightValue": "ERROR:"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "25d826fe-52b4-4b94-82c4-eec691a3eb73",
      "name": "Analisa gambar",
      "type": "n8n-nodes-base.httpRequest",
      "disabled": true,
      "position": [
        16,
        1680
      ],
      "parameters": {
        "url": "=https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"contents\": [\n    {\n      \"parts\": [\n        {\n          \"inline_data\": {\n            \"mime_type\": \"image/jpeg\",\n            \"data\": \"{{ $('from File').item.json.data }}\"\n          }\n        },\n        {\n          \"text\": \"Lakukan OCR pada dokumen ini dan kembalikan hasil ekstraksi dalam format JSON di bawah ini. Identifikasi jenis formulir secara otomatis berdasarkan judul atau pola isi.\\n\\nFormat wajib:\\n\\n{\\n  \\\"form_type\\\": \\\"pendaftaran_sempro | undangan_sempro | bap_sempro | cover_acc | lembar_kendali | lembar_bimbingan | peminjaman_ruangan | other\\\",\\n  \\\"nama\\\": null,\\n  \\\"nim\\\": null,\\n  \\\"tanggal\\\": null,\\n  \\\"judul_proposal\\\": null,\\n  \\\"pembimbing_1\\\": null,\\n  \\\"pembimbing_2\\\": null,\\n  \\\"penguji_1\\\": null,\\n  \\\"penguji_2\\\": null,\\n  \\\"nomor_surat\\\": null,\\n  \\\"ruangan\\\": null,\\n  \\\"waktu\\\": null,\\n  \\\"raw_text\\\": \\\"...\\\"\\n}\\n\\nAturan:\\n- Jangan tulis teks lain di luar JSON.\\n- Jika data tidak ada, isi null.\\n- Pastikan nama dosen terbaca lengkap.\\n- Jika ada tabel, baca isinya.\\n- Jika dokumen multi-halaman, baca semua.\"\n        }\n      ]\n    }\n  ]\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "edbcab18-0dbb-4806-82f2-8dd4cdc47a72",
      "name": "Respon error",
      "type": "n8n-nodes-base.telegram",
      "position": [
        336,
        1632
      ],
      "parameters": {
        "text": "=Formi tidak dapat dibaca dengan jelas. Pastikan foto form jelas dan tidak blur, pencahayaan cukup, dan semua text terlihat. Silakan coba foto ulang! \ud83d\udcf7",
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "7eb9f58a-cde5-4f06-8f51-12510a514603",
      "name": "Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        336,
        1792
      ],
      "parameters": {
        "columns": {
          "value": {
            "nim": "={{ $json.candidates[0].content.parts[0].text.match(/\"nim\":\\s*\"([^\"]+)\"/)[1] }}",
            "nama": "={{ $json.candidates[0].content.parts[0].text.match(/\"nama\":\\s*\"([^\"]+)\"/)[1] }}",
            "waktu": "={{ ($json.candidates[0].content.parts[0].text.match(/\"waktu\":\\s*\"([^\"]*)\"/) || [null,null])[1] }}",
            "ruangan": "={{ ($json.candidates[0].content.parts[0].text.match(/\"ruangan\":\\s*\"([^\"]*)\"/) || [null,null])[1] }}",
            "tanggal": "={{ $json.candidates[0].content.parts[0].text.match(/\"tanggal\":\\s*\"([^\"]+)\"/)[1] }}",
            "raw_text": "={{ ($json.candidates[0].content.parts[0].text.match(/\"raw_text\":\\s*\"([\\s\\S]*?)\"$/) || [null,null])[1] }}\n",
            "form_type": "={{ $json.candidates[0].content.parts[0].text.match(/\"form_type\":\\s*\"([^\"]+)\"/)[1] }}",
            "penguji_1": "={{ ($json.candidates[0].content.parts[0].text.match(/\"penguji_1\":\\s*\"([^\"]*)\"/) || [null,null])[1] }}",
            "penguji_2": "={{ ($json.candidates[0].content.parts[0].text.match(/\"penguji_2\":\\s*\"([^\"]*)\"/) || [null,null])[1] }}",
            "nomor_surat": "={{ ($json.candidates[0].content.parts[0].text.match(/\"nomor_surat\":\\s*\"([^\"]*)\"/) || [null,null])[1] }}",
            "pembimbing_1": "={{ ($json.candidates[0].content.parts[0].text.match(/\"pembimbing_1\":\\s*\"([^\"]*)\"/) || [null,null])[1] }}",
            "pembimbing_2": "={{ ($json.candidates[0].content.parts[0].text.match(/\"pembimbing_2\":\\s*\"([^\"]*)\"/) || [null,null])[1] }}",
            "judul_proposal": "={{ ($json.candidates[0].content.parts[0].text.match(/\"judul_proposal\":\\s*\"([^\"]*)\"/) || [null,null])[1] }}"
          },
          "schema": [
            {
              "id": "form_type",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "form_type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "nama",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "nama",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "nim",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "nim",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "tanggal",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "tanggal",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "judul_proposal",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "judul_proposal",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "pembimbing_1",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "pembimbing_1",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "pembimbing_2",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "pembimbing_2",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "penguji_1",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "penguji_1",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "penguji_2",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "penguji_2",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "nomor_surat",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "nomor_surat",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ruangan",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "ruangan",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "waktu",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "waktu",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "raw_text",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "raw_text",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "raw_text"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1igRBimZm2BRJQ_9N0IKFFUuTsim9a9lJ0jPwm--Brrc/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1igRBimZm2BRJQ_9N0IKFFUuTsim9a9lJ0jPwm--Brrc",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1igRBimZm2BRJQ_9N0IKFFUuTsim9a9lJ0jPwm--Brrc/edit?usp=drivesdk",
          "cachedResultName": "TA_SEMPRO_DATABASE"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "6501350b-a9a0-4b84-be9d-3784a0bc184b",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        1616
      ],
      "parameters": {
        "color": 4,
        "width": 788,
        "height": 332,
        "content": "## Workflow untuk upload gambar form"
      },
      "typeVersion": 1
    },
    {
      "id": "c22e9058-c600-4d76-94e4-2beb38e04f1f",
      "name": "Telegram1",
      "type": "n8n-nodes-base.telegram",
      "position": [
        496,
        1792
      ],
      "parameters": {
        "text": "=Data berhasil disimpan ke database. Berikut ringkasan hasil OCR:\n\n\ud83d\udcc4 Jenis Form : {{ $json.form_type }}\n\ud83d\udc64 Nama        : {{ $json.nama }}\n\ud83c\udd94 NIM         : {{ $json.nim }}\n\ud83d\udcc5 Tanggal     : {{ $json.tanggal }}\n\ud83c\udfdb\ufe0f Ruangan     : {{ $json.ruangan }}\n\u23f0 Waktu       : {{ $json.waktu }}\n\nTerima kasih, dokumen kamu sudah tercatat. Jika ingin mengecek status kapan saja, gunakan perintah:\n/cek_status\n",
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "1c14d410-939c-45ce-98ac-1da7476e9013",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -144,
        944
      ],
      "parameters": {
        "color": 5,
        "width": 568,
        "height": 400,
        "content": "## RAG"
      },
      "typeVersion": 1
    },
    {
      "id": "0b95b103-e406-48d6-ad60-2cd238a5c1e2",
      "name": "Telegram4",
      "type": "n8n-nodes-base.telegram",
      "position": [
        272,
        2336
      ],
      "parameters": {
        "text": "={{ $json.output }}",
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "942f85a7-9e8b-47b1-b07c-d1841e0f896a",
      "name": "Telegram5",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -64,
        2048
      ],
      "parameters": {
        "text": "=Berikut adalah panduan penggunaan bot:\n\n/help\nUntuk menampilkan menu bantuan.\n\n/cek_status\nUntuk mengecek status Tugas Akhir kamu berdasarkan data yang sudah masuk di sistem.\n\nKirim foto atau PDF\nBot akan memproses dokumen formulir TA melalui OCR dan menyimpannya ke database.\n\nTanya informasi\nKamu dapat bertanya seputar Tugas Akhir, Sempro, Semhas, revisi, dan administrasi lainnya. Bot akan menjawab berdasarkan data resmi melalui RAG.\n\nJika membutuhkan bantuan lainnya, tinggal kirim pesan di sini.\n",
        "chatId": "={{ $json.message.chat.id }}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "cbad4b33-fcc5-44db-9b33-1be305c6378b",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        2256
      ],
      "parameters": {
        "color": 6,
        "width": 584,
        "height": 380,
        "content": "## Request status"
      },
      "typeVersion": 1
    },
    {
      "id": "d3ea14b6-7944-4114-8f75-adca2ce86274",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        1984
      ],
      "parameters": {
        "width": 300,
        "height": 240,
        "content": "## Request /help"
      },
      "typeVersion": 1
    },
    {
      "id": "a3a9b1be-431d-4679-a35f-10b9ec38cb93",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        0,
        2496
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "94dc8e5a-b32d-4fbe-89cb-af1a8d648bdb",
      "name": "AI Agent2",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        0,
        2336
      ],
      "parameters": {
        "text": "=Berikut adalah data status Tugas Akhir dari Google Sheets:\n\n{{ JSON.stringify($json, null, 2) }}\n\nJelaskan status mahasiswa berdasarkan data ini.\n",
        "options": {
          "systemMessage": "Kamu adalah asisten akademik yang bertugas memberikan status perkembangan Tugas Akhir mahasiswa.\n\nTugasmu:\n1. Terima data yang dikirim sistem dalam bentuk JSON dari Google Spreadsheet.\n2. Baca dan rangkum status mahasiswa berdasarkan field berikut apabila tersedia:\n   - form_type\n   - tanggal\n   - ruangan\n   - waktu\n   - pembimbing_1\n   - pembimbing_2\n   - penguji_1\n   - penguji_2\n   - nomor_surat\n   - raw_text\n   - status (waiting_for_examiner, complete, atau lainnya)\n\n3. Berikan respons yang jelas, singkat, informatif, dan tidak mengarang data di luar input.\n4. Jika beberapa field kosong atau null, abaikan saja tanpa menyebutkan error.\n5. Jika data tidak ditemukan, jawab: \u201cStatus Tugas Akhir belum terdaftar.\u201d\n\nFormat jawaban:\n- Tampilkan ringkasan status dalam bahasa Indonesia yang sopan.\n- Berikan informasi yang paling penting lebih dulu (status utama).\n- Tambahkan detail seperti pembimbing, ruangan, atau tanggal jika ada.\n- Jangan tampilkan JSON mentah.\n- Jangan menambahkan hal di luar konteks administrasi Tugas Akhir.\n\nContoh gaya jawaban:\n\u201cStatus Tugas Akhir Anda saat ini: Menunggu penetapan dosen penguji. Formulir pendaftaran telah diterima pada tanggal 7 November 2025. Jika ada dokumen yang ingin diperbarui, silakan kirim ulang melalui sistem.\u201d\n\nFokus utama:\n- Tidak boleh melakukan asumsi.\n- Tidak boleh membuat informasi baru.\n- Hanya rangkum berdasarkan data yang diterima."
        },
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "ef6b2648-afd6-463b-bae3-b7eb36c9be05",
      "name": "Get row(s) in sheet in Google Sheets",
      "type": "n8n-nodes-base.googleSheetsTool",
      "position": [
        160,
        2480
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Return_only_First_Matching_Row', ``, 'boolean') }}"
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1igRBimZm2BRJQ_9N0IKFFUuTsim9a9lJ0jPwm--Brrc/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1igRBimZm2BRJQ_9N0IKFFUuTsim9a9lJ0jPwm--Brrc",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1igRBimZm2BRJQ_9N0IKFFUuTsim9a9lJ0jPwm--Brrc/edit?usp=drivesdk",
          "cachedResultName": "TA_SEMPRO_DATABASE"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "5947be32-89c0-4691-88e3-811291ccf73e",
      "name": "Get row(s) in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -144,
        2336
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1igRBimZm2BRJQ_9N0IKFFUuTsim9a9lJ0jPwm--Brrc/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1igRBimZm2BRJQ_9N0IKFFUuTsim9a9lJ0jPwm--Brrc",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1igRBimZm2BRJQ_9N0IKFFUuTsim9a9lJ0jPwm--Brrc/edit?usp=drivesdk",
          "cachedResultName": "TA_SEMPRO_DATABASE"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "93652721-b311-4026-adc7-05f9f8221f53",
      "name": "Google Drive Trigger",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "position": [
        -112,
        704
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {
          "fileType": "all"
        },
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "list",
          "value": "1VSFtJe8dRJ5IbNmazp4SE1aQJENM7YM_",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1VSFtJe8dRJ5IbNmazp4SE1aQJENM7YM_",
          "cachedResultName": "kbchatbotbaru"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ea0a3c38-ef3e-4f2d-9aed-9c9761375353",
      "name": "Download file",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        32,
        704
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "513ebace-f452-4809-8dc9-c9cf177c2901",
      "name": "Embeddings OpenAI",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        176,
        832
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "871b681a-64b9-4389-aeeb-e3ddc8a78369",
      "name": "Supabase Vector Store1",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "position": [
        176,
        704
      ],
      "parameters": {
        "mode": "insert",
        "options": {
          "queryName": "match_documents"
        },
        "tableName": {
          "__rl": true,
          "mode": "list",
          "value": "documents",
          "cachedResultName": "documents"
        }
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "496f3026-a99d-4b44-b333-0338a486bde4",
      "name": "Default Data Loader",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        304,
        832
      ],
      "parameters": {
        "options": {},
        "dataType": "binary"
      },
      "typeVersion": 1.1
    },
    {
      "id": "b5d12b17-5365-4499-b486-94a1feb625b3",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -64,
        960
      ],
      "parameters": {
        "text": "={{ $json.message.text }}",
        "options": {
          "systemMessage": "Peran kamu adalah asisten akademik resmi Program Studi Sains Data ITERA\nyang bertugas menjawab pertanyaan mahasiswa terkait Tugas Akhir.\n\nKamu WAJIB menggunakan informasi yang berasal dari knowledge base\n(Supabase Vector Store) yang diberikan oleh sistem melalui hasil retrieval.\n\nAturan yang HARUS kamu patuhi:\n\n1. Kamu HANYA BOLEH menjawab berdasarkan isi dokumen yang muncul\n   pada hasil retrieval dari Supabase Vector Store.\n2. Kamu DILARANG menambah, mengarang, mengasumsikan, atau\n   menggeneralisasi informasi yang tidak secara eksplisit tertulis\n   pada dokumen hasil retrieval.\n3. Jika informasi yang ditanyakan TIDAK ditemukan atau TIDAK dijelaskan\n   pada dokumen hasil retrieval, kamu WAJIB menjawab dengan kalimat berikut\n   (tanpa modifikasi):\n\n   \"Informasi tersebut tidak terdapat dalam dokumen panduan Tugas Akhir.\"\n\n4. Kamu TIDAK BOLEH menjawab menggunakan pengetahuan umum,\n   pengalaman pribadi, atau logika di luar dokumen.\n5. Jika terdapat beberapa dokumen hasil retrieval,\n   prioritaskan informasi yang PALING relevan dengan pertanyaan.\n6. Jika dokumen yang di-retrieve hanya sebagian,\n   rangkum bagian yang relevan TANPA menambah informasi baru.\n7. Jika jawaban berupa prosedur atau tahapan,\n   sampaikan dalam bentuk poin-poin yang jelas dan ringkas.\n8. Gunakan bahasa formal akademik yang singkat, jelas, dan mudah dipahami.\n9. Jangan menyebutkan istilah seperti \"berdasarkan pengetahuan saya\",\n   \"biasanya\", atau \"umumnya\".\n10. Jangan menyebutkan sistem, model, AI, atau proses retrieval\n    dalam jawaban ke pengguna.\n\nTujuan utama kamu adalah memastikan jawaban bersifat faktual,\nterverifikasi oleh dokumen, dan bebas dari halusinasi.\npakai informasi dari Supabase Vector Store!!"
        },
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "3099b95b-2aa1-4375-976a-331793fe26d1",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -80,
        1104
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "gpt-4o-mini"
        },
        "options": {
          "temperature": 0.5
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "bcdc084a-dbf5-4a77-924f-912d259d1257",
      "name": "Supabase Vector Store",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "position": [
        96,
        1136
      ],
      "parameters": {
        "mode": "retrieve-as-tool",
        "topK": 10,
        "options": {},
        "tableName": {
          "__rl": true,
          "mode": "list",
          "value": "documents",
          "cachedResultName": "documents"
        },
        "toolDescription": "supabase vector store ini sebagai knowledge base untuk menjawab semua pertanyaan dan query message user, wajib pakai informasi dari supabase vector store ini"
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "62ef9238-04e9-4fe9-9cbe-4fa95cdf163e",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -144,
        640
      ],
      "parameters": {
        "color": 5,
        "width": 576,
        "height": 288,
        "content": "## Knowledge Base"
      },
      "typeVersion": 1
    },
    {
      "id": "2bfb8253-67b7-4cc0-8a56-313e0ce82f89",
      "name": "When Executed by Another Workflow",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        -128,
        1424
      ],
      "parameters": {
        "inputSource": "passthrough"
      },
      "typeVersion": 1.1
    },
    {
      "id": "cf8fd7c4-768b-4ea0-a443-af3756985e8a",
      "name": "Get many rows",
      "type": "n8n-nodes-base.supabase",
      "position": [
        16,
        1424
      ],
      "parameters": {
        "tableId": "n8n_chat_histories",
        "operation": "getAll"
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f2d6f9d7-69af-4d16-9554-91f39faed09c",
      "name": "Append or update row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        176,
        1424
      ],
      "parameters": {
        "columns": {
          "value": {
            "id": "={{ $json.id }}",
            "message": "={{ $json.message }}",
            "session_id": "={{ $json.session_id }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "session_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "session_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "message",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "message",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1665060728,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1igRBimZm2BRJQ_9N0IKFFUuTsim9a9lJ0jPwm--Brrc/edit#gid=1665060728",
          "cachedResultName": "chathistory"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1igRBimZm2BRJQ_9N0IKFFUuTsim9a9lJ0jPwm--Brrc",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1igRBimZm2BRJQ_9N0IKFFUuTsim9a9lJ0jPwm--Brrc/edit?usp=drivesdk",
          "cachedResultName": "TA_SEMPRO_DATABASE"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "97ba79ce-54fa-4afa-89cc-cfd4e06446ce",
      "name": "Send a text message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        208,
        960
      ],
      "parameters": {
        "text": "={{ $json.output }}",
        "chatId": "={{ $node[\"Telegram Trigger\"].json.message.from.id }}",
        "additionalFields": {
          "parse_mode": "HTML",
          "appendAttribution": false
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2,
      "alwaysOutputData": false
    },
    {
      "id": "64e34487-2f23-4de9-8b04-8c1927e744d9",
      "name": "Postgres Chat Memory1",
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "position": [
        -16,
        1232
      ],
      "parameters": {
        "sessionKey": "={{ $json.message.message_id }}",
        "sessionIdType": "customKey"
      },
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "63543787-4815-4fc5-940b-95996d19c23d",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -144,
        1360
      ],
      "parameters": {
        "color": 5,
        "width": 488,
        "height": 240,
        "content": "## Pencatatan riwayat ke spreadsheet"
      },
      "typeVersion": 1
    },
    {
      "id": "40214665-dd74-45e4-abbb-d1ba3b0b8826",
      "name": "from File",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -128,
        1680
      ],
      "parameters": {
        "options": {},
        "operation": "binaryToPropery"
      },
      "typeVersion": 1
    },
    {
      "id": "13350c2d-6290-49d6-9696-677fd2f139d2",
      "name": "Embeddings HuggingFace Inference1",
      "type": "@n8n/n8n-nodes-langchain.embeddingsHuggingFaceInference",
      "position": [
        160,
        1248
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "huggingFaceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "726ab240-eb56-475c-a462-f6613aa4add4",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1088,
        1712
      ],
      "parameters": {
        "color": "#D7E147",
        "width": 484,
        "height": 236,
        "content": "##  Entry Point: Telegram Trigger\nWorkflow ini dimulai dari pesan di Telegram. Bot akan memilah input pengguna melalui node Switch menjadi 4 jalur utama:\n\nTanya Jawab (RAG): Pesan teks biasa diproses oleh AI Agent.\n\nUpload Dokumen: Gambar diproses untuk ekstraksi data (OCR).\n\nBantuan: Perintah /help mengirimkan panduan penggunaan.\n\nCek Status: Perintah /cekstatus mengambil data dari database mahasiswa"
      },
      "typeVersion": 1
    },
    {
      "id": "63c771c4-af01-4baa-affe-631096409b4f",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        432,
        1360
      ],
      "parameters": {
        "color": "#D7E147",
        "width": 484,
        "height": 236,
        "content": "## OCR & Database (Ekstraksi Form)\nJalur untuk memproses foto formulir Tugas Akhir:\n\nAnalisa Gambar: Menggunakan model Gemini untuk melakukan OCR pada dokumen (pendaftaran sempro, lembar bimbingan, dll).\n\nValidasi: Jika gambar blur atau tidak terbaca, bot mengirimkan Respon Error.\n\nGoogle Sheets: Data hasil ekstraksi (Nama, NIM, Tanggal, dll) disimpan secara otomatis ke spreadsheet TA_SEMPRO_DATABASE."
      },
      "typeVersion": 1
    },
    {
      "id": "1da62dcd-c3ed-4f43-8c79-189069450247",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        464,
        816
      ],
      "parameters": {
        "color": "#D7E147",
        "width": 484,
        "height": 268,
        "content": "## Knowledge Base & RAG System\nSistem cerdas untuk menjawab pertanyaan seputar prosedur akademik:\n\nKnowledge Base: Dokumen panduan di Google Drive diunduh secara otomatis, dipotong-potong (chunking), dan disimpan ke Supabase Vector Store.\n\nAI Agent (GPT-4o mini): Bertugas menjawab pertanyaan user HANYA berdasarkan data resmi di Supabase agar tidak terjadi halusinasi informasi.\n\nMemory: Menggunakan Postgres untuk mengingat konteks percakapan sebelumnya."
      },
      "typeVersion": 1
    },
    {
      "id": "8fbb0c7e-c0da-4835-b920-18555762529a",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -912,
        656
      ],
      "parameters": {
        "color": "#D7E147",
        "width": 484,
        "height": 636,
        "content": "## \ud83d\ude80 Welcome to Academic Assistant Bot (OCR + RAG)\nWorkflow ini dirancang sebagai asisten akademik otomatis untuk Program Studi Sains Data ITERA. Sistem ini menggabungkan kekuatan OCR, Vector Database, dan AI Agent untuk mengelola administrasi Tugas Akhir (TA) secara mandiri.\n\n\ud83d\udee0\ufe0f Fitur Utama:\nAutomated OCR: Mengekstrak data mahasiswa dari foto formulir pendaftaran, undangan, hingga BAP Sempro menggunakan model Gemini.\n\nRAG-based Q&A: Menjawab pertanyaan seputar prosedur akademik berdasarkan dokumen panduan resmi yang tersimpan di Supabase Vector Store.\n\nLive Status Tracking: Mahasiswa dapat mengecek status perkembangan TA mereka secara real-time yang ditarik langsung dari database Google Sheets.\n\nHistory Logging: Mencatat setiap interaksi dan riwayat percakapan ke dalam database untuk pemantauan admin.\n\n## \ud83d\udccb Setup (Credentials Required):\nSebelum mengaktifkan workflow ini, pastikan kamu telah menghubungkan:\n\nTelegram Bot API (Trigger & Respon).\n\nGoogle Sheets & Drive API (Penyimpanan Data & Dokumen Sumber).\n\nOpenAI API (Otak AI Agent & Embeddings).\n\nSupabase API (Vektor Database & Chat History).\n\nGemini API (Proses OCR Gambar)."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "eb8bc072-6a50-4dca-ba51-a516fcad509b",
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Respon error",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "from File",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Telegram5",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get row(s) in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Send a text message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent2": {
      "main": [
        [
          {
            "node": "Telegram4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "from File": {
      "main": [
        [
          {
            "node": "Analisa gambar",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download file": {
      "main": [
        [
          {
            "node": "Supabase Vector Store1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get many rows": {
      "main": [
        [
          {
            "node": "Append or update row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets": {
      "main": [
        [
          {
            "node": "Telegram1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analisa gambar": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI": {
      "ai_embedding": [
        [
          {
            "node": "Supabase Vector Store1",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent2",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Default Data Loader": {
      "ai_document": [
        [
          {
            "node": "Supabase Vector Store1",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s) in sheet": {
      "main": [
        [
          {
            "node": "AI Agent2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive Trigger": {
      "main": [
        [
          {
            "node": "Download file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Postgres Chat Memory1": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Vector Store": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings HuggingFace Inference1": {
      "ai_embedding": [
        [
          {
            "node": "Supabase Vector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "When Executed by Another Workflow": {
      "main": [
        [
          {
            "node": "Get many rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s) in sheet in Google Sheets": {
      "ai_tool": [
        [
          {
            "node": "AI Agent2",
            "type": "ai_tool",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

🛠️ How It Works: System Architecture Workflow ini bekerja melalui empat lapisan proses utama yang terintegrasi secara otomatis: Input Processing & Routing Telegram Trigger: Menangkap setiap pesan masuk dari mahasiswa.

Source: https://n8n.io/workflows/15564/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

A lightweight, self-hosted AI assistant built entirely in n8n. Multi-channel messaging (Telegram, WhatsApp, Gmail), persistent memory, task management, and autonomous work — all in a single visual wor

Telegram Trigger, OpenRouter Chat, Data Table +20
AI & RAG

This workflow implements an advanced AI automation agent (OpenClaw Agent) that interacts with users through Telegram and integrates multiple AI models, external tools, and cloud services to automate c

Telegram Trigger, Telegram, OpenAI +21
AI & RAG

📌 Overview

Redis, WhatsApp, OpenAI Chat +12
AI & RAG

Your AI workforce is ready. Are you?

Google Sheets Tool, Mcp Trigger, Google Drive +29
AI & RAG

This comprehensive workflow bundle is designed as a powerful starter kit, enabling you to build a multi-functional AI assistant on Telegram. It seamlessly integrates AI-powered voice interactions, an

Telegram Trigger, Telegram, OpenAI +19