Track your meals, not your data.
Meet NutriGram – a.k.a. “Macro‑Bot” – a Telegram mini‑app that turns a quick chat, photo, or voice note into a full macronutrient read‑out in seconds. It’s powered by a swarm of specialized OpenAI Assistants, runs on a lean Node.js backend, and never stores a single piece of personally‑identifiable information. You can start logging today at @self_nutri_bot.
1. Why build nutrition tracking inside Telegram?
Most food‑logging apps lose people at the install‑sign‑up‑onboard gauntlet. Telegram already lives on your phone, provides text/voice/image input for free, and – thanks to Telegram Stars – now offers in‑chat payments that bypass app‑store friction. That combination let me ship a fully‑featured tracker without designing another mobile UI or storing sensitive user profiles.
Privacy by design
- No email, phone number, or name is required – the bot receives a numeric chat ID only.
- Photos and audio are deleted right after they’re processed.
- Meal logs live for as long as you choose; delete a message in Telegram and it vanishes from the database as well.
2. Key features at a glance
Input | What you do | What the bot does |
---|---|---|
Text | “2 eggs + spinach” | Returns calories, protein, carbs, fat |
Photo | Snap your plate | CV + LLM pipeline identifies foods & weights |
Nutrition label | Shoot the label | OCR → structured nutrients |
Voice note | Speak while cooking | Transcribes & analyses the description |
Daily wrap‑up | Nothing – it’s automatic | Sends a 22:00 summary adjusted to your timezone |
Pricing sits at 100 Stars / month (≈ €3) with a 15‑day free trial and a discounted yearly plan.
3. Under the hood: a multi‑assistant AI system
Instead of one monolithic model, NutriGram chains seven purpose‑built OpenAI Assistants – each a specialist with its own system prompt and tools.
flowchart TD
A[Telegram message] --> B{Handler Factory}
B -->|text| T(TextHandler)
B -->|photo| P(PhotoHandler)
B -->|audio| A1(AudioHandler)
P --> C(Image Type Check)
C -->|food photo| D(Dish Description)
C -->|label| L(Label Extraction)
T --> I(Text→Ingredients)
A1 --> STT(Audio Transcription)
subgraph "Macro Assistants"
D & L & I & STT --> M(Macro Calculator)
end
M --> DB[(MongoDB)]
M --> TG[Telegram reply]
Assistant roster
- Image Type Check – routes photos to label‑vs‑dish paths.
- Nutrition Label Extractor – OCR + structuring of nutrition panels.
- Dish Description Bot – turns a food photo into a natural‑language ingredient list.
- Text → Ingredients – parses free‑form meal descriptions.
- Audio Transcription – converts voice notes to text via Whisper.
- Macro Assistant – looks up USDA food vectors and computes calories & macros.
- False Input Check – filters spam or policy violations.
All assistants share a single thread ID per user session so context flows smoothly down the chain.
4. A step‑by‑step example: processing a food photo
- User → sends a plate snapshot.
- PhotoHandler uploads the image to OpenAI.
- Image Type Check decides it’s a dish, not a label.
- False Input Check approves the content.
- Dish Description Bot returns: “A bowl of oatmeal topped with ½ banana, 10 g chia seeds, and a drizzle of honey.”
- Macro Assistant converts that description into precise grams, queries the USDA embedding index, and sums the macros.
- MongoDB stores the entry; Telegram replies with a formatted nutrient card and cumulative daily totals.
Total latency: ≈ 4.8 s end‑to‑end on a standard GPT‑4o model mix.
5. Tech stack & code snippets
Layer | Tech |
---|---|
Backend | Node.js 20 + Express |
AI | OpenAI Assistants API (GPT‑4o) |
Database | MongoDB 6 (Mongoose ORM) |
Messaging | Telegram Bot API (webhook) |
Dev infra | ngrok ↔ local tunnel, Railway for prod |
Thread management pattern
// Create a thread once per chat session
const { id: threadId } = await openai.createThread();
// Re‑use across assistants
await imageTypeCheck.process(openai, threadId, imageUrl);
await dishDescriptionBot.process(openai, threadId, photoAnalysis);
await macroAssistant.process(openai, threadId, ingredientJson);
Handler factory
export function getHandler(type, ctx) {
const map = {
text: TextHandler,
photo: PhotoHandler,
voice: AudioHandler
};
return new map[type](ctx);
}
6. Research takeaways
- Specialists beat generalists – smaller prompts + focused tools yield faster, cheaper, more accurate results than a single giant prompt.
- Context matters – OpenAI threads let each assistant build on prior outputs without leaking user data into prompts.
- Modalities converge – with images and audio now first‑class citizens in GPT‑4o, users expect friction‑less logging regardless of input type.
7. Roadmap
- Parallel inference – run label/dish + validation assistants concurrently to shave another second off latency.
- Personalised goals – adapt macro targets based on user‑set objectives and health metrics.
- Recipe RAG – query a private recipe KB to auto‑log complex dishes.
- Wearable integrations – merge CGM/heart‑rate data for holistic nutrition insights.
8. Try it & tell me what you think
Ready to ditch clunky food diaries? Fire up Telegram and DM @self_nutri_bot. The first 15 days are on me, and every message hits my inbox – so bug reports, feature ideas, or spicy feedback are more than welcome.
Happy logging & healthy eating! 🚀