
Caltext
iMessage calorie tracking assistant powered by AI.
Stack
- Runtime: Bun + Turborepo monorepo
- API: Hono on Nitro (deployed to Vercel, 3 regions)
- iMessage: Chat SDK + Sendblue adapter
- AI: AI SDK v6 + GPT-4.1 (vision + agent)
- Database: Upstash Redis (global, 3 regions)
- Workflows: Vercel Workflow SDK for durable pipelines
- Nutrition: USDA FoodData Central API
Setup
1. Install dependencies
bun install
2. Configure environment
cp .env.example .env
Fill in the required keys:
| Variable | Source |
|---|---|
SENDBLUE_API_KEY / SENDBLUE_API_SECRET | sendblue.co |
SENDBLUE_FROM_NUMBER | Your Sendblue phone number |
UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN | console.upstash.com |
REDIS_URL | Same Upstash Redis in redis:// format |
OPENAI_API_KEY | platform.openai.com |
USDA_API_KEY | fdc.nal.usda.gov (free) |
3. Run locally
bun run dev
4. Deploy to Vercel
vercel deploy
Deploys to 3 regions: US East (iad1), London (lhr1), Tokyo (hnd1).
5. Set Sendblue webhook
Point your Sendblue incoming message webhook to:
https://your-app.vercel.app/webhooks/sendblue
Project Structure
caltext/apps/api/ # Hono API serversrc/index.ts # Routes + webhook handlerbot.ts # Chat SDK singletonrouter.ts # Onboarding vs assistant routingworkflows/handle-message.ts # Main message handleronboarding.ts # Multi-step onboardingreminder-loop.ts # Daily reminders + summariespackages/ai/ # AI agent + toolsdb/ # Upstash Redis data layershared/ # Types, locale, timezone utils
How It Works
- User texts the Caltext number via iMessage
- Sendblue forwards the message via webhook
- New users go through conversational onboarding (name, stats, goal)
- Returning users interact with the AI assistant
- Photos are analyzed with GPT-4.1 vision, then grounded in USDA nutrition data
- Text descriptions are matched against USDA database directly
- Daily reminders at breakfast/lunch/dinner times (timezone-aware)
- End-of-day summaries with calorie/macro breakdown
- Weekly recaps with progress bars and trends


