def ProviderIVR_Options(request, internalCall=False): r = twilio.Response() if (not internalCall and request.method == 'POST' and 'Digits' in request.POST): digits = request.POST['Digits'] p = re.compile('[0-9#*]$') if (not p.match(digits)): r.append(tts('I\'m sorry, I didn\'t understand that.')) elif (digits == '1'): # Change name request.session['ivr_call_stack'].append('ProviderIVR_Options') request.session.modified = True event = callEvent(callSID=request.POST['CallSid'], event='F_NCH') return changeName(request) elif (digits == '3'): # Change greeting request.session['ivr_call_stack'].append('ProviderIVR_Options') request.session.modified = True event = callEvent(callSID=request.POST['CallSid'], event='F_GCH') return changeGreeting(request) elif (digits == '5'): # Change pin request.session['ivr_call_stack'].append('ProviderIVR_Options') request.session.modified = True event = callEvent(callSID=request.POST['CallSid'], event='F_PCH') return changePin(request, None, True) elif (digits == '*'): # Repeat menu pass elif (digits == '9'): # Return to the main menu r.append( twilio.Redirect( reverse(request.session['ivr_call_stack'].pop()))) request.session.modified = True return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) else: r.append(tts('I\'m sorry, that wasn\t a valid selection.')) gather = twilio.Gather(finishOnKey='', numDigits=1, action=reverse('ProviderIVR_Options')) gather.append(tts('Options menu')) gather.append(tts('To re-record your name, press 1')) gather.append(tts('To record a new greeting, press 3')) gather.append(tts('To change your pin, press 5')) gather.append(tts('To return to the main menu, press 9')) gather.append(tts('To repeat this menu, press star')) r.append(gather) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def ProviderIVR_Options_Actions(request): """ Options to change VM settings - twilio calls back here We do the option processing here We track the ivr2_sub_state so we know where recording and pin go since we call the same method for setup """ assert (request.session['provider_id']) assert (request.session['ivr2_state'] == 'ProviderIVR_Options_New') provider = Provider.objects.get(id=request.session['provider_id']) logger.debug( '%s: ProviderIVR_Options_Actions provider %s POST data is %s' % (request.session.session_key, provider, str(request.POST))) r = twilio.Response() if (request.method == 'POST' and 'Digits' in request.POST): digits = request.POST['Digits'] p = re.compile('[0-9#*]$') if (not p.match(digits)): r.append(tts('I\'m sorry, I didn\'t understand that.')) elif (digits == '1'): # Change name event = callEvent(callSID=request.POST['CallSid'], event='F_NCH') request.session['ivr2_sub_state'] = 'ProviderIVR_Options_1' return changeNameNew(request) elif (digits == '3'): # Change greeting event = callEvent(callSID=request.POST['CallSid'], event='F_GCH') request.session['ivr2_sub_state'] = 'ProviderIVR_Options_3' return changeGreetingNew(request) elif (digits == '5'): # change pin event = callEvent(callSID=request.POST['CallSid'], event='F_PCH') request.session['ivr2_sub_state'] = 'ProviderIVR_Options_5' return changePinNew(request) elif (digits == '9'): # Return to the main menu request.session['ivr2_state'] = 'ProviderIVR_TreeRoot_New' r.append(twilio.Redirect(reverse('ProviderIVR_TreeRoot_New'))) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) elif (digits == '*'): # Repeat menu pass else: r.append(tts('I\'m sorry, that wasn\'t a valid selection.')) return ProviderIVR_Options_New(request, r) else: # should never happen - but if we get here without Digits, we log and go back to Main logger.debug( '%s: ProviderIVR_TreeRoot_Actions is called with no post or digits' % (request.session.session_key)) request.session['ivr2_state'] = 'ProviderIVR_Main_New' return ProviderIVR_Main_New(request)
def ProviderIVR_Options_Actions(request): """ Options to change VM settings - twilio calls back here We do the option processing here We track the ivr2_sub_state so we know where recording and pin go since we call the same method for setup """ assert(request.session['provider_id']) assert(request.session['ivr2_state'] == 'ProviderIVR_Options_New') provider = Provider.objects.get(id=request.session['provider_id']) logger.debug('%s: ProviderIVR_Options_Actions provider %s POST data is %s' % ( request.session.session_key, provider, str(request.POST))) r = twilio.Response() if (request.method == 'POST' and 'Digits' in request.POST): digits = request.POST['Digits'] p = re.compile('[0-9#*]$') if (not p.match(digits)): r.append(tts('I\'m sorry, I didn\'t understand that.')) elif (digits == '1'): # Change name event = callEvent(callSID=request.POST['CallSid'], event='F_NCH') request.session['ivr2_sub_state'] = 'ProviderIVR_Options_1' return changeNameNew(request) elif (digits == '3'): # Change greeting event = callEvent(callSID=request.POST['CallSid'], event='F_GCH') request.session['ivr2_sub_state'] = 'ProviderIVR_Options_3' return changeGreetingNew(request) elif (digits == '5'): # change pin event = callEvent(callSID=request.POST['CallSid'], event='F_PCH') request.session['ivr2_sub_state'] = 'ProviderIVR_Options_5' return changePinNew(request) elif (digits == '9'): # Return to the main menu request.session['ivr2_state'] = 'ProviderIVR_TreeRoot_New' r.append(twilio.Redirect(reverse('ProviderIVR_TreeRoot_New'))) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) elif (digits == '*'): # Repeat menu pass else: r.append(tts('I\'m sorry, that wasn\'t a valid selection.')) return ProviderIVR_Options_New(request, r) else: # should never happen - but if we get here without Digits, we log and go back to Main logger.debug('%s: ProviderIVR_TreeRoot_Actions is called with no post or digits' % ( request.session.session_key)) request.session['ivr2_state'] = 'ProviderIVR_Main_New' return ProviderIVR_Main_New(request)
def ProviderIVR_Options(request, internalCall=False): r = twilio.Response() if (not internalCall and request.method == 'POST' and 'Digits' in request.POST): digits = request.POST['Digits'] p = re.compile('[0-9#*]$') if (not p.match(digits)): r.append(tts('I\'m sorry, I didn\'t understand that.')) elif (digits == '1'): # Change name request.session['ivr_call_stack'].append('ProviderIVR_Options') request.session.modified = True event = callEvent(callSID=request.POST['CallSid'], event='F_NCH') return changeName(request) elif (digits == '3'): # Change greeting request.session['ivr_call_stack'].append('ProviderIVR_Options') request.session.modified = True event = callEvent(callSID=request.POST['CallSid'], event='F_GCH') return changeGreeting(request) elif (digits == '5'): # Change pin request.session['ivr_call_stack'].append('ProviderIVR_Options') request.session.modified = True event = callEvent(callSID=request.POST['CallSid'], event='F_PCH') return changePin(request, None, True) elif (digits == '*'): # Repeat menu pass elif (digits == '9'): # Return to the main menu r.append(twilio.Redirect(reverse(request.session['ivr_call_stack'].pop()))) request.session.modified = True return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) else: r.append(tts('I\'m sorry, that wasn\t a valid selection.')) gather = twilio.Gather(finishOnKey='', numDigits=1, action=reverse('ProviderIVR_Options')) gather.append(tts('Options menu')) gather.append(tts('To re-record your name, press 1')) gather.append(tts('To record a new greeting, press 3')) gather.append(tts('To change your pin, press 5')) gather.append(tts('To return to the main menu, press 9')) gather.append(tts('To repeat this menu, press star')) r.append(gather) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def ProviderIVR_ForwardCall_Vet(request): """ This function is executed on Number nouns within Dial verbs. The idea is to try to determine if it's a human who picked up, or a machine. Alternatively, this gives the called party a chance to send the call to voicemail without the caller knowing they're rejecting the call. """ logger.debug('%s: ProviderIVR_ForwardCall_Vet POST %s' % (request.session.session_key, str(request.POST))) r = twilio.Response() callSID = request.POST['CallSid'] # second leg calls have their own callSIDs - may need parentCallSID (log, plog) = _getCallLogOrParent(request) if (request.method == 'POST' and 'Digits' in request.POST): # Connect the calls, get parent log if any if log: logger.debug('%s: ProviderIVR_ForwardCall_Vet connected callsid %s logSID %s' % (request.session.session_key, callSID, log.callSID)) log.call_connected = True log.save() if plog: plog.call_connected = True plog.save() logger.debug('%s: ProviderIVR_ForwardCall_Vet update parent of logsid %s plogSID %s' % (request.session.session_key, log.callSID, plog.callSID)) else: logger.debug('%s: ProviderIVR_ForwardCall_Vet connected log not found %s' % (request.session.session_key, callSID)) event = callEvent(callSID=request.POST['CallSid'], event='C_ACC') event.save() return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) if log: caller_spoken_name = log.caller_spoken_name if (log.mdcom_caller): # Great. Is it a Provider? if (isinstance(log.mdcom_caller, Provider) and log.mdcom_caller.vm_config.count()): vm_config = log.mdcom_caller.vm_config.get() if (vm_config.config_complete): caller_spoken_name = vm_config.name else: logger.debug('%s: ProviderIVR_ForwardCall_Vet call log sid %s not found' % (request.session.session_key, callSID)) gather = twilio.Gather(numDigits=1, finishOnKey='', action=reverse('ProviderIVR_ForwardCall_Vet')) gather.append(tts("You have a call from")) gather.append(twilio.Play(caller_spoken_name)) gather.append(tts("Press any key to accept.")) r.append(gather) r.append(twilio.Hangup()) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def changeGreeting(request, prependPrompt=''): """Requests the user record their greeting and stores it in the config with id at request.session['config_id']. :param request: the usual Django view argument :param prependPrompt: The string to prepend to the start of the request. Note that sending None will result in an error. If you don't wish to prepend anything explicitly, please pass in an empty string. :returns: django.http.HttpResponse -- the result """ if ('ivr_makeRecording_recording' in request.session): if ('answering_service' in request.session and request.session['answering_service'] == 'yes'): practice = PracticeLocation.objects.get(id=request.session['practice_id']) if (request.session['ivr_setup_stage'] == 3): practice.greeting_closed = request.session['ivr_makeRecording_recording'] else: practice.greeting_lunch = request.session['ivr_makeRecording_recording'] del request.session['ivr_makeRecording_recording'] practice.save() else: config = VMBox_Config.objects.get(id=request.session['config_id']) config.greeting = request.session['ivr_makeRecording_recording'] del request.session['ivr_makeRecording_recording'] config.save() event = callEvent(callSID=request.POST['CallSid'], event='F_GCH') event.save() r = twilio.Response() r.append(twilio.Redirect(reverse(request.session['ivr_call_stack'].pop()))) request.session.modified = True return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) #make twilio say different things based on who called it, prepend seemed to #be never used, i will investigate later and see why not to use it if ('answering_service' in request.session and request.session['answering_service'] == 'yes'): if (request.session['ivr_setup_stage'] == 3): request.session['ivr_makeRecording_prompt'] = tts(_("Please say your " "new greeting for closed office after the tone. Press pound to finish.")) else: request.session['ivr_makeRecording_prompt'] = tts(_("Please say your greeting " "greeting for temporarily closed office after the tone. Press pound to finish.")) else: request.session['ivr_makeRecording_prompt'] = tts(_("Please say your new " "greeting after the tone. Press pound to finish.")) request.session['ivr_makeRecording_maxLength'] = 120 request.session['ivr_makeRecording_timeout'] = 3 request.session['ivr_call_stack'].append('changeGreeting') return getRecording(request)
def PracticeIVR_ForwardCall_Vet(request): """ This function is executed on Number nouns within Dial verbs. The idea is to try to determine if it's a human who picked up, or a machine. Alternatively, this gives the called party a chance to send the call to voicemail without the caller knowing they're rejecting the call. """ logger.debug('%s: PracticeIVR_ForwardCall_Vet ' % (request.session.session_key)) r = twilio.Response() # First, find the recording to play callSID = request.POST['CallSid'] # second leg calls have their own callSIDs - may need parentCallSID (log, plog) = _getCallLogOrParent(request) if (request.method == 'POST' and 'Digits' in request.POST): # Connect the calls log.call_connected = True log.save() if plog: plog.call_connected = True plog.save() logger.debug('%s: PracticeIVR_ForwardCall_Vet update parent of logsid %s plogSID %s' % (request.session.session_key, log.callSID, plog.callSID)) event = callEvent(callSID=callSID, event='C_ACC') event.save() return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) caller_spoken_name = log.caller_spoken_name gather = twilio.Gather(numDigits=1, finishOnKey='', action=reverse('PracticeIVR_ForwardCall_Vet')) if('click2call' in request.session): gather.append(tts(_("You have a call from"))) gather.append(twilio.Play(caller_spoken_name)) gather.append(tts(_("Press any key to accept."))) else: gather.append(tts(_("You have an urgent answering service call from"))) gather.append(twilio.Play(caller_spoken_name)) gather.append(tts(_("Press any key to accept."))) r.append(gather) r.append(twilio.Hangup()) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def ProviderIVR_ForwardCall_VetAnswer(request): """ This function is executed on Number nouns within Dial verbs. The idea is to try to determine if it's a human who picked up, or a machine. Alternatively, this gives the called party a chance to send the call to voicemail without the caller knowing they're rejecting the call. """ r = twilio.Response() request.session.modified = True callSID = request.POST['CallSid'] log = callLog.objects.get(callSID=callSID) if (request.method == 'POST' and 'Digits' in request.POST): # Connect the calls log.call_connected = True log.save() event = callEvent(callSID=callSID, event='C_ACC') event.save() return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) caller_spoken_name = log.caller_spoken_name if (log.mdcom_caller): # Great. Is it a Provider? if (isinstance(log.mdcom_caller, Provider) and log.mdcom_caller.vm_config.count()): vm_config = log.mdcom_caller.vm_config.get() if (vm_config.config_complete): caller_spoken_name = vm_config.name gather = twilio.Gather(numDigits=1, finishOnKey='', action=reverse('ProviderIVR_ForwardCall_VetAnswer')) gather.append(tts("You have a call from")) gather.append(twilio.Play(caller_spoken_name)) gather.append(tts("Press any key to accept.")) r.append(gather) r.append(twilio.Hangup()) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def PracticeIVR_ForwardCall_VetAnswer(request): """ This function is executed on Number nouns within Dial verbs. The idea is to try to determine if it's a human who picked up, or a machine. Alternatively, this gives the called party a chance to send the call to voicemail without the caller knowing they're rejecting the call. """ r = twilio.Response() request.session.modified = True # First, find the recording to play callSID = request.POST['CallSid'] log = callLog.objects.get(callSID=callSID) if 'Digits' in request.POST: # Connect the calls log.call_connected = True log.save() event = callEvent(callSID=request.POST['CallSid'], event='C_ACC') event.save() return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) caller_spoken_name = log.caller_spoken_name gather = twilio.Gather(numDigits=1, finishOnKey='', action=reverse('PracticeIVR_ForwardCall_VetAnswer')) if('click2call' in request.session): gather.append(tts(_("You have a call from"))) gather.append(twilio.Play(caller_spoken_name)) gather.append(tts(_("Press any key to accept."))) else: gather.append(tts(_("You have an urgent answering service call from"))) gather.append(twilio.Play(caller_spoken_name)) gather.append(tts(_("Press any key to accept."))) r.append(gather) r.append(twilio.Hangup()) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def ProviderIVR_ForwardCall_VetAnswer(request): """ This function is executed on Number nouns within Dial verbs. The idea is to try to determine if it's a human who picked up, or a machine. Alternatively, this gives the called party a chance to send the call to voicemail without the caller knowing they're rejecting the call. """ r = twilio.Response() request.session.modified = True callSID = request.POST['CallSid'] log = callLog.objects.get(callSID=callSID) if (request.method == 'POST' and 'Digits' in request.POST): # Connect the calls log.call_connected = True log.save() event = callEvent(callSID=callSID, event='C_ACC') event.save() return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) caller_spoken_name = log.caller_spoken_name if (log.mdcom_caller): # Great. Is it a Provider? if (isinstance(log.mdcom_caller, Provider) and log.mdcom_caller.vm_config.count()): vm_config = log.mdcom_caller.vm_config.get() if (vm_config.config_complete): caller_spoken_name = vm_config.name gather = twilio.Gather(numDigits=1, finishOnKey='', action=reverse( 'ProviderIVR_ForwardCall_VetAnswer')) gather.append(tts("You have a call from")) gather.append(twilio.Play(caller_spoken_name)) gather.append(tts("Press any key to accept.")) r.append(gather) r.append(twilio.Hangup()) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def changeName(request, prependPrompt=''): """Requests the user record their name and stores it in the config with id at request.session['config_id']. :param request: the usual Django view argument :param prependPrompt: The string to prepend to the start of the request. Note that sending None will result in an error. If you don't wish to prepend anything explicitly, please pass in an empty string. :returns: django.http.HttpResponse -- the result """ if ('ivr_makeRecording_recording' in request.session): if ('answering_service' in request.session and request.session['answering_service'] == 'yes'): practice = PracticeLocation.objects.get(id=request.session['practice_id']) practice.name_greeting = request.session['ivr_makeRecording_recording'] del request.session['ivr_makeRecording_recording'] practice.save() else: config = VMBox_Config.objects.get(id=request.session['config_id']) config.name = request.session['ivr_makeRecording_recording'] del request.session['ivr_makeRecording_recording'] config.save() event = callEvent(callSID=request.POST['CallSid'], event='F_NCH') event.save() r = twilio.Response() r.append(twilio.Redirect(reverse(request.session['ivr_call_stack'].pop()))) request.session.modified = True return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) request.session['ivr_makeRecording_prompt'] = tts(_("Please say your name " "after the tone. Press pound to finish.")) request.session['ivr_makeRecording_maxLength'] = 10 request.session['ivr_makeRecording_timeout'] = 3 request.session['ivr_call_stack'].append('changeName') return getRecording(request)
def changePin(request, twilioResponse=None, internalCall=False): """This function gets called three times per successful PIN change. The first time, it requests the user's pin. The second time, it requests confirmation of the pin. The last time, it finally saves the pin, then :returns: to the function specified at request.session['ivr_call_stack'][-1] """ r = twilioResponse or twilio.Response() if (not internalCall and 'Digits' in request.POST): digits = request.POST['Digits'] if (not 'ivr_changePin_hash' in request.session): # This is the first time the PIN has been entered. p = re.compile('\d{4,8}#?$') if (not p.match(digits)): r.append(tts(_("An in valid pin was entered."))) else: request.session['ivr_changePin_hash'] = get_new_pin_hash(digits) gather = twilio.Gather(numDigits=8, action=reverse('changePin')) gather.append(tts(_('To verify that we have the correct pin, ' 'please enter it again. Press pound to finish.'))) r.append(gather) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) else: # The PIN has been entered once. Time to verify it. p = re.compile('\d{4,8}#?$') if (p.match(digits)): if (check_pin(digits, request.session['ivr_changePin_hash'])): r.append(twilio.Redirect(reverse(request.session['ivr_call_stack'].pop()))) response = HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) if ('answering_service' in request.session and request.session['answering_service'] == 'yes'): practice = PracticeLocation.objects.get(id=request.session['practice_id']) practice.pin = request.session['ivr_changePin_hash'] practice.save() else: config = VMBox_Config.objects.get(id=request.session['config_id']) # Note: request.user is anon for twilio sessions, issue 1362 # get_user_key assumes cookie has 'ss' and ss def arg None by def old_key = get_user_key(request) if 'ss' in request.COOKIES else None config.change_pin(request, old_key=old_key, new_pin=digits) config.pin = request.session['ivr_changePin_hash'] config.save() del request.session['ivr_changePin_hash'] event = callEvent(callSID=request.POST['CallSid'], event='F_PCH') event.save() request.session.modified = True return response r.append(tts(_('The entered pins do not match.'))) del request.session['ivr_changePin_hash'] if (not 'ivr_changePin_hash' in request.session): # This is the code that gets executed on the first run of this function. # It also gets run if the PIN verification fails. gather = twilio.Gather(numDigits=8, action=reverse('changePin')) gather.append(tts(_("Please enter four to eight digits. Press pound to finish."))) r.append(gather) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def ProviderIVR_Setup_New(request, provider=None): """ New version of ProviderIVR_Setup processing. This is done in 4 consecutive steps: 0. initial sub state: ProviderIVR_Setup_Start 1. setup pin 2. setup Name 3. setup Greeting We use generic calls to setup Pin, Name and Greeting, but use ivr2_state to direct the return calls here so it could be redirected to the next step """ # we always need provider assert(request.session['provider_id']) assert(request.session['ivr2_state'] == 'ProviderIVR_Setup_New') if (provider == None): provider = Provider.objects.get(id=request.session['provider_id']) # we also need VMBox_config's config_id if (not 'config_id' in request.session): config = _getProviderVMConfig(provider) request.session['config_id'] = config.id logger.debug('%s: ProviderIVR_Setup_New state %s provider %s config %s' % ( request.session.session_key, request.session['ivr2_state'], provider, request.session['config_id'])) if ('ivr2_sub_state' not in request.session): # new setup processing request.session['ivr2_sub_state'] = 'ProviderIVR_Setup_Start' else: logger.debug('%s: ProviderIVR_Setup_New sub_state %s' % ( request.session.session_key, request.session['ivr2_sub_state'])) if (request.session['ivr2_sub_state'] == 'ProviderIVR_Setup_Start'): # set up pin 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." event = callEvent(callSID=request.POST['CallSid'], event='I_STR') event.save() request.session['ivr2_sub_state'] = 'ProviderIVR_Setup_Pin' return changePinNew(request, r) elif (request.session['ivr2_sub_state'] == 'ProviderIVR_Setup_Pin'): request.session['ivr2_sub_state'] = 'ProviderIVR_Setup_Name' return changeNameNew(request, 'Now, we need to record your name.') elif (request.session['ivr2_sub_state'] == 'ProviderIVR_Setup_Name'): request.session['ivr2_sub_state'] = 'ProviderIVR_Setup_Greeting' return changeGreetingNew(request, 'Finally, we need to set up a greeting.') elif (request.session['ivr2_sub_state'] == 'ProviderIVR_Setup_Greeting'): # setup is complete - automatically "log" user in request.session['authenticated'] = True del request.session['ivr2_sub_state'] request.session['ivr2_state'] = 'ProviderIVR_TreeRoot_New' config = VMBox_Config.objects.get(id=request.session['config_id']) config.config_complete = True config.save() event = callEvent(callSID=request.POST['CallSid'], event='I_FIN') event.save() logger.debug('%s: ProviderIVR_Setup is complete config %s' % ( request.session.session_key, config)) # 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, or stay on the line to be taken to your voice mail box home.')) # after VM Setup, we go to main r.append(twilio.Redirect(reverse('ProviderIVR_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 logger.debug('%s: ProviderIVR_Setup has unhandled state set to %s' % ( request.session.session_key, request.session['ivr2_state'])) request.session['ivr2_state'] = 'ProviderIVR_Main_New' return ProviderIVR_Main_New(request)
def ProviderIVR_ForwardCall_Vet(request): """ This function is executed on Number nouns within Dial verbs. The idea is to try to determine if it's a human who picked up, or a machine. Alternatively, this gives the called party a chance to send the call to voicemail without the caller knowing they're rejecting the call. """ logger.debug('%s: ProviderIVR_ForwardCall_Vet POST %s' % (request.session.session_key, str(request.POST))) r = twilio.Response() callSID = request.POST['CallSid'] # second leg calls have their own callSIDs - may need parentCallSID (log, plog) = _getCallLogOrParent(request) if (request.method == 'POST' and 'Digits' in request.POST): # Connect the calls, get parent log if any if log: logger.debug( '%s: ProviderIVR_ForwardCall_Vet connected callsid %s logSID %s' % (request.session.session_key, callSID, log.callSID)) log.call_connected = True log.save() if plog: plog.call_connected = True plog.save() logger.debug( '%s: ProviderIVR_ForwardCall_Vet update parent of logsid %s plogSID %s' % (request.session.session_key, log.callSID, plog.callSID)) else: logger.debug( '%s: ProviderIVR_ForwardCall_Vet connected log not found %s' % (request.session.session_key, callSID)) event = callEvent(callSID=request.POST['CallSid'], event='C_ACC') event.save() return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) if log: caller_spoken_name = log.caller_spoken_name if (log.mdcom_caller): # Great. Is it a Provider? if (isinstance(log.mdcom_caller, Provider) and log.mdcom_caller.vm_config.count()): vm_config = log.mdcom_caller.vm_config.get() if (vm_config.config_complete): caller_spoken_name = vm_config.name else: logger.debug( '%s: ProviderIVR_ForwardCall_Vet call log sid %s not found' % (request.session.session_key, callSID)) gather = twilio.Gather(numDigits=1, finishOnKey='', action=reverse('ProviderIVR_ForwardCall_Vet')) gather.append(tts("You have a call from")) gather.append(twilio.Play(caller_spoken_name)) gather.append(tts("Press any key to accept.")) r.append(gather) r.append(twilio.Hangup()) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def ProviderIVR_Setup_New(request, provider=None): """ New version of ProviderIVR_Setup processing. This is done in 4 consecutive steps: 0. initial sub state: ProviderIVR_Setup_Start 1. setup pin 2. setup Name 3. setup Greeting We use generic calls to setup Pin, Name and Greeting, but use ivr2_state to direct the return calls here so it could be redirected to the next step """ # we always need provider assert (request.session['provider_id']) assert (request.session['ivr2_state'] == 'ProviderIVR_Setup_New') if (provider == None): provider = Provider.objects.get(id=request.session['provider_id']) # we also need VMBox_config's config_id if (not 'config_id' in request.session): config = _getProviderVMConfig(provider) request.session['config_id'] = config.id logger.debug('%s: ProviderIVR_Setup_New state %s provider %s config %s' % (request.session.session_key, request.session['ivr2_state'], provider, request.session['config_id'])) if ('ivr2_sub_state' not in request.session): # new setup processing request.session['ivr2_sub_state'] = 'ProviderIVR_Setup_Start' else: logger.debug( '%s: ProviderIVR_Setup_New sub_state %s' % (request.session.session_key, request.session['ivr2_sub_state'])) if (request.session['ivr2_sub_state'] == 'ProviderIVR_Setup_Start'): # set up pin 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." event = callEvent(callSID=request.POST['CallSid'], event='I_STR') event.save() request.session['ivr2_sub_state'] = 'ProviderIVR_Setup_Pin' return changePinNew(request, r) elif (request.session['ivr2_sub_state'] == 'ProviderIVR_Setup_Pin'): request.session['ivr2_sub_state'] = 'ProviderIVR_Setup_Name' return changeNameNew(request, 'Now, we need to record your name.') elif (request.session['ivr2_sub_state'] == 'ProviderIVR_Setup_Name'): request.session['ivr2_sub_state'] = 'ProviderIVR_Setup_Greeting' return changeGreetingNew(request, 'Finally, we need to set up a greeting.') elif (request.session['ivr2_sub_state'] == 'ProviderIVR_Setup_Greeting'): # setup is complete - automatically "log" user in request.session['authenticated'] = True del request.session['ivr2_sub_state'] request.session['ivr2_state'] = 'ProviderIVR_TreeRoot_New' config = VMBox_Config.objects.get(id=request.session['config_id']) config.config_complete = True config.save() event = callEvent(callSID=request.POST['CallSid'], event='I_FIN') event.save() logger.debug('%s: ProviderIVR_Setup is complete config %s' % (request.session.session_key, config)) # 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, or stay on the line to be taken to your voice mail box home.' )) # after VM Setup, we go to main r.append(twilio.Redirect(reverse('ProviderIVR_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 logger.debug( '%s: ProviderIVR_Setup has unhandled state set to %s' % (request.session.session_key, request.session['ivr2_state'])) request.session['ivr2_state'] = 'ProviderIVR_Main_New' return ProviderIVR_Main_New(request)
def ProviderIVR_Setup(request, config=None): """ This function is heavily dependent upon request.session; Twilio is kind enough to keep session cookies for us. """ # DEBUG: #if (not 'ProviderIVR_Setup' in request.session['callCounts']): # request.session['callCounts']['ProviderIVR_Setup'] = 1 #else: # request.session['callCounts']['ProviderIVR_Setup'] += 1 # DEBUG: #if (not 'debug_semaphore' in request.session): # request.session['ivr_setup_stage'] = 1 # request.session['debug_semaphore'] = True #else: # raise Exception(request.session['ivr_call_stack']) if ('CallStatus' in request.POST and request.POST['CallStatus'] == 'completed'): # call ended #raise Exception('Ending inappropriately. Call stack is %s'%(str( # request.session['ivr_call_stack']),)) # DEBUG r = twilio.Response() return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) elif (not 'CallStatus' in request.POST): # call ended #raise Exception('Ending inappropriately. Call stack is %s'%(str( # request.session['ivr_call_stack']),)) # DEBUG r = twilio.Response() return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) if 'ivr_setup_stage' not in request.session: # Okay, this is the first time this function is being executed for this # call. #raise Exception(request.session['ivr_call_stack']) # DEBUG r = twilio.Response() # Set up our session variables. request.session['ivr_setup_stage'] = 1 request.session['ivr_call_stack'].append('ProviderIVR_Setup') request.session.modified = True provider = Provider.objects.get(id=request.session['provider_id']) if (not provider.vm_config.count()): # This user needs a voicemailbox configuration object config = VMBox_Config() config.owner = provider config.save() request.session['config_id'] = config.id r.append(twilio.Pause()) # one second pause keeps the first words from getting cut off. r.append(tts("Welcome to your voicemail account. It looks like some " "setup is needed. Let's get started.")) r.append(tts("First, we need to set up your pin number.")) event = callEvent(callSID=request.POST['CallSid'], event='I_STR') event.save() #raise Exception(request.session['ivr_call_stack']) # DEBUG return changePin(request, r, True) elif (request.session['ivr_setup_stage'] == 1): # Record name request.session['ivr_call_stack'].append('ProviderIVR_Setup') request.session.modified = True request.session['ivr_setup_stage'] = 2 return changeName(request, 'Now, we need to record your name.') elif (request.session['ivr_setup_stage'] == 2): # Record a greeting request.session['ivr_call_stack'].append('ProviderIVR_Setup') request.session.modified = True request.session['ivr_setup_stage'] = 3 return changeGreeting(request, 'Finally, we need to set up a greeting.') elif (request.session['ivr_setup_stage'] == 3): # Configuration complete! #raise Exception(request.session['ivr_call_stack']) # DEBUG #raise Exception(request.session['callCounts']) # DEBUG # Automatically "log" this user in. request.session['authenticated'] = True config = VMBox_Config.objects.get(id=request.session['config_id']) config.config_complete = True config.save() r = twilio.Response() r.append(tts('Your voice mail account is now set up. You may hang up ' 'now, or stay on the line to be taken to your voice mail box home.')) event = callEvent(callSID=request.POST['CallSid'], event='I_FIN') event.save() r.append(twilio.Redirect(reverse(request.session['ivr_call_stack'].pop()))) request.session.modified = True return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) raise Exception('Reached the end of ProviderIVR_Setup. This should never happen.')
def playMessages(request, msgs_querySet=None, twilioResponse=None): """Plays and gives the menu tree to act on messages. :param request: the usual Django view argument :param msgs_querySet: django query set of voice messages :param twilioResponse: None if direct from Twilio, set if called within IVR :returns: django.http.HttpResponse -- the result """ # msgs_querySet is None when called from Twilio and session is setup if msgs_querySet != None: # msgs_querySet is not None when called within IVR tree but may be empty set request.session['ivr_playMessages_newMessages'] = list(msgs_querySet.filter( read_flag=False, delete_flag=False).order_by('msg_body__message__message_type', '-msg_body__message__send_timestamp').all()) if len(request.session['ivr_playMessages_newMessages']): request.session['ivr_playMessages_newMsgsFlag'] = True request.session['ivr_playMessages_oldMessages'] = list(msgs_querySet.filter( read_flag=True, delete_flag=False).order_by('msg_body__message__message_type', '-msg_body__message__send_timestamp').all()) # We're pretty much always going to be manipulating the session. request.session.modified = True r = twilioResponse or twilio.Response() replayFlag = False playFlag = True call_sid = request.POST['CallSid'] if (not msgs_querySet and 'Digits' in request.POST): digits = request.POST['Digits'] p = re.compile('[0-9#*]$') if (not p.match(digits)): r.append(tts('I\'m sorry, I didn\'t understand that.')) playFlag = False if (digits == '1'): # do nothing pass elif (digits == '3'): replayFlag = True elif (digits == '5'): return callBackUser(request, request.session['ivr_playMessages_currentMsg'].msg_body.message) elif (digits == '7'): # Merely sets the 'deleted' flag to hide the message. r.append(tts('Message resolved')) event = callEvent(callSID=call_sid, event='V_MDL') event.save() target = callEventTarget(event=event, target=request.session['ivr_playMessages_currentMsg']) target.save() request.session['ivr_playMessages_currentMsg'].\ msg_body.message.resolved_by = request.user elif (digits == '9'): r.append(twilio.Redirect(reverse(request.session['ivr_call_stack'].pop()))) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) if (replayFlag): r.append(tts('Re-playing message')) elif (not playFlag): pass # do nothing -- we don't want to move to the next message. elif (len(request.session['ivr_playMessages_newMessages'])): if (msgs_querySet): r.append(tts('Playing the first new message')) else: r.append(tts('Playing the next new message')) request.session['ivr_playMessages_currentMsg'] = \ request.session['ivr_playMessages_newMessages'].pop(0) event = None if(request.session['ivr_playMessages_currentMsg'].msg_body.message.message_type == 'ANS'): event = callEvent(callSID=call_sid, event='V_NAP') event.save() else: event = callEvent(callSID=call_sid, event='V_NMP') event.save() target = callEventTarget(event=event, target=request.session['ivr_playMessages_currentMsg']) target.save() request.session['ivr_playMessages_currentMsg'].read_flag = True request.session['ivr_playMessages_currentMsg'].save() elif (len(request.session['ivr_playMessages_oldMessages'])): #if (request.session['ivr_playMessages_newMsgsFlag']): # Done playing new messages. # pass if (msgs_querySet): r.append(tts('Playing the first old message')) else: r.append(tts('Playing the next old message')) request.session['ivr_playMessages_currentMsg'] = \ request.session['ivr_playMessages_oldMessages'].pop(0) event = None if(request.session['ivr_playMessages_currentMsg'].msg_body.message.message_type == 'ANS'): event = callEvent(callSID=call_sid, event='V_OAP') event.save() else: event = callEvent(callSID=call_sid, event='V_OMP') event.save() target = callEventTarget(event=event, target=request.session['ivr_playMessages_currentMsg']) target.save() else: r.append(tts('End of messages')) r.append(twilio.Redirect(reverse(request.session['ivr_call_stack'].pop()))) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) gather = twilio.Gather(finishOnKey='', numDigits=1, action=reverse('playMessages')) if (playFlag): url = '' if (request.session['ivr_playMessages_currentMsg'].\ msg_body.message.message_type == 'ANS'): spoken_number = [] digits = request.session['ivr_playMessages_currentMsg'].\ msg_body.message.callback_number [spoken_number.extend([i, ' ']) for i in digits] spoken_number.pop() # drop the last element #spoken_number.insert(5, ',') #spoken_number.insert(12, ',') gather.append(tts('Call from %s .' % (''.join(spoken_number),))) msg = request.session['ivr_playMessages_currentMsg'].msg_body.message try: uuid = MessageAttachment.objects.get(message=msg).uuid url = reverse("fetchRecording", kwargs={"uuid": uuid}) gather.append(twilio.Play(url)) except MessageAttachment.DoesNotExist: errors = { 'U': _("User hung up before confirming number."), 'C': _("User hung up before leaving message."), 'R': _("An error occurred downloading the recording. We will retry until " "successful and you will receive a new message at that time."), } gather.append(tts(errors[msg.vmstatus])) gather.append(twilio.Pause()) gather.append(tts(_('Press 1 to move to the next message. '))) gather.append(tts(_('Press 3 to re-play the message. '))) callback_number = request.session['ivr_playMessages_currentMsg'].\ msg_body.message.callback_number if(re.match("1?\d{10}", callback_number)): gather.append(tts(_('Press 5 to call this person back. '))) gather.append(tts(_('Press 7 to mark the message resolved and hide it. '))) gather.append(tts(_('Press 9 to return to the main menu. '))) r.append(gather) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def authenticateSession(request, twilioResponse=None): """ :param request: The standard Django request argument :param request.session Keys: config_id - The ID of the VMBox_Config object pertaining to the current voicemail session. :param twilioResponse: A twilio response object. Use this to pass in any verbs that should be run before the prompt. Note that any verbs passed in will be lost on subsequent runs through this function (e.g., when the user enters an incorrect pin) :returns: django.http.HttpResponse -- the result """ r = twilioResponse or twilio.Response() if (not 'pin_errCount' in request.session): request.session['pin_errCount'] = 0 if 'Digits' in request.POST: call_sid = request.POST['CallSid'] digits = request.POST['Digits'] p = re.compile('\d{4,8}#?$') if (p.match(digits)): if ('answering_service' in request.session and request.session['answering_service'] == 'yes'): practice = PracticeLocation.objects.get(id=request.session['practice_id']) if (practice.verify_pin(digits)): request.session['authenticated'] = True r.append(twilio.Redirect(reverse(request.session['ivr_call_stack'].pop()))) request.session.modified = True return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) else: user = authenticate(config_id=request.session['config_id'], pin=digits) if (user): login(request, user) # TESTING_KMS_INTEGRATION uprivs = UserPrivateKey.objects.filter(user=user, credtype=CRED_IVRPIN, gfather=True) if uprivs.exists(): config = VMBox_Config.objects.get(id=request.session['config_id']) config.change_pin(request, new_pin=digits) request.session['authenticated'] = True event = callEvent(callSID=call_sid, event='V_ASU') event.save() r.append(twilio.Redirect(reverse(request.session['ivr_call_stack'].pop()))) request.session.modified = True response = HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) store_user_key(request, response, digits) return response event = callEvent(callSID=call_sid, event='V_AFL') event.save() r.append(tts('An in valid pin was entered.')) request.session['pin_errCount'] += 1 if (request.session['pin_errCount'] >= 3): # give the user three erroneous pin entries. r.append(tts('Good bye.')) r.append(twilio.Hangup()) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) # This is the code that gets executed on the first run of this function. gather = twilio.Gather(numDigits=8, action=reverse('authenticateSession')) gather.append(tts(_("Please enter your pin number. Press pound to finish."))) r.append(gather) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def ProviderIVR_Setup(request, config=None): """ This function is heavily dependent upon request.session; Twilio is kind enough to keep session cookies for us. """ # DEBUG: #if (not 'ProviderIVR_Setup' in request.session['callCounts']): # request.session['callCounts']['ProviderIVR_Setup'] = 1 #else: # request.session['callCounts']['ProviderIVR_Setup'] += 1 # DEBUG: #if (not 'debug_semaphore' in request.session): # request.session['ivr_setup_stage'] = 1 # request.session['debug_semaphore'] = True #else: # raise Exception(request.session['ivr_call_stack']) if ('CallStatus' in request.POST and request.POST['CallStatus'] == 'completed'): # call ended #raise Exception('Ending inappropriately. Call stack is %s'%(str( # request.session['ivr_call_stack']),)) # DEBUG r = twilio.Response() return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) elif (not 'CallStatus' in request.POST): # call ended #raise Exception('Ending inappropriately. Call stack is %s'%(str( # request.session['ivr_call_stack']),)) # DEBUG r = twilio.Response() return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) if 'ivr_setup_stage' not in request.session: # Okay, this is the first time this function is being executed for this # call. #raise Exception(request.session['ivr_call_stack']) # DEBUG r = twilio.Response() # Set up our session variables. request.session['ivr_setup_stage'] = 1 request.session['ivr_call_stack'].append('ProviderIVR_Setup') request.session.modified = True provider = Provider.objects.get(id=request.session['provider_id']) if (not provider.vm_config.count()): # This user needs a voicemailbox configuration object config = VMBox_Config() config.owner = provider config.save() request.session['config_id'] = config.id r.append(twilio.Pause( )) # one second pause keeps the first words from getting cut off. r.append( tts("Welcome to your voicemail account. It looks like some " "setup is needed. Let's get started.")) r.append(tts("First, we need to set up your pin number.")) event = callEvent(callSID=request.POST['CallSid'], event='I_STR') event.save() #raise Exception(request.session['ivr_call_stack']) # DEBUG return changePin(request, r, True) elif (request.session['ivr_setup_stage'] == 1): # Record name request.session['ivr_call_stack'].append('ProviderIVR_Setup') request.session.modified = True request.session['ivr_setup_stage'] = 2 return changeName(request, 'Now, we need to record your name.') elif (request.session['ivr_setup_stage'] == 2): # Record a greeting request.session['ivr_call_stack'].append('ProviderIVR_Setup') request.session.modified = True request.session['ivr_setup_stage'] = 3 return changeGreeting(request, 'Finally, we need to set up a greeting.') elif (request.session['ivr_setup_stage'] == 3): # Configuration complete! #raise Exception(request.session['ivr_call_stack']) # DEBUG #raise Exception(request.session['callCounts']) # DEBUG # Automatically "log" this user in. request.session['authenticated'] = True config = VMBox_Config.objects.get(id=request.session['config_id']) config.config_complete = True config.save() r = twilio.Response() r.append( tts('Your voice mail account is now set up. You may hang up ' 'now, or stay on the line to be taken to your voice mail box home.' )) event = callEvent(callSID=request.POST['CallSid'], event='I_FIN') event.save() r.append( twilio.Redirect(reverse(request.session['ivr_call_stack'].pop()))) request.session.modified = True return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) raise Exception( 'Reached the end of ProviderIVR_Setup. This should never happen.')