feat: reschedule-by-office batch SMS, AI follow-up toggle, date-shortcut fix, combined flow diagram
- Add Reschedule for Column button on schedule page with AI follow-up toggle (default on)
- Add POST /api/twilio/send-reschedule-batch — sends Reschedule by Office template, starts AI reschedule conversation per patient
- Add {officePhone} (office call-in number) and {twilioPhone} (SMS number) variable replacement in both batch endpoints
- Fix broken variable names in Reschedule by Office template ({office phone number) → {officePhone}, {Twilio phone number} → {twilioPhone})
- Fix reschedule-graph: when patient replies with date in same message as YES/NO (e.g. "ok, 5/18"), AI now checks day open and asks for time instead of asking "what day and time?"
- Fix twilio-webhooks: same date-shortcut logic for reminder flow — "no, 5/18" skips "when to reschedule?" and goes straight to day check
- Update LangGraph SVG: rename to Reminder & Reschedule Flow, combine both entry points (Reminder SMS + Reschedule SMS) into one diagram with date-shortcut annotations
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -293,6 +293,20 @@ router.post("/webhook/sms", async (req: Request, res: Response): Promise<any> =>
|
||||
await saveOutbound(patient.id, introText);
|
||||
}
|
||||
|
||||
// If patient said "no" but already included a date (e.g. "no, 5/18"),
|
||||
// skip "when to reschedule?" and go straight to date processing
|
||||
if (intent === "no") {
|
||||
const hasDateInMessage =
|
||||
/\b\d{1,2}[\/\-]\d{1,2}\b/.test(Body) ||
|
||||
/\b(monday|tuesday|wednesday|thursday|friday|saturday|sunday|tomorrow|next week)\b/i.test(Body);
|
||||
if (hasDateInMessage) {
|
||||
const { reply: rescheduleReply, nextStage: rescheduleNextStage } = await runRescheduleStep(
|
||||
Body, "asked_reschedule_datetime", language, patient.id, aiSettings.apiKey, patient.userId
|
||||
);
|
||||
return reply(rescheduleReply, rescheduleNextStage);
|
||||
}
|
||||
}
|
||||
|
||||
// Send message 2 (yes/no response) via TwiML — queued SECOND
|
||||
return reply(intentReply, nextStage);
|
||||
}
|
||||
@@ -313,6 +327,20 @@ router.post("/webhook/sms", async (req: Request, res: Response): Promise<any> =>
|
||||
if (intent === "no") nextStage = "asked_reschedule_datetime";
|
||||
else if (intent === "wants_appointment") nextStage = "asked_new_or_existing";
|
||||
else nextStage = "done";
|
||||
|
||||
// If patient said "no" but already included a date, skip straight to date processing
|
||||
if (intent === "no") {
|
||||
const hasDateInMessage =
|
||||
/\b\d{1,2}[\/\-]\d{1,2}\b/.test(Body) ||
|
||||
/\b(monday|tuesday|wednesday|thursday|friday|saturday|sunday|tomorrow|next week)\b/i.test(Body);
|
||||
if (hasDateInMessage) {
|
||||
const { reply: rescheduleReply, nextStage: rescheduleNextStage } = await runRescheduleStep(
|
||||
Body, "asked_reschedule_datetime", language, patient.id, aiSettings.apiKey, patient.userId
|
||||
);
|
||||
return reply(rescheduleReply, rescheduleNextStage);
|
||||
}
|
||||
}
|
||||
|
||||
return reply(aiReply, nextStage);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user