private void ProcessScreeningResponse(PmsAppointment appt, SmsMessage msg) { // the patient should respond with "yes" or "no" but they may not bother and just respond with "arrived" // of course they might respond with anything else that we can't understand, so we'll explain apologetically if they do if (MessageMatches(msg.message, "yes", "y")) { // twilio: SmsMessage rmsg = new SmsMessage(msg.phone, TemplateProcessor.processTemplate(MessageTemplate.MSG_SCREENING_YES, appt, null)); SmsSender.SendMessage(rmsg); LogMsg(OUT, rmsg, "process screening response 'yes'", appt); if (IsDoingVideo) { // PMS: appt.IsVideoConsultation = true; if (VideoManager.AsksForVideoUrl()) { AppointmentUpdater.SaveAppointmentAsVideoMeeting(appt, null, null); } else { var details = VideoManager.getConferenceDetails(appt, false); AppointmentUpdater.SaveAppointmentAsVideoMeeting(appt, "Video URL: " + details, details); } } // local storage appt.ExternalData.ScreeningMessageResponse = true; if (IsDoingVideo) { appt.ExternalData.IsVideoConsultation = true; } else { appt.IsVideoConsultation = false; } Storage.SaveAppointmentStatus(appt); } else if (MessageMatches(msg.message, "no", "n")) { SmsMessage rmsg = new SmsMessage(msg.phone, TemplateProcessor.processTemplate(MessageTemplate.MSG_SCREENING_NO, appt, null)); SmsSender.SendMessage(rmsg); LogMsg(OUT, rmsg, "process screening response 'no'", appt); appt.ExternalData.ScreeningMessageResponse = true; appt.IsVideoConsultation = false; Storage.SaveAppointmentStatus(appt); } else if (MessageMatches(msg.message, "arrived", "here", "a")) { ProcessArrivalMessage(appt, msg); } else { // we haven't understood it SmsMessage rmsg = new SmsMessage(msg.phone, TemplateProcessor.processTemplate(MessageTemplate.MSG_DONT_UNDERSTAND_SCREENING, appt, null)); SmsSender.SendMessage(rmsg); LogMsg(OUT, rmsg, "fail to process screening response", appt); UnprocessableMessages.Add(msg); } }
/// <summary> /// This method is called every X seconds to process any changes to the appointments on the PMS side /// </summary> /// <param name="stored">The view of the appointments we already had (important, because it remembers what messages we already sent)</param> /// <param name="incoming">The current information from the PMS</param> public int ProcessTodaysAppointments(List <PmsAppointment> appointments) { // pseudo code // for each incoming appointment // is it new?- add it to the stored list // has the status changed from arrived to fulfilled? - send the invite message if it's not a TeleHealth consultation // if the appointment is within 3 hours, and the screening message hasn't been sent, send it // if the appointment is within 10 minutes a TeleHealth consultation, and the setup message hasn't been sent, send it int t = 0; foreach (var appt in appointments.Where(n => IsUseablePhoneNumber(n.PatientMobilePhone) && IsToday(n.AppointmentStartTime) && isNotIgnoreDoctor(n.PractitionerFhirID))) { try { if (appt.ExternalData.ArrivalStatus == AppointmentStatus.Arrived && appt.ArrivalStatus == AppointmentStatus.Fulfilled) { t++; Dictionary <string, string> vars = new Dictionary <string, string>(); vars.Add("room", FindRoomNote(appt.PractitionerFhirID)); SmsMessage msg = new SmsMessage(NormalisePhoneNumber(appt.PatientMobilePhone), TemplateProcessor.processTemplate(MessageTemplate.MSG_APPT_READY, appt, vars)); SmsSender.SendMessage(msg); LogMsg(OUT, msg, "invite patient to come in", appt); appt.ExternalData.ArrivalStatus = appt.ArrivalStatus; Storage.SaveAppointmentStatus(appt); } else if (appt.ArrivalStatus == AppointmentStatus.Booked && IsInTimeWindow(appt.AppointmentStartTime, MinutesBeforeScreening) && !appt.ExternalData.ScreeningMessageSent && !appt.IsVideoConsultation) { t++; SmsMessage msg; if (NoVideoForDoctor(appt.PractitionerFhirID)) { msg = new SmsMessage(NormalisePhoneNumber(appt.PatientMobilePhone), TemplateProcessor.processTemplate(MessageTemplate.MSG_SCREENING_NOVIDEO, appt, null)); // this one doesn't ask for a yes/no so we say that we have already received the appt response appt.ExternalData.ScreeningMessageResponse = true; } else { msg = new SmsMessage(NormalisePhoneNumber(appt.PatientMobilePhone), TemplateProcessor.processTemplate(MessageTemplate.MSG_SCREENING, appt, null)); } SmsSender.SendMessage(msg); LogMsg(OUT, msg, "send out screening message", appt); appt.ExternalData.ScreeningMessageSent = true; Storage.SaveAppointmentStatus(appt); } else if (appt.ArrivalStatus == AppointmentStatus.Booked && IsInTimeWindow(appt.AppointmentStartTime, MinutesBeforeScreening) && !appt.ExternalData.ScreeningMessageSent && appt.IsVideoConsultation) { //t++; // it was made as as telehealth consultation manually // twilio: if (IsDoingVideo) { SmsMessage rmsg = new SmsMessage(appt.PatientMobilePhone, TemplateProcessor.processTemplate(MessageTemplate.MSG_VIDEO_WELCOME, appt, null)); SmsSender.SendMessage(rmsg); LogMsg(OUT, rmsg, "start video sequence", appt); // PMS: appt.IsVideoConsultation = true; if (VideoManager.AsksForVideoUrl()) { AppointmentUpdater.SaveAppointmentAsVideoMeeting(appt, null, null); } else { var details = VideoManager.getConferenceDetails(appt, false); AppointmentUpdater.SaveAppointmentAsVideoMeeting(appt, "Video URL: " + details, details); } } // local storage appt.ExternalData.ScreeningMessageSent = true; appt.ExternalData.ScreeningMessageResponse = true; appt.ExternalData.IsVideoConsultation = true; Storage.SaveAppointmentStatus(appt); } else if (appt.ArrivalStatus == AppointmentStatus.Booked && (appt.IsVideoConsultation || appt.ExternalData.IsVideoConsultation) && IsInTimeWindow(appt.AppointmentStartTime, MinutesBeforeVideoInvite) && !appt.ExternalData.VideoInviteSent) { t++; Dictionary <string, string> vars = new Dictionary <string, string>(); var details = VideoManager.getConferenceDetails(appt, true); vars.Add("url", details); SmsMessage msg = new SmsMessage(NormalisePhoneNumber(appt.PatientMobilePhone), TemplateProcessor.processTemplate(MessageTemplate.MSG_VIDEO_INVITE, appt, vars)); SmsSender.SendMessage(msg); LogMsg(OUT, msg, "invite to video", appt); appt.ExternalData.VideoInviteSent = true; Storage.SaveAppointmentStatus(appt); } else if (appt.ArrivalStatus == AppointmentStatus.Booked && (appt.IsVideoConsultation || appt.ExternalData.IsVideoConsultation) && appt.ExternalData.VideoInviteSent && !String.IsNullOrEmpty(appt.ExternalData.VideoSessionId) && VideoManager.canKnowIfJoined()) { if (VideoManager.hasSomeoneJoined(appt.ExternalData.VideoSessionId)) { // PMS: appt.ArrivalStatus = AppointmentStatus.Arrived; AppointmentUpdater.SaveAppointmentStatusValue(appt); // Storage appt.ExternalData.ArrivalStatus = appt.ArrivalStatus; Storage.SaveAppointmentStatus(appt); } } } catch (Exception e) { Logger.Log(ERR, "Exception processing " + appt.AppointmentFhirID + ": " + e.Message); } } return(t); }