Du mergar en PR, allt ser bra ut, och sedan fallerar bygget för att en enda iOS-nyckel i .strings saknas i en locale. Nu letar du i filer för att lista ut vilken vy som introducerade den, och någon pingar dig och frågar: ”Kan översättarna få en lista?”
Den här typen av röra drabbar iOS-utvecklare först, men lokaliseringsansvariga känner av det lika mycket, och byråteam som levererar white-label-appar stöter på det hela tiden. Med den här GitHub Sheets-automationen får du en löpande rapport över ”saknade nycklar” plus en valfri PR som lägger in platshållare så att appen fortfarande kan kompilera.
Nedan ser du vad arbetsflödet gör, vad det sparar dig, och hur du kan anpassa det för flera språk eller striktare regler.
Så fungerar den här automationen
Hela n8n-arbetsflödet, från trigger till slutresultat:
n8n Workflow Template: GitHub + Google Sheets: hitta saknade iOS-strängar
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/>Webhook"]
n1@{ icon: "mdi:swap-vertical", form: "rounded", label: "Config", 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/code.svg' width='40' height='40' /></div><br/>Process File Tree"]
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/httprequest.dark.svg' width='40' height='40' /></div><br/>Get Source File"]
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/code.svg' width='40' height='40' /></div><br/>Find Missing Keys"]
n5@{ icon: "mdi:database", form: "rounded", label: "Google Sheets", 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/httprequest.dark.svg' width='40' height='40' /></div><br/>Get GitHub Tree"]
n7["<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"]
n8@{ icon: "mdi:swap-vertical", form: "rounded", label: "Edit Fields", pos: "b", h: 48 }
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/>HTTP Request"]
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/code.svg' width='40' height='40' /></div><br/>Code"]
n10 --> n9
n7 --> n4
n1 --> n6
n0 --> n1
n8 --> n10
n9 --> n7
n6 --> n2
n3 --> n8
n4 --> n5
n2 --> n3
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 n5 database
class n0,n3,n6,n9 api
class n2,n4,n10 code
classDef customIcon fill:none,stroke:none
class n0,n2,n3,n4,n6,n7,n9,n10 customIcon
Problemet: saknade .strings-nycklar upptäcks för sent
Lokaliseringsglapp misslyckas sällan tydligt vid rätt tidpunkt. En utvecklare lägger till en ny knapptext i Base.lproj (eller en.lproj), PR:en mergas, och först senare upptäcker någon att fr.lproj (eller någon annan locale) saknar nyckeln. Då får du den sämsta kombon: kontextbyten plus gissningar. Du jämför filer för hand, försöker att inte missa en duplicerad nyckel eller något märkligt formateringsfall, och översättarna har fortfarande ingen gemensam källa som är uppdaterad. Samtidigt pausar inte release-pressen.
Friktionen växer snabbt.
- Saknade nycklar upptäcks under QA eller precis före ett bygge, när det är som mest störande att åtgärda.
- Manuell diffning mellan
Base.lproj,en.lprojoch varje locale-fil går långsamt, och det är lätt att missa en nyckel. - Översättare jobbar till slut från skärmdumpar, Slack-meddelanden eller inaktuella kalkylblad i stället för en aktuell lista.
- Byggen kan fallera (eller så skeppas tomma strängar), vilket gör att releaser halkar efter för ett problem som borde vara rutin.
Lösningen: GitHub-skanning + ett live Google Sheet (plus valfri PR)
Det här arbetsflödet lyssnar på GitHub-aktivitet (pushar eller pull requests) och kontrollerar automatiskt dina iOS-lokaliseringsfiler efter saknade .strings-nycklar. Det skannar ditt repo efter källfiler i Base.lproj eller en.lproj, och hittar sedan matchande målspråksfiler under *.lproj. Därefter jämför det nycklar och bygger en strukturerad lista över ”vad som saknas” per locale. De saknade posterna läggs till i en Google Sheet-flik (till exempel en fr-flik), som blir en delad kö för översättningsarbete. Om du vill kan det också öppna en GitHub-PR som lägger in platshållarvärden som __TODO_TRANSLATE__, så att projektet fortsätter vara byggbart medan översättningarna kommer ikapp.
Arbetsflödet startar med en GitHub-webhook och hämtar repo-trädet via HTTP-anrop. Det hämtar relevanta .strings-filer, identifierar saknade nycklar och skriver en enkel rapport i Google Sheets. Om ENABLE_PR är aktiverat (och du inte kör DRY_RUN) förbereder det också ändringarna som krävs för en PR med platshållare.
Vad du får: automation vs. resultat
| Vad det här arbetsflödet automatiserar | Resultat du får |
|---|---|
|
|
Exempel: så här ser det ut
Säg att din app stöder 6 locales och att du lägger till 12 nya strängar för en ny vy. Manuellt innebär en snabb ”missade vi något?”-koll oftast att du öppnar minst 6 filer, söker efter de nya nycklarna och dubbelkollar formatering, vilket lätt blir 10 minuter per locale (ungefär en timme), plus det oundvikliga uppföljningsmeddelandet till översättarna. Med det här arbetsflödet mergar du som vanligt och webhooken drar igång; den skannar, loggar saknade nycklar till Sheets och (om aktiverat) förbereder en PR med platshållare. Din ”nedlagda tid” blir ett par minuter för att kika på arket, inte en timme av diffning.
Det här behöver du
- n8n-instans (testa n8n Cloud gratis)
- Self-hosting-alternativ om du föredrar det (Hostinger fungerar bra)
- GitHub för att trigga körningar och öppna PR:er.
- Google Sheets för att lagra rapporten över saknade nycklar.
- GitHub-token (skapa den i GitHubs utvecklarinställningar).
Kompetensnivå: Medel. Du kopierar konfigvärden, kopplar in credentials och justerar fil-globs så att de matchar ditt repo.
Vill du inte sätta upp det här själv? Prata med en automationsexpert (gratis 15-minuters konsultation).
Så fungerar det
En GitHub-webhook triggar vid push eller pull request. Du pekar GitHub till din n8n-webhook-URL och väljer de händelser du bryr dig om, så att skanningen sker automatiskt när kod ändras.
Arbetsflödet mappar ditt repo och hittar lokaliseringsfiler. Med dina konfigurerade globmönster (som **/Base.lproj/*.strings och **/*.lproj/*.strings) hämtar det repo-trädet och bygger en lista med kandidatfiler att jämföra.
Nycklar jämförs och saknade poster extraheras. Det hämtar källinnehållet i .strings, läser nycklar och upptäcker sedan vad som saknas i varje mållocale. Om du har konfigurerat ignore-prefix hoppas de över så att interna/debug-strängar inte skräpar ner rapporten.
Resultatet går till Google Sheets (och valfritt tillbaka till GitHub). Saknade nycklar läggs till i en locale-specifik flik i Sheets, som blir översättarnas arbetslista. Om PR-skapande är aktiverat förbereder arbetsflödet också platshållarvärden och öppnar en GitHub-PR på en branch som chore/l10n-gap-YYYYMMDD.
Du kan enkelt ändra locale-listan och globmönstren för att skanna bara vissa moduler, eller för att loopa igenom 5+ språk i en körning. Se hela implementationsguiden nedan för anpassningsalternativ.
Steg-för-steg-guide för implementering
Steg 1: konfigurera webhook-triggern
Sätt upp den inkommande endpointen som startar arbetsflödet när ert system skickar en request.
- Lägg till och öppna Inbound Webhook Trigger.
- Ställ in HTTP Method på
POST. - Ställ in Path på
new-pathss. - Kopiera produktions-URL:en från noden efter att ni har sparat, och använd den i er webhook-avsändare.
Steg 2: anslut GitHub och definiera repository-parametrar
Konfigurera repo-parametrar och anslut GitHub för att hämta filträdet och källfilerna.
- Öppna Parameter Setup och ange värden: GITHUB_OWNER till
github_user_name, GITHUB_REPO tilln8n-iOS-Github-repo, BASE_BRANCH tillmain, SOURCE_LANG tillen, TARGET_LANG tillfroch PLACEHOLDER_VALUE till__TODO_TRANSLATE__. - Öppna Retrieve Repo Tree och bekräfta att uttrycket för URL är satt till
={{"https://api.github.com/repos/" + $json.GITHUB_OWNER + "/" + $json.GITHUB_REPO + "/git/trees/" + $json.BASE_BRANCH + "?recursive=1"}}. - Credential Required: Anslut era githubApi-credentials i Retrieve Repo Tree.
- Öppna Fetch Source File och verifiera att URL är
{{"https://api.github.com/repos/github-user-name/n8n-iOS-Github-repo/contents/" + $json.source.path + "?ref=main"}}. - Credential Required: Anslut era githubApi-credentials i Fetch Source File.
Steg 3: sätt upp filidentifiering och URL-konstruktion
Tolka repo-trädet, välj lokaliseringsfilerna och bygg URL:er för hämtning.
- Öppna Analyze File Tree och låt den befintliga JavaScript Code vara oförändrad för att extrahera
.strings-filer och mappa käll-/målpar medTARGET_LANGfrån Parameter Setup. - Öppna Adjust Fields och bekräfta att tilldelningarna inkluderar en.lproj satt till
https://api.github.com/repos/github-user-name/n8n-iOS-Github-repo/contents/en.lproj/Localizable.stringsoch fr.lproj satt tillhttps://api.github.com/repos/github-user-name/n8n-iOS-Github-repo/contents/fr.lproj/Localizable.strings. - Öppna Build URL List och verifiera att koden returnerar de två URL:erna med värden för
langochurl. - Öppna Remote API Call och sätt URL till
={{ $json["url"] }}så att varje genererad URL hämtas.
Remote API Call skickar utdata parallellt till både Combine Streams och Combine Streams, och därefter går den sammanslagna utdata vidare till Identify Missing Keys.
Steg 4: identifiera saknade nycklar och lägg till i Google Sheets
Slå ihop käll- och mållokaliseringsinnehåll och skriv sedan saknade nycklar till ett Google Sheet för spårning av översättningar.
- Öppna Combine Streams och säkerställ att Mode är
combinemed Combine By satt tillcombineByPosition. - Öppna Identify Missing Keys och låt JavaScript Code vara oförändrad för att jämföra käll-/målnycklar och mata ut saknade poster med
__TODO_TRANSLATE__. - Öppna Append to Sheet och sätt Operation till
append. - Sätt Document till Google Sheet-ID:t
[YOUR_ID]och Sheet Name tilllocalize. - Bekräfta att kolumnmappningarna använder uttryck som
={{ $json["Key"] }},={{ $json["File"] }},={{ $json["Source Path"] }},={{ $json["Target Path"] }},={{ $json["Source Value"] }}och={{ $json["Placeholder"] }}. - Credential Required: Anslut era googleSheetsOAuth2Api-credentials i Append to Sheet.
⚠️ Vanlig fallgrop: Om Google Sheet saknar matchande kolumnrubriker kommer append att misslyckas eller skriva tomma värden. Säkerställ att rubrikerna exakt matchar fältnamnen som används i Append to Sheet.
Steg 5: testa och aktivera ert arbetsflöde
Validera körningen från start till mål och aktivera arbetsflödet för produktion.
- Klicka på Execute Workflow och skicka en test-POST-request till Inbound Webhook Trigger-URL:en.
- Bekräfta att Retrieve Repo Tree och Fetch Source File returnerar GitHub-data och att Identify Missing Keys matar ut saknade nycklar.
- Kontrollera ert Google Sheet för att verifiera nya rader som lagts till av Append to Sheet.
- Slå på arbetsflödets Active för att möjliggöra kontinuerlig webhook-hantering.
Vanliga fallgropar
- GitHub-credentials kan gå ut eller kräva specifika behörigheter. Om något slutar fungera: kontrollera först token-scopes (repo-åtkomst) och n8n:s test av credential-anslutningen.
- Om du använder Wait-noder eller extern rendering varierar processtiderna. Öka väntetiden om efterföljande noder fallerar på tomma svar.
- Uppdateringar i Google Sheets kan misslyckas utan tydlig felbild när
SHEET_IDär fel eller arket inte är delat med det anslutna Google-kontot. Kontrollera delningsinställningarna och bekräfta att fliknamnen matchar dina locale-koder.
Vanliga frågor
Cirka 30 minuter när din GitHub-token och Google-åtkomst är på plats.
Nej. Du klistrar mest in konfigurationsvärden och kopplar konton i n8n.
Ja. n8n har ett gratis self-hosted-alternativ och en gratis provperiod på n8n Cloud. Cloud-planer börjar på $20/månad för högre volymer. Du behöver också räkna in Google Sheets-användning (oftast gratis) och de hostingkostnader du väljer om du self-hostar.
Två alternativ: n8n Cloud (hanterat, enklast att komma igång) eller self-hosting på en VPS. För self-hosting är Hostinger VPS prisvärt och kör n8n bra. Self-hosting ger dig obegränsat antal körningar men kräver grundläggande serveradministration.
Ja. Du kan utöka din locale-lista (till exempel via ett TARGET_LANGS_CSV-värde som fr,de,es) och loopa åtgärden ”lägg till i sheet” så att varje språk får en egen flik. Många team justerar också IOS_SOURCE_GLOB och IOS_TARGET_GLOB för att skanna bara specifika moduler, och lägger till IGNORE_KEY_PREFIXES_CSV så att debug-strängar inte fyller rapporten.
Oftast är det en utgången token eller att token saknar repo-scope. Generera om GitHub-token (eller uppdatera behörigheterna för din GitHub App) och välj om credential i n8n så att HTTP-anropen kan läsa repo-trädet och skapa PR:er. Om fel bara händer på intensiva dagar kan rate limiting vara orsaken; att sprida ut anrop och minska glob-scope hjälper. Kontrollera också att webhook-händelsen du valde (push vs pull request) matchar det du testar.
Ett typiskt iOS-repo med några tusen nycklar är inga problem, och den verkliga begränsningen är hur många webhook-händelser du kör per månad (i Cloud) eller hur mycket CPU din server har (self-hosted).
Ofta, ja, eftersom det här arbetsflödet bygger på filträdsskanning, grenad logik och anpassade jämförelser som blir klumpiga (och dyra) i enklare automationverktyg. n8n hanterar flera HTTP-anrop, att slå ihop flöden och logik som ”om PR-skapande är aktiverat” utan att bli en skör kedja. Du får också self-hosting-alternativet, vilket är praktiskt när webhooks triggas ofta under aktiv utveckling. Å andra sidan, om allt du vill är ”skicka ett meddelande när en PR öppnas”, kan Zapier eller Make gå snabbare att sätta upp. Vill du stämma av upplägget? Prata med en automationsexpert.
När det här väl kör är saknade iOS-strängar inte längre en sista-minuten-paniksituation, utan en prydlig, delad lista som uppdaterar sig själv. Helt ärligt: det är hela vinsten.
Kontakta oss
Hör av dig, så diskuterar vi hur just din verksamhet kan dra nytta av alla fantastiska möjligheter som AI skapar.