public bool PersistIncommingTwillioMessage(string twilioMessageUrl) { NameValueCollection vals = HttpUtility.ParseQueryString(twilioMessageUrl); var twilioMessage = new TwilioMessageSM { From = vals["From"], Body = vals["body"], }; if (twilioMessage.Body == null) { _log.Warning("twilioMessage body is null, unable to process."); return false; } if (twilioMessage.From == null) { _log.Warning("twilioMessage From is null, unable to process."); return false; } var txt = new TxtMsgInbound { MobilePhone = twilioMessage.From, Message = twilioMessage.Body, State = TxtMsgProcessState.New, }; _txtMsgInboundDal.Insert(txt); return true; }
public IHttpActionResult SendSimulatedInboundMessage([FromBody] SimulatedInboundTxt simMsg) { var txt = new TxtMsgInbound { MobilePhone = simMsg.FromMobilePhone, Message = simMsg.Message }; _smsSimulatorRepository.InsertInbound(txt); return Ok(); }
private void ProcessInviteCommand(TxtMsgInbound msgInbound, AppUser user) { if (user.UserRole != UserRole.Parent) { //STEP - make sure user is a Parent, if not say only parents can invite sitters. _omm.SendFeedbackToInboundMessage(msgInbound, MessageTemplates.OnlyParentsCanSendSignupInvites(), user.Id); } else { _omm.SendFeedbackToInboundMessageAndAwait(msgInbound, "Ok, I'll invite someone to join your MySitters. What is their mobile number?", user.Id, InboundMessageType.SignupInvite); } }
public void ProcessNewConverastion(TxtMsgInbound msgInbound) { // STEP - Check if user is member AppUser user = _appUserDal.GetByMobile(msgInbound.MobilePhone); if (user == null) { if (msgInbound.Message == NewCommandType.signup.ToString()) { ProcessSignupCommand(msgInbound, null); return; } string msg = "To signup for mysitterhub.com, say 'signup' or go to the website"; _omm.SendFeedbackToInboundMessage(msgInbound, msg, AppUser.NotSignedUpUserId); return; } NewCommandType newCommand; Enum.TryParse(msgInbound.Message, out newCommand); switch (newCommand) { case NewCommandType.unrecognized: _omm.SendFeedbackToInboundMessage(msgInbound, "mysitterhub.com " + MessageTemplates.FormatValidCommands(user.UserRole), user.Id); break; case NewCommandType.job: ProcessPostJobCommand(msgInbound, user); break; case NewCommandType.help: ProcessHelpCommand(msgInbound, user); break; case NewCommandType.invite: ProcessInviteCommand(msgInbound, user); break; case NewCommandType.status: ProcessStatusCommand(msgInbound, user); break; case NewCommandType.signup: ProcessSignupCommand(msgInbound, user); break; default: throw new Exception("command not implimented: " + newCommand); } }
public void ProcessSelfSignupConversation_Step2(TxtMsgInbound msgInbound, TxtMsgAwaitingResponse awaiting, AppUser user) { }
public void ProcessPostJobConversation(TxtMsgInbound msgInbound, TxtMsgAwaitingResponse awaiting, AppUser parentUser) { string conversationContext; string msg; if (MessageUtility.IsCancelRequested(msgInbound)) { msg = "Ok, job posting cancelled"; _omm.SendFeedbackToInboundMessageAndDeleteAwaiting(msgInbound, msg, parentUser.Id, awaiting); } switch (msgInbound.InboundMessageType) { case InboundMessageType.PostJob_Step2_DayOfWeek: DayOfWeekMessage? dayOfWeek = MessageUtility.ParseDayOfWeek(msgInbound.Message); if (dayOfWeek == null) { msg = string.Format("Invalid day of week, post a job for which day: {0}? Or say 'cancel'", new NewCommandManager().DaysOfWeekStartingToday(parentUser)); _omm.SendFeedbackToInboundMessage(msgInbound, msg, parentUser.Id); } else { conversationContext = JsonSerializerHelper.Serialize(new PostJobViaTxtAnswers {DayOfWeek = dayOfWeek.Value}); msg = "What time?"; _omm.SendFeedbackToInboundMessageAndAwait(msgInbound, msg, parentUser.Id, InboundMessageType.PostJob_Step3_StartTime, awaiting, conversationContext); } break; case InboundMessageType.PostJob_Step3_StartTime: JobTimeSmall startHour = MessageUtility.ParseStartTime(msgInbound.Message, _log); if (startHour == null) { msg = string.Format("Please enter a valid job start time. Valid examples: 9am, 9pm, 12:30am, 10:00pm. What time?"); _omm.SendFeedbackToInboundMessage(msgInbound, msg, parentUser.Id); } else { var postJobAnswers = JsonSerializerHelper.DeSerialize<PostJobViaTxtAnswers>(awaiting.ConversationMemory); postJobAnswers.StartHour = startHour; conversationContext = JsonSerializerHelper.Serialize(postJobAnswers); #if OFF var sits = ListSittersForParent(msgInbound.UserId); if (sits == null) { msg = "Unable to post job because you do not have any sitters. Please invite babysitters to your MySitters."; //FutureDev: do this earlier _omm.SendFeedbackToInboundMessage(msgInbound, msg); _txtMsgAwaitingResponseDal.DeleteAwaiting(awaiting.Id); } else { newAwaitingType = InboundMessageType.PostJob_Step5_Confirm; msg = string.Format("Which sitters? {0}", sits); } #endif msg = MessageUtility.FormatJobConfirm(postJobAnswers, parentUser, _parentRepository); _omm.SendFeedbackToInboundMessageAndAwait(msgInbound, msg, parentUser.Id, InboundMessageType.PostJob_Step5_Confirm, awaiting, conversationContext); } break; #if OFF case InboundMessageType.PostJob_Step4_SelectSitters: int? sitterId = ParseSitterNum(msgInbound.Message, msgInbound.UserId); #endif case InboundMessageType.PostJob_Step5_Confirm: MessageAffirmativeType affirmative = MessageUtility.ParseAffirmativeType(msgInbound, true); if (affirmative == MessageAffirmativeType.yes) { var pa = JsonSerializerHelper.DeSerialize<PostJobViaTxtAnswers>(awaiting.ConversationMemory); var jobSM = new PostJobSM(); jobSM.DateTimeStartDte = MessageUtility.CalcJobStartTime(pa).AddHours(- parentUser.TimezoneOffset); // Convert to UTC jobSM.Duration = 3; // note, default to 3 jobSM.JobInvites = new List<JobInvite>(); List<ParentMySitterSM> psitters = _parentRepository.GetSittersForParent(parentUser.Id).Sitters; foreach (ParentMySitterSM s in psitters) { jobSM.JobInvites.Add(new JobInvite { SitterId = s.Id, InvitedDate = TimeUtil.GetCurrentUtcTime(), RatePerHour = s.Rate, State = InvitationState.InvitePending }); } jobSM.ParentId = parentUser.Id; _jobRepo.PostJob(jobSM); _omm.SendFeedbackToInboundMessageAndDeleteAwaiting(msgInbound, "Congrats! Job posted. You can view details at mysitterhub.com", parentUser.Id, awaiting); } else if (affirmative == MessageAffirmativeType.no) { _omm.SendFeedbackToInboundMessageAndDeleteAwaiting(msgInbound, "Ok, Job posting cancelled", parentUser.Id, awaiting); //note, this will only get hit when the user says "no". } else { _omm.SendFeedbackToInboundMessage(msgInbound, "Please say 'yes' to post job or 'cancel'", parentUser.Id); } break; default: throw new Exception("InboundMessageType not recognized in ProcessPostJobConversation. " + msgInbound.InboundMessageType); } }
public void ProcessSitterResonseToJobPosting(TxtMsgInbound msgInbound, TxtMsgAwaitingResponse awaiting, AppUser user) { string feedback = null; bool stillAwaiting = true; Job job = _jobRepo.GetById(awaiting.JobId); if (job == null) { string msgError = "Unable to find job with id " + awaiting.JobId; _log.Error(msgInbound.MobilePhone, msgError, null); _txtMsgInboundDal.UpdateState(msgInbound.Id, TxtMsgProcessState.Error, msgError); _txtMsgAwaitingResponseDal.DeleteAwaiting(awaiting.Id); return; } var response = new SitterJobInviteResponseSM { JobId = job.Id, SitterId = awaiting.WaitingForUserId, Message = msgInbound.Message }; MessageAffirmativeType aff = MessageUtility.ParseAffirmativeType(msgInbound); if (aff == MessageAffirmativeType.yes) { response.Response = SitterResponse.Accept; feedback = MessageTemplates.FormatSitterAcceptJob(); stillAwaiting = false; } else if (aff == MessageAffirmativeType.no) { response.Response = SitterResponse.Decline; feedback = MessageTemplates.FormatSitterDeclineJob("parent"); //TODO stillAwaiting = false; } else { response.Response = SitterResponse.Unrecognized; feedback = MessageTemplates.FormatSitterInvalidResponseToJobOrSignup(true); stillAwaiting = true; } _jobRepo.ProcessSitterResponse(response, job); _txtMsgInboundDal.UpdateState(msgInbound.Id, TxtMsgProcessState.Processed); if (feedback != null) { _omm.SendFeedbackToInboundMessage(msgInbound, feedback, user.Id); } if (!stillAwaiting) { _txtMsgAwaitingResponseDal.DeleteAwaiting(awaiting.Id); } if (aff == MessageAffirmativeType.yes && job != null) { try { // STEP - Send confirm to parent, and closed notice to other sitters _omm.SendNoticeOfSitterAccept(job); } catch (Exception ex) { _log.Error(job.ParentId.ToString(), "error while SendParentNoticeOfSitterAccept(). msgInbound.Id:" + msgInbound.Id, ex); throw; } } }
public void ProcessSelfSignupConversation_Step1(TxtMsgInbound msgInbound, TxtMsgAwaitingResponse awaiting, AppUser user) { bool deleteAwaiting = true; if (MessageUtility.IsCancelRequested(msgInbound)) { _omm.SendFeedbackToInboundMessage(msgInbound, "Ok, signup cancelled", user.Id); } else if (msgInbound.Message == "sitter" || msgInbound.Message == "parent" || msgInbound.Message == "babysitter") { bool isSitter = (msgInbound.Message == "sitter" || msgInbound.Message == "babysitter"); // STEP - Create new AppUser var newUser = new SignupInfo { User = new AppUser { FirstName = "New Self Signup", LastName = "", Email = "", MobilePhone = msgInbound.MobilePhone, UserRole = isSitter ? UserRole.Sitter : UserRole.Parent, }, Pass = GeneratePassForNewUser() }; if (isSitter) { newUser.SitterSignupInfo = new SitterSignupInfo {ParentEmail = "", ParentMobile = ""}; } SignupResult result = new SignupRepository().SaveNewSignup(newUser, false); if (result.IsSuccess) { _omm.SendFeedbackToInboundMessage(msgInbound, string.Format("Ok, you have signed up for mysitterhub.com, you can login at mysitterhub.com with your mobile number and password: {0}.", newUser.Pass), user.Id); //_omm.SendFeedbackToInboundMessage(msgInbound, string.Format("You can finish filling out your profile. What is your name? Or say 'cancel'.")); //_txtMsgAwaitingResponseDal.Insert(new TxtMsgAwaitingResponse(outboundTxtMsgId, 0, msgInbound.MobilePhone, InboundMessageType.SelfSignup_Step2_Name, 0)); //FutureDev } else { _omm.SendFeedbackToInboundMessage(msgInbound, string.Format("Error while signing up:" + result.Error), user.Id); new LogUtil().LogMessage("signup unsuccessful " + result.Error); deleteAwaiting = false; } } else { _omm.SendFeedbackToInboundMessage(msgInbound, string.Format("Invalid response, are you a 'parent' or a 'sitter'? Or say 'cancel' to quit the signup process."), user.Id); deleteAwaiting = false; } if (deleteAwaiting) _txtMsgAwaitingResponseDal.DeleteAwaiting(awaiting.Id); }
public void SendFeedbackToInboundMessageAndDeleteAwaiting(TxtMsgInbound msgInbound, string feedback, int senderId, TxtMsgAwaitingResponse previousAwaitingMsgToDelete) { SendFeedbackToInboundMessage(msgInbound, feedback, senderId); _txtMsgAwaitingResponseDal.DeleteAwaiting(previousAwaitingMsgToDelete.Id); }
public void ProcessSignupInviteConversation(TxtMsgInbound msgInbound, TxtMsgAwaitingResponse awaiting, AppUser user) { string mobileToInvite = PhoneUtil.CleanAndEnsureCountryCode(msgInbound.Message); if (MessageUtility.IsCancelRequested(msgInbound)) { _omm.SendFeedbackToInboundMessageAndDeleteAwaiting(msgInbound, string.Format("Ok, invitation cancelled."), user.Id, awaiting); return; } if (!PhoneUtil.IsValidPhoneNumber(mobileToInvite)) { _omm.SendFeedbackToInboundMessage(msgInbound, string.Format("'{0}' is not a valid mobile number to invite to signup for mysitterhub.com. Please enter 10 digit number. Or say 'cancel'.", msgInbound.Message), user.Id); return; } int parentId = awaiting.WaitingForUserId; AppUser parentUser = new AppUserDal().GetById(parentId); if (parentUser.UserRole != UserRole.Parent) { //STEP - make sure user is a Parent, if not say only parents can invite sitters. _omm.SendFeedbackToInboundMessage(msgInbound, MessageTemplates.OnlyParentsCanSendSignupInvites(), user.Id); } else { //STEP - confirm sending invite _omm.SendFeedbackToInboundMessage(msgInbound, "Sending invite to " + mobileToInvite, user.Id); var sitterInvite = new InviteToSignup {MobilePhone = mobileToInvite}; ServiceResult result = new ParentRepository().AddSitterInviteByMobile(parentId, sitterInvite); if (!result.IsSuccess) { _omm.SendFeedbackToInboundMessage(msgInbound, "Error while sending invite to " + mobileToInvite + " please try again.", user.Id); } } _txtMsgAwaitingResponseDal.DeleteAwaiting(awaiting.Id); }
public string SendFeedbackToInboundMessage(TxtMsgInbound msgInbound, string feedback, int senderId) { var txtFeedback = new TxtMsgOutbound { MobilePhone = msgInbound.MobilePhone, Message = feedback, OutboundMessageType = OutboundMessageType.Feeback, SenderId = senderId, MessageDate = TimeUtil.GetCurrentUtcTime() }; return _smsOutboundRepo.QueueSmsForSend(txtFeedback); }
private void ProcessStatusCommand(TxtMsgInbound msgInbound, AppUser user) { _omm.SendFeedbackToInboundMessage(msgInbound, "Ok, I'll list your jobs. Your open jobs are..", user.Id); //FutureDev: implement }
public void ProcessResponseToSignupInvite(TxtMsgInbound msgInbound, TxtMsgAwaitingResponse awaiting, AppUser user) { MessageAffirmativeType affirmativeType = MessageUtility.ParseAffirmativeType(msgInbound); string feedback = null; Parent parent = _parentRepository.GetById(awaiting.ParentId, true); if (parent == null) throw new Exception("Error while processing inbound message. Parent not found with ID" + awaiting.ParentId); // If user answers 'yes'. if (affirmativeType == MessageAffirmativeType.yes) { // If user already exists we simply add hib to parent's sitterhub. if (user != null) { if (user.UserRole == UserRole.Sitter) { // ..sure if this user is a sitter. AddSitterToParentMySitters(user.Id, parent, msgInbound.MobilePhone); feedback = MessageTemplates.FormatUserAddedToSitters(parent); } else { // Otherwise we cannot add user because he is not a sitter. feedback = MessageTemplates.FormatInvitedUserIsNotASitter(); } } // If user doesn't exist we need to create new one. else { // Create new (default) sitter profile. var newSitter = new SignupInfo { User = new AppUser { FirstName = "New Sitter", LastName = "", Email = "", MobilePhone = msgInbound.MobilePhone, UserRole = UserRole.Sitter, }, Pass = GeneratePassForNewUser() //FutureDev: text this password to sitter as their new temp password. }; newSitter.SitterSignupInfo = new SitterSignupInfo {ParentEmail = "", ParentMobile = ""}; SignupResult result = new SignupRepository().SaveNewSignup(newSitter, false, false); if (!result.IsSuccess) throw new Exception("Failed to create new profile for sitter during parent invite." + result.Error); // If there were no errors we can continue. // We need to add newly created user into parent's sitterhub. AddSitterToParentMySitters(result.NewId, parent, msgInbound.MobilePhone); // Send message about new account created and user successfully added to parent's hub. feedback = MessageTemplates.FormatUserAddedToSittersAndProfileCreated(parent, newSitter.Pass); } } // If user answered 'no'. else if (affirmativeType == MessageAffirmativeType.no) { // TODO: separate failure message. // We send message to sitter that we didn't added him to parent's hub. feedback = MessageTemplates.FormatDeclineInvitationToSitterhub(parent); _parentRepository.CancelInviteSitter(parent.Id, msgInbound.MobilePhone, true); } // If user's answer can't be parsed. else { feedback = MessageTemplates.FormatSitterInvalidResponseToJobOrSignup(false); } // Update state of message. _txtMsgInboundDal.UpdateState(msgInbound.Id, TxtMsgProcessState.Processed); // If sitter's answer was successfully parsed we can mark this message as processed. if (affirmativeType != MessageAffirmativeType.Unknown) { _txtMsgAwaitingResponseDal.DeleteAwaiting(awaiting.Id); } // TODO: where we send messages to parent? Seems like we can do it here. if (feedback != null) { _omm.SendFeedbackToInboundMessage(msgInbound, feedback, user.Id); } }
public void ProcessPostJobCommand(TxtMsgInbound msgInbound, AppUser parentUser) { if (parentUser.UserRole != UserRole.Parent) { string msg3 = string.Format(MessageTemplates.MySitterHubPefix() + " Sorry, only parents can post jobs."); _omm.SendFeedbackToInboundMessage(msgInbound, msg3, parentUser.Id); return; } int count = new ParentRepository().GetSitterCountForParent(parentUser.Id); if (count == 0) { string msg2 = string.Format(MessageTemplates.MySitterHubPefix() + " Sorry, you can't post a job until you have added sitters. Say 'invite' to invite sitters."); _omm.SendFeedbackToInboundMessage(msgInbound, msg2, parentUser.Id); return; } string msg = string.Format("I'll post a job for you. Which day: {0}?", DaysOfWeekStartingToday(parentUser)); _omm.SendFeedbackToInboundMessageAndAwait(msgInbound, msg, parentUser.Id, InboundMessageType.PostJob_Step2_DayOfWeek); }
private void ProcessSignupCommand(TxtMsgInbound msgInbound, AppUser user) { if (user != null) { _omm.SendFeedbackToInboundMessage(msgInbound, "You are already signed up for mysitterhub.com", user.Id); return; } string msg = MessageTemplates.MySitterHubPefix() + " OK, I'll sign you up for mysitterhub.com, the easiest way to hire a sitter. Would you like to signup as a parent or a sitter?"; _omm.SendFeedbackToInboundMessageAndAwait(msgInbound, msg, AppUser.NotSignedUpUserId, InboundMessageType.SelfSignup_Step1_ParentOrSitter); }
public string SendFeedbackToInboundMessageAndAwait(TxtMsgInbound inboundMsg, string feedback, int senderId, InboundMessageType inboundMessageType, TxtMsgAwaitingResponse previousAwaitingMsg = null, string conversationMemory = null) { string outboundTxtMsgId = SendFeedbackToInboundMessage(inboundMsg, feedback, senderId); var t = new TxtMsgAwaitingResponse(outboundTxtMsgId, senderId, inboundMsg.MobilePhone, inboundMessageType, previousAwaitingMsg == null ? 0 : previousAwaitingMsg.JobId, previousAwaitingMsg == null ? 0 : previousAwaitingMsg.ParentId) {ConversationMemory = conversationMemory}; _txtMsgAwaitingResponseDal.Insert(t); if (previousAwaitingMsg != null) { _txtMsgAwaitingResponseDal.DeleteAwaiting(previousAwaitingMsg.Id); } return outboundTxtMsgId; }
public void InsertInbound(TxtMsgInbound msg) { //TODO: validation _txtMsgInboundDal.Insert(msg); }
public void Insert(TxtMsgInbound msg) { msg.Id = ObjectId.GenerateNewId().ToString(); MongoCnn.GetTxtMsgInboundCollection().Insert(msg); }
private void ProcessHelpCommand(TxtMsgInbound msgInbound, AppUser user) { _omm.SendFeedbackToInboundMessage(msgInbound, "mysitterhub.com help. " + MessageTemplates.FormatValidCommands(user.UserRole), user.Id); }