Esempio n. 1
0
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)
Esempio n. 2
0
 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>')
Esempio n. 3
0
 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())
Esempio n. 4
0
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)
Esempio n. 5
0
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.')
Esempio n. 6
0
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)
Esempio n. 7
0
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)
Esempio n. 8
0
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)
Esempio n. 9
0
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)