Skip to main content
The main backend is a Flask application that receives WhatsApp webhooks, manages users and location, generates panchangam data, and sends messages via the Meta Graph API. Background jobs (daily 6:30 AM sends) are handled by Celery and Beat; see Scheduling for that flow.

High-level flow

  1. Webhook — Meta sends POST requests to /webhook (e.g. https://api.lokpanchang.com/webhook) for every user message and status update.
  2. Verification — GET /webhook with hub.mode=subscribe and hub.verify_token=<token> is used by Meta to verify the endpoint; the app responds with hub.challenge.
  3. Message handling — For each incoming message, the app deduplicates by message ID, then routes by type:
    • Text (e.g. “start”, “stop”, “help”) → create/update user, send reply or request location.
    • Location → resolve timezone and city (OpenCage + fallback), save to user, generate panchangam, send template message and confirmation.
  4. Panchangam — Generated in-process via generate_panchangam_with_timezone() (see Core Panchangam calculation), then formatted as WhatsApp template parameters and sent using messaging.send_panchangam_template() or similar.
  5. Daily sends — Celery Beat runs a JIT planner every 10 minutes; it enqueues send_for_timezone tasks so each user gets panchangam at 6:30 AM local time. Those tasks run in Celery workers and use the same panchangam generation and messaging code.
Meta webhook verification uses VERIFY_TOKEN = "test123" (defined in app.py). When configuring the webhook in the Meta developer app, set the verify token to this value.

Main modules and files

File / folderRole
app.pyFlask app: webhook routes (GET/POST /webhook), request logging, message deduplication, get_or_create_user, handle_location_message, handle_text_message, generate_panchangam_with_timezone, and many test/admin endpoints (e.g. /test-db, /test/whatsapp/*, /send-panchang-*).
messaging.pyWhatsApp API wrapper: send_whatsapp_message (text, respects ENV for mock), send_panchangam_template, send_whatsapp_template_message, send_location_request_message, template parameter builders. Uses WHATSAPP_PHONE_NUMBER_ID, WHATSAPP_ACCESS_TOKEN, and Meta Graph API URL.
tasks.pyCelery app, Beat schedule, and tasks: jit_planner, send_for_timezone, log backup, S3 upload, metrics, etc. Imports panchangam formatting and messaging from app and messaging.
db.pySingle SQLAlchemy instance (db) used across the app.
models/SQLAlchemy models: UserDetail, CityDetail, MessageLog, DailyMetrics, SystemHealthLog, ApiDetail, RituDetail, AyanamDetail, ApiUsageLog. Used by app.py, tasks.py, and the admin portal. See Database.
panchangam/Panchangam calculation (Swiss Ephemeris, tithi/nakshatra/yoga/karana, day divisions). app.py calls into panchangam.panchangam_main via generate_panchangam_with_timezone.
helpers/Geocoding (hybrid_geocoding.py, city_utils.py), timezone fallback, metrics, log collection, S3 upload, etc.

Webhook routes

  • GET /webhook — Meta subscription verification. Query params: hub.mode, hub.verify_token, hub.challenge. Returns hub.challenge with 200 if hub.verify_token == VERIFY_TOKEN; otherwise 403.
  • POST /webhook — Receives all WhatsApp events. Only entries with messages are processed; status updates are skipped. For each message, deduplication is applied, then:
    • type == "location"handle_location_message (timezone, city, save user, generate panchangam, send template + optional text).
    • type == "text"handle_text_message (“start” → request location; “stop”/“unsubscribe” → unsubscribe; “help” → help text; etc.).
    • Other types (e.g. image) → log and optionally ask for location if user is in awaiting_location.
All other routes in app.py are for health checks, testing, or admin (e.g. /test-db, /test/whatsapp/generate/<phone_number>, /send-panchang-user/<user_id>). The admin portal and test routes are documented in Admin portal and Testing routes.

Entrypoints

  • Web server — The Flask app runs as the main process in the web Docker service. Default command is flask run --host=0.0.0.0 --port=5050 (see root Dockerfile). In production, a WSGI server such as Gunicorn may be used behind Caddy.
  • Celery workercelery -A tasks.celery worker (see docker-compose.yml for the celery service).
  • Celery Beatcelery -A tasks.celery beat (see beat service). Schedules jit_planner and other periodic tasks.

Dependencies

  • Flask — Web framework.
  • Flask-SQLAlchemy, Flask-Migrate — Database and migrations.
  • Celery, Redis — Task queue and broker.
  • requests — HTTP calls to Meta Graph API (from messaging.py).
  • panchangam — Uses pyswisseph, astral, pytz, and other libs (see Core Panchangam calculation).
For a full list, see requirements.txt in the repo root.