Overview
Total Users
β
Active Today
β
Active This Week
β
Flagged (>60 days)
β
| Child | Mobile | Calls | Last Seen | Days on Plan | Status | |
|---|---|---|---|---|---|---|
| Loading⦠| ||||||
Rows per page:
| Time (IST) | Mobile | muser_id | child_id | Child Name | Experience | Msg 1 | Status 1 | Reply 1 | Msg 2 | Status 2 | Reply 2 | 7d List | 3d List | Food Group | Days | No of Items | IP |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Loading⦠| |||||||||||||||||
Rows per page:
Grocery List Generator
Enter the user's mobile number β template and day range are calculated automatically.
Generated List
π
Enter a mobile number and click Generate
Generatingβ¦
| Mobile (10-digit) | muser_id | |
|---|---|---|
| Loading⦠| ||
π‘
Turn Mapping ON (header) β run the SQL in your Postgres client β paste the returned muser_id into User Mappings above (set 7083382423 β that ID) β text the trigger to live that exact flow.
| # | Experience | grocery_decision | experience_type | Postgres query (run in your DB client) |
|---|---|---|---|---|
| 1 | Mobile not in system | user_not_found | β | No mapping needed β remove your entry or use an unregistered number |
| 2 | No active template | change_plan | β |
SELECT m.muser_id, c.child_name FROM muser m JOIN child c ON c.child_id = m.sel_child_id WHERE m.plan_id != 4 AND (c.active_template_id IS NULL OR c.active_template_id = 0) LIMIT 1; |
| 3 | Not active in last 7 days | user_inactive_l7d | β |
SELECT m.muser_id, c.child_name
FROM muser m
JOIN child c ON c.child_id = m.sel_child_id
WHERE m.plan_id != 4
AND c.active_template_id IS NOT NULL
AND NOT EXISTS (
SELECT 1 FROM timelog t
WHERE t.child_id = m.sel_child_id
AND t.date_of_plan > NOW() - INTERVAL '7 days'
)
LIMIT 1;
|
| 4 | Standard β smooth flow | get_list | standard |
SELECT m.muser_id, c.child_name, c.ts_template_active
FROM muser m
JOIN child c ON c.child_id = m.sel_child_id
WHERE m.plan_id != 4
AND c.active_template_id IS NOT NULL
AND c.ts_template_active > NOW() - INTERVAL '40 days'
AND EXISTS (
SELECT 1 FROM timelog t
WHERE t.child_id = m.sel_child_id
AND t.date_of_plan > NOW() - INTERVAL '7 days'
)
LIMIT 1;
|
| 5 | Standard β old plan >40 days | full | old_plan |
SELECT m.muser_id, c.child_name, c.ts_template_active
FROM muser m
JOIN child c ON c.child_id = m.sel_child_id
WHERE m.plan_id != 4
AND c.active_template_id IS NOT NULL
AND c.ts_template_active < NOW() - INTERVAL '40 days'
AND EXISTS (
SELECT 1 FROM timelog t
WHERE t.child_id = m.sel_child_id
AND t.date_of_plan > NOW() - INTERVAL '7 days'
)
LIMIT 1;
|
| 6 | NourishPro β no dishes | support_only | β |
SELECT m.muser_id, c.child_name
FROM muser m
JOIN child c ON c.child_id = m.sel_child_id
WHERE m.plan_id = 4
AND NOT EXISTS (
SELECT 1 FROM timelog t
WHERE t.child_id = m.sel_child_id
AND t.date_of_plan BETWEEN NOW()::date + 1
AND NOW()::date + 7
AND t.flag_expert = true
AND t.deleted = false
)
LIMIT 1;
|
| 7 | NourishPro β full 7-day | get_list | npro_full |
SELECT m.muser_id, c.child_name,
MAX(t.date_of_plan) AS max_plan_date
FROM muser m
JOIN child c ON c.child_id = m.sel_child_id
JOIN timelog t ON t.child_id = m.sel_child_id
WHERE m.plan_id = 4
AND t.flag_expert = true
AND t.deleted = false
AND t.date_of_plan BETWEEN NOW()::date + 1
AND NOW()::date + 7
GROUP BY m.muser_id, c.child_name
HAVING MAX(t.date_of_plan) >= (NOW()::date + 7)
LIMIT 1;
|
| 8 | NourishPro β partial coverage | get_list | npro_partial |
SELECT m.muser_id, c.child_name,
MAX(t.date_of_plan) AS max_plan_date
FROM muser m
JOIN child c ON c.child_id = m.sel_child_id
JOIN timelog t ON t.child_id = m.sel_child_id
WHERE m.plan_id = 4
AND t.flag_expert = true
AND t.deleted = false
AND t.date_of_plan BETWEEN NOW()::date + 1
AND NOW()::date + 7
GROUP BY m.muser_id, c.child_name
HAVING MAX(t.date_of_plan) < (NOW()::date + 7)
LIMIT 1;
|
π‘
Messages are hardcoded in the worker (grocery.ts). To change any message, edit the file and run npx wrangler deploy.
Stage 1 β /grocery-text
| # | Condition | Plan | Message |
|---|---|---|---|
| 1 | Maintenance mode ON | All | HappyEaters Grocery List is temporarily unavailable due to maintenance. π οΈ HappyEaters Grocery List is temporarily unavailable due to maintenance. π οΈ Please try again in a little while. |
| 2 | Mobile not found in muser | All | We couldn't find a HappyEaters account linked to this WhatsApp number. We couldn't find a HappyEaters account linked to this WhatsApp number. Please click below to update your mobile number and try again. π https://happyeaters.in/redirections/user_settings |
| 3 | No active template assigned | Plan β 4 | No active meal plan found for {baby}. π± No active meal plan found for {baby}. π± Click below to get the best-suited meal plan assigned automatically: https://happyeaters.in/redirections/app?tab=1 Or Explore all meal plans suitable for your baby here: https://happyeaters.in/redirections/TEMPLATE_SEARCH?filter_view=false Choose the plan you're comfortable with and activate it. π |
| 4.* | Template activated >40 days ago β no longer blocked here. User gets the grocery list first (Stage 1 proceeds normally, button_type = full). A plan-switch nudge is sent as a follow-up via /grocery-nudge (see below). |
||
| 5 | No timelog in last 7 days user_inactive_l7d |
Plan β 4 | It looks like {baby}'s meal plan hasn't been refreshed in a while. π± It looks like {baby}'s meal plan hasn't been refreshed in a while. π± Please open the HappyEaters app to sync the latest plan: https://happyeaters.in/redirections/app?tab=1 Once done, send the trigger message again and your grocery list will be ready! π |
| 6.1 | No dishes at all in expert timelog for next 7 days | Plan 4 | We couldn't find any meals scheduled for {baby} right now. π We couldn't find any meals scheduled for {baby} right now. π Please contact HappyEaters Support and we'll help you get this sorted. https://api.whatsapp.com/send?phone=7899918510&text=Need%20help%20with%20grocery%20list |
| β 6.2 | Partial dish coverage β plan ends before 7-day window (generates list for available days) | Plan 4 | {baby}'s grocery list is ready. π± {baby}'s grocery list is ready. π± Your current plan covers the next {X} days through {Xth Month Year}. Book your next consult to continue, please ignore if already done. Tap below to receive the grocery list. β¬οΈ |
| 7 | Template not found in Redis | Plan β 4 | We're having trouble loading {baby}'s meal plan right now. π We're having trouble loading {baby}'s meal plan right now. π Please contact HappyEaters Support and we'll be happy to help. https://api.whatsapp.com/send?phone=7899918510&text=Need%20help%20with%20grocery%20list |
| 8 | No dish IDs found for day range | Plan β 4 | We couldn't find any meals scheduled for {baby} right now. π We couldn't find any meals scheduled for {baby} right now. π Please contact HappyEaters Support and we'll help you get this sorted. https://api.whatsapp.com/send?phone=7899918510&text=Need%20help%20with%20grocery%20list |
| 9 | Total grocery items = 0 after generation | All | We couldn't prepare a grocery list for {baby} right now. π We couldn't prepare a grocery list for {baby} right now. π Please contact HappyEaters Support and we'll be happy to help. https://api.whatsapp.com/send?phone=7899918510&text=Need%20help%20with%20grocery%20list |
| β | Generation successful | Plan β 4 | {baby} is on {meal_template_name}. π± {baby} is on {meal_template_name}. π± This is a {num_first_day_slots}-meal {North Indian/South Indian/Mixed} {pref} meal plan. π Your grocery list is ready. Tap below to receive it. β¬οΈ |
| β | Generation successful β full 7-day coverage | Plan 4 | {baby}'s grocery list is ready. π Tap below to receive it. β¬οΈ |
Stage 2 β /grocery-list
| # | Condition | Plan | Message |
|---|---|---|---|
| 1 | Mobile not found in muser | All | β Same as Stage 1 #2 |
| 2 | Cache hit β list found & start > today | All | π Cached grocery list returned immediately |
| 3 | Cache miss / stale β re-generation fails | All | {baby}'s grocery list is not ready yet. {baby}'s grocery list is not ready yet. Please send "Send me grocery list for next 7 days" first to generate it. |
| β | Cache miss / stale β re-generation succeeds | All | π Freshly generated grocery list returned |
Nudge β /grocery-nudge
Sent as a follow-up message after Stage 1 for users with
button_type = full (template active >40 days). Body: { "mobile": "XXXXXXXXXX" }
| # | Condition | Plan | Message |
|---|---|---|---|
| β | All users (no age split) | Plan β 4 | Just a heads up β {baby}'s been on his current plan for a while. π± If you'd like to explore what's new for his current age, we've got updated meal plans ready. Explore here: https://happyeaters.in/redirections/TEMPLATE_SEARCH?filter_view=false |
Filter β /grocery-filter
Called after user selects a food group and duration. Reads from the cached list generated by Stage 1. Body:
Group options:
Days options:
Returns the filtered, formatted grocery list as plain text. Both caches are generated together by Stage 1 (and Stage 2 re-generation).
{ "mobile": "...", "group": "veg_fruits|veg_fruits_dairy|all", "days": "3|7" }Group options:
veg_fruits β Vegetables + Fruits only Β· veg_fruits_dairy β Veg + Fruits + Dairy Β· all β All food groupsDays options:
7 (default, uses grocerylist:{child_id}) Β· 3 (uses grocerylist:{child_id}:3d)Returns the filtered, formatted grocery list as plain text. Both caches are generated together by Stage 1 (and Stage 2 re-generation).
| # | Condition | Response |
|---|---|---|
| 1 | Cache not found for requested day range | Your grocery list isn't ready yet. Please send the trigger message to generate it first. |
| β | Cache found β group = veg_fruits or veg_fruits_dairy |
π Filtered grocery list (only matching food groups, recounted total) |
| β | Cache found β group = all |
π Full unfiltered grocery list returned as-is |
| Worker URL | https://happyeaters-grocery-worker.vaibhav-334.workers.dev | |
| Dashboard URL | https://happyeaters-grocery-dashboard.pages.dev | |
| D1 Database | happyeaters-grocery (018badc7-323a-496a-8771-40b7e60448fc) | |
| KV Namespace | SETTINGS_KV (809fedcc88ad4844a2a4ff84257b5045) | |
| Postgres | 103.118.17.24:5432 β user: db_ro (read-only) | |
| Upstash Redis | faithful-piranha-123464.upstash.io |
| Activate / assign plan | https://happyeaters.in/redirections/app?tab=1 | |
| Browse meal plans | https://happyeaters.in/redirections/TEMPLATE_SEARCH?filter_view=false | |
| Update mobile number | https://happyeaters.in/redirections/user_settings | |
| Support WhatsApp | https://api.whatsapp.com/send?phone=7899918510&text=Need%20help%20with%20grocery%20list |
Campaign Manager
Users with expert timelog entries in a date range β download as CSV
| Name | User Type | From | To | Users | Created | |
|---|---|---|---|---|---|---|
| Loading⦠| ||||||