AI-powered grocery expiry tracker. Send a photo, voice note, or text via WhatsApp — Freshly tracks your groceries and notifies you before they go bad.
- Next.js 15 + Bun
- Groq — Whisper (voice), Llama Vision (receipts), Llama 70B (text)
- Supabase — Postgres DB
- Twilio — WhatsApp + SMS
- Vercel — hosting + cron jobs
Send any of these to your Twilio WhatsApp number:
| Message | What happens |
|---|---|
| Photo of receipt/groceries | AI extracts items and sets expiry dates |
| Voice note | Transcribed and parsed for items |
| "bought milk, eggs and spinach" | Items added with estimated shelf life |
| "what do I have?" | Lists all current items |
| "what's expiring soon?" | Shows items expiring within 3 days |
| "what dairy do I have?" | Filters by category |
| "milk is still fine, 3 more days" | Updates expiry date |
| "spinach has gone bad" | Marks item as expired |
| "remove milk from my list" | Deletes item |
| "clear everything" | Resets entire list |
| "help" | Shows all commands |
The app learns from your usage — if you consistently update an item's expiry to be shorter than the default estimate, it remembers and uses that as the baseline next time.
A daily cron runs at 9am IST and sends a WhatsApp notification for anything expiring within 2 days.
git clone https://github.com/yourusername/freshly.git
cd freshly
bun installcp .env.example .env.localFill in .env.local:
| Variable | Where to get it |
|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Supabase → Settings → API |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Supabase → Settings → API |
SUPABASE_SERVICE_ROLE_KEY |
Supabase → Settings → API → Reveal |
GROQ_API_KEY |
console.groq.com |
TWILIO_ACCOUNT_SID |
twilio.com/console |
TWILIO_AUTH_TOKEN |
twilio.com/console |
TWILIO_PHONE_NUMBER |
Your Twilio phone number (e.g. +1234567890) |
TWILIO_WHATSAPP_NUMBER |
whatsapp:+14155238886 (sandbox) |
CRON_SECRET |
Any random string |
Run supabase/schema.sql in your Supabase SQL editor.
- Go to Twilio Console → Messaging → Try it out → Send a WhatsApp message
- Send the join message from your phone to connect to the sandbox
- In Sandbox Settings, set the webhook URL to
https://your-app.vercel.app/api/webhook/whatsapp
bun devFor local webhook testing, expose port 3000 with ngrok:
ngrok http 3000Then update the Twilio webhook URL to your ngrok URL.
Push to GitHub and import the project on Vercel. Add all env variables under Settings → Environment Variables. The cron job auto-registers from vercel.json and runs daily at 9am IST.
| Method | Route | Description |
|---|---|---|
| POST | /api/auth/send-otp |
Send OTP to phone |
| POST | /api/auth/verify-otp |
Verify OTP, set session |
| GET | /api/items |
Get all active items |
| POST | /api/items |
Add/update items (text, image, audio) |
| POST | /api/webhook/whatsapp |
Twilio inbound webhook |
| GET | /api/cron/notify |
Daily expiry notifications |
src/
├── app/
│ └── api/
│ ├── auth/
│ │ ├── send-otp/
│ │ └── verify-otp/
│ ├── items/
│ ├── cron/notify/
│ └── webhook/whatsapp/
├── lib/
│ ├── groq/client.ts
│ ├── supabase/
│ │ ├── client.ts
│ │ └── shelf-life.ts
│ └── twilio/client.ts
└── types/index.ts