Household chore manager for Logan and Yael. Chores live in Notion; a Telegram bot logs completions via natural language and sends a daily 9am reminder.
- Node.js 20+ (or Docker)
- A Telegram account
- A Notion account with an integration token
- An Anthropic API key
- Open Telegram and message @BotFather
- Send
/newbotand follow the prompts to choose a name and username - Copy the bot token — this is your
TELEGRAM_BOT_TOKEN - Add the bot to your shared group chat
- Send a message in the group, then visit
https://api.telegram.org/bot<TOKEN>/getUpdatesto find thechat.id— this is yourTELEGRAM_CHAT_ID
To find your personal Telegram user ID, message @userinfobot.
- Go to notion.so/my-integrations and create a new integration
- Copy the token — this is your
NOTION_API_KEY - Share your Chores, Completion Log, and Members databases with the integration (open each database → ··· menu → Connections → add your integration)
- Copy each database ID from its URL:
notion.so/<workspace>/<DATABASE_ID>?v=...
cp .env.example .envFill in .env:
| Variable | Where to get it |
|---|---|
TELEGRAM_BOT_TOKEN |
BotFather (step 1) |
TELEGRAM_CHAT_ID |
getUpdates (step 1) |
NOTION_API_KEY |
Notion integration (step 2) |
NOTION_CHORES_DB_ID |
Chores database URL |
NOTION_LOG_DB_ID |
Completion Log database URL |
NOTION_MEMBERS_DB_ID |
Members database URL |
ANTHROPIC_API_KEY |
console.anthropic.com |
TZ |
Leave as Europe/Berlin |
Start the bot, then in the group chat send:
/register Logan
/register Yael
Each person should send this from their own Telegram account so the bot can map their Telegram ID to their name.
With Docker (recommended):
docker compose upWithout Docker:
yarn install
yarn devOpen the Chores database in Notion and add rows directly. Each chore needs:
- Name — something natural, e.g. "dishes", "vacuuming", "take out the bins"
- Assignee — Logan / Yael / Shared
- Frequency Days — how often it should be done (1 = daily, 7 = weekly, 14 = fortnightly, 30 = monthly)
- Frequency Label — human-readable label (Daily, Weekly, etc.)
- Last Done — date it was last completed (leave blank if never done — it'll show as immediately due)
Chore names should be natural enough to match what you'd say in a message: "I did the laundry" → matches "laundry".
Logging a chore — just say it naturally in the group:
"I did the dishes" "just vacuumed" "took out the bins"
The bot reacts with an emoji to confirm. If it can't match the chore, it'll ask for clarification.
Commands:
/ping— health check (bot replies "pong")/register <name>— register your Telegram ID (run once per person)
Daily reminder — at 9:00am Europe/Berlin the bot lists what's due or overdue, grouped by person.
The bot uses long polling — no public URL or webhook needed. No flyctl install required — all fly.io operations run via Docker using scripts/fly.ps1.
-
Create a free account at fly.io
-
Authenticate (opens a browser tab):
.\scripts\fly.ps1 login
-
Create the app (once, to claim the name):
.\scripts\fly.ps1 setup
If
domovoyis taken, update theappfield infly.tomland the name inscripts/fly.ps1. -
Push secrets from your
.envfile to fly.io:.\scripts\fly.ps1 secrets
Re-run this any time you add new environment variables.
-
Create a deploy token for CI/CD:
.\scripts\fly.ps1 token
Copy the output, then go to your GitHub repo → Settings → Secrets and variables → Actions → New repository secret:
- Name:
FLY_API_TOKEN - Value: the token
- Name:
-
Deploy:
.\scripts\fly.ps1 deploy
.\scripts\fly.ps1 deployOr trigger from GitHub without touching the terminal: Actions → CI/CD → Run workflow.
Every push to main runs tests and deploys automatically.
Add the variable to .env, then re-sync:
.\scripts\fly.ps1 secretsyarn lint # ESLint
yarn format # Prettier
yarn tsc # TypeScript type check
yarn test # Vitest