{
  "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
          }
        ]
      ]
    }
  }
}