Skip to content

samaluk/fintual-api

Repository files navigation

fintual-api

fintual-api is a one-shot worker that logs into Fintual, fetches investment performance data, and imports the resulting variation transactions into Actual Budget.

The repo intentionally supports only two flows:

  • pnpm once runs the full sync once
  • unattended 2FA retrieval via Gmail IMAP + app password

Requirements

  • Node.js 24+
  • pnpm
  • Fintual credentials
  • Actual Budget server credentials
  • Gmail app password for unattended 2FA

Setup

  1. Install dependencies:
pnpm install
  1. Create a local env file:
cp .env.example .env
  1. Fill in your Actual, Fintual, and Gmail values.

Gmail IMAP Setup

Enable 2-Step Verification in Google Account settings, then create a Gmail app password for the mailbox used to receive Fintual 2FA emails.

Simplified Gmail app password generation

  1. Open the 2-Step Verification page (you only need to do this once): 2-Step Verification
  2. Open App Passwords directly: App Passwords
  3. Create an app password for any label (for example: fintual-api), then copy the generated 16-character password.
  4. Paste it into .env as GMAIL_APP_PASSWORD.

If you prefer a quick copy/paste terminal flow:

read -s "GMAIL_APP_PASSWORD?Paste Gmail app password: "; echo
cat >> .env <<EOF
GMAIL_USER_EMAIL=your@gmail.com
GMAIL_APP_PASSWORD=$GMAIL_APP_PASSWORD
GMAIL_IMAP_HOST=imap.gmail.com
GMAIL_IMAP_PORT=993
EOF
unset GMAIL_APP_PASSWORD

Set these values in .env (or your runtime secret manager):

  • GMAIL_USER_EMAIL
  • GMAIL_APP_PASSWORD
  • GMAIL_IMAP_HOST (default: imap.gmail.com)
  • GMAIL_IMAP_PORT (default: 993)

fintual-api polls IMAP over TLS and extracts the 6-digit code from matching emails.

gcloud Secret Manager (CLI-only)

Use gcloud CLI to store and retrieve the Gmail app password without committing it:

gcloud secrets create fintual-gmail-app-password --replication-policy=automatic
printf '%s' "$GMAIL_APP_PASSWORD" | gcloud secrets versions add fintual-gmail-app-password --data-file=-
gcloud secrets versions access latest --secret=fintual-gmail-app-password

Example to materialize a local .env value from Secret Manager:

echo "GMAIL_APP_PASSWORD=$(gcloud secrets versions access latest --secret=fintual-gmail-app-password)" >> .env

Run Once

Optionally type-check the project, then run the sync directly from the TypeScript source:

pnpm typecheck
pnpm once

The worker will:

  • log in to Fintual over HTTP (initiate_login → Gmail IMAP 2FA when required → finalize_login_web) and fetch GraphQL performance data
  • write the result to tmp/fintual-data/balance-2.json
  • import variation transactions into Actual Budget

Reverse-engineering Fintual HTTP (agent-browser)

To capture login and GraphQL traffic for analysis (HAR), use agent-browser ≥ 0.22 and run:

pnpm capture:har

Details and observed endpoints are in docs/fintual-http-capture.md. Output goes to tmp/fintual-capture.har (gitignored).

Docker Image

The published container image is designed as a one-shot worker. Its default command runs the sync once:

docker run --rm --env-file .env docker.io/samaluk/fintual-api:latest

Mount ./tmp if you want to inspect the generated files locally:

docker run --rm --env-file .env -v "$(pwd)/tmp:/app/tmp" docker.io/samaluk/fintual-api:latest

Local Compose Workflow

The local compose file keeps the worker container idle so you can run the sync manually with the exact same Docker environment each time:

docker compose --env-file .compose.env up -d --build
docker exec -it fintual-api-local ./bin/run-sync.sh

The compose stack also starts ofelia, so you can test the scheduled job-exec path and inspect scheduler logs:

docker logs -f fintual-api-ofelia

Set OFELIA_SYNC_SCHEDULE in .compose.env if you want a faster local test cadence, for example:

OFELIA_SYNC_SCHEDULE=@every 5m

If you keep runtime secrets in Secret Manager, fetch GMAIL_APP_PASSWORD at deploy time and inject it into the homelab runtime env instead of storing it in compose files.

Useful commands while debugging:

docker logs -f fintual-api-local
docker logs -f fintual-api-ofelia
docker exec -it fintual-api-local sh
docker exec -it fintual-api-local ./bin/run-sync.sh
docker compose --env-file .compose.env down

GitHub Actions Publishing

This repo publishes docker.io/samaluk/fintual-api from GitHub Releases.

Repository secrets required for publishing:

  • DOCKERHUB_USERNAME
  • DOCKERHUB_TOKEN

Published tags:

  • sha-<commit>
  • latest from GitHub Releases
  • the GitHub Release tag itself, such as v1.0.0

Homelab Deployment

The intended production model is:

  • GitHub Actions publishes the worker image to Docker Hub
  • the homelab compose stack pulls the image
  • a long-lived idle worker keeps secrets in its runtime environment
  • Ofelia schedules job-exec runs inside that worker
  • Komodo deploys compose changes from the homelab repo

Recommended Ofelia schedule for Santiago, Chile weekdays at 21:00:

  • cron: 0 21 * * 1-5
  • timezone: America/Santiago

Use an idle fintual-api worker plus an ofelia service that executes ./bin/run-sync.sh on schedule.

For homelab deployments, store GMAIL_APP_PASSWORD in your secret manager (for example, GCP Secret Manager) and inject it into the worker environment at runtime.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors