A Telegram bot that automatically syncs your ICS Bank (ABN AMRO) credit card transactions to Lunch Money.
- π Secure login with 2FA support
- π³ Automatic transaction fetching
- π Sync to Lunch Money with deduplication
- π€ Simple Telegram interface
- π³ Docker-ready deployment
- π Automated CI/CD with GitHub Actions
- π¦ Pre-built Docker images from GHCR
- π Browser bookmarklet for manual syncing
In addition to the Telegram bot, this project includes a browser bookmarklet for manual syncing. See bookmarklet/README.md for details.
Quick start:
cd bookmarklet
bun install
bun run watch # Edit src/bookmarklet.js and auto-buildUsing Portainer (Recommended):
- In Portainer, go to Stacks β Add stack
- Upload from git:
https://github.com/H1D/ics_lunchmoney_sync.git - In Portainer's Environment variables section, add:
TOKEN= your Telegram bot tokenUSER_ID= your Telegram user IDICS_EMAIL= your ICS emailICS_PASSWORD= your ICS passwordICS_ACCOUNT_NUMBER= your account number (optional)LUNCHMONEY_TOKEN= your Lunch Money tokenLUNCHMONEY_ASSET_ID= your asset IDSYNC_DAYS=30(or your preferred number of days)
- Deploy the stack
The docker-compose.yml uses ${VARIABLE} syntax and will automatically pull values from Portainer's environment variables.
Using docker-compose directly:
# Clone the repository
git clone https://github.com/H1D/ics_lunchmoney_sync.git
cd ics_lunchmoney_sync
# Edit docker-compose.yml and replace YOUR_*_HERE placeholders
# Then run:
docker-compose up -ddocker pull ghcr.io/temasus/ics_lunchmoney_sync:latest
docker run -d \
-e TOKEN=your_token \
-e USER_ID=your_user_id \
-e ICS_EMAIL=your@email.com \
-e ICS_PASSWORD=your_password \
-e LUNCHMONEY_TOKEN=your_lm_token \
-e LUNCHMONEY_ASSET_ID=your_asset_id \
ghcr.io/temasus/ics_lunchmoney_sync:latest- Docker and Docker Compose
- Telegram bot token (get from @BotFather)
- ICS Bank account credentials
- Lunch Money API token and asset ID
-
Clone or copy this project
-
Create
.envfile:cp .env.example .env
-
Edit
.envwith your credentials:TOKEN=your_telegram_bot_token USER_ID=your_telegram_user_id ICS_EMAIL=your_email@example.com ICS_PASSWORD="your_password" LUNCHMONEY_TOKEN=your_lunchmoney_token LUNCHMONEY_ASSET_ID=your_asset_id SYNC_DAYS=60
-
Start the bot:
docker-compose up -d
-
Test it:
- Send any message to your Telegram bot
- Click the "GO" button
- Approve 2FA on your phone when prompted
- Wait for sync to complete
- You send a message to the bot in Telegram
- Bot responds with a "GO" button
- When clicked, the bot:
- Launches a headless browser
- Logs into ICS bank website
- Waits for your 2FA approval (check your phone!)
- Fetches transactions for the configured period
- Transforms and syncs them to Lunch Money
- Reports back the results
| Variable | Required | Description |
|---|---|---|
TOKEN |
Yes | Telegram bot token from @BotFather |
USER_ID |
Yes | Your Telegram user ID (bot only responds to you) |
ICS_EMAIL |
Yes | ICS bank login email |
ICS_PASSWORD |
Yes | ICS bank password (use quotes if contains #) |
ICS_ACCOUNT_NUMBER |
No | Account number (auto-detected if only one account) |
LUNCHMONEY_TOKEN |
Yes | Lunch Money API token |
LUNCHMONEY_ASSET_ID |
Yes | Lunch Money asset ID for this account |
SYNC_DAYS |
Yes | Number of days to sync (default: 30) |
Send a message to @userinfobot on Telegram to get your user ID.
- Go to Lunch Money
- Click on your ICS/ABN AMRO asset/account
- The asset ID is in the URL:
https://my.lunchmoney.app/transactions/2026/01?asset=12345&match=any&time=year- Use
12345as yourLUNCHMONEY_ASSET_ID
- Use
# Install dependencies
cd telegram-bot
bun install
# Set environment variables
export $(cat ../.env | grep -v '^#' | xargs)
# Run bot
bun run bot.js
# Run sync script directly (for testing)
bun run scripts/sync-transactions.jsIf your password contains # or other special characters, make sure to quote it in .env:
ICS_PASSWORD="your#password"If you see a 2FA timeout error:
- Make sure to approve the login on your phone quickly
- The timeout is 2 minutes
- Try clicking "GO" again
If you have multiple ICS accounts, the bot will show you account details and ask you to set ICS_ACCOUNT_NUMBER in .env.
If Chromium fails to launch in Docker:
- Make sure the Dockerfile includes all Chromium dependencies
- Check container logs:
docker-compose logs telegram-bot
- Never commit your
.envfile - Keep your Telegram bot token secure
- The bot only responds to messages from your
USER_ID - All sensitive data is stored in environment variables
This repository uses gitleaks to prevent secrets from being committed.
Install pre-commit hooks to scan for secrets before each commit:
# Install pre-commit (if not already installed)
pip install pre-commit
# or
brew install pre-commit
# Install the hooks
pre-commit install
# Test the hook
pre-commit run --all-filesThe hook will automatically run before each commit. To skip it for a specific commit:
SKIP=gitleaks git commit -m "your message"GitHub Actions automatically scans all pushes and pull requests using gitleaks. If secrets are detected, the workflow will fail and results will be uploaded to the GitHub Security tab.
Docker images are automatically built and pushed to GitHub Container Registry on every push to main:
latest- Latest build from main branchmain- Build from main branchvX.Y.Z- Version tags (when releases are created)sha-<commit>- Build from specific commit
If you prefer to build the image yourself:
cd telegram-bot
docker build -t ics-lunchmoney-sync .This repository uses GitHub Actions to:
- Build Docker image on every push to
main - Push to GitHub Container Registry (ghcr.io)
- Tag with branch name, commit SHA, and version tags
- Cache layers for faster builds
View available packages at: https://github.com/temasus/ics_lunchmoney_sync/pkgs/container/ics_lunchmoney_sync
MIT