Du gör klart jobbet, och sedan “gör du klart adminen”. Timmar senare letar du fortfarande igenom skickade mejl, kalenderhändelser och GitHub för att minnas vad som faktiskt hände.
Den här tidsrapportautomatiseringen slår ärligt talat först mot konsulter. Men även byråansvariga och utvecklare känner av det, särskilt när kundfaktureringen bygger på strukturerade anteckningar. Resultatet är enkelt: en kundklar tidsrapport i Google Sheets som fylls i dagligen, utan att du behöver backfylla i slutet av veckan.
Nedan ser du hur flödet hämtar din dagliga aktivitet från Gmail, Google Kalender och GitHub, sammanfattar den med AI (kort och konsekvent) och lägger till den som prydliga rader i rätt månadsark.
Så fungerar den här automatiseringen
Hela n8n-flödet, från trigger till slutresultat:
n8n Workflow Template: Gmail + Google Sheets: tidsrapporter som kan skickas
flowchart LR
subgraph sg0["Generate Journal Sum Flow"]
direction LR
n0@{ icon: "mdi:location-exit", form: "rounded", label: "Get Today's Calendar Events", pos: "b", h: 48 }
n1@{ icon: "mdi:message-outline", form: "rounded", label: "Get Today's Emails", pos: "b", h: 48 }
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/github.dark.svg' width='40' height='40' /></div><br/>Get GitHub PRs"]
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/>Format All Data"]
n4@{ icon: "mdi:robot", form: "rounded", label: "Generate Journal Summary", pos: "b", h: 48 }
n5@{ icon: "mdi:cog", form: "rounded", label: "Aggregate", pos: "b", h: 48 }
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/merge.svg' width='40' height='40' /></div><br/>Merge"]
n7@{ icon: "mdi:cog", form: "rounded", label: "Aggregate1", pos: "b", h: 48 }
n8@{ icon: "mdi:cog", form: "rounded", label: "Aggregate2", pos: "b", h: 48 }
n9@{ icon: "mdi:cog", form: "rounded", label: "Daily at 7PM", pos: "b", h: 48 }
n10@{ icon: "mdi:swap-vertical", form: "rounded", label: "Set Variables", pos: "b", h: 48 }
n11@{ icon: "mdi:cog", form: "rounded", label: "Aggregate3", pos: "b", h: 48 }
n12@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If Authors Commit", pos: "b", h: 48 }
n13@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If it's closed today", pos: "b", h: 48 }
n14@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If it's created today", pos: "b", h: 48 }
n15@{ icon: "mdi:swap-vertical", form: "rounded", label: "Split Out", pos: "b", h: 48 }
n16@{ icon: "mdi:swap-vertical", form: "rounded", label: "Split Out1", pos: "b", h: 48 }
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/httprequest.dark.svg' width='40' height='40' /></div><br/>Get Commits From Github"]
n18@{ icon: "mdi:database", form: "rounded", label: "Insert Sheets Entry", pos: "b", h: 48 }
n19@{ icon: "mdi:database", form: "rounded", label: "Create Sheet If It Doesn't E..", pos: "b", h: 48 }
n20@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If it didn't exist", pos: "b", h: 48 }
n21@{ icon: "mdi:swap-vertical", form: "rounded", label: "Init Sheet Headers", pos: "b", h: 48 }
n22@{ icon: "mdi:database", form: "rounded", label: "init Sheet Columns", pos: "b", h: 48 }
n23@{ icon: "mdi:swap-vertical", form: "rounded", label: "Split Out2", pos: "b", h: 48 }
n6 --> n3
n5 --> n6
n15 --> n18
n7 --> n6
n8 --> n6
n11 --> n6
n16 --> n17
n23 --> n2
n9 --> n10
n10 --> n1
n10 --> n0
n10 --> n19
n10 --> n16
n10 --> n23
n2 --> n14
n2 --> n13
n3 --> n4
n12 --> n11
n1 --> n5
n20 --> n21
n21 --> n22
n13 --> n8
n14 --> n8
n17 --> n12
n4 --> n15
n0 --> n7
n19 --> n20
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 n4 ai
class n12,n13,n14,n20 decision
class n18,n19,n22 database
class n17 api
class n3 code
classDef customIcon fill:none,stroke:none
class n2,n3,n6,n17 customIcon
Problemet: tidsrapporter blir gjorda sist (och det märks)
Manuell tidrapportering sker oftast efter det riktiga jobbet, vilket betyder att den sker när ditt minne är som sämst. Du slutar med att skanna gårdagens kalender, söka i inkorgen efter den där tråden och gissa vilka GitHub-commits som faktiskt var kundarbete. Det är inte bara långsamt, det är mentalt dränerande. Ännu värre: anteckningarna du faktiskt skriver blir inkonsekventa, så fakturor ser otydliga ut (“mejl + dev”) och kunder ifrågasätter. Då lägger du ännu mer tid på att förklara arbete du redan har gjort.
Friktionen byggs på, särskilt när din vecka är full.
- Backfyllning i slutet av veckan kan sluka runt 2 timmar, och det blir sällan korrekt.
- Kalendern visar möten, men inte de viktigaste resultaten eller vad du följde upp efteråt.
- GitHub-aktivitet är ett faktiskt bevis på arbete, men att översätta commits och PR:ar till kundvänligt språk är ett slit.
- När poster inte är standardiserade blir debiteringsanteckningar röriga och rapportering blir en huvudvärk.
Lösningen: dagliga AI-tidsrapporter som skrivs in i Google Sheets
Det här flödet kör automatiskt enligt ett schema (som standard kl. 19:00) och bygger din tidsrapport åt dig utifrån jobbet du redan har gjort. Det hämtar dagens relevanta mejl från Gmail, bekräftade möten från Google Kalender och utvecklingsaktivitet från GitHub (commits samt PR:ar som öppnats/stängts). Sedan filtrerar och slår det ihop dessa källor så att du inte loggar nyhetsbrev, no-reply-brus eller irrelevant repo-aktivitet. Till sist använder det en OpenAI-chatmodell för att skriva om varje punkt till en kortfattad beskrivning (avsiktligt kort, ungefär som en tweet) och lägger till strukturerade rader i en Google Sheets-flik för aktuell månad. Om månadens flik inte finns ännu skapar den den och initierar rubriker.
Flödet startar med en daglig trigger och sätter körvärden (datum, arknamn, repo-lista). Därefter samlar det in och aggregerar data från Gmail, Kalender och GitHub till ett enhetligt “aktivitetsflöde”. Efter AI-sammanfattning delas varje sammanfattad punkt upp igen till separata poster och läggs till i Google Sheets som en tidsradsrad.
Det du får: automatisering vs. resultat
| Det här flödet automatiserar | Resultat du får |
|---|---|
|
|
Exempel: så här ser det ut
Säg att en normal dag innehåller 8 meningsfulla mejl, 3 kalendermöten och 6 GitHub-händelser (commits eller PR-uppdateringar). Manuellt innebär loggning ofta att du öppnar tre verktyg och skriver 17 anteckningar. Om du bara lägger cirka 2 minuter per post blir det ungefär 30–40 minuter per dag, och sedan mer tid för att rätta otydliga beskrivningar i efterhand. Med det här flödet låter du det köra kl. 19:00, skummar igenom de genererade raderna i Google Sheets i cirka 5 minuter och är klar. Det ger dig ungefär en halvtimme tillbaka, de flesta dagar.
Det här behöver du
- n8n-instans (testa n8n Cloud gratis)
- Alternativ för egen drift om du föredrar det (Hostinger fungerar bra)
- Google Sheets för att lagra månatliga tidsrader.
- Gmail för att fånga skickad/mottagen arbetsaktivitet.
- Google Kalender för att logga möten, varaktighet, deltagare.
- GitHub för att spåra commits och pull requests.
- OpenAI API-nyckel (hämta den i OpenAI API-dashboarden).
Kunskapsnivå: Nybörjare. Du kopplar konton, klistrar in en repo-lista och testar en dags körning.
Vill du inte sätta upp detta själv? Prata med en automationsexpert (gratis 15-minuters konsultation).
Så fungerar det
Ett dagligt schema drar igång det. Flödet körs på en Cron-trigger (inställd på kl. 19:00 som standard) och sätter sedan körvärden som “dagens datum” och arknamnet för aktuell månad.
Din dag samlas in från verktygen du redan använder. n8n hämtar dagens mejl från Gmail och dina bekräftade händelser från Google Kalender. Parallellt kontrollerar det GitHub-repon efter commits och pull request-aktivitet.
Brus filtreras bort, sedan slås allt ihop. Mejl aggregeras så att nyhetsbrev och no-reply-meddelanden inte skräpar ner loggen. GitHub-aktivitet valideras (så att du inte loggar någon annans commits), PR:ar kontrolleras för status öppnad/stängd, och alla källor kombineras till ett strukturerat aktivitetsflöde.
AI gör om råhändelser till debiteringsvänliga anteckningar. OpenAI-steget skriver om varje punkt till en kort sammanfattning (avsiktligt kort). Varje sammanfattning blir en egen rad, och sedan uppdateras Google Sheets i rätt månadsflik.
Du kan enkelt ändra schemat kl. 19:00 till en annan tid, eller utöka datakällorna bortom mejl/kalender/utvecklingsarbete. Se den fullständiga implementationsguiden nedan för anpassningsalternativ.
Steg-för-steg-guide för implementering
Steg 1: Konfigurera den schemalagda triggern
Det här arbetsflödet startar varje kväll för att sammanställa föregående dags aktivitet till en journal.
- Lägg till och öppna Scheduled 7PM Trigger.
- Ställ in schemat att köras dagligen kl. 19:00 i nodens cron-gränssnitt.
- Koppla Scheduled 7PM Trigger till Assign Runtime Values.
Steg 2: Anslut Google Workspace-källor
Samla in e-post- och kalenderdata för föregående dag som underlag till journalsammanfattningen.
- Öppna Assign Runtime Values och ställ in fälten:
- today_date till
{{ $now.format('yyyy-MM-dd') }} - github_handle till
[YOUR_ID] - repositoriesToTrack till
{{ ['[YOUR_ID]', '[YOUR_ID]'] }} - myEmail till
[YOUR_EMAIL]
- today_date till
- Öppna Fetch Today's Emails och ställ in:
- Operation till
getAll - Return All till
true - Filters → Sender till
{{ $json.myEmail }} - Filters → Received After till
{{ $now.minus(1).startOf('day').toISO() }}
- Operation till
- Inloggning krävs: Anslut era gmailOAuth2-uppgifter i Fetch Today's Emails.
- Öppna Retrieve Daily Calendar Events och ställ in:
- Operation till
getAll - Return All till
true - Options → Time Min till
{{ $today.minus(1).startOf('day').toISO() }} - Options → Time Max till
{{ $today.minus(1).endOf('day').toISO() }}
- Operation till
- Inloggning krävs: Anslut era googleCalendarOAuth2Api-uppgifter i Retrieve Daily Calendar Events.
- Bekräfta den parallella grenen: Assign Runtime Values matar ut till Fetch Today's Emails och Retrieve Daily Calendar Events parallellt (tillsammans med andra grenar).
Tips: Ersätt [YOUR_ID] och [YOUR_EMAIL] i Assign Runtime Values innan er första testkörning, annars kommer efterföljande filter att exkludera all data.
Steg 3: Konfigurera insamling av GitHub-aktivitet
Dela upp repositories, hämta commits och pull requests och filtrera sedan till enbart er aktivitet.
- I Split Repo List och Split Repo List 2 ställer ni Field To Split Out till
repositoriesToTrack. - Öppna Fetch GitHub Commits och ställ in URL till:
=https://api.github.com/repos/{{ $('Assign Runtime Values').item.json.github_handle }}/{{ $json.repositoriesToTrack }}/commits?since={{ $now.minus(1).startOf('day').toUTC().toISO() }} &until={{ $now.minus(1).endOf('day').toUTC().toISO() }} - Inloggning krävs: Anslut era githubApi-uppgifter i Fetch GitHub Commits.
- Inloggning krävs: Anslut era httpHeaderAuth-uppgifter i Fetch GitHub Commits.
- Öppna Retrieve GitHub Pulls och ställ in:
- Owner till
{{ $('Assign Runtime Values').item.json.github_handle }} - Repository till
{{ $json.repositoriesToTrack }} - Operation till
getPullRequests - Return All till
true
- Owner till
- Inloggning krävs: Anslut era githubApi-uppgifter i Retrieve GitHub Pulls.
- Bekräfta parallell logik: Retrieve GitHub Pulls matar ut till både Check PRs Created Today och Check PRs Closed Today parallellt.
- I Validate Author Commits behåller ni villkoret:
- Left Value
{{ $json.author.login }}är lika med Right Value{{ $('Assign Runtime Values').item.json.github_handle }}
- Left Value
- I Check PRs Created Today säkerställer ni:
{{ $json.created_at.toDateTime().format('yyyy-MM-dd') }}är lika med{{ $('Assign Runtime Values').item.json.today_date }}{{ $json.user.login }}är lika med{{ $('Assign Runtime Values').item.json.github_handle }}
- I Check PRs Closed Today säkerställer ni:
{{ $json.closed_at?.toDateTime().format('yyyy-MM-dd') }}finns{{ $json.closed_at?.toDateTime().format('yyyy-MM-dd') }}är lika med{{ $('Assign Runtime Values').item.json.today_date }}
⚠️ Vanlig fallgrop: Om er GitHub-handle i Assign Runtime Values inte matchar användarnamnen för commit-författare kommer Validate Author Commits att filtrera bort alla commits.
Steg 4: Aggregera och kombinera dataströmmar
Aggregera e-post, kalenderhändelser, commits och PR:ar och slå sedan ihop dem till ett enda sammanfattningsobjekt.
- I Aggregate Emails ställer ni Aggregate till
aggregateAllItemDataoch Destination Field Name tillemails. - I Aggregate Calendar ställer ni Aggregate till
aggregateAllItemDataoch Destination Field Name tillcalendarEvents. - I Aggregate Commits ställer ni Aggregate till
aggregateAllItemDataoch Destination Field Name tillcommits. - I Aggregate PRs ställer ni Aggregate till
aggregateAllItemDataoch Destination Field Name tillprs. - Öppna Combine Data Streams och ställ in Number Inputs till
4. - Bekräfta sammanslagningsflödet: Aggregate Emails, Aggregate Calendar, Aggregate Commits och Aggregate PRs matar alla in till Combine Data Streams.
- Öppna Prepare Combined Data och behåll JavaScript-transformeringen som den är för att formatera e-post, kalender och GitHub-aktivitet.
Steg 5: Sätt upp AI-skapande av journal
Generera en ren, strukturerad lista över dagens händelser med hjälp av AI-sammanfattningen.
- Öppna Create Journal Summary och säkerställ att JSON Output är satt till
true. - Verifiera att prompten innehåller referensen till JSON-payloaden:
{{ JSON.stringify($json, null, 2) }}. - Inloggning krävs: Anslut era openAiApi-uppgifter i Create Journal Summary.
- I Split AI Events ställer ni Field To Split Out till
message.content.events.
Tips: Om AI-svarets format ändras, uppdatera Split AI Events så att det matchar den exakta sökvägen i svaret (t.ex. message.content.events).
Steg 6: Konfigurera utdata till Google Sheets
Skapa ett månadsark om det saknas, lägg till rubriker och append:a dagliga poster.
- Öppna Create Sheet If Missing och ställ in:
- Operation till
create - Title till
{{ $now.format('MMMM') }}
- Operation till
- Inloggning krävs: Anslut era googleSheetsOAuth2Api-uppgifter i Create Sheet If Missing.
- I Check Sheet Creation behåller ni villkoret att
{{ $json.title }}finns. - Öppna Initialize Headers och bekräfta att den definierar tomma fält: Date, Type, Description.
- Öppna Append Header Row och ställ in Sheet Name till
{{ $('Create Sheet If Missing').item.json.title }}. - Inloggning krävs: Anslut era googleSheetsOAuth2Api-uppgifter i Append Header Row.
- Öppna Append Sheet Entry och ställ in:
- Operation till
append - Sheet Name till
{{ $now.format('MMMM') }} - Columns → Date till
{{ $now.format('yyyy-MM-dd') }} - Columns → Type till
{{ $json.type }} - Columns → Description till
{{ $json.description }}
- Operation till
- Inloggning krävs: Anslut era googleSheetsOAuth2Api-uppgifter i Append Sheet Entry.
⚠️ Vanlig fallgrop: Om arknamnet inte matchar månaden (t.ex. September) kommer Append Sheet Entry att misslyckas med att skriva rader.
Steg 7: Testa och aktivera ert arbetsflöde
Kör ett fullständigt test för att bekräfta datainsamling, skapande av AI-sammanfattning och uppdateringar i arket.
- Klicka på Execute Workflow med start från Scheduled 7PM Trigger för att simulera en körning.
- Verifiera att Combine Data Streams tar emot fyra indata och att Prepare Combined Data matar ut ett rent sammanfattningsobjekt.
- Bekräfta att Create Journal Summary returnerar en JSON-array och att Split AI Events matar ut ett item per händelse.
- Kontrollera Google Sheets för en ny månadsflik och en rad per händelse som lagts till av Append Sheet Entry.
- När ni är nöjda, slå på arbetsflödet Active för att aktivera dagliga körningar kl. 19:00.
Vanliga fallgropar
- Google-behörigheter kan vara kinkiga. Om skrivningar till Sheets eller Kalender misslyckas, kontrollera först vilket Google-konto som är kopplat i n8n-credentials och bekräfta att det har åtkomst till målarket.
- Om du använder Wait-noder eller extern rendering varierar processtiderna. Öka väntetiden om nedströms noder fallerar på tomma svar.
- Standardprompter i AI-noder är generiska. Lägg in din tonalitet tidigt, annars kommer du redigera resultat i all evighet.
Vanliga frågor
Cirka 30 minuter om dina konton redan är anslutna.
Nej. Du kopplar credentials och redigerar en repo-lista i en Set-nod.
Ja. n8n har ett gratis alternativ för egen drift och en gratis provperiod på n8n Cloud. Cloud-planer börjar på 20 USD/månad för högre volymer. Du behöver även räkna in kostnader för OpenAI API (oftast några cent per dag för korta sammanfattningar).
Två alternativ: n8n Cloud (hanterat, enklast att komma igång) eller egen drift på en VPS. För egen drift är Hostinger VPS prisvärd och hanterar n8n bra. Egen drift ger dig obegränsade körningar men kräver grundläggande serverhantering.
Ja, men du behöver ändra triggern och bredda datumintervallet. Byt det dagliga Cron-schemat till veckovis och justera sedan Gmail-/Kalender-frågorna i stegen “Hämta dagens mejl” och “Hämta dagens kalenderhändelser” så att de tar senaste 7 dagarna. Många team justerar även prompten i “Skapa journalsammanfattning” för att få ett veckostycke per kund, i stället för en rad per händelse.
Oftast beror det på en utgången Google-auktorisering eller att fel Google-konto är anslutet. Anslut Gmail på nytt i n8n-credentials och bekräfta sedan att flödet får läsa den inkorg du förväntar dig. Om det fortfarande fallerar, kontrollera Google-säkerhetsuppmaningar på kontot och se till att du inte stöter på begränsningar för brevlådeåtkomst i en låst workspace-miljö.
En typisk daglig volym (dussintals mejl/händelser/commits) fungerar fint även på en liten n8n-installation. I n8n Cloud handlar din gräns mest om månadsvisa körningar, inte om det här flödets komplexitet. Vid egen drift beror det på din server, men de flesta små team kör detta dagligen utan att behöva tänka på skalning.
Ofta, ja. Det här flödet tjänar på grenlogik (olika hantering för mejl, kalenderhändelser, commits, PR:ar), aggregering och ett tydligt “slå ihop och sammanfatta”-upplägg, vilket kan bli krångligt eller dyrt i enklare verktyg. n8n ger dig också alternativet för egen drift, vilket spelar roll om du vill ha förutsägbara kostnader när volymen växer. Zapier eller Make kan fortfarande vara bra om du bara vill ha “kalenderhändelse → arkrad” utan AI och utan GitHub. Om du är osäker, prata med en automationsexpert och beskriv din debiteringsprocess; rätt verktyg beror på den.
När detta väl kör blir din tidsrapport inte längre en veckovis gissningslek, utan en daglig biprodukt av arbetet. Sätt upp det en gång och fakturera med trygghet.
Kontakta oss
Hör av dig, så diskuterar vi hur just din verksamhet kan dra nytta av alla fantastiska möjligheter som AI skapar.