Rimaimy: pronounced "remind me"
A Telegram bot that extracts tasks from messages using an LLM, stores them in Supabase, and sends reminders based on urgency. Runs on Cloudflare Workers.
| Service | Free Tier |
|---|---|
| Cloudflare Workers | 100,000 requests/day |
| Groq | Free tier (Llama, GPT-OSS models) |
| Supabase | 500MB DB, unlimited API |
| Telegram Bot API | Free |
- Multi-user — each Telegram user sees only their own tasks
- Forward or send any message — the LLM extracts a task title, description, and due date
- Smart reminders — reminder frequency scales with how close the due date is
- Inline action buttons on each task: Done, Undone, Due, Delete
- Link back to the original forwarded message
- Commands:
- List:
/list,/list by created,/list done,/remaining,/today - Create:
/add <title>,/add <title> | <date> - Update:
/update <id> due <date>,/update <id> title <text> - Delete:
/delete <id> - Status:
/done <id>,/undone <id>
- List:
- Accepted date formats:
2026-03-10,4/3/2026,tomorrow,today,next week,in 2 days
- Open Telegram and message @BotFather
- Send
/newbotand follow the prompts - Copy the bot token — it looks like
123456789:ABCdef...
- Go to supabase.com and create a free project
- In Project Settings → API, copy:
- Project URL → this is your
SUPABASE_URL - service_role key → this is your
SUPABASE_SERVICE_KEY(use the service_role key, not the anon key)
- Project URL → this is your
- Go to console.groq.com and create a free account
- Generate an API key → this is your
GROQ_API_KEY
In Supabase, go to SQL Editor and run the contents of supabase/schema.sql. This creates the tasks table.
Copy the example config and fill in your values:
cp wrangler.toml.example wrangler.tomlOpen wrangler.toml and replace the placeholder values under [vars]:
[vars]
TELEGRAM_BOT_TOKEN = "your-telegram-bot-token"
SUPABASE_URL = "https://your-project.supabase.co"
SUPABASE_SERVICE_KEY = "eyJ..."
GROQ_API_KEY = "gsk_..."
GROQ_MODEL = "openai/gpt-oss-20b" # or openai/gpt-oss-120b for better accuracy
CRON_SECRET = "any-random-string" # used to protect the /cron-reminder endpointwrangler.toml is listed in .gitignore and will not be committed.
npm install
npm run deployAfter deploying, Wrangler will print your worker URL:
https://remind-me-bot.<your-subdomain>.workers.dev
Tell Telegram where to send updates. Replace the values below with your bot token and worker URL:
curl "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/setWebhook?url=https://remind-me-bot.<your-subdomain>.workers.dev/webhook"A successful response looks like:
{"ok":true,"result":true,"description":"Webhook was set"}The cron handler runs at /cron-reminder?secret=<CRON_SECRET> and checks all users' tasks.
Option A: Cloudflare Cron Triggers (requires Workers Paid plan, $5/month)
The cron schedule is already set in wrangler.toml (0 * * * * = every hour). No extra setup needed if you have a paid
plan.
Option B: External Cron (free)
Use cron-job.org or any HTTP cron service:
- URL:
https://remind-me-bot.<your-subdomain>.workers.dev/cron-reminder?secret=<CRON_SECRET> - Method: GET
- Schedule: every hour (
0 * * * *)
The CRON_SECRET value must match what you set in wrangler.toml.
| Time until due date | Reminder frequency |
|---|---|
| No due date or overdue | Every hour |
| Less than 1 day | Every hour |
| 1–3 days | Every 4 hours |
| 3–5 days | Every 8 hours |
| More than 5 days | No reminder |
cp .dev.vars.example .dev.vars
# Fill in .dev.vars with your credentials (same keys as wrangler.toml [vars])
npm run devTo test the Telegram webhook locally, expose your local server with ngrok or Cloudflare Tunnel, then register that URL as your webhook.
Create a task
- Forward or send any message: "Call mom tomorrow at 5pm"
- Or use the command:
/add Buy groceriesor/add Finish report | tomorrow
List tasks
/list— all pending tasks, sorted by due date/list by created— sorted by creation date/list done— includes completed tasks/remaining— incomplete tasks only/today— tasks due today
Manage tasks
/update <id> due tomorrowor/update <id> title New title/done <id>//undone <id>/delete <id>— permanent, no confirmation
Each user is identified by their Telegram user ID. All data is scoped per user — tasks, reminders, and commands only affect the requesting user's data. No registration required.
rimaimy/
├── src/
│ ├── index.ts # Webhook + cron handler
│ ├── llm.ts # LLM task extraction
│ ├── db.ts # Supabase CRUD
│ ├── telegram.ts # Telegram API helpers
│ └── types.ts # TypeScript types
├── supabase/
│ └── schema.sql # Database schema
├── wrangler.toml # Cloudflare config (gitignored, contains secrets)
├── wrangler.toml.example
└── package.json
MIT