Exemplo n.º 1
0
 private void ProcessArrivalMessage(PmsAppointment appt, SmsMessage msg)
 {
     if (MessageMatches(msg.message, "arrived", "here", "a"))
     {
         // twilio:
         SmsMessage rmsg = new SmsMessage(msg.phone, TemplateProcessor.processTemplate(MessageTemplate.MSG_ARRIVED_THX, appt, null));
         SmsSender.SendMessage(rmsg);
         LogMsg(OUT, rmsg, "process arrival message", appt);
         // PMS:
         appt.ArrivalStatus = AppointmentStatus.Arrived;
         AppointmentUpdater.SaveAppointmentStatusValue(appt);
         // local storage
         appt.ExternalData.ScreeningMessageResponse = true;
         appt.ExternalData.ArrivalStatus            = AppointmentStatus.Arrived;
         Storage.SaveAppointmentStatus(appt);
     }
     else
     {
         // we haven't understood it
         SmsMessage rmsg = new SmsMessage(msg.phone, TemplateProcessor.processTemplate(MessageTemplate.MSG_DONT_UNDERSTAND_ARRIVING, appt, null));
         SmsSender.SendMessage(rmsg);
         LogMsg(OUT, rmsg, "fail to process arrival message", appt);
         UnprocessableMessages.Add(msg);
     }
 }
Exemplo n.º 2
0
        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);
            }
        }
Exemplo n.º 3
0
 private void ProcessVideoInviteResponse(PmsAppointment appt, SmsMessage msg)
 {
     if (MessageMatches(msg.message, "joined", "ok", "j"))
     {
         // twilio:
         SmsMessage rmsg = new SmsMessage(msg.phone, TemplateProcessor.processTemplate(MessageTemplate.MSG_VIDEO_THX, appt, null));
         SmsSender.SendMessage(rmsg);
         LogMsg(OUT, rmsg, "accept video response", appt);
         // PMS:
         appt.ArrivalStatus = AppointmentStatus.Arrived;
         AppointmentUpdater.SaveAppointmentStatusValue(appt);
         // local storage:
         appt.ExternalData.ArrivalStatus = appt.ArrivalStatus;
         Storage.SaveAppointmentStatus(appt);
     }
     else
     {
         // we haven't understood it
         SmsMessage rmsg = new SmsMessage(msg.phone, TemplateProcessor.processTemplate(MessageTemplate.MSG_DONT_UNDERSTAND_VIDEO, appt, null));
         SmsSender.SendMessage(rmsg);
         LogMsg(OUT, rmsg, "fail to process video response", appt);
         UnprocessableMessages.Add(msg);
     }
 }
Exemplo n.º 4
0
        /// <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);
        }
Exemplo n.º 5
0
        /// <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)))
            {
                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, 180) && !appt.ExternalData.ScreeningMessageSent)
                    {
                        t++;
                        SmsMessage 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 && (appt.IsVideoConsultation || appt.ExternalData.IsVideoConsultation) && IsInTimeWindow(appt.AppointmentStartTime, VideoManager.getNotificationMinutes()) && !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);
        }