J4H lets you log entries, get AI summaries, and focus on specific symptoms — all by phone call or text message, no app required. This explainer covers how it works, every word the voice says, the text commands, and how to customize it.
Twilio is a cloud communications platform. It gives developers a real phone number that can send and receive calls and text messages. Your code never touches a cell tower — Twilio handles all the carrier infrastructure and just calls your app's web endpoints when something arrives.
In J4H, one Twilio phone number does two things:
First register your number at /phone-setup. After that, just text naturally:
End your text with a number 1–10 and it's automatically saved as the pain level:
[SMS]. Voice entries are tagged [VOICE].
Both appear in the app alongside normal entries.
If the first word of your text is a command keyword, J4H handles it as a command instead of a diary entry. Commands are case-insensitive.
| Text this | What you get back |
|---|---|
| SUMMARY | AI summary of your last 30 days — general health focus |
| SUMMARY 7 | AI summary of the last 7 days (any number 1–365 works) |
| SUMMARY dentist | Summary tailored for a dentist appointment |
| SUMMARY neurologist | Summary focused on neurological symptoms |
| FOCUS knee | Focused summary on "knee" — searches 90 days of entries |
| FOCUS lower back pain | Focused summary on any topic or body part you name |
| HELP | Lists all commands + all available specialty names |
These keywords work after SUMMARY:
When someone calls the J4H Twilio number, they hear Polly.Joanna — Amazon Polly's neural text-to-speech voice. After logging an entry and pain level, callers can now press 1 to hear an AI summary read aloud.
APP_PASSCODE environment variable.[VOICE] entry.
Every word Joanna says is a Python string passed to resp.say().
There is no separate script file. Changing any line is a one-line edit in app.py
followed by a deploy.
| What Joanna says | Function in app.py |
|---|---|
| "Welcome to J4H Health Diary…" | voice_incoming() |
| "Hello [name]. Please describe your symptoms…" | voice_verify_pin() |
| "Entry saved. On a scale of 1 to 10…" | voice_save_entry() |
| "Pain level N recorded." / "Press 1 to hear a summary…" | voice_save_pain() |
| "Here is a summary of your recent health…" | voice_summary() |
| All error messages | All five functions |
Replace Polly.Joanna everywhere with any Amazon Polly voice:
Polly.Matthew — male, US EnglishPolly.Amy — female, British EnglishPolly.Brian — male, British EnglishPolly.Joanna — female, US English (current)"j4h dot org"
not "j4h.org", and write "slash phone dash setup" not
"/phone-setup" — otherwise Joanna will read the punctuation characters aloud.
| Item | Cost | Notes |
|---|---|---|
| Trial account | $0 (free credit) | Expires when credit runs out. Can only text/call verified numbers. |
| US local phone number | ~$1.15/month | Yours indefinitely while account is paid |
| Inbound SMS | $0.0075/message | Each text you receive |
| AI summary reply | ~$0.03 | ~4 SMS segments for a 2-paragraph summary |
| Inbound voice | ~$0.0085/min | Charged per minute |
| Speech transcription | ~$0.02/30 sec | Per voice entry recorded |
| Route | What it does |
|---|---|
POST /api/sms | Inbound text — commands (SUMMARY, FOCUS, HELP) or save diary entry |
POST /api/voice | Call entry point — check registration, ask for PIN |
POST /api/voice/verify-pin | Validate PIN, ask for spoken entry |
POST /api/voice/save-entry | Save transcribed speech, ask for pain level |
POST /api/voice/save-pain | Save pain level, offer summary option |
POST /api/voice/summary | Generate & read AI summary aloud if caller pressed 1 |
Both the SMS handler and the voice summary route use the same helper to fetch entries for a patient within a date window:
Every incoming call or text is validated with a cryptographic signature Twilio attaches to each request. J4H rejects anything that doesn't match:
| Variable | Where to get it | What it does |
|---|---|---|
TWILIO_AUTH_TOKEN | Twilio console → Account → Auth Token | Validates requests are genuinely from Twilio |
APP_PASSCODE | Set by you | PIN callers must enter to log an entry |
ANTHROPIC_API_KEY | Anthropic console | Required for SUMMARY/FOCUS/voice summary |
https://j4h.org/api/voice (HTTP POST)https://j4h.org/api/sms (HTTP POST)