NanaGPT — WhatsApp Health Companion for Elderly Care


Inspiration

India has over 140 million people above the age of 60. A significant portion of them manage chronic conditions like diabetes, hypertension, and thyroid disorders — often alone, with minimal support between doctor visits. They forget medications, struggle to read prescriptions written in medical shorthand, and have no easy way to ask basic health questions without calling a family member or waiting for the next appointment.

The solution should not require learning new technology. Most elderly individuals in India already use WhatsApp daily — it is familiar, accessible, and does not intimidate them. This insight led to NanaGPT: a health assistant that lives entirely within WhatsApp, requiring zero installation and zero learning curve.


What It Does

NanaGPT is a WhatsApp-based AI health companion designed specifically for senior citizens. It communicates through a simple numbered menu system that any elderly user can navigate.

Core features:

  • Onboarding Profile — On first use, the bot collects the user's name, age, known health conditions, current medicines, and an optional prescription photo. This profile is stored and used to personalize every subsequent interaction.

  • Medicine Reminders — Users describe their reminder in natural language (e.g., "Remind me to take Metformin at 8 AM daily") and the bot parses this into a structured reminder, saved to a database and delivered automatically via WhatsApp at the scheduled time.

  • Persistent Follow-Up Reminders — If a user does not reply "done" after the initial reminder, the bot sends up to two follow-up nudges at 10-minute intervals, escalating in tone, before stopping automatically.

  • Prescription Reader — The user photographs their prescription and sends it. The bot reads the image, identifies each medicine, explains its purpose, dosage, and precautions — all in the user's preferred language.

  • Health Question Answering — Users can ask any health-related question and receive a concise, contextual response informed by their stored medical profile.

  • Health Log — Users can log readings such as blood pressure, blood sugar, or weight. The bot stores these with timestamps and allows users to view their recent history, helping them and their caregivers track trends.

  • Multilingual Support — The bot can communicate in English, Hindi, Marathi, Gujarati, and Tamil. Language can be changed at any time and applies globally across all features.


How We Built It

Technology Stack

Layer Technology
Conversational AI ASI:ONE API (asi1-mini model)
Backend Python, Flask
Database PostgreSQL (hosted on Supabase)
Scheduler APScheduler (medicine reminder delivery, follow-up nudges)
WhatsApp Integration Meta WhatsApp Business API (WABA)
Hosting Render (cloud deployment)
Uptime Monitoring UptimeRobot

Architecture

WhatsApp User
     |
     v
Meta WABA Webhook (POST /webhook)
     |
     v
Flask App (Render)
     |
     ├── State Machine (menu / onboarding / reminder / prescription / ...)
     |
     ├── ASI:ONE API  ←── Natural language understanding, multilingual replies,
     |                     prescription image analysis, reminder parsing
     |
     ├── PostgreSQL (Supabase) ←── User profiles, conversation history,
     |                              reminders, health logs (persistent)
     |
     └── APScheduler  ←── Checks active reminders every minute, sends
                           WhatsApp alerts, tracks follow-up confirmations

UptimeRobot pings the Render URL every 5 minutes to prevent the free-tier
instance from sleeping, keeping the scheduler alive continuously.

How ASI:ONE Powers the Application

ASI:ONE is the core intelligence layer of NanaGPT. It is accessed via an OpenAI-compatible API, which allowed rapid integration using the standard Python openai SDK simply by pointing base_url at ASI:ONE's endpoint.

1. Personalized System Prompt Every call to ASI:ONE includes a dynamically built system prompt containing the user's name, known conditions, and current medicines. This means responses are not generic — when a user asks "Can I take Crocin?", ASI:ONE already knows they have diabetes and responds accordingly.

2. Multilingual Instruction Following The system prompt explicitly instructs ASI:ONE to respond in the user's selected language and script (Devanagari for Hindi/Marathi, Gujarati script, Tamil script). This is enforced strictly and repetitively in the prompt to prevent language mixing or silent fallback to English.

3. Structured Output Extraction Rather than relying on function calling, we prompt ASI:ONE to embed structured data inside custom XML-like tags within its response:

  • <REMINDER>{"medicine":"Metformin","time":"08:00","frequency":"daily"}</REMINDER> — for reminder creation
  • <HEALTHLOG>{"type":"BP","value":"130/85"}</HEALTHLOG> — for health readings

The application strips these tags before sending the reply to the user and processes the JSON separately to update the database.

4. Prescription Image Analysis Prescription photos are downloaded directly from WhatsApp's media servers, converted to base64, and sent to ASI:ONE as a vision input via a data URI. The model reads the handwritten or printed prescription and generates a structured explanation in the user's language — covering medicine names, purpose, dosage, and precautions.

5. Contextual Conversation History The last three conversation exchanges are retrieved from the database and included in every ASI:ONE call, allowing the bot to maintain context across a session without server-side session management.


Challenges We Ran Into

WhatsApp token expiry — Meta's temporary access tokens expire every 24 hours, causing repeated 401 authentication failures during development. Resolved by switching to a permanent System User token via Meta Business Manager.

Ephemeral filesystem on Render's free tier — The application initially used SQLite for simplicity. However, Render's free tier filesystem resets on every redeploy and spin-down, silently wiping all user profiles and reminders. This caused users to be asked to onboard again on every session and reminders to vanish without warning. Resolved by migrating the entire data layer to a hosted PostgreSQL database on Supabase, which persists independently of the application instance.

Database driver compatibility — The hosting environment runs Python 3.14, which is incompatible with psycopg2-binary's compiled wheels (undefined symbol errors at import time). Resolved by switching to psycopg (psycopg3), which ships native Python 3.14 support.

Scheduler silently not running — APScheduler was started inside an if __name__ == "__main__": block, which never executes under Gunicorn (Gunicorn imports the app as a module rather than running it as a script). Reminders were being saved correctly but never checked or sent. Resolved by moving scheduler startup to module level so it initializes regardless of how the app is run.

Render free tier sleep cycles — Even after fixing the scheduler, Render's free tier spins the instance down after 15 minutes of inactivity, killing the background scheduler entirely. Resolved by configuring an UptimeRobot monitor to ping the app's health endpoint every 5 minutes, keeping the instance continuously alive.

Prescription image delivery — WhatsApp media URLs expire within minutes and require an Authorization header to download; passing these URLs directly to ASI:ONE failed. Resolved by downloading the image immediately upon receipt, converting it to base64, and embedding it in the API request as a data URI rather than a remote link.

State management over stateless HTTP — WhatsApp webhooks are stateless POST requests. Maintaining conversational state (which menu option a user is currently in) required a persistent state field per user, with state-based routing always taking priority over keyword/number detection to prevent menu option numbers from being misinterpreted while inside an unrelated flow (e.g., typing "2" during language selection being read as a main menu selection).

Language instruction compliance — ASI:ONE's model tended to default toward English even when instructed otherwise via a single-line system prompt. Resolved with a much more explicit, repeated language directive specifying the exact script per language and an immediate post-change test message to confirm compliance.

Duplicate reminders — Early testing showed reminders being saved multiple times. A duplicate check against medicine name, time, and active status was added at the database level before any insert.


Accomplishments That We Are Proud Of

  • A fully functional end-to-end WhatsApp bot, deployable with a single Render deployment and a Meta webhook configuration — no mobile app, no app store approval, no installation required for the end user.
  • A reminder system that doesn't just fire once — it follows up automatically if the user hasn't confirmed taking their medicine, closely mirroring how an actual caregiver would nudge a forgetful elder.
  • Prescription explanation in regional Indian languages from a photo, directly addressing a real and common problem faced by elderly patients.
  • Migrated the entire persistence layer from a local file-based database to a properly hosted, production-grade PostgreSQL instance mid-build, without altering the application's external behavior.
  • A clean state machine architecture that handles onboarding, menu navigation, feature flows, and global shortcuts (returning to menu, confirming medicine taken) in a single, maintainable codebase.
  • Personalized AI responses using the user's stored medical profile — the same health question receives a different, more relevant answer depending on the user's conditions and current medicines.

What We Learned

  • WhatsApp is not just a messaging app for elderly users — it is their primary and often only digital interface. Building within it removes the single largest barrier to adoption for health technology in this demographic.
  • Free-tier infrastructure has hidden constraints (ephemeral filesystems, sleep cycles) that don't show up until real usage patterns expose them — what looks like a logic bug in reminders was actually an infrastructure persistence issue.
  • Structured output extraction via prompt engineering (using custom tags) is a practical alternative to formal function calling when working with models that support it inconsistently.
  • State machines are the correct abstraction for multi-turn conversational bots over stateless webhooks. Trying to infer intent from message content alone leads to routing conflicts and unpredictable behavior.
  • Language model compliance with language instructions requires explicit, repetitive instruction — stating the language once in a system prompt is insufficient for consistent multilingual output.
  • Background schedulers under WSGI servers like Gunicorn need to be initialized at module import time, not inside a __main__ guard, or they silently never run in production.

What's Next for NanaGPT

  • Drug Interaction Checker — Leveraging ASI:ONE to flag potentially dangerous combinations between medicines in the user's profile and any new medicine they ask about.
  • Voice Message Support — Full support for voice notes via Whisper-compatible transcription, making the bot accessible to users who cannot type comfortably.
  • Production-Grade Hosting — Move off Render's free tier to a paid always-on instance, removing the dependency on uptime-monitoring workarounds for reliable scheduled delivery.
  • Proactive Health Nudges — Weekly summaries of health log trends sent automatically, with ASI:ONE generating a plain-language interpretation (e.g., "Your blood pressure readings this week have been consistently above 140 — consider discussing this with your doctor").

Built With

Share this project:

Updates