🇬🇧 English · 🇷🇺 Русский
Open-source non-commercial Telegram bot for people with type 1 diabetes. Built for friends and family by a sibling-of-T1D developer, shared with the community. Active development — contributors welcome under non-commercial terms.
Every meal for a person with type 1 diabetes is a math problem. You estimate the carbohydrates on your plate, convert them to bread units (XE), and calculate the insulin dose. An error of 1–2 XE can cause hypoglycaemia or hyperglycaemia — hospitalisation, loss of consciousness, coma. People do this 4–6 times a day, every day, for the rest of their lives.
DiaBot turns carb counting into a single action: send a photo — get the result. AI recognises the food, the user confirms or corrects, the bot calculates KBJU and bread units, writes a diary entry, and shows progress against daily targets. Carbs and XE are always rendered first — because that is what insulin dose depends on.
This project is in active development and shared under the PolyForm Noncommercial 1.0.0 licence. You may run it for yourself, your family, or a friends-and-family circle. Commercial use — including hosting it as a paid service or bundling it into a paid product — is not permitted. Contributors are welcome under the same terms.
The bot needs help with: tighter LLM prompting, more precise dietetic calculations, user-facing answer verification, integration with external KBJU databases (USDA, OpenFoodFacts, regional sources), and regional adaptation. See Roadmap & known limitations and CONTRIBUTING.md for the priority list.
UI shown in Russian (default locale). English locale also fully supported — language follows the user's Telegram preference.
| Layer | Technology | Notes |
|---|---|---|
| Language | Python 3.11+, fully async | one event loop, no thread pools |
| Telegram | python-telegram-bot 21+ |
polling mode, ConversationHandler for state |
| LLM router | litellm Router with two chains |
vision (Gemini 2.5 Flash → OpenRouter Gemini) + text (Gemini → OpenRouter → Groq Llama 4) |
| Search grounding | google-genai |
Google Search tool — fallback for low-confidence branded products |
| Database | SQLite via aiosqlite |
no ORM, plain SQL, schema fits in one file |
| Config | python-dotenv |
frozen Settings dataclass validated at start |
| Deployment | systemd unit included | runs as a non-privileged user under /opt/diabot/ |
| Tests | 72 pytest cases | covers every handler and service |
- Send a photo of your meal (or describe it in text)
- Bot recognises items and portions via the vision LLM
- Confirm or correct — the bot prints what it saw, you adjust if anything is off
- Get KBJU + XE — calculation with carbs prioritised
- Track progress — diary, weekly stats, progress bars towards daily targets
Food recognition
- 📷 Photo → AI recognition of products and portions
- ✏️ Text-based food description (no photo needed)
- 📷+✏️ Photo with caption for extra context
- 🏷 Branded-product recognition with Google Search grounding for rare brands
Precise calculation
- 🔢 Calories, protein, fat, carbohydrates (KBJU)
- 🍞 Bread units (XE / HE) — configurable ratio (default 1 XE = 12 g carbs)
- 🎯 Carbs always rendered first — insulin dosing priority
- ✅ Two-step flow: recognise → confirm → save
Daily targets and progress
- 👤 Profile: gender, height, weight, age
- 📊 Automatic target calculation via Mifflin-St Jeor
- ✍️ Manual target override (for dietician-prescribed values)
- 📈 Compact progress after every meal
- ▓▓▓░░░ Visual progress bars in the diary
Food diary
- 📅 Today's diary with per-meal breakdown (
/today) - 📊 Weekly statistics (
/week) - 📜 Meal history (
/history N) - ↩️ Undo last entry (
/undo) - 🩸 Glucose readings tracking (
/sugar)
Privacy and data
- 🔒 Consent on first launch with data-processing details
- 🚫 Photos are NEVER saved to disk — only Telegram
file_idis stored - 📦 Full data export (
/exportas JSON) - 🗑 Complete data deletion (
/delete_my_data) - ✅ GDPR-style compliance
Multi-user
- 👥 Self-hosted with admin approval workflow
- 📩 User requests access → admin gets notification → user is notified back
- ⚡ Per-user rate limiting
Safety disclaimer. This is an assistance tool, not a medical device. Always cross-check critical carb counts before insulin dosing. The two-step recognise → confirm flow is safety-critical, not cosmetic — do not skip it. Not a substitute for an endocrinologist or a dietician.
- Tighter LLM prompting — stricter JSON-schema validation, lower temperature, deterministic portion estimation
- More precise dietetic calculations — verified portion-size heuristics, glycaemic load, fibre subtraction in digestible carbs
- User-facing answer verification — confidence scores per item, explicit "double-check this" flag at low confidence
- External KBJU databases — USDA FoodData Central, OpenFoodFacts, regional Russian / Eastern-European sources
- Regional adaptation — EU / US / RU / Asia food norms and cuisines, branded products, locally common dishes
- LLM may misidentify food (poor lighting, small portions, regional dishes, unusual angles). The two-step confirmation exists exactly because of this.
- No CGM integration yet
- Bilingual prompts mostly tested in RU; EN locale verification is ongoing
- Google Search grounding is available only for the Gemini chain — OpenRouter / Groq fallbacks do not support it yet
- Onboarding asks for body metrics in metric units only — imperial conversion is on the backlog
git clone https://github.com/CreatmanCEO/diabot.git
cd diabot
python -m venv venv
source venv/bin/activate # Linux / macOS — on Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
# Fill in your API keys in .env
python main.py| Variable | Description | Required |
|---|---|---|
TELEGRAM_TOKEN |
Bot token from @BotFather | yes |
ADMIN_IDS |
Comma-separated admin Telegram IDs | yes |
GEMINI_API_KEY |
Google AI Studio API key | * |
OPENROUTER_API_KEY |
OpenRouter API key | * |
GROQ_API_KEY |
Groq API key | * |
DEFAULT_TIMEZONE |
Default timezone (Europe/Moscow) |
no |
DEFAULT_HE_GRAMS |
Grams of carbs per 1 XE (12) |
no |
DEFAULT_LANGUAGE |
Default language (ru) |
no |
RATE_LIMIT_REQUESTS |
Per-user requests per hour (30) |
no |
DB_PATH |
Path to SQLite database | no |
* At least one LLM API key required. Photo recognition needs GEMINI_API_KEY or OPENROUTER_API_KEY.
sudo useradd -r -s /bin/false diabot
sudo mkdir -p /opt/diabot
sudo git clone https://github.com/CreatmanCEO/diabot.git /opt/diabot
cd /opt/diabot
sudo python3 -m venv venv
sudo venv/bin/pip install -r requirements.txt
sudo cp .env.example .env
sudo nano .env # fill in tokens
sudo cp diabot.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable diabot
sudo systemctl start diabotdiabot/
├── main.py # Entry point, ConversationHandler wiring
├── config.py # Settings dataclass from .env (frozen, validated)
├── handlers/ # Telegram handlers (thin I/O, no business logic)
│ ├── start.py # /start, 5-step onboarding, /help
│ ├── photo.py # Food photo recognition pipeline
│ ├── text.py # Text food input + reply keyboard routing
│ ├── confirm.py # Confirmation, correction, cancellation
│ ├── diary.py # /today, /week, /history, /undo
│ ├── glucose.py # /sugar — glucose readings
│ ├── settings.py # Profile / target editing, admin panel
│ ├── admin.py # /adduser, /removeuser, /listusers, approval workflow
│ ├── privacy.py # /privacy, /export, /delete_my_data, consent
│ └── keyboards.py # Keyboard factory (reply + inline)
├── services/ # Business logic (no Telegram imports)
│ ├── llm.py # litellm Router, two chains, auto-failover
│ ├── nutrition.py # KBJU formatting, progress bars, XE calculation
│ ├── database.py # aiosqlite CRUD
│ └── auth.py # Access control, rate limiting, approval queue
├── models/schemas.py # Dataclasses: MealItem, User, NutritionTarget, …
├── locales/ # i18n strings + LLM prompts (tied to language)
│ ├── ru.py # Russian (default)
│ └── en.py # English
├── docs/
│ ├── architecture.svg # this README's pipeline diagram
│ ├── plans/ # design docs and implementation plans
│ └── screenshots/ # README assets
├── tests/ # 72 automated tests (pytest)
├── diabot.service # systemd unit
├── CHANGELOG.md
├── CONTRIBUTING.md
├── CLAUDE.md # Claude Code project constitution
└── LICENSE # PolyForm Noncommercial 1.0.0
ONBOARDING: consent → gender → height → weight → age → targets → IDLE
IDLE ↔ AWAITING_CONFIRM (food recognition flow)
IDLE ↔ AWAITING_GLUCOSE (glucose recording)
- Handlers are thin — every business decision lives in
services/. Handlers only do Telegram I/O. - Two LLM chains — vision (Gemini → OpenRouter) for photos; text (Gemini → OpenRouter → Groq Llama 4) for descriptions.
litellmRouter handles automatic failover. - Google Search grounding — when the primary model returns low confidence on a branded product, a separate
google-genaicall with the Search tool retrieves accurate KBJU. - Carb accuracy over calorie accuracy — reflected in prompts, formatting, and UI ordering. Insulin dosing depends on carb precision; calories are secondary.
- No ORM — plain SQL with
aiosqlite. The schema fits in one file; an ORM would add complexity without benefit. - Photos never touch disk — only Telegram
file_idis stored. Image bytes are fetched on demand and passed directly to the LLM API as bytes. - Two-step confirmation is a safety mechanism — recognition → confirm. Without explicit confirmation no meal is saved and no insulin guidance is implied.
The project is configured for Claude Code as the primary development driver — see CLAUDE.md for the project constitution. The same author maintains a Claude Code Anti-Regression Setup — that pattern is what keeps the 72-test suite green during refactors.
Run tests:
python -m pytest tests/ -vPer-iteration design docs live in docs/plans/. New work starts with a design doc, then code follows.
PRs are welcome under the same non-commercial terms as the project. See CONTRIBUTING.md for priorities (LLM prompt-tightening, dietetic accuracy, answer verification, external KBJU databases, regional adaptation, native localisations beyond RU/EN).
- Claude Code Anti-Regression Setup — sister repo by the same author. The
.claude/config + subagents + hooks pattern that keeps the 72-test suite green during refactors. - ai-context-hierarchy — sister repo. Three-level context system used by Claude Code on this project.
- claude-statusline — sister repo. Statusline for Claude Code with VPS monitoring.
- lingua-companion — sister product from the same author — a voice-first English tutor for Russian-speaking IT professionals. Different domain, same engineering discipline.
Nick Podolyak — Python developer and digital architect at CREATMAN
- GitHub: @CreatmanCEO
- Habr: creatman
- dev.to: @creatman
PolyForm Noncommercial 1.0.0 · Nick Podolyak. Non-commercial use only — see the Status section.




