Beispiel #1
0
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)
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
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)
Beispiel #5
0
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)
Beispiel #6
0
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)
Beispiel #7
0
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)
Beispiel #8
0
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)
Beispiel #9
0
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)
Beispiel #10
0
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)
Beispiel #11
0
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)
Beispiel #12
0
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)
Beispiel #13
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)
Beispiel #14
0
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)
Beispiel #15
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)
Beispiel #16
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.')
Beispiel #17
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)
Beispiel #18
0
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)
Beispiel #19
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.')