def UnaffiliatedNumber(request): r = twilio.Response() r.append(twilio.Pause()) # one second pause keeps the first words from getting cut off. r.append(tts(_("You have called an inactive phone number affiliated with " "doctorcom. Please visit us online at w w w dot m d com dot com. Good bye."))) r.append(twilio.Hangup()) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def testNestedSayPlayPause(self): """ a gather with a say, play, and pause """ r = Response() g = twiml.Gather() g.append(twiml.Say("Hey")) g.append(twiml.Play("hey.mp3")) g.append(twiml.Pause()) r.append(g) r = self.strip(r) assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Gather><Say>Hey</Say><Play>hey.mp3</Play><Pause /></Gather></Response>')
def improperAppend(self, verb): self.assertRaises(TwimlException, verb.append, twiml.Say("")) self.assertRaises(TwimlException, verb.append, twiml.Gather()) self.assertRaises(TwimlException, verb.append, twiml.Play("")) self.assertRaises(TwimlException, verb.append, twiml.Record()) self.assertRaises(TwimlException, verb.append, twiml.Hangup()) self.assertRaises(TwimlException, verb.append, twiml.Reject()) self.assertRaises(TwimlException, verb.append, twiml.Redirect()) self.assertRaises(TwimlException, verb.append, twiml.Dial()) self.assertRaises(TwimlException, verb.append, twiml.Conference("")) self.assertRaises(TwimlException, verb.append, twiml.Sms("")) self.assertRaises(TwimlException, verb.append, twiml.Pause())
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 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 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 getRecording(request, twilioResponse=None): """ Takes a recording from the user. This function uses the session dictionary at request.session for inputs and outputs. This is necessary because Twilio will make multiple calls to this function. This function differs from getQuickRecording in that it allows a user to confirm their recording. :param request: The standard Django request argument :returns: django.http.HttpResponse -- the result Required Session Keys: request.session['ivr_makeRecording_prompt'] - A Twilio verb object (pretty much always Say or Play) that is used to lead into the recording. e.g., tts('Leave a message.') Optional Session Keys: request.session['ivr_makeRecording_promptOnce'] - A flag that specifies if the prompt should be spoken only once, if True. The stored value must be one that can be tested against for truth. (i.e., the value must be able to be used in an if statement such as, "if (request.session['ivr_makeRecording_promptOnce']):...." request.session['ivr_makeRecording_maxLength'] - The Twilio gather max_length value. Default is 180: 3 minutes. request.session['ivr_makeRecording_timeout'] - The Twilio record timeout value. Default is 5. request.session['ivr_makeRecording_transcribe'] - The Twilio gather transcribe value. Default is False. request.session['ivr_makeRecording_finishOnKey'] - The Twilio gather finishOnKey value. Default is any key. request.session['ivr_makeRecording_playBeep'] - The Twilio gather playBeep value. Default is True. request.session['ivr_makeRecording_leadSilence'] - How many seconds of silence to give before starting any prompts. This is necessary because the first second or so of sound at the very beginning of any Twilio call is lost. Default is 0. request.session['ivr_makeRecording_returnOnHangup'] - The name of the function to return control flow to, should the user hang up on the recording (e.g., to terminate a voicemail message). The function gets called with a single argument -- the standard Django request object, default is None. Output Session Keys: request.session['ivr_makeRecording_recording'] - The Twilio URL of the recording Make sure you clear this key using the 'del' built-in function so that other fucntions can test against it to see if getRecording has succeeded. To "return" to your function, push it onto the end of request.session['ivr_call_stack'], as per the usual IVR philosophy. """ # FIXME: # There's gotta be a less complicated way of doing this. The biggest # complicating factor when writing a generic function for Twilio is that # every time we want to get anything from the user, we need to return and # wait for Twilio to establish a new HTTP connection. # # There are two design patterns that I've come up with so far. The first is # what you see implemented here, where Twilio accesses this function # directly via a REST API we provide. The two biggest problems here are that # it requires us to rely heavily on the session database, and that we become # reliant on Twilio to functionally return to the calling function. This # second problem is generally annoying, but becomes a meaningful problem # when Twilio won't redirect for us -- e.g., when the user hangs up on the # recording. The current solution is to use an eval() statement to directly # call the "caller" function, but this is kind of kludgey. # # The other design pattern is to have Twilio keep calling the "caller" # function, and have that call this function. The problem is that it makes # caller functions more complicated since they have to check the return # data from this function to determine what happened, and potentially keep # track of where this function is, in terms of its execution path across # HTTP connections. # # I'm not sure what we want to do about this. I'm inclined to say that the # latter implementation is going to be somewhat cleaner since we can # probably just pass a tuple of values with state and whatnot, as well as # the return value for the function at large? if 'CallStatus' in request.POST: logger.debug('%s: Into getRecording with call status %s' % ( request.session.session_key, request.POST['CallStatus'])) r = twilioResponse or twilio.Response() request.session.modified = True # First, check to see if the caller has hung up. #if (request.POST['CallStatus'] == 'completed'): if ('CallStatus' in request.POST and request.POST['CallStatus'] == 'completed'): if('RecordingUrl' in request.POST): request.session['ivr_makeRecording_recording'] = request.POST['RecordingUrl'] if 'ivr_makeRecording_recording' in request.session: view = request.session.get('ivr_makeRecording_returnOnHangup', None) if view: try: # TODO: no more exec() but validation on view is needed mod, func = view.rsplit('.', 1) mod = import_module(mod) getattr(mod, func)(request) # call the view function except Exception as e: mail_admins("Problem calling view in getRecording", str(e)) cleanup_recording_state(request) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) if 'RecordingUrl' in request.POST: recording_url = request.POST['RecordingUrl'] p1 = re.compile('http://api.twilio.com/\d{4}-\d{2}-\d{2}/Accounts/AC[0-9a-f]'\ '{32}/Recordings/RE[0-9a-f]{32}$') if (not p1.match(recording_url)): raise Exception(_('Recording url failed to match regex: %s') % (recording_url,)) request.session['ivr_makeRecording_recording'] = recording_url getRecording_playRecordingAndConfirmation(request, r) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) elif ('ivr_makeRecording_recording' in request.session): if 'Digits' in request.POST: digits = request.POST['Digits'] p2 = re.compile('[0-9*#]$') if (not p2.match(digits)): raise Exception('') if (digits == '1'): # User accepted the recording. cleanup_recording_state(request) r.append(twilio.Redirect(reverse(request.session['ivr_call_stack'].pop()))) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) if (digits == '3'): del request.session['ivr_makeRecording_recording'] # And just fall through. User wishes to record again, so pretty much start over. else: getRecording_playRecordingAndConfirmation(request, r) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) else: getRecording_getConfirmation(request, r) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) # Check for required values if (not 'ivr_makeRecording_prompt' in request.session): raise Exception(_('Error. Required session key \'ivr_makeRecording_prompt\' undefined.')) # Set up default values if (not 'ivr_makeRecording_promptOnce' in request.session): request.session['ivr_makeRecording_promptOnce'] = False if (not 'ivr_makeRecording_maxLength' in request.session): request.session['ivr_makeRecording_maxLength'] = 180 if (not 'ivr_makeRecording_timeout' in request.session): request.session['ivr_makeRecording_timeout'] = 5 if (not 'ivr_makeRecording_transcribe' in request.session): request.session['ivr_makeRecording_transcribe'] = False if (not 'ivr_makeRecording_finishOnKey' in request.session): request.session['ivr_makeRecording_finishOnKey'] = '1234567890*#' if (not 'ivr_makeRecording_playBeep' in request.session): request.session['ivr_makeRecording_playBeep'] = True if (not 'ivr_makeRecording_leadSilence' in request.session): request.session['ivr_makeRecording_leadSilence'] = 0 if (not 'ivr_makeRecording_returnOnHangup' in request.session): request.session['ivr_makeRecording_returnOnHangup'] = None if (request.session['ivr_makeRecording_promptOnce']): if (not 'ivr_makeRecording_promptOnce_played' in request.session): request.session['ivr_makeRecording_promptOnce_played'] = True r.append(request.session['ivr_makeRecording_prompt']) else: r.append(request.session['ivr_makeRecording_prompt']) if (request.session['ivr_makeRecording_leadSilence']): r.append(twilio.Pause(length=request.session['ivr_makeRecording_leadSilence'])) r.append(twilio.Record( action=reverse('getRecording'), maxLength=request.session['ivr_makeRecording_maxLength'], timeout=request.session['ivr_makeRecording_timeout'], finishOnKey=request.session['ivr_makeRecording_finishOnKey'], transcribe=request.session['ivr_makeRecording_transcribe'], playBeep=request.session['ivr_makeRecording_playBeep'], )) r.append(twilio.Redirect(reverse('getRecording'))) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
def getQuickRecording(request): """Takes a recording from the user. This function uses the session dictionary at request.session for inputs and outputs. This is done to maintain code base flexibility with this and getRecording. This function differs from getRecording in that strictly gets a recording from the user, without allowing the user to confirm that they wish to keep the recording. :param request: The standard Django request argument :returns: django.http.HttpResponse -- the result Required Session Keys: request.session['ivr_makeRecording_prompt'] - A Twilio verb object (pretty much always Say or Play) that is used to lead into the recording. e.g., tts('Leave a message.') Optional Session Keys: request.session['ivr_makeRecording_maxLength'] - The Twilio gather max_length value. Default is 5: 5 seconds. request.session['ivr_makeRecording_timeout'] - The Twilio record timeout value. Default is 6. request.session['ivr_makeRecording_leadSilence'] - How many seconds of silence to give before starting any prompts. This is necessary because the first second or so of sound at the very beginning of any Twilio call is lost. Default is 1. request.session['ivr_makeRecording_playBeep'] - Set to True if you want the recording to be prompted with a tone. Default is True. request.session['ivr_makeRecording_finishOnKey'] - The Twilio gather finishOnKey value. Default is any key. Output Session Keys: request.session['ivr_makeRecording_recording'] - The Twilio URL of the recording Make sure you clear this key using the 'del' built-in function so that other fucntions can test against it to see if getRecording has succeeded. To "return" to your function, push it onto the end of request.session['ivr_call_stack'], as per the usual IVR philosophy. """ if 'CallStatus' in request.POST: logger.debug('%s: Into getQuickRecording with call status %s' % ( request.session.session_key, request.POST['CallStatus'])) r = twilio.Response() request.session.modified = True request.session['ivr_only_callbacknumber'] = True if 'CallStatus' in request.POST and request.POST['CallStatus'] == 'completed': view = request.session.get('ivr_makeRecording_returnOnHangup', None) if view: # The user hung up. Return out and tell twilio no message recorded. request.session['ivr_no_pound'] = True if 'RecordingUrl' in request.POST: request.session['ivr_makeRecording_recording'] = request.POST['RecordingUrl'] request.session['ivr_only_callbacknumber'] = False else: request.session['ivr_only_callbacknumber'] = True try: # TODO: no more exec() but validation on view is needed mod, func = view.rsplit('.', 1) mod = import_module(mod) getattr(mod, func)(request) # call the view function except Exception as e: mail_admins("Problem calling view in getQuickRecording", str(e)) cleanup_recording_state(request) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) if 'CallStatus' in request.POST and 'RecordingUrl' in request.POST: if request.POST['CallStatus'] == 'completed': # The user hung up. Return out and tell Twilio to do nothing. return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) recording_url = request.POST['RecordingUrl'] p1 = re.compile('http://api.twilio.com/\d{4}-\d{2}-\d{2}/Accounts/AC[0-9a-f]{32}'\ '/Recordings/RE[0-9a-f]{32}$') if (not p1.match(recording_url)): raise Exception(_('Recording url failed to match regex: %s') % (recording_url,)) request.session['ivr_makeRecording_recording'] = recording_url request.session['ivr_only_callbacknumber'] = False cleanup_recording_state(request) del request.session['getQuickRecording_subsequentExcecution'] r.append(twilio.Redirect(reverse(request.session['ivr_call_stack'].pop()))) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE) # Check for required values if (not 'ivr_makeRecording_prompt' in request.session): raise Exception(_('Error. Required session key \'ivr_makeRecording_prompt\' ' 'undefined. Request.method is %s.') % (request.POST,)) # Set up default values if (not 'ivr_makeRecording_maxLength' in request.session): request.session['ivr_makeRecording_maxLength'] = 5 if (not 'ivr_makeRecording_timeout' in request.session): request.session['ivr_makeRecording_timeout'] = 6 if (not 'ivr_makeRecording_leadSilence' in request.session): request.session['ivr_makeRecording_leadSilence'] = 1 if (not 'ivr_makeRecording_playBeep' in request.session): request.session['ivr_makeRecording_playBeep'] = True if (not 'ivr_makeRecording_finishOnKey' in request.session): request.session['ivr_makeRecording_finishOnKey'] = '1234567890*#' # Use this to keep track of if we've been through here before. if ('getQuickRecording_subsequentExcecution' in request.session): r.append(tts('Sorry, I didn\'t get that.')) request.session['getQuickRecording_subsequentExcecution'] = True if (request.session['ivr_makeRecording_leadSilence']): r.append(twilio.Pause(length=request.session['ivr_makeRecording_leadSilence'])) r.append(request.session['ivr_makeRecording_prompt']) r.append(twilio.Record( action=reverse('getQuickRecording'), maxLength=request.session['ivr_makeRecording_maxLength'], finishOnKey=request.session['ivr_makeRecording_finishOnKey'], timeout=request.session['ivr_makeRecording_timeout'], playBeep=request.session['ivr_makeRecording_playBeep'], )) r.append(twilio.Redirect(reverse('getQuickRecording'))) #raise Exception(str(r)) return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)