Att jaga rätt på ”vilken fil som blev bearbetad” är en riktig tidstjuv. Du laddar upp en PDF, någon uppdaterar den, OCR:en körs (kanske), och plötsligt gräver du i mappar, Slack-trådar och halvt färdiga kalkylark.
Det är här Drive OCR logging ger effekt. Marketing ops-team märker det när kreativa briefar och leverantörsdokument staplas på hög, och byråägare stöter på det när kunder fortsätter att ”bara byta ut filen”. Till och med en småföretagsadministratör hamnar i samma arbete: bekräfta, kopiera, byta namn, logga, notifiera.
Det här flödet bevakar en Google Drive-mapp, kör OCR via Mistral Document, sparar korrekt formaterade utdata tillbaka till Drive och loggar varje steg i Google Sheets (med Slack-notiser). Du ser vad det automatiserar, vilka resultat du kan förvänta dig och vad du behöver för att köra det stabilt.
Så fungerar den här automationen
Hela n8n-flödet, från trigger till slutligt resultat:
n8n Workflow Template: Google Drive till Google Sheets, OCR loggas strukturerat
flowchart LR
subgraph sg0["New Drive File Watch Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "New Drive File Watch", pos: "b", h: 48 }
n1@{ icon: "mdi:play-circle", form: "rounded", label: "Updated Drive File Watch", pos: "b", h: 48 }
n2@{ icon: "mdi:swap-vertical", form: "rounded", label: "Iterate Batches", pos: "b", h: 48 }
n3@{ icon: "mdi:swap-vertical", form: "rounded", label: "Map File Identifiers", pos: "b", h: 48 }
n4@{ icon: "mdi:swap-vertical", form: "rounded", label: "Workflow Settings", pos: "b", h: 48 }
n5@{ icon: "mdi:cog", form: "rounded", label: "Generate Output Folder", pos: "b", h: 48 }
n6@{ icon: "mdi:database", form: "rounded", label: "Initialize Sheet Row", pos: "b", h: 48 }
n7@{ icon: "mdi:cog", form: "rounded", label: "Duplicate Source File", pos: "b", h: 48 }
n8@{ icon: "mdi:database", form: "rounded", label: "Log Source File", pos: "b", h: 48 }
n9@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Route by Mime Type", pos: "b", h: 48 }
n10@{ icon: "mdi:swap-vertical", form: "rounded", label: "Select Document URL", pos: "b", h: 48 }
n11@{ icon: "mdi:swap-vertical", form: "rounded", label: "Select Image URL", pos: "b", h: 48 }
n12@{ icon: "mdi:database", form: "rounded", label: "Record Unsupported Type", pos: "b", h: 48 }
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/slack.svg' width='40' height='40' /></div><br/>Notify Error in Slack"]
n14@{ icon: "mdi:swap-vertical", form: "rounded", label: "Apply Document URL", pos: "b", h: 48 }
n15@{ icon: "mdi:cog", form: "rounded", label: "Fetch Drive File", pos: "b", h: 48 }
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/httprequest.dark.svg' width='40' height='40' /></div><br/>Run OCR Request"]
n17@{ icon: "mdi:cog", form: "rounded", label: "Save OCR JSON", pos: "b", h: 48 }
n18@{ icon: "mdi:database", form: "rounded", label: "Log JSON Link", pos: "b", h: 48 }
n19@{ icon: "mdi:swap-vertical", form: "rounded", label: "Split Document Pages", pos: "b", h: 48 }
n20@{ icon: "mdi:cog", form: "rounded", label: "Write Page Markdown", pos: "b", h: 48 }
n21@{ icon: "mdi:cog", form: "rounded", label: "Aggregate Markdown", 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/code.svg' width='40' height='40' /></div><br/>Assemble Markdown Text"]
n23@{ icon: "mdi:cog", form: "rounded", label: "Write Full Markdown", pos: "b", h: 48 }
n24@{ icon: "mdi:database", form: "rounded", label: "Log Markdown Link", pos: "b", h: 48 }
n25@{ icon: "mdi:swap-vertical", form: "rounded", label: "Separate Image Items", pos: "b", h: 48 }
n26@{ icon: "mdi:swap-vertical", form: "rounded", label: "Strip Image Base64", pos: "b", h: 48 }
n27@{ icon: "mdi:cog", form: "rounded", label: "Binary File Converter", pos: "b", h: 48 }
n28@{ icon: "mdi:cog", form: "rounded", label: "Store Image to Drive", pos: "b", h: 48 }
n29["<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/>Combine Streams"]
n30["<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 Results Gate"]
n31@{ icon: "mdi:database", form: "rounded", label: "Finalize Sheet Row", pos: "b", h: 48 }
n32["<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/slack.svg' width='40' height='40' /></div><br/>Notify Success in Slack"]
n29 --> n30
n30 --> n31
n14 --> n15
n21 --> n22
n7 --> n8
n28 --> n29
n3 --> n4
n19 --> n25
n19 --> n20
n19 --> n21
n0 --> n2
n1 --> n2
n16 --> n17
n16 --> n19
n23 --> n24
n25 --> n26
n5 --> n6
n15 --> n16
n11 --> n14
n27 --> n28
n2 --> n3
n10 --> n14
n20 --> n29
n17 --> n18
n22 --> n23
n13 --> n2
n12 --> n13
n24 --> n29
n26 --> n27
n31 --> n32
n6 --> n7
n32 --> n2
n18 --> n30
n4 --> n5
n9 --> n10
n9 --> n11
n9 --> n12
n8 --> n9
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 n0,n1 trigger
class n9 decision
class n6,n8,n12,n18,n24,n31 database
class n16 api
class n22 code
classDef customIcon fill:none,stroke:none
class n13,n16,n22,n29,n30,n32 customIcon
Problemet: OCR-arbete blir snabbt omöjligt att spåra
OCR låter enkelt tills du gör det i verkligheten. Filer kommer som PDF:er, skanningar, skärmdumpar, DOCX-exporter och ”final_v7_REALfinal.pdf”. Någon uppdaterar källfilen efter att du redan har behandlat den. En annan vill ha den extraherade texten, men inte den stökiga versionen. Samtidigt behöver du fortfarande ett spårbart underlag: vad som har bearbetats, var utdata finns och om det lyckades. Utan ett konsekvent flöde slutar det med att du kör OCR igen, missar uppdateringar och svarar på samma statusfrågor hela veckan.
Ingen av de här sakerna är problemet i sig. Tillsammans är de det.
- Manuell OCR blir en återkommande rutin med ”ladda ner, kör, ladda upp igen, byt namn, dela” som slukar cirka 1–2 timmar en stressig dag.
- När en fil uppdateras i Drive är det lätt att behandla fel version och skicka föråldrad text till teamet.
- Resultat sprids över mappar, vilket gör att du inte snabbt kan svara på ”var är JSON/Markdown för det här dokumentet?”
- Det finns ingen felfri loggbok, så uppföljningar blir till Slack-arkeologi och gissningar i kalkylark.
Lösningen: Drive → OCR → organiserade utdata + logg i Sheets
Det här n8n-flödet gör din Google Drive-mapp till en kontrollerad OCR-intagspipeline. När en fil skapas eller uppdateras plockar den upp den automatiskt, skapar en unikt namngiven målmapp och kopierar källfilen så att du har en stabil ögonblicksbild av indata. Därefter skickar den filen till Mistral Document för OCR och parsing, som returnerar strukturerat innehåll (plus separat hantering för bilder som inte kan OCR:as felfritt). Till sist sparar flödet allt tillbaka till Google Drive som återanvändbara artefakter (rå JSON, Markdown per sida, en sammanslagen Markdown-fil och extraherade bilder) och loggar länkar till dessa utdata i Google Sheets. Om det fungerar får teamet en lyckad-notis i Slack. Om något misslyckas eller filtypen inte stöds får du i stället ett felmeddelande.
Flödet startar med två Drive-bevakare (nya filer och uppdaterade filer). Därifrån routar det efter MIME-typ, hämtar filen, kör OCR-anropet via HTTP och skriver organiserade utdata till en målmapp. Google Sheets fungerar som din loggbok, och Slack stänger loopen så att du slipper sitta och passa körningar.
Det du får: automation vs. resultat
| Vad det här flödet automatiserar | Resultaten du får |
|---|---|
|
|
Exempel: så här ser det ut i praktiken
Säg att teamet hanterar 15 inkommande dokument per vecka (leverantörs-PDF:er, signerade formulär, skannade kvitton). Manuellt tar även en ”snabb” cykel med nedladdning, OCR, uppladdning, organisering och loggning kanske 15 minuter per fil, så du lägger cirka 4 timmar i veckan. Med det här flödet lägger du filer i en Drive-mapp och väntar på Slack: cirka 2 minuter mänsklig tid per fil för att bekräfta utdata och gå vidare. Det är ungefär 3 timmar tillbaka de flesta veckor, och loggen i Sheets betyder färre ”kan du skicka OCR:en igen?”-meddelanden.
Det här behöver du
- n8n-instans (prova n8n Cloud gratis)
- Självhostat alternativ om du föredrar det (Hostinger fungerar bra)
- Google Drive för filintag och lagring av utdata
- Google Sheets för att hålla bearbetningsloggen
- Mistral Cloud API-nyckel (hämta den i din Mistral Cloud-dashboard)
- Slack för att skicka lyckade- och felnotiser
Kunskapsnivå: Medel. Du kopplar upp inloggningar, uppdaterar node-inställningar och förstår grundläggande n8n-uttryck och behörigheter.
Vill du inte sätta upp det här själv? Prata med en automationsexpert (gratis 15-minuters konsultation).
Så fungerar det
En ny eller uppdaterad fil dyker upp i Google Drive. Flödet använder två Drive-triggers så att det reagerar både på helt nya uppladdningar och uppdateringar av typen ”samma fil, nyare version”.
Identifierare och målmappen förbereds. n8n mappar fildetaljer, tillämpar dina flödesinställningar, genererar sedan en unikt namngiven utdatamapp och initierar en rad i Google Sheets så att spårning startar direkt.
Filen hämtas och skickas för OCR. Baserat på routing via MIME-typ väljer flödet rätt dokument-URL, laddar ner Drive-filen och kör OCR-anropet till Mistral Document. Om filtypen inte stöds registrerar det detta i arket och larmar dig i Slack.
Utdata sparas och loggas. Rå OCR-JSON lagras i Drive och länkas i Google Sheets, Markdown per sida skrivs och aggregeras sedan till en komplett Markdown-fil. Extraherade bilder konverteras till binärdata och sparas också, och den sista raden i arket uppdateras innan lyckad-notisen skickas i Slack.
Du kan enkelt ändra utdatastukturen så att den passar din fortsatta pipeline (till exempel annan mappnamngivning eller extra metadatakolumner i Sheets) utifrån dina behov. Se hela implementationsguiden nedan för anpassningsalternativ.
Steg-för-steg-guide för implementering
Steg 1: Konfigurera Google Drive-triggers
Ställ in arbetsflödet så att det bevakar en specifik Google Drive-mapp efter nya och uppdaterade filer.
- Öppna New Drive File Watch och ställ in Event till
fileCreatedoch Trigger On tillspecificFolder. - I New Drive File Watch ställer ni in Folder To Watch till målmappens ID.
- Öppna Updated Drive File Watch och ställ in Event till
fileUpdatedoch Trigger On tillspecificFolder. - I Updated Drive File Watch ställer ni in Folder To Watch till samma eller ett annat mapp-ID beroende på ert användningsfall.
- Credentials krävs: Anslut era googleDriveOAuth2Api-credentials i både New Drive File Watch och Updated Drive File Watch.
Steg 2: Anslut konfigurationsnoder för Google Drive och Google Sheets
Konfigurera metadata-mappning, skapande av destinationsmapp och initial loggning för varje fil.
- I Map File Identifiers behåller ni tilldelningsuttrycken för nyckelfält som file_id =
{{$json.id}}, file_name ={{$json.name}}och mime_type ={{$json.mimeType}}. - I Workflow Settings ställer ni in google_sheet_id och dest_folder_id till ert Google Sheet-ID och ID:t för den överordnade destinationsmappen.
- I Generate Output Folder bekräftar ni att Name är
{{ $('Map File Identifiers').item.json.dest_folder }}_{{ $now.format('yyyyMMdd-hhmmss') }}och att Folder ID är{{ $('Workflow Settings').item.json.dest_folder_id }}. - I Initialize Sheet Row verifierar ni att Operation är
appendOrUpdateoch att Document ID är{{ $('Workflow Settings').item.json.google_sheet_id }}. - I Duplicate Source File behåller ni Operation som
copyoch Name som{{ $('Map File Identifiers').item.json.file_name }}, och lagrar i utdatamappen{{ $('Generate Output Folder').item.json.id }}. - I Log Source File säkerställer ni att Document ID använder
{{ $('Workflow Settings').item.json.google_sheet_id }}så att länken till källfilen loggas. - Credentials krävs: Anslut era googleDriveOAuth2Api-credentials i Generate Output Folder och Duplicate Source File.
- Credentials krävs: Anslut era googleSheetsOAuth2Api-credentials i Initialize Sheet Row och Log Source File.
Steg 3: Ställ in routning för MIME-typ och hantering av filer som inte stöds
Routa dokument och bilder till OCR-bearbetning, och hantera filtyper som inte stöds med en loggpost och en Slack-notis.
- I Route by Mime Type behåller ni de två regex-reglerna: dokument
^(application\/pdf|application\/vnd\.openxmlformats\-officedocument\.wordprocessingml\.document)$och bilder^image\/(png|jpeg|jpg)$. - I Select Document URL ställer ni in document_type till
document_urlmed Include Other Fields aktiverat. - I Select Image URL ställer ni in document_type till
image_urlmed Include Other Fields aktiverat. - I Record Unsupported Type verifierar ni att Status är
Unsupported Typeoch att Completed är{{ $now.format('yyyy-MM-dd hh:mm:ss') }}. - I Notify Error in Slack bekräftar ni att meddelandet använder fil- och mapplänkarna:
https://drive.google.com/file/d/{{ $('Duplicate Source File').item.json.id }}ochhttps://drive.google.com/drive/folders/{{ $('Generate Output Folder').item.json.id }}. - Credentials krävs: Anslut era googleSheetsOAuth2Api-credentials i Record Unsupported Type.
- Credentials krävs: Anslut era slackOAuth2Api-credentials i Notify Error in Slack.
Steg 4: Ställ in OCR-bearbetning med Mistral
Hämta filen från Drive och skicka den till Mistral OCR med rätt dokumenttyp.
- I Apply Document URL behåller ni document_type satt till
{{ $json.document_type }}för att skicka igenom den valda typen. - I Fetch Drive File ställer ni in Operation till
downloadoch behåller File ID som{{ $('Duplicate Source File').item.json.id }}. - I Run OCR Request ställer ni in URL till
https://api.mistral.ai/v1/ocroch Method tillPOST. - I Run OCR Request ställer ni in JSON Body till hela uttrycket:
{ "model": "mistral-ocr-latest", "document": { "type": "{{ $('Apply Document URL').item.json.document_type }}", "{{ $('Apply Document URL').item.json.document_type }}": "data:{{ $('Map File Identifiers').item.json.mime_type }};base64,{{ $('Fetch Drive File').item.binary.binary_file_data.data }}" }, "include_image_base64": true }. - Credentials krävs: Anslut era googleDriveOAuth2Api-credentials i Fetch Drive File.
- Credentials krävs: Anslut era mistralCloudApi-credentials i Run OCR Request.
Steg 5: Konfigurera parallella utdata, sammanställning av Markdown och lagring av bilder
Dela upp sidor, spara JSON- och Markdown-utdata och lagra extraherade bilder i Drive.
- Run OCR Request skickar utdata parallellt till både Save OCR JSON och Split Document Pages, så säkerställ att båda grenarna är anslutna.
- I Save OCR JSON behåller ni Name som
{{ $('Map File Identifiers').item.json.file_name_no_ext }}.jsonoch Content som{{ JSON.stringify($json.body, null, 2) }}. - I Log JSON Link behåller ni JSON file satt till
https://drive.google.com/file/d/{{ $json.id }}och Document ID till{{ $('Workflow Settings').item.json.google_sheet_id }}. - Split Document Pages skickar utdata parallellt till Separate Image Items, Write Page Markdown och Aggregate Markdown; behåll alla tre anslutningarna.
- I Write Page Markdown behåller ni Name som
{{ $('Map File Identifiers').item.json.file_name_no_ext }}_page_{{ String($json.index + 1).padStart($('Run OCR Request').item.json.body.pages.length.toString().length, '0') }}.mdoch Content som{{ $json.markdown }}. - I Aggregate Markdown säkerställer ni att Output Field Name är
full_markdownoch att Field to Aggregate ärmarkdown. - I Assemble Markdown Text behåller ni JS Code som
return { markdown: $json.full_markdown.join('\n\n') };. - I Write Full Markdown ställer ni in Name till
{{ $('Map File Identifiers').item.json.file_name_no_ext }}.mdoch Content till{{ $json.markdown }}. - I Log Markdown Link behåller ni MD File som
https://drive.google.com/file/d/{{ $json.id }}. - För bildextrahering behåller ni Separate Image Items som delar upp Field To Split Out som
images, och i Strip Image Base64 ställer ni in stripped_image_base64 till{{ $json.image_base64.split(',').pop() }}. - I Binary File Converter ställer ni in Operation till
toBinary, Source Property tillstripped_image_base64och Binary Property Name tillimage. - I Store Image to Drive behåller ni Name som
{{ $binary.data.fileName }}och Input Data Field Name somimage. - Credentials krävs: Anslut era googleDriveOAuth2Api-credentials i Save OCR JSON, Write Page Markdown, Write Full Markdown och Store Image to Drive.
- Credentials krävs: Anslut era googleSheetsOAuth2Api-credentials i Log JSON Link och Log Markdown Link.
image.Steg 6: Slå ihop resultat och skicka framgångsnotifieringar
Konsolidera utdata, uppdatera spårningsarket och notifiera Slack vid lyckat resultat.
- Säkerställ att Combine Streams tar emot indata från Log Markdown Link, Write Page Markdown och Store Image to Drive.
- Bekräfta att Combine Streams skickar vidare till Merge Results Gate och därefter till Finalize Sheet Row.
- I Finalize Sheet Row ställer ni in Status till
Doneoch Completed till{{ $now.format('yyyy-MM-dd hh:mm:ss') }}. - I Notify Success in Slack verifierar ni att meddelandet använder fillänken
https://drive.google.com/file/d/{{ $('Duplicate Source File').item.json.id }}och länken till utdatamappenhttps://drive.google.com/drive/folders/{{ $('Generate Output Folder').item.json.id }}. - Credentials krävs: Anslut era googleSheetsOAuth2Api-credentials i Finalize Sheet Row.
- Credentials krävs: Anslut era slackOAuth2Api-credentials i Notify Success in Slack.
Steg 7: Testa och aktivera ert arbetsflöde
Validera hela processen från start till mål och aktivera arbetsflödet för produktionsdrift.
- Klicka på Execute Workflow och ladda upp en test-PDF eller testbild till den bevakade mappen.
- Bekräfta att Initialize Sheet Row, Log JSON Link och Log Markdown Link uppdaterar Google Sheet med länkar.
- Verifiera att utdatamappen innehåller den duplicerade källfilen, JSON, Markdown-filer per sida och den fullständiga Markdown-filen.
- Kontrollera Slack efter ett lyckat meddelande från Notify Success in Slack eller en notis om ej stödd typ från Notify Error in Slack.
- När allt är validerat växlar ni arbetsflödet till Active så att det körs automatiskt var 5:e minut.
Vanliga fallgropar
- Inloggningar för Google Drive och Google Sheets kan löpa ut eller sakna ”Editor”-åtkomst. Om det slutar fungera, kontrollera credential-kopplingen i n8n och bekräfta först att Drive-mappen och arket är delade med samma Google-konto.
- Om du använder Wait-noder eller extern rendering varierar processtiderna. Öka väntetiden om noder längre fram fallerar på tomma svar.
- Standardprompter i AI-noder är generiska. Lägg in er tonalitet tidigt, annars kommer du redigera utdata i all evighet.
Vanliga frågor
Räkna med cirka en timme om dina Google-, Slack- och Mistral-konton är redo.
Nej. Du kopplar främst inloggningar och klistrar in några ID:n (Drive-mapp-ID, Sheet-ID).
Ja. n8n har ett gratis självhostat alternativ och en gratis provperiod på n8n Cloud. Cloud-planer startar på 20 USD/månad för högre volymer. Du behöver också räkna in kostnader för Mistral API-användning, som beror på hur många sidor du bearbetar.
Två alternativ: n8n Cloud (hanterat, enklast att sätta upp) eller självhostning på en VPS. För självhostning är Hostinger VPS prisvärt och hanterar n8n bra. Självhostning ger dig obegränsade körningar men kräver grundläggande serveradministration.
Ja, och det är en av de bästa anledningarna att använda n8n. Du kan behålla samma triggers och OCR-anrop och sedan byta ut delarna ”Write Page Markdown” och ”Write Full Markdown” för att skapa Google Docs, ren text eller till och med skicka innehåll till en kunskapsbas. Vanliga justeringar är att ändra namngivningen av målmappen i noden ”Generate Output Folder”, lägga till extra kolumner i Google Sheets i ”Initialize Sheet Row” och logga fler länkar i ”Finalize Sheet Row”. Om du vill routa vissa dokument till olika mappar justerar du MIME-typ-routingen och lägger till enkla villkor.
Oftast handlar det om behörigheter. Bekräfta att Google-credential i n8n har åtkomst till den bevakade mappen och att platsen för utdatamappen är korrekt delad, och kontrollera sedan mapp-ID:n igen i Set-/Configuration-noderna. Om det fortfarande misslyckas, autentisera Google-credential på nytt och säkerställ att Drive API-åtkomst är aktiverad för det Google-projektet/kontot.
Många, så länge dina Mistral-användningsgränser och n8n:s körkapacitet hänger med.
För OCR-pipelines är n8n oftast det mer praktiska valet eftersom du kan förgrena på filtyp, skriva flera utdata (JSON + Markdown per sida + bilder) och slå ihop resultat utan att betala extra för varje liten del. Självhostning är också en stor fördel om du bearbetar många dokument. Zapier och Make kan fungera, men dokumenthantering i flera steg blir snabbt klumpig, ärligt talat, och kostnaderna drar iväg när du triggar på uppdateringar och loggar många artefakter. Om du bara behöver ”ny fil → skicka Slack-meddelande”, håll det enkelt och använd det du redan gillar. Om du är osäker, prata med en automationsexpert så tar vi fram den billigaste vägen.
När det här väl rullar blir varje inkommande fil behandlad, lagrad och loggad på samma sätt. Mindre jagande. Mer leverans.
Kontakta oss
Hör av dig, så diskuterar vi hur just din verksamhet kan dra nytta av alla fantastiska möjligheter som AI skapar.