Du känner igen känslan: en skokartong med kvitton, ett rörigt bankflöde och ett kalkylark du svär att du ska “komma ikapp med” senare. Sen kommer månadsslutet, och du sitter och kisar på suddiga totalsummor och gissar kategorier du borde ha bokfört för flera veckor sedan.
Den här automationen för kvittologgning i Telegram träffar småföretagare först, men byråägare och finansansvariga som städar i efterhand känner också igen det. I stället för att skriva in varje leverantör, datum och totalsumma på nytt vidarebefordrar du ett kvitto i Telegram och din utgiftsrad dyker upp i Google Sheets på cirka 10 sekunder.
Nedan ser du hur flödet körs, vad det faktiskt producerar och var de riktiga tidsbesparingarna finns (inte bara “automation för automationens skull”).
Så fungerar automationen
Hela n8n-workflowen, från trigger till slutresultat:
n8n Workflow Template: Telegram till Google Sheets: kvitton loggas åt dig
flowchart LR
subgraph sg0["Flow 1"]
direction LR
n0["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Telegram Webhook"]
n1["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Get File Info"]
n2["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Download Photo"]
n3["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Convert to Base64"]
n4["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Extract with easybits"]
n5["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Process Extraction"]
n6["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Check Sheet Exists"]
n7@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Sheet Exists?", pos: "b", h: 48 }
n8["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Create Sheet"]
n9["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Setup Headers"]
n10["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Add Expense Row"]
n11["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Send Confirmation"]
n12["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>No Photo Message"]
n13["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Respond OK"]
n14["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Respond OK 2"]
n15["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Build Headers Request"]
n16["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Build Expense Data"]
n17["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Build Row Format"]
n18["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Format Data Row"]
n19["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Get Sheet Info"]
n20["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Extract Sheet ID"]
n21@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Needs Category?", pos: "b", h: 48 }
n22["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/telegram.svg' width='40' height='40' /></div><br/>Ask for Category"]
n23@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Has Photo or PDF?", pos: "b", h: 48 }
n8 --> n15
n1 --> n2
n9 --> n16
n7 --> n8
n7 --> n19
n2 --> n3
n19 --> n20
n10 --> n17
n18 --> n11
n21 --> n22
n21 --> n6
n22 --> n13
n17 --> n18
n20 --> n16
n12 --> n14
n0 --> n23
n3 --> n4
n23 --> n1
n23 --> n12
n11 --> n13
n16 --> n10
n6 --> n7
n5 --> n21
n15 --> n9
n4 --> n5
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n7,n21,n23 decision
class n0,n1,n2,n4,n6,n8,n9,n10,n11,n12,n13,n14,n18,n19 api
class n3,n5,n15,n16,n17,n20 code
classDef customIcon fill:none,stroke:none
class n0,n1,n2,n3,n4,n5,n6,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n22 customIcon
Problemet: kvittologgning blir till panik vid månadsskiftet
Manuell utgiftsloggning är bedrägligt dyr. Ett kvitto är “snabbt”, men 40 kvitton blir till en lördag du inte ville offra. Och det är inte bara knappandet. Det är växlingen mellan appar, jakten på datumet, valutakonverteringar, att bestämma kategori och att försöka minnas vad “SP*ABC” var på kontoutdraget. Befintliga utgiftsappar kan hjälpa, men många team stöter på två problem: de kostar mer än du vill betala för enkel insamling och extraktionskvaliteten är ojämn, så du måste ändå dubbelkolla allt.
Det blir snabbt mycket. Här är var det faller isär i verkligheten.
- Kvitton samlas på hög, så du gör klumpjobb när du redan har fullt upp.
- Att skriva leverantör, totalsumma och datum för hand bjuder in småfel som förstör rapporter senare.
- Kategorier glider över tid, vilket gör att din rad för “Måltider” blir en skräplåda.
- Ersättningsregler (som “bara 80 % av telefonräkningar”) är lätta att glömma när du har bråttom.
Lösningen: Telegram → AI-extraktion → felfria rader i Google Sheets
Det här flödet gör Telegram till din inkorg för kvitton och PDF:er och förvandlar sedan det stökiga “verkliga” dokumentet till strukturerad utgiftsdata. Du skickar ett kvitto till din Telegram-bot (foto eller PDF). n8n hämtar filen, konverterar den till ett format som extraktorn kan läsa och skickar den till en extraktionspipeline (easybits) för att plocka ut nyckelfält som leverantörsnamn, totalbelopp, valuta, transaktionsdatum, kategori och konfidens. Om kategorin är oklar ställer boten en snabb följdfråga i Telegram i stället för att gissa. Till sist hittar (eller skapar) flödet rätt månadsflik i Google Sheets och lägger till en felfri, formaterad rad, och skickar sedan en bekräftelse med detaljerna som loggades.
Det börjar med ett Telegram-meddelande, går igenom AI-baserad dokumentextraktion plus några rimlighetskontroller och slutar i ett kalkylark som är klart för rapportering. Det bästa är rytmen: logga när det händer, inte flera veckor senare.
Det du får: automation vs. resultat
| Vad det här flödet automatiserar | Resultat du får |
|---|---|
|
|
Exempel: så här ser det ut
Säg att du samlar in cirka 60 kvitton på en månad (kaffemöten, mjukvarutillägg, resor, som vanligt). Manuellt blir även “snabba” 2 minuter per kvitto ungefär 2 timmar knappande, plus den irriterande delen: att kontrollera totalsummor och datum när fotot är suddigt. Med det här flödet vidarebefordrar du varje kvitto när det händer, väntar cirka 10 sekunder på extraktionen och sen är du klar. På en månad är det flera timmar tillbaka och ett kalkylark som redan är organiserat i månadsflikar.
Det här behöver du
- n8n-instans (prova n8n Cloud gratis)
- Alternativ för self-hosting om du föredrar det (Hostinger fungerar bra)
- Telegram-bot som tar emot kvittofoton och PDF:er.
- Google Sheets för att lagra och organisera utgiftsrader.
- easybits API-nyckel (hämta den från sidan easybits Pipeline Details).
Kunskapsnivå: Nybörjare. Du kommer mest att kopiera inloggningsuppgifter, klistra in ID:n och testa med några kvitton.
Vill du inte sätta upp det här själv? Prata med en automationsexpert (gratis 15-minuters konsultation).
Så fungerar det
Du skickar ett kvitto till Telegram. Flödet startar när din Telegram-bot tar emot ett meddelande med en bilaga (foto eller PDF), och den kontrollerar direkt filtypen så att den inte försöker bearbeta slumpmässiga saker.
Kvittofilen hämtas och förbereds. n8n hämtar filmetadata och binärdata från Telegram och konverterar sedan till base64 så att den kan skickas på ett säkert och kompatibelt sätt till extraktionstjänsten.
AI extraherar nyckelfälten. easybits returnerar strukturerad data (leverantör, totalsumma, valuta, datum, kategori, konfidens) och flödet tolkar svaret. Om konfidensen för kategorin är låg pingar den dig i Telegram för att förtydliga, vilket ärligt talat slår att “gissa fel för alltid”.
Ditt Google Sheet hålls prydligt. n8n kontrollerar om rätt månadsflik finns, skapar den om den saknas, lägger på rubriker, lägger till den nya raden, formaterar den och skickar sedan en bekräftelse så att du vet vad som loggades.
Du kan enkelt justera kategorireglerna så att de matchar din kontoplan utifrån dina behov. Se den fullständiga implementationsguiden nedan för alternativ för anpassning.
Steg-för-steg-guide för implementation
Steg 1: Konfigurera webhook-triggern
Det här arbetsflödet startar när Telegram skickar en webhook-händelse som innehåller ett kvittofoto eller ett dokument.
- Lägg till noden Incoming Telegram Trigger och ställ in Path till
expense-botoch HTTP Method tillPOST. - Ställ in Response Mode till
responseNodeså att arbetsflödet kan svara via Return Webhook Ack och Return Webhook Ack 2. - I Validate Attachment Type behåller ni villkorsuttrycket
{{ $json.body.message.photo || $json.body.message.document ? 'yes' : 'no' }}lika medyesför att filtrera giltiga kvitto-uppladdningar. - Observera att Validate Attachment Type skickar vidare till både Fetch File Metadata och Notify Missing Receipt parallellt beroende på villkorsresultatet.
[CONFIGURE_YOUR_TOKEN]-platshållare i Telegram-URL:er i Fetch File Metadata, Retrieve File Binary, Run Receipt Extraction, Send User Confirmation och Notify Missing Receipt, annars triggas webhooken men inga filer kommer att hämtas.Steg 2: Anslut Google Sheets
Flera noder läser och skriver till er utgiftsarbetsbok i Google Sheets, så anslut autentisering en gång och återanvänd den.
- Öppna Verify Sheet Presence och ställ in URL till
https://sheets.googleapis.com/v4/spreadsheets/[YOUR_ID]/values/'{{ $('Interpret Extraction Data').item.json.sheet_name }}'!A1. - Anslut autentisering: Credential Required: Anslut era googleSheetsOAuth2Api-autentiseringsuppgifter.
- Upprepa samma autentisering för Google Sheets-noder som skriver och formaterar data: Generate Monthly Sheet, Apply Sheet Headers, Retrieve Sheet List, Append Expense Entry och Format Expense Row.
- Ersätt
[YOUR_ID]i alla Google Sheets-URL:er med ert kalkylblads-ID.
Steg 3: Sätt upp kvittohantering
Dessa noder hämtar kvittofilen, kodar den, extraherar fält och normaliserar data som används i senare steg.
- I Fetch File Metadata ställer ni in URL till
=https://api.telegram.org/bot[CONFIGURE_YOUR_TOKEN]/getFileoch JSON Body till{{ JSON.stringify({ file_id: $json.body.message.photo ? $json.body.message.photo.slice(-1)[0].file_id : $json.body.message.document.file_id }) }}. - I Retrieve File Binary ställer ni in URL till
=https://api.telegram.org/file/bot[CONFIGURE_YOUR_TOKEN]/{{ $json.result.file_path }}och säkerställer att svarsformatet är fil/binärt. - Behåll den befintliga JavaScript-koden i Encode File Base64 för att bygga en data-URI och hämta
chatIdochmimeTypefrån Incoming Telegram Trigger. - I Run Receipt Extraction ställer ni in URL till
https://extractor.easybits.tech/api/pipelines/dYI3r9xfHldQBlei34Peoch JSON Body till{{ JSON.stringify({ files: ["https://api.telegram.org/file/bot[CONFIGURE_YOUR_TOKEN]/" + $('Fetch File Metadata').first().json.result.file_path] }) }}. - Lämna Interpret Extraction Data som den är; den standardiserar fält som
category,vendor_name,total_amountoch beräknarsheet_nameocheur_amount.
Authorization med er giltiga token, annars kommer extraktionen att returnera tomma data.Steg 4: Konfigurera villkorsstyrd routning och kategori-frågor
Arbetsflödet förgrenas beroende på om en kategori upptäcktes och om ett månadsblad redan finns.
- I Check Category Needed behåller ni det booleska villkoret
{{ $json.needs_category_input }}lika medtrue. - Check Category Needed skickar vidare till både Request Category Detail och Verify Sheet Presence parallellt, så att användaren ombeds ange en kategori samtidigt som bladkontrollen körs.
- Öppna Request Category Detail och verifiera meddelandemallen och Chat ID-mappningen:
{{ $('Interpret Extraction Data').item.json.chat_id }}. Credential Required: Anslut era telegramApi-autentiseringsuppgifter. - I Sheet Missing Check behåller ni villkorsuttrycket
{{ $json.values ? 'yes' : 'no' }}lika mednoför att upptäcka saknade månadsblad. - Sheet Missing Check skickar vidare till både Generate Monthly Sheet och Retrieve Sheet List parallellt, så att bladet kan skapas och därefter hittas via ID.
Steg 5: Konfigurera utdataåtgärder
Dessa noder skapar eller formaterar bladet, lägger till utgiftsraden och notifierar användaren i Telegram.
- I Generate Monthly Sheet behåller ni batchUpdate-body och säkerställer att uttrycket för bladets titel använder
{{ $('Interpret Extraction Data').item.json.sheet_name }}. Credential Required: Anslut era googleSheetsOAuth2Api-autentiseringsuppgifter. - I Assemble Header Payload behåller ni befintlig JS så att den skapar ett formaterat sidhuvud, styling för datarad och formel för totalrad; den skickar
requestBodytill Apply Sheet Headers. - I Apply Sheet Headers ställer ni in JSON Body till
{{ $json.requestBody }}. Credential Required: Anslut era googleSheetsOAuth2Api-autentiseringsuppgifter. - I Compose Expense Row behåller ni den nuvarande JS-mappningen så att den output:ar
expenseBody-arrayen ochsheetId. - I Append Expense Entry ställer ni in URL till
https://sheets.googleapis.com/v4/spreadsheets/[YOUR_ID]/values/{{ $('Interpret Extraction Data').item.json.sheet_name }}!A4:G4:append?valueInputOption=USER_ENTERED&insertDataOption=OVERWRITEoch JSON Body till{{ $json.expenseBody }}. Credential Required: Anslut era googleSheetsOAuth2Api-autentiseringsuppgifter. - I Prepare Row Formatting behåller ni JS:en som extraherar det tillagda radnumret och förbereder
formatBodyför formatering. - I Format Expense Row ställer ni in JSON Body till
{{ $json.formatBody }}. Credential Required: Anslut era googleSheetsOAuth2Api-autentiseringsuppgifter. - I Send User Confirmation behåller ni Telegram-meddelandemallen med uttryck som
{{ $('Interpret Extraction Data').item.json.sheet_name }}för återkoppling till användaren.
Steg 6: Testa och aktivera ert arbetsflöde
Validera hela flödet end-to-end genom att skicka ett testkvitto och bekräfta att data hamnar i rätt Google Sheet.
- Klicka på Execute Workflow och skicka ett kvittofoto eller en PDF till er Telegram-bot för att trigga Incoming Telegram Trigger.
- Bekräfta att Send User Confirmation postar ett lyckat meddelande och att raden visas i rätt månadsblad i Google Sheets.
- Testa den ogiltiga vägen genom att skicka ett meddelande som inte är en bild och verifiera att Notify Missing Receipt och Return Webhook Ack 2 körs.
- När ni är nöjda, slå på arbetsflödet till Active för produktion.
Vanliga fallgropar
- Telegram-inloggningar kan gå ut eller så kan bot-token klistras in fel. Om det skapar fel: kontrollera Telegram-credential i n8n och bekräfta först att boten fortfarande svarar i Telegram.
- Om du använder Wait-noder eller extern rendering varierar processtiderna. Öka väntetiden om noder längre fram fallerar på tomma svar.
- easybits API-headers kräver exakt format: “Bearer YOUR_API_KEY”. Om extraktionen plötsligt returnerar obehörig, kopiera API-nyckeln igen från sidan easybits Pipeline Details och uppdatera HTTP Request-noden.
Vanliga frågor
Cirka 30 minuter om din Telegram-bot och ditt Google Sheet är redo.
Nej. Du kopplar ihop konton, klistrar in några ID:n och testar med riktiga kvitton.
Ja. n8n har ett gratis self-hosted-alternativ och en gratis provperiod på n8n Cloud. Cloud-planer börjar på 20 USD/månad för högre volym. Du behöver också räkna med kostnader för easybits-extraktion och eventuell OpenAI-användning om du utökar AI-promptarna.
Två alternativ: n8n Cloud (hanterat, enklast att komma igång) eller self-hosting på en VPS. För self-hosting är Hostinger VPS prisvärd och hanterar n8n bra. Self-hosting ger dig obegränsat antal körningar men kräver grundläggande serverhantering.
Ja, men planera reglerna i förväg. De flesta gör det genom att ändra logiken som bygger utgiftsraden (kodsteget “Compose Expense Row”) så att den tillämpar en multiplikator för vissa kategorier. Du kan också justera beslutet “Check Category Needed” så att boten bara ber om extra detaljer för kategorier du bryr dig om (som kunders återdebiterbara kostnader). Vanliga justeringar är egna kategorilistor, en “debiterbar”-flagga och olika satser per leverantör.
Oftast är det bot-token eller steget där Telegram-filen hämtas. Bekräfta att boten fortfarande svarar i Telegram och kontrollera sedan Telegram-credentials i n8n igen. Om kvittot är en udda filtyp kan flödet routa till “Notify Missing Receipt”-spåret i stället för att bearbeta det. Kontrollera också att n8n kan nå Telegrams API från din hostingmiljö (vissa företagsnätverk blockerar det).
På n8n Cloud Starter brukar du ligga bra till för en typisk småföretagsvolym, och self-hosting tar bort exekveringsgränser (din server blir begränsningen). I praktiken tar varje kvitto cirka 10 sekunder att extrahera, så stadig daglig användning är inget problem. Om du kör hundratals i en batch kan du slå i rate limits på extraktions-API:t eller Google Sheets-anrop, så lägg till throttling eller en kö.
Ofta, ja. n8n är mer bekvämt när du behöver förgrenad logik (som “be om kategoriförtydligande” bara ibland), skapande av månadsark och radformatering utan att betala extra för varje villkorssteg. Zapier eller Make kan fortfarande fungera om du bara vill ha “skicka fil → tolka → lägg till rad”, men så fort du lägger till regler och undantag blir det klumpigt. Om du är osäker: rita upp din “happy path” och dina två vanligaste edge cases och välj utifrån det. Prata med en automationsexpert om du vill ha en second opinion.
När det här väl rullar slutar kvitton vara ett “sen”-problem. Du skickar, det loggas och ditt kalkylark hålls tyst uppdaterat.
Kontakta oss
Hör av dig, så diskuterar vi hur just din verksamhet kan dra nytta av alla fantastiska möjligheter som AI skapar.