@vojtatranta/receipt-scanner
v1.0.0
Published
CLI pro vytěžení účtenek a faktur z fotografií a export do PDF
Readme
Receipt Scanner
Node.js CLI, které rekurzivně projde složku s fotografiemi účtenek a faktur, pomocí OpenAI Vision přečte typ dokladu, prodejce, celkovou částku a účel. Pro každý doklad vytvoří čisté PDF obsahující pouze jeho fotografie. Název má podobu uctenka-lidl-459.90-CZK.pdf nebo faktura-makro-1250.00-CZK.pdf.
Každou fotografii program porovná s předchozí podle obsahu dokladu, návaznosti položek a názvů souborů. Potvrzené stránky spojí do jednoho vícestránkového PDF a do tabulky zapíše pouze jeden výsledný řádek. U vícestránkových faktur ignoruje průběžné součty stran a jako výslednou částku hledá konečný údaj Celkem s DPH nebo Celkem k úhradě na poslední souhrnné straně.
Požadavky
- Node.js 20 nebo novější
- OpenAI API klíč
Instalace
npm install
cp .env.example .envDo .env vložte svůj klíč:
OPENAI_API_KEY=sk-proj-vas-klic
OPENAI_MODEL=gpt-5.1Soubor .env je v .gitignore, takže se klíč necommitne.
Použití
Nejjednodušší spuštění přes Bun bez klonování repozitáře:
OPENAI_API_KEY=sk-proj-... bunx @vojtatranta/receipt-scanner /cesta/ke/slozce/s/fotkamiKlíč se hledá automaticky v tomto pořadí: --api-key, proměnná OPENAI_API_KEY, .env v aktuální složce a poté ~/.config/openai/api_key, ~/.openai/api_key, ~/.config/openai/.env, ~/.openai/.env nebo ~/.env. Pokud už máte OPENAI_API_KEY exportovaný například v .zshrc, není potřeba nic dalšího nastavovat. Přihlášení do ChatGPT nebo Codexu se z bezpečnostních důvodů nepoužívá jako API klíč.
Balíček musí být nejprve publikovaný na npm pomocí CI popsaného níže.
Spuštění ze zdrojového kódu:
npm start -- /cesta/ke/slozce/s/fotkamiSamostatná Bun binárka
Lokální sestavení jednoho spustitelného souboru:
bun install
bun run build:binVýsledek je dist/receipt-scanner.bin. Na cílovém počítači už není potřeba Node.js, Bun ani node_modules; stačí API klíč a cesta ke složce:
OPENAI_API_KEY=sk-proj-... ./receipt-scanner.bin /cesta/k/fotkamGitHub Actions workflow Build standalone binary lze spustit ručně. Vytvoří stažitelný artefakt receipt-scanner-macos. Každý push do větve main navíc automaticky sestaví binárku a vytvoří nový GitHub Release pro daný commit:
git push origin mainStejný push publikuje veřejný balíček @vojtatranta/receipt-scanner na npm s unikátní CI verzí. V nastavení GitHub repozitáře je před prvním pushem potřeba přidat secret NPM_TOKEN obsahující npm access token s oprávněním publikovat balíčky pod účtem vojtatranta.
První verzi lze publikovat také lokálně po npm login:
npm publish --access publicProvenance se přidává pouze v GitHub Actions; lokální npm prostředí ji samo vytvořit neumí.
Vlastní výstupní složka:
npm start -- /cesta/k/fotkam --output /cesta/k/vystupuKlíč lze předat i přímo, ale může zůstat v historii shellu:
npm start -- /cesta/k/fotkam --api-key sk-proj-...Podporované vstupy: JPG, PNG, WebP, HEIC/HEIF, TIFF a AVIF. Výstupní složka uvnitř vstupu se při dalším běhu ignoruje. Pokud už stejný název existuje, nový soubor dostane příponu -2, -3 atd. Volba --overwrite dovolí přepsat první soubor se shodným názvem.
Kopírování do Google Sheets
Ve výstupní složce vznikne results.tsv. Otevřete jej, zkopírujte všechny řádky a vložte je do Google Sheets. Tabulátory automaticky rozdělí hodnoty do čtyř sloupců bez hlavičky:
Jídlo - Košík\t48 711,40 Kč\t\tfaktura\tjídloSloupce jsou: popis/prodejce, částka, prázdný oddělovací sloupec, typ dokladu a účel/kategorie. Tím odpovídají rozložení cílového Google Sheetu. Odkaz na Google Drive se nevytváří, protože soubory zůstávají lokálně; lze jej doplnit po jejich nahrání. Strojová data zůstávají také v results.json a results.csv.
Přesnost
U rozmazaných nebo oříznutých fotek nemusí být částka čitelná. Program v takovém případě uloží null namísto domyšlené hodnoty. Výsledky určené pro účetnictví vždy zkontrolujte proti originálu.
