def ProviderIVR_LeaveMsg_Action(request): """ Step 2 of ProviderIVR_LeaveMsg_New - we get called back from getRecording process based on ivr2_state. We save the message recorded and continue TODO: if caller is a provider, we want to be able to hit the # key to go back to his voice mailbox """ provider = Provider.objects.get(id=request.session['provider_id']) logger.debug( '%s: ProviderIVR_LeaveMsg_Action provider %s state %s POST data %s' % (request.session.session_key, provider, request.session.get('ivr2_state', 'None'), str(request.POST))) callEnded = _checkCallbackDuration(request, False) if ('ivr2_Record_recording' in request.session): # if caller is provider, we mask the callbacknumber; otherwise, show it in message provider_qs = Provider.objects.filter( mobile_phone=request.session['Caller']) if (provider_qs): request.session['ivr2_Record_callbacknumber'] = provider_qs[ 0].mdcom_phone subject = "Voice Mail from %s %s" % (provider_qs[0].first_name, provider_qs[0].last_name) else: request.session['ivr2_Record_callbacknumber'] = request.session[ 'Caller'] subject = "Voice Mail from %s" % request.session[ 'ivr2_Record_callbacknumber'] # set up for save_message request.session['ivr_makeRecording_recording'] = request.session[ 'ivr2_Record_recording'] if ('ivr2_Record_callbacknumber' in request.session): request.session[ 'ivr_makeRecording_callbacknumber'] = request.session[ 'ivr2_Record_callbacknumber'] del request.session['ivr2_Record_callbacknumber'] logger.debug( '%s: ProviderIVR_LeaveMsg_Action recording url: %s callback %s' % (request.session.session_key, request.session['ivr_makeRecording_recording'], request.session['ivr_makeRecording_callbacknumber'])) else: logger.debug('%s: ProviderIVR_LeaveMsg_Action recording url: %s ' % (request.session.session_key, request.session['ivr_makeRecording_recording'])) _copyStateVariables(request) save_message(request, subject, [provider.user], None, "VM", False) del request.session['ivr2_Record_recording'] r = twilio.Response() r.append(tts('Good bye')) r.append(twilio.Hangup()) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) else: # no recording? user might have hung up logger.debug( '%s: ProviderIVR_LeaveMsg_Action is called with no recording for provider %s' % (request.session.session_key, request.session['provider_id'])) r = twilio.Response() return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def PracticeIVR_LeaveRegularMsg_New(request): """ 3 steps: 1. get callback number 2. get message (recording) from caller 3. Sends office manager text message, in attachment there is voice file of recording """ callEnded = _checkCallbackDuration(request, False) # if someone hangs up, we still want to keep processing logger.debug('%s: PracticeIVR_LeaveRegularMsg_New state %s' % (request.session.session_key, request.session['ivr2_state'])) if ('ivr2_sub_state' not in request.session): # first time around request.session['ivr2_sub_state'] = 'PracticeIVR_LeaveRegularMsg_Start' else: logger.debug('%s: PracticeIVR_LeaveRegularMsg_New sub_state %s' % (request.session.session_key, request.session['ivr2_sub_state'])) # we have recording, or callback number or we are in the GetMsg sub_state if ('ivr2_Record_recording' in request.session or ('ivr2_only_callbacknumber' in request.session and request.session['ivr2_only_callbacknumber'] == True) or request.session['ivr2_sub_state'] == 'PracticeIVR_LeaveRegularMsg_GetMsg'): # final or third iteration - get and send message del request.session['ivr2_sub_state'] # get a list of all office managers for this practice mgrs = get_all_practice_managers(request.session['practice_id']) # after unique'ifying save_answering_service_message() expects recips # as a list, see https://redmine.mdcom.com/issues/1374 for details _copyStateVariables(request) save_answering_service_message(request, False, list(set(m.user for m in mgrs))) r = twilio.Response() r.append(tts(_('Your message have been sent. Good Buy'))) r.append(twilio.Hangup()) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) if (request.session['ivr2_sub_state'] == 'PracticeIVR_LeaveRegularMsg_Start'): # first iteration, getCallBackNumber request.session['ivr2_sub_state'] = 'PracticeIVR_LeaveRegularMsg_GetCallback' request.session['ivr2_returnOnHangup'] = \ 'MHLogin.DoctorCom.IVR.views_practice_v2.PracticeIVR_LeaveRegularMsg_New' return getCallBackNumberNew(request) elif request.session['ivr2_sub_state'] == 'PracticeIVR_LeaveRegularMsg_GetCallback': # second iteration, get Message recording request.session['ivr2_sub_state'] = 'PracticeIVR_LeaveRegularMsg_GetMsg' request.session['ivr2_Record_maxLength'] = 600 # 10 minutes request.session['ivr2_Record_leadSilence'] = 2 request.session['ivr2_Record_promptOnce'] = True request.session['ivr2_Record_prompt_str'] = 'Please say your \ non urgent message after the beep. Please state your name and \ speak clearly. Press pound when finished.' request.session['ivr2_returnOnHangup'] = \ 'MHLogin.DoctorCom.IVR.views_practice_v2.PracticeIVR_LeaveRegularMsg_New' request.session.modified = True # Pass off the recording action to the getRecording function. return getQuickRecordingNew(request) else: # should never get here with unknown state logger.info('%s: PracticeIVR_LeaveRegularMsg_New called with state %s' % ( request.session.session_key, request.session['ivr2_state'])) request.session['ivr2_state'] = 'PracticeIVR_LeaveRegularMsg_New' return PracticeIVR_LeaveRegularMsg_New(request)
def ProviderIVR_Status(request): """ callback for call status at the end of call first we need to check if there are unhandled state we need to wrap up then we get the call back duration and fill the call log """ logger.debug('%s: ProviderIVR_Status POST data is %s' % (request.session.session_key, str(request.POST))) # state = request.session.get('ivr2_state', 'None') # logger.debug('%s: ProviderIVR_Status state is %s' % # (request.session.session_key, state)) # wrap up if user was in the process of leaving a msg return _checkCallbackDuration(request, returnflag=True)
def PracticeIVR_Status(request): """ callback for call status at the end of call first we need to check if there are unhandled state we need to wrap up (mainly from getting recording) then we get the call back duration and fill the call log """ state = request.session.get('ivr2_state', 'None') logger.debug('%s: PracticeIVR_Status POST %s state is %s' % (request.session.session_key, str(request.POST), state)) # if state == 'PracticeIVR_LeaveRegularMsg_New': # return PracticeIVR_LeaveRegularMsg_New(request) # elif state == 'PracticeIVR_LeaveUrgentMsg_New': # return PracticeIVR_LeaveUrgentMsg_New(request) # else: return _checkCallbackDuration(request)
def ProviderIVR_LeaveMsg_Action(request): """ Step 2 of ProviderIVR_LeaveMsg_New - we get called back from getRecording process based on ivr2_state. We save the message recorded and continue TODO: if caller is a provider, we want to be able to hit the # key to go back to his voice mailbox """ provider = Provider.objects.get(id=request.session['provider_id']) logger.debug('%s: ProviderIVR_LeaveMsg_Action provider %s state %s POST data %s' % ( request.session.session_key, provider, request.session.get('ivr2_state', 'None'), str(request.POST))) callEnded = _checkCallbackDuration(request, False) if ('ivr2_Record_recording' in request.session): # if caller is provider, we mask the callbacknumber; otherwise, show it in message provider_qs = Provider.objects.filter(mobile_phone=request.session['Caller']) if(provider_qs): request.session['ivr2_Record_callbacknumber'] = provider_qs[0].mdcom_phone subject = "Voice Mail from %s %s" % (provider_qs[0].first_name, provider_qs[0].last_name) else: request.session['ivr2_Record_callbacknumber'] = request.session['Caller'] subject = "Voice Mail from %s" % request.session['ivr2_Record_callbacknumber'] # set up for save_message request.session['ivr_makeRecording_recording'] = request.session['ivr2_Record_recording'] if ('ivr2_Record_callbacknumber' in request.session): request.session['ivr_makeRecording_callbacknumber'] = request.session['ivr2_Record_callbacknumber'] del request.session['ivr2_Record_callbacknumber'] logger.debug('%s: ProviderIVR_LeaveMsg_Action recording url: %s callback %s' % ( request.session.session_key, request.session['ivr_makeRecording_recording'], request.session['ivr_makeRecording_callbacknumber'])) else: logger.debug('%s: ProviderIVR_LeaveMsg_Action recording url: %s ' % ( request.session.session_key, request.session['ivr_makeRecording_recording'])) _copyStateVariables(request) save_message(request, subject, [provider.user], None, "VM", False) del request.session['ivr2_Record_recording'] r = twilio.Response() r.append(tts('Good bye')) r.append(twilio.Hangup()) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) else: # no recording? user might have hung up logger.debug('%s: ProviderIVR_LeaveMsg_Action is called with no recording for provider %s' % ( request.session.session_key, request.session['provider_id'])) r = twilio.Response() return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def ProviderIVR_Main_New(request): """ initial call into provider -- Only called with new Twilio 2010 API initializes caller, called, provider_id, callLog and mask caller number with doctorcom Number if caller has a doctorcom number I leave the numbers with + and country code but strip them off the number of caller/called when we lookup the database for provider or mhluser """ if (not 'ivr2_state' in request.session): # beginning of the very first call request.session['ivr2_state'] = 'ProviderIVR_Main_New' logger.debug('%s: ProviderIVR_Main_New is initiated' % (request.session.session_key)) elif (request.session['ivr2_state'] and (request.session['ivr2_state'] != 'ProviderIVR_Main_New') and (request.session['ivr2_state'] != 'ProviderIVR_TreeRoot_New')): # this shouldn't happen, but if it did, and we log and keep going if (not 'provider_id' in request.session): logger.debug('%s: ProviderIVR_Main_New is called with state already set to %s, prov.id is null' % ( request.session.session_key, request.session['ivr2_state'])) else: logger.debug('%s: ProviderIVR_Main_New is called with state already set to %s, prov.id %s' % ( request.session.session_key, request.session['ivr2_state'], request.session['provider_id'])) request.session['ivr2_state'] = 'ProviderIVR_Main_New' logger.debug('%s: ProviderIVR_Main_New POST data is %s' % (request.session.session_key, str(request.POST))) # logger.debug('%s: ProviderIVR_Main_New META data is %s' % (request.session.session_key, str(request.META))) # check if this is the callback when call is completed (should redirect to ProviderIVR_Status) callEnded = _checkCallbackDuration(request) if callEnded: # we are done return callEnded # main functionality of this call (caller, called) = _setup_Main_callers(request) # set up provider_id in session provider_called = _getUniqueProvider(called) request.session['provider_id'] = provider_called.id # if caller has a doctorcom number, mask it caller_mhluser = _getMHLUser(caller) caller_provider = _maskProviderCaller(request, caller_mhluser) # set up callLog if none is defined: callSID = request.POST['CallSid'] log = _getOrCreateCallLog(request, callSID, caller, called, 'OC', provider_called, caller_mhluser) if caller_provider: log.mdcom_caller = caller_provider log.save() logger.debug('%s: ProviderIVR_Main_New caller %s called %s callSid %s prov mobile %s' % ( request.session.session_key, caller, called, callSID, provider_called.user.mobile_phone)) if provider_called.user.mobile_phone != caller: request.session['ivr2_state'] = 'ProviderIVR_ForwardCall_New' logger.debug('%s: ProviderIVR_Main_New forwarding caller %s called %s called mobile %s' % ( request.session.session_key, caller, called, provider_called.user.mobile_phone)) return ProviderIVR_ForwardCall_New(request, provider_called) # otherwise, this is owner calling in log.call_source = 'VM' log.save() # check if VM config is all set up - if not, we go to ProviderIVR_Setup try: config = provider_called.vm_config.get() except MultipleObjectsReturned: raise Exception("Provider %s %s has multiple vm_config objects." % ( provider_called.user.first_name, provider_called.user.last_name)) except ObjectDoesNotExist: request.session['ivr2_state'] = 'ProviderIVR_Setup_New' return ProviderIVR_Setup_New(request) # Check to see if the PIN value exists in the configuration. Pin *should* be set through the web interface # or it won't be able to be set/changed as anonymous user if (not config.pin): logger.debug('%s: ProviderIVR_Main_New config pin not set - provider %s' % ( request.session.session_key, provider_called.user.mobile_phone)) request.session['ivr2_state'] = 'ProviderIVR_Setup_New' request.session.modified = True return ProviderIVR_Setup_New(request) request.session['config_id'] = config.id if (not 'authenticated' in request.session): logger.debug('%s: ProviderIVR_Main_New authenticating - provider %s' % ( request.session.session_key, provider_called.user.mobile_phone)) request.session['ivr2_state'] = 'ProviderIVR_Main_New' request.session.modified = True r = twilio.Response() return authenticateSessionNew(request, r) # Now, check to ensure that user voicemail configuration was completed successfully. if (not config.config_complete): logger.debug('%s: ProviderIVR_Main_New config incomplete - provider %s' % ( request.session.session_key, provider_called.user.mobile_phone)) request.session['ivr2_state'] = 'ProviderIVR_Setup_New' return ProviderIVR_Setup_New(request, provider_called) # everything else goes to main call tree request.session['ivr2_state'] = 'ProviderIVR_TreeRoot_New' return ProviderIVR_TreeRoot_New(request, provider_called)
def ProviderIVR_ForwardCall_New(request, provider=None, twilioResponse=None): """ new version of ProviderIVR_ForwardCall - forward call to dialed user as per user preference called by ProviderIVR_Main_New Steps: 1. get name 2. Dial - based on provider.forward_voicemail state to Mobile, office, other (VM already handled) 3. After dialed: handle failure by going to LeaveMsg or hangup? """ assert(request.session['provider_id']) provider = Provider.objects.get(id=request.session['provider_id']) logger.debug('%s: ProviderIVR_ForwardCall_New is initiated provider %s state %s substate %s POST %s' % ( request.session.session_key, provider, request.session.get('ivr2_state', None), request.session.get('ivr2_sub_state', None), str(request.POST))) callEnded = _checkCallbackDuration(request, False) # check user forwarding preference forward = provider.forward_voicemail if (forward == 'VM'): # go to voicemail request.session['ivr2_state'] = 'ProviderIVR_LeaveMsg_New' logger.debug('%s: ProviderIVR_ForwardCall_New forwarding to voicemail of %s' % ( request.session.session_key, provider)) return ProviderIVR_LeaveMsg_New(request) # State processing - 1. get caller name or ask for it r = twilioResponse or twilio.Response() if ('ivr2_sub_state' not in request.session): request.session['ivr2_sub_state'] = 'ProviderIVR_ForwardCall_Start' else: logger.debug('%s: ProviderIVR_ForwardCall_New sub_state %s' % ( request.session.session_key, request.session['ivr2_sub_state'])) if (request.session['ivr2_sub_state'] == 'ProviderIVR_ForwardCall_Start'): request.session['ivr2_sub_state'] = 'ProviderIVR_ForwardCall_GetName' # is this a doctorcom user with recorded name? callSID = request.POST['CallSid'] log = callLog.objects.get(callSID=callSID) if (log.mdcom_caller and isinstance(log.mdcom_caller, Provider)): if (log.mdcom_caller.vm_config.count()): prov_vmconfig = log.mdcom_caller.vm_config.get() if (prov_vmconfig.config_complete): logger.debug('%s/%s: Found the caller\'s name!' % ( request.session.session_key, request.session['ivr2_state'], )) log.caller_spoken_name = prov_vmconfig.name log.save() # got the recorded name; just go back to the next step - Dial return ProviderIVR_ForwardCall_New(request, provider, r) # next step else: logger.debug('%s/%s: ProviderIVR_ForwardCall_New GetName: Caller\'s ' 'vm_config incomplete!' % (request.session.session_key, request.session['ivr2_state'])) else: logger.debug('%s/%s: ProviderIVR_ForwardCall_New GetName: unsuitable ' 'number of vm_config objects found: %i' % (request.session.session_key, request.session['ivr2_state'], log.mdcom_caller.vm_config.count())) else: logger.debug('%s/%s: ProviderIVR_ForwardCall_New GetName: mdcom_caller %s ' 'either isn\'t defined or doesn\'t seem to be a Provider' % (request.session.session_key, request.session['ivr2_state'], str(log.mdcom_caller))) # Not a user with a name recording. Get one. # ivr2_state already set to ProviderIVR_ForwardCall_GetName request.session['ivr2_Record_prompt_str'] = 'Please say your name after the tone.' request.session['ivr2_Record_maxLength'] = 4 request.session['ivr2_Record_timeout'] = 2 request.session['ivr2_Record_leadSilence'] = 1 return getQuickRecordingNew(request) elif (request.session['ivr2_sub_state'] == 'ProviderIVR_ForwardCall_GetName'): request.session['ivr2_sub_state'] = 'ProviderIVR_ForwardCall_Dial' # save the caller name callSID = request.POST['CallSid'] log = callLog.objects.get(callSID=callSID) if (not log.caller_spoken_name): log.caller_spoken_name = request.session['ivr2_Record_recording'] del request.session['ivr2_Record_recording'] log.save() # Okay, let's find number to dial! user_number = None if (forward == 'MO'): user_number = provider.user.mobile_phone elif (forward == 'OF'): user_number = provider.office_phone elif (forward == 'OT'): user_number = provider.user.phone logger.debug('%s/%s: ProviderIVR_ForwardCall_New Dial user number is \'%s\' forward %s' % ( request.session.session_key, request.session['ivr2_state'], user_number, forward)) if (not user_number): # no flags were set. if (provider.user.mobile_phone): user_number = provider.user.mobile_phone else: return ProviderIVR_LeaveMsg_New(request, r) # when dial action is done, we go back to its actionurl - which is here with state Dial dial = twilio.Dial( action=reverse('ProviderIVR_ForwardCall_New'), timeout=22, timeLimit=14400, # 4 hours callerId=_makeUSNumber(request.session['Caller']) ) # we also want to allow call vetting dial.append(twilio.Number(user_number, url=reverse('ProviderIVR_ForwardCall_Vet'))) r.append(dial) # If the call did not connect, we go to LeaveMsg r.append(twilio.Redirect(reverse('ProviderIVR_LeaveMsg_New'))) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) elif (request.session['ivr2_sub_state'] == 'ProviderIVR_ForwardCall_Dial'): # done with forward call del request.session['ivr2_sub_state'] # need to get parent call log for caller and connected; also update child log for duration (log, plog) = _getCallLogOrParent(request) if log: logger.debug('%s/%s: ProviderIVR_ForwardCall_New state connected %s' % ( request.session.session_key, request.session['ivr2_state'], str(log.call_connected))) else: logger.debug('%s/%s: ProviderIVR_ForwardCall_New state no log SID %s' % ( request.session.session_key, request.session['ivr2_state'], request.POST['CallSid'])) if ('DialCallStatus' in request.POST): if (request.POST['DialCallStatus'] == 'completed'): # update child log call duration diallog = callLog.objects.get(callSID=request.POST['DialCallSid']) if diallog: diallog.call_duration = request.POST['DialCallDuration'] diallog.save() logger.debug('%s: ProviderIVR_ForwardCall_New update child diallog ' 'dialSid %s duration %s' % (request.session.session_key, request.POST['DialCallSid'], request.POST['DialCallDuration'])) else: logger.debug('%s: ProviderIVR_ForwardCall_New diallog not found: dialSid %s duration %s' % ( request.session.session_key, request.POST['DialCallSid'], request.POST['DialCallDuration'])) # Do nothing so that the second leg call continues un-interrupted return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) else: # (request.POST['DialCallStatus'] != 'completed'): logger.debug('%s/%s: ProviderIVR_ForwardCall_New DialStatus not answered' % ( request.session.session_key, request.session['ivr2_state'])) if (request.POST['DialCallStatus'] == 'failed'): # TODO: Figure out how to deal with connection problems. Most # likely, send an email to the user and administrators. logger.debug('%s/%s: ProviderIVR_ForwardCall_New DialStatus failed' % ( request.session.session_key, request.session['ivr2_state'])) subject = 'ProviderIVR_ForwardCall Call Forward DialStatus Fail' message = 'ProviderIVR_ForwardCall got DialStatus failed. Post data: %s' \ % (str(request.POST),) mail_admins(subject=subject, message=message, fail_silently=False) # else request.POST['DialStatus'] == 'busy' or request.POST['DialStatus'] == 'no-answer' return ProviderIVR_LeaveMsg_New(request, r) # if we connected (in Vet), we hang up here if (log.call_connected): r.append(twilio.Hangup()) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) # if not connected, we go to LeaveMsg return ProviderIVR_LeaveMsg_New(request, r)
def ProviderIVR_Main_New(request): """ initial call into provider -- Only called with new Twilio 2010 API initializes caller, called, provider_id, callLog and mask caller number with doctorcom Number if caller has a doctorcom number I leave the numbers with + and country code but strip them off the number of caller/called when we lookup the database for provider or mhluser """ if (not 'ivr2_state' in request.session): # beginning of the very first call request.session['ivr2_state'] = 'ProviderIVR_Main_New' logger.debug('%s: ProviderIVR_Main_New is initiated' % (request.session.session_key)) elif (request.session['ivr2_state'] and (request.session['ivr2_state'] != 'ProviderIVR_Main_New') and (request.session['ivr2_state'] != 'ProviderIVR_TreeRoot_New')): # this shouldn't happen, but if it did, and we log and keep going if (not 'provider_id' in request.session): logger.debug( '%s: ProviderIVR_Main_New is called with state already set to %s, prov.id is null' % (request.session.session_key, request.session['ivr2_state'])) else: logger.debug( '%s: ProviderIVR_Main_New is called with state already set to %s, prov.id %s' % (request.session.session_key, request.session['ivr2_state'], request.session['provider_id'])) request.session['ivr2_state'] = 'ProviderIVR_Main_New' logger.debug('%s: ProviderIVR_Main_New POST data is %s' % (request.session.session_key, str(request.POST))) # logger.debug('%s: ProviderIVR_Main_New META data is %s' % (request.session.session_key, str(request.META))) # check if this is the callback when call is completed (should redirect to ProviderIVR_Status) callEnded = _checkCallbackDuration(request) if callEnded: # we are done return callEnded # main functionality of this call (caller, called) = _setup_Main_callers(request) # set up provider_id in session provider_called = _getUniqueProvider(called) request.session['provider_id'] = provider_called.id # if caller has a doctorcom number, mask it caller_mhluser = _getMHLUser(caller) caller_provider = _maskProviderCaller(request, caller_mhluser) # set up callLog if none is defined: callSID = request.POST['CallSid'] log = _getOrCreateCallLog(request, callSID, caller, called, 'OC', provider_called, caller_mhluser) if caller_provider: log.mdcom_caller = caller_provider log.save() logger.debug( '%s: ProviderIVR_Main_New caller %s called %s callSid %s prov mobile %s' % (request.session.session_key, caller, called, callSID, provider_called.user.mobile_phone)) if provider_called.user.mobile_phone != caller: request.session['ivr2_state'] = 'ProviderIVR_ForwardCall_New' logger.debug( '%s: ProviderIVR_Main_New forwarding caller %s called %s called mobile %s' % (request.session.session_key, caller, called, provider_called.user.mobile_phone)) return ProviderIVR_ForwardCall_New(request, provider_called) # otherwise, this is owner calling in log.call_source = 'VM' log.save() # check if VM config is all set up - if not, we go to ProviderIVR_Setup try: config = provider_called.vm_config.get() except MultipleObjectsReturned: raise Exception( "Provider %s %s has multiple vm_config objects." % (provider_called.user.first_name, provider_called.user.last_name)) except ObjectDoesNotExist: request.session['ivr2_state'] = 'ProviderIVR_Setup_New' return ProviderIVR_Setup_New(request) # Check to see if the PIN value exists in the configuration. Pin *should* be set through the web interface # or it won't be able to be set/changed as anonymous user if (not config.pin): logger.debug( '%s: ProviderIVR_Main_New config pin not set - provider %s' % (request.session.session_key, provider_called.user.mobile_phone)) request.session['ivr2_state'] = 'ProviderIVR_Setup_New' request.session.modified = True return ProviderIVR_Setup_New(request) request.session['config_id'] = config.id if (not 'authenticated' in request.session): logger.debug( '%s: ProviderIVR_Main_New authenticating - provider %s' % (request.session.session_key, provider_called.user.mobile_phone)) request.session['ivr2_state'] = 'ProviderIVR_Main_New' request.session.modified = True r = twilio.Response() return authenticateSessionNew(request, r) # Now, check to ensure that user voicemail configuration was completed successfully. if (not config.config_complete): logger.debug( '%s: ProviderIVR_Main_New config incomplete - provider %s' % (request.session.session_key, provider_called.user.mobile_phone)) request.session['ivr2_state'] = 'ProviderIVR_Setup_New' return ProviderIVR_Setup_New(request, provider_called) # everything else goes to main call tree request.session['ivr2_state'] = 'ProviderIVR_TreeRoot_New' return ProviderIVR_TreeRoot_New(request, provider_called)
def ProviderIVR_ForwardCall_New(request, provider=None, twilioResponse=None): """ new version of ProviderIVR_ForwardCall - forward call to dialed user as per user preference called by ProviderIVR_Main_New Steps: 1. get name 2. Dial - based on provider.forward_voicemail state to Mobile, office, other (VM already handled) 3. After dialed: handle failure by going to LeaveMsg or hangup? """ assert (request.session['provider_id']) provider = Provider.objects.get(id=request.session['provider_id']) logger.debug( '%s: ProviderIVR_ForwardCall_New is initiated provider %s state %s substate %s POST %s' % (request.session.session_key, provider, request.session.get('ivr2_state', None), request.session.get('ivr2_sub_state', None), str(request.POST))) callEnded = _checkCallbackDuration(request, False) # check user forwarding preference forward = provider.forward_voicemail if (forward == 'VM'): # go to voicemail request.session['ivr2_state'] = 'ProviderIVR_LeaveMsg_New' logger.debug( '%s: ProviderIVR_ForwardCall_New forwarding to voicemail of %s' % (request.session.session_key, provider)) return ProviderIVR_LeaveMsg_New(request) # State processing - 1. get caller name or ask for it r = twilioResponse or twilio.Response() if ('ivr2_sub_state' not in request.session): request.session['ivr2_sub_state'] = 'ProviderIVR_ForwardCall_Start' else: logger.debug( '%s: ProviderIVR_ForwardCall_New sub_state %s' % (request.session.session_key, request.session['ivr2_sub_state'])) if (request.session['ivr2_sub_state'] == 'ProviderIVR_ForwardCall_Start'): request.session['ivr2_sub_state'] = 'ProviderIVR_ForwardCall_GetName' # is this a doctorcom user with recorded name? callSID = request.POST['CallSid'] log = callLog.objects.get(callSID=callSID) if (log.mdcom_caller and isinstance(log.mdcom_caller, Provider)): if (log.mdcom_caller.vm_config.count()): prov_vmconfig = log.mdcom_caller.vm_config.get() if (prov_vmconfig.config_complete): logger.debug('%s/%s: Found the caller\'s name!' % ( request.session.session_key, request.session['ivr2_state'], )) log.caller_spoken_name = prov_vmconfig.name log.save() # got the recorded name; just go back to the next step - Dial return ProviderIVR_ForwardCall_New(request, provider, r) # next step else: logger.debug( '%s/%s: ProviderIVR_ForwardCall_New GetName: Caller\'s ' 'vm_config incomplete!' % (request.session.session_key, request.session['ivr2_state'])) else: logger.debug( '%s/%s: ProviderIVR_ForwardCall_New GetName: unsuitable ' 'number of vm_config objects found: %i' % (request.session.session_key, request.session['ivr2_state'], log.mdcom_caller.vm_config.count())) else: logger.debug( '%s/%s: ProviderIVR_ForwardCall_New GetName: mdcom_caller %s ' 'either isn\'t defined or doesn\'t seem to be a Provider' % (request.session.session_key, request.session['ivr2_state'], str(log.mdcom_caller))) # Not a user with a name recording. Get one. # ivr2_state already set to ProviderIVR_ForwardCall_GetName request.session[ 'ivr2_Record_prompt_str'] = 'Please say your name after the tone.' request.session['ivr2_Record_maxLength'] = 4 request.session['ivr2_Record_timeout'] = 2 request.session['ivr2_Record_leadSilence'] = 1 return getQuickRecordingNew(request) elif (request.session['ivr2_sub_state'] == 'ProviderIVR_ForwardCall_GetName'): request.session['ivr2_sub_state'] = 'ProviderIVR_ForwardCall_Dial' # save the caller name callSID = request.POST['CallSid'] log = callLog.objects.get(callSID=callSID) if (not log.caller_spoken_name): log.caller_spoken_name = request.session['ivr2_Record_recording'] del request.session['ivr2_Record_recording'] log.save() # Okay, let's find number to dial! user_number = None if (forward == 'MO'): user_number = provider.user.mobile_phone elif (forward == 'OF'): user_number = provider.office_phone elif (forward == 'OT'): user_number = provider.user.phone logger.debug( '%s/%s: ProviderIVR_ForwardCall_New Dial user number is \'%s\' forward %s' % (request.session.session_key, request.session['ivr2_state'], user_number, forward)) if (not user_number): # no flags were set. if (provider.user.mobile_phone): user_number = provider.user.mobile_phone else: return ProviderIVR_LeaveMsg_New(request, r) # when dial action is done, we go back to its actionurl - which is here with state Dial dial = twilio.Dial( action=reverse('ProviderIVR_ForwardCall_New'), timeout=22, timeLimit=14400, # 4 hours callerId=_makeUSNumber(request.session['Caller'])) # we also want to allow call vetting dial.append( twilio.Number(user_number, url=reverse('ProviderIVR_ForwardCall_Vet'))) r.append(dial) # If the call did not connect, we go to LeaveMsg r.append(twilio.Redirect(reverse('ProviderIVR_LeaveMsg_New'))) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) elif (request.session['ivr2_sub_state'] == 'ProviderIVR_ForwardCall_Dial'): # done with forward call del request.session['ivr2_sub_state'] # need to get parent call log for caller and connected; also update child log for duration (log, plog) = _getCallLogOrParent(request) if log: logger.debug( '%s/%s: ProviderIVR_ForwardCall_New state connected %s' % (request.session.session_key, request.session['ivr2_state'], str(log.call_connected))) else: logger.debug( '%s/%s: ProviderIVR_ForwardCall_New state no log SID %s' % (request.session.session_key, request.session['ivr2_state'], request.POST['CallSid'])) if ('DialCallStatus' in request.POST): if (request.POST['DialCallStatus'] == 'completed'): # update child log call duration diallog = callLog.objects.get( callSID=request.POST['DialCallSid']) if diallog: diallog.call_duration = request.POST['DialCallDuration'] diallog.save() logger.debug( '%s: ProviderIVR_ForwardCall_New update child diallog ' 'dialSid %s duration %s' % (request.session.session_key, request.POST['DialCallSid'], request.POST['DialCallDuration'])) else: logger.debug( '%s: ProviderIVR_ForwardCall_New diallog not found: dialSid %s duration %s' % (request.session.session_key, request.POST['DialCallSid'], request.POST['DialCallDuration'])) # Do nothing so that the second leg call continues un-interrupted return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) else: # (request.POST['DialCallStatus'] != 'completed'): logger.debug( '%s/%s: ProviderIVR_ForwardCall_New DialStatus not answered' % (request.session.session_key, request.session['ivr2_state'])) if (request.POST['DialCallStatus'] == 'failed'): # TODO: Figure out how to deal with connection problems. Most # likely, send an email to the user and administrators. logger.debug( '%s/%s: ProviderIVR_ForwardCall_New DialStatus failed' % (request.session.session_key, request.session['ivr2_state'])) subject = 'ProviderIVR_ForwardCall Call Forward DialStatus Fail' message = 'ProviderIVR_ForwardCall got DialStatus failed. Post data: %s' \ % (str(request.POST),) mail_admins(subject=subject, message=message, fail_silently=False) # else request.POST['DialStatus'] == 'busy' or request.POST['DialStatus'] == 'no-answer' return ProviderIVR_LeaveMsg_New(request, r) # if we connected (in Vet), we hang up here if (log.call_connected): r.append(twilio.Hangup()) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) # if not connected, we go to LeaveMsg return ProviderIVR_LeaveMsg_New(request, r)
def PracticeIVR_Setup_New(request): """ This function is heavily dependent upon request.session; Twilio is kind enough to keep session cookies for us. sets up doctor com answering service practice open/closed greetings and pin """ assert(request.session['practice_id']) assert(request.session['ivr2_state'] == 'PracticeIVR_Setup_New') _checkCallbackDuration(request) logger.debug('%s: PracticeIVR_Setup_New POST data is %s' % ( request.session.session_key, str(request.POST))) logger.debug('%s: PracticeIVR_Setup_New state %s practice %s' % ( request.session.session_key, request.session['ivr2_state'], request.session['practice_id'])) # TODO - check if we need to create event for this if ('ivr2_sub_state' not in request.session): request.session['ivr2_sub_state'] = 'PracticeIVR_Setup_Start' else: logger.debug('%s: PracticeIVR_Setup_New sub_state %s' % ( request.session.session_key, request.session['ivr2_sub_state'])) if (request.session['ivr2_sub_state'] == 'PracticeIVR_Setup_Start'): # Okay, this is the first time this function is being executed for this call. request.session['ivr2_sub_state'] = 'PracticeIVR_Setup_1' #will need to Practice Location and see if this needs set up and values that are there already r = twilio.Response() r.append(twilio.Pause()) # one second pause keeps the first words from getting cut off. request.session['ivr2_prompt_str'] = "Welcome to your voicemail account. It looks like some setup is needed. \ Let's get started. First, we need to set up your pin number." return changePinNew(request, r) elif (request.session['ivr2_sub_state'] == 'PracticeIVR_Setup_1'): # Record name request.session['ivr2_sub_state'] = 'PracticeIVR_Setup_2' return changeNameNew(request, _('Now, we need to record your office name.')) elif (request.session['ivr2_sub_state'] == 'PracticeIVR_Setup_2'): # Record a greeting for closed office request.session['ivr2_sub_state'] = 'PracticeIVR_Setup_3' # request.session['ivr2_setup_stage'] = 3 # deprecated return changeGreetingNew(request, _('Next, we need to set up your answering service ' 'greeting. This will be played when the office is closed.')) elif (request.session['ivr2_sub_state'] == 'PracticeIVR_Setup_3'): # Record a greeting for open request.session['ivr2_sub_state'] = 'PracticeIVR_Setup_4' # request.session['ivr2_setup_stage'] = 4 # deprecated return changeGreetingNew(request, _('Finally, we need to set up a greeting that ' 'will be played when the office is open.')) elif (request.session['ivr2_sub_state'] == 'PracticeIVR_Setup_4'): # Configuration complete! #store new information in Practice Locations del request.session['ivr2_sub_state'] request.session['ivr2_state'] = 'PracticeIVR_TreeRoot_New' practice = PracticeLocation.objects.get(id=request.session['practice_id']) practice.config_complete = True practice.save() # we don't need the welcome msg anymore if ('ivr2_prompt_str' in request.session): del request.session['ivr2_prompt_str'] r = twilio.Response() r.append(tts(_('Your voice mail account is now set up. You may hang up now.'))) r.append(twilio.Redirect(reverse('PracticeIVR_TreeRoot_New'))) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) else: # should not get here with unknown state - log state and return to main; or throw exception? logger.debug('%s: PracticeIVR_Setup_New has unhandled state set to %s' % ( request.session.session_key, request.session['ivr2_state'])) request.session['ivr2_state'] = 'PracticeIVR_Main_New' return PracticeIVR_Main_New(request)
def PracticeIVR_LeaveUrgentMsg_New(request): """ This lets caller leave an urgent message for a practice in foll steps: 1. get callback number 2. Records a voicemail message for the doctor on call 3. leave notification to the doctor based on preferences. """ # TODO: # Update this code so that users can hit the pound key to pop back and log # into their own voicemail box. requestDataDict = {"GET": request.GET, "POST": request.POST}[request.method] logger.debug('%s: PracticeIVR_LeaveUrgentMsg_New state %s POST data is %s' % ( request.session.session_key, request.session['ivr2_state'], str(request.POST))) # if caller hangs up, we still continue if ('ivr2_sub_state' not in request.session): request.session['ivr2_sub_state'] = 'PracticeIVR_LeaveUrgentMsg_Start' else: logger.debug('%s: PracticeIVR_LeaveUrgentMsg_New sub_state %s' % ( request.session.session_key, request.session['ivr2_sub_state'])) callEnded = _checkCallbackDuration(request, False) if (callEnded): logger.debug('%s: PracticeIVR_LeaveUrgentMsg_New caller hung up. State %s' % ( request.session.session_key, request.session.get('ivr2_sub_state', 'None'))) # we deal with leftover recording or , if any if (request.session['ivr2_sub_state'] == 'PracticeIVR_LeaveUrgentMsg_GetMsg' or 'ivr2_Record_recording' in request.session or ('ivr2_only_callbacknumber' in request.session and request.session['ivr2_only_callbacknumber'] == True)): # send msg to office managers del request.session['ivr2_sub_state'] provider = Provider.objects.get(id=_getRecentOncallProviderId(request)) logger.debug('%s: PracticeIVR_LeaveUrgentMsg_New caller hung up -- saving urgent msg for %s' % ( request.session.session_key, provider)) config = None config_complete = provider.vm_config.count() == 1 and provider.vm_config.get().config_complete if (config_complete): config = provider.vm_config.get() mgrs = get_all_practice_managers(request.session['practice_id']) _copyStateVariables(request) save_answering_service_message(request, True, [provider], list(set(m.user for m in mgrs))) else: if (request.session['ivr2_sub_state'] == 'PracticeIVR_LeaveUrgentMsg_Start'): # step 1: get callback number request.session['ivr2_sub_state'] = 'PracticeIVR_LeaveUrgentMsg_GetCallback' request.session['ivr2_returnOnHangup'] = \ 'MHLogin.DoctorCom.IVR.views_practice_v2.PracticeIVR_LeaveUrgentMsg_New' return getCallBackNumberNew(request) elif request.session['ivr2_sub_state'] == 'PracticeIVR_LeaveUrgentMsg_GetCallback': # step 2: after getting callback number, we get caller's message request.session['ivr2_sub_state'] = 'PracticeIVR_LeaveUrgentMsg_GetMsg' request.session['ivr2_Record_prompt_str'] = 'Please say your message \ for the doctor on call after the beep. Press pound when finished.' request.session['ivr2_Record_maxLength'] = 600 # 10 minutes request.session['ivr2_Record_leadSilence'] = 2 request.session['ivr2_Record_promptOnce'] = True request.session['ivr2_returnOnHangup'] = \ 'MHLogin.DoctorCom.IVR.views_practice_v2.PracticeIVR_LeaveUrgentMsg_New' request.session.modified = True # Pass off the recording action to the getRecording function. return getQuickRecordingNew(request) elif (request.session['ivr2_sub_state'] == 'PracticeIVR_LeaveUrgentMsg_GetMsg' or 'ivr2_Record_recording' in request.session or ('ivr2_only_callbacknumber' in request.session and request.session['ivr2_only_callbacknumber'] == True)): # step 3 - send msg to office managers del request.session['ivr2_sub_state'] provider = Provider.objects.get(id=_getRecentOncallProviderId(request)) logger.debug('%s: PracticeIVR_LeaveUrgentMsg_New saving urgent msg for %s' % ( request.session.session_key, provider)) config = None config_complete = provider.vm_config.count() == 1 and provider.vm_config.get().config_complete if (config_complete): config = provider.vm_config.get() mgrs = get_all_practice_managers(request.session['practice_id']) _copyStateVariables(request) save_answering_service_message(request, True, [provider], list(set(m.user for m in mgrs))) #if pager number is entered, also page call back number r = twilio.Response() r.append(tts(_('Your message has been sent. Good bye'))) r.append(twilio.Hangup()) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) else: # should not get here logger.debug('%s: Into PracticeIVR_LeaveUrgentMsg_New with invalid ivr2_state %s' % (request.session.session_key, request.session['ivr2_state'])) request.session['ivr2_state'] = 'PracticeIVR_LeaveUrgentMsg_New' return PracticeIVR_LeaveUrgentMsg_New(request)
def PracticeIVR_Main_New(request): """ entry point when call comes in to doctor.com number associated with Practice """ logger.debug('%s: PracticeIVR_Main_New POST data is %s' % (request.session.session_key, str(request.POST))) # logger.debug('%s: PracticeIVR_Main_New META data is %s' % (request.session.session_key, str(request.META))) # if call ended, we don't process anymore; just get call duration callEnded = _checkCallbackDuration(request) if callEnded: # we are done return callEnded request.session['answering_service'] = 'yes' (caller, called) = _setup_Main_callers(request) # set up practice_id in session try: practice = PracticeLocation.objects.get(mdcom_phone=called) can_have_answering_service = practice.get_setting_attr('can_have_answering_service') if (not can_have_answering_service): r = twilio.Response() r.append(tts(_("I'm sorry, answering service is not available. Good bye."))) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) except MultipleObjectsReturned: raise Exception(_('Multiple Practice Locations have mdcom_phone %s') % (called,)) except ObjectDoesNotExist: raise Exception(_('No Practice Location have mdcom_phone %s') % (called,)) # if caller is an existing user with doctorcom number, mask the caller number with doctorcom number caller_mhluser = _getMHLUser(caller) caller_provider = _maskProviderCaller(request, caller_mhluser) logger.debug('%s: PracticeIVR_Main_New practice %s caller %s provider %s' % ( request.session.session_key, practice, caller_mhluser, caller_provider)) # set up callLog if none is defined: callSID = request.POST['CallSid'] log = _getOrCreateCallLog(request, callSID, caller, called, 'OC', practice, caller_mhluser) if caller_provider: log.mdcom_caller = caller_provider log.save() # setup session variables needed # request.session['practice'] = practice #removed, look up practice by id as needed, do not store objects in the session request.session['practice_id'] = practice.id # request.session['callgroup_id'] = practice.call_group.id if (practice.uses_original_answering_serice()): request.session['callgroup_id'] = practice.call_group.id # ONLY for V 1 groups, for V2 determine based on user selection later request.session['practice_phone'] = practice.practice_phone request.session['ivr2_only_callbacknumber'] = False # done with initialization ############################################################################ # see if this is office manager calling, if yes - goto set up # NOTE: compare phone numbers without country code if from the database vs. with country code if from twilio parameters # TO DO - MANAGERS CELL ALSO NEED TO BE ADDED if (request.session['practice_phone'] == caller or practice.accessnumber_set.filter(number=caller)): # Great, now we know that this is the owner calling in. First up, check to # see if the user has a configuration file and that they've completed setup #it is stored with practice location, for now act like first time # Now, check to ensure that user voicemail configuration was completed successfully. if (not practice.config_complete): request.session['ivr2_state'] = 'PracticeIVR_Setup_New' request.session.modified = True logger.debug('%s: PracticeIVR_Main_New need setup for practice %s' % ( request.session.session_key, practice)) return PracticeIVR_Setup_New(request) #config was complete, but call is made, ask if want to change settings else: #make sure they have pin for setting logger.debug('%s: PracticeIVR_Main_New setup complete; need auth for practice %s' % ( request.session.session_key, practice)) if (not 'authenticated' in request.session): request.session['ivr2_state'] = 'PracticeIVR_TreeRoot_New' request.session.modified = True r = twilio.Response() return authenticateSessionNew(request, r) request.session['ivr2_state'] = 'PracticeIVR_TreeRoot_New' request.session.modified = True logger.debug('%s: PracticeIVR_Main_New setup complete; need auth for practice %s' % ( request.session.session_key, practice)) return PracticeIVR_TreeRoot_New(request) ############################################################################ #phone call from outside called, they want to call answering service #lets see if we open/close/or lunch - based on that we decide on call tree #get current time in timezone of our practice, use gmt and then make it into local, #calltime_local is the time we use. gmttz = timezone('GMT') mytz = timezone(practice.time_zone) calltime_gmt = datetime.now(gmttz) calltime_local = calltime_gmt.astimezone(mytz) request.session['calltime_local_string'] = calltime_local.strftime("%Y-%m-%d %H:%M:%S") request.session['calltime_local'] = calltime_local return PracticeIVR_CallerResponse_New(request) # both old and new way