コード例 #1
0
ファイル: views_generic.py プロジェクト: cnzhuran/mdcom
def getRecording_playRecordingAndConfirmation(request, twilioResponse):
	gather = twilio.Gather(numDigits=1, finishOnKey='', action=reverse('getRecording'))
	gather.append(tts(_("You said")))
	gather.append(twilio.Play(request.session['ivr_makeRecording_recording']))
	gather.append(tts(_('If you wish to record again, please press three.'
			'Press one to continue. Press any other key to replay the recording.')))
	twilioResponse.append(gather)
	twilioResponse.append(twilio.Redirect())
コード例 #2
0
 def testRedirectEmpty(self):
     r = Response()
     r.append(twiml.Redirect())
     r = self.strip(r)
     self.assertEquals(
         r,
         '<?xml version="1.0" encoding="UTF-8"?><Response><Redirect /></Response>'
     )
コード例 #3
0
 def testRedirectMethod(self):
     r = Response()
     r.append(twiml.Redirect(url="example.com", method="POST"))
     r = self.strip(r)
     self.assertEquals(
         r,
         '<?xml version="1.0" encoding="UTF-8"?><Response><Redirect method="POST">example.com</Redirect></Response>'
     )
コード例 #4
0
ファイル: test_twiml.py プロジェクト: kazuar/twilio-python
 def testRedirectMethodGetParams(self):
     r = Response()
     r.append(
         twiml.Redirect(url="example.com?id=34&action=hey", method="POST"))
     r = self.strip(r)
     assert_equal(
         r,
         '<?xml version="1.0" encoding="UTF-8"?><Response><Redirect method="POST">example.com?id=34&amp;action=hey</Redirect></Response>'
     )
コード例 #5
0
def PracticeIVR_Options_Actions(request, internalCall=False):
	"""
	changes setting on doctor com number for practice
	"""
	#practice = PracticeLocation.objects.get(id=request.session['practice_id'])
	logger.debug('%s: PracticeIVR_Options_Actions POST data is %s' % (
		request.session.session_key, str(request.POST)))

	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 = twilio.Response()
			r.append(tts(_('I\'m sorry, I didn\'t understand that.')))
		elif (digits == '1'):
			# Change name
			request.session['ivr2_sub_state'] = 'PracticeIVR_Options_1'
			request.session.modified = True
			return changeNameNew(request)
		elif (digits == '3'):
			# Change closed greeting - ivr2_setup_stage to indicate which greeting
#			request.session['ivr2_setup_stage'] = 3  # deprecated
			request.session['ivr2_sub_state'] = 'PracticeIVR_Options_2'
			request.session.modified = True
			return changeGreetingNew(request)
		elif (digits == '5'):
			# change temporarily closed office greeting
#			request.session['ivr2_setup_stage'] = 5  # deprecated
			request.session['ivr2_sub_state'] = 'PracticeIVR_Options_3'
			request.session.modified = True
			return changeGreetingNew(request)
		elif (digits == '7'):
			# change pin
			request.session['ivr2_sub_state'] = 'PracticeIVR_Options_4'
			request.session.modified = True
			return changePinNew(request)
		elif (digits == '9'):
			# Return to the main menu
			r = twilio.Response()
			request.session['ivr2_state'] = 'PracticeIVR_TreeRoot_New'
			r.append(twilio.Redirect(reverse('PracticeIVR_TreeRoot_New')))
			return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
		elif (digits == '*'):
			# Repeat menu
			r = twilio.Response()
			pass
		else:
			r = twilio.Response()
			r.append(tts(_('I\'m sorry, that wasn\'t a valid selection.')))
		return PracticeIVR_Options_New(request, r)
	else:
		# should never happen but if we get here, we log and goto main
		logger.debug('%s: PracticeIVR_Options_Actions is called with no post or digits' % (
			request.session.session_key))
		request.session['ivr2_state'] = 'PracticeIVR_Main_New'
		return PracticeIVR_Main_New(request)
コード例 #6
0
 def testImproperNesting(self):
     """ bad nesting """
     verb = twiml.Gather()
     self.assertRaises(TwimlException, verb.append, twiml.Gather())
     self.assertRaises(TwimlException, verb.append, twiml.Record())
     self.assertRaises(TwimlException, verb.append, twiml.Hangup())
     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(""))
コード例 #7
0
ファイル: views_provider.py プロジェクト: cnzhuran/mdcom
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)
コード例 #8
0
ファイル: test_twiml.py プロジェクト: B-Rich/twilio-python
 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())
コード例 #9
0
ファイル: views_generic.py プロジェクト: cnzhuran/mdcom
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)
コード例 #10
0
ファイル: views_provider_v2.py プロジェクト: cnzhuran/mdcom
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)
コード例 #11
0
def PracticeIVR_CallerResponse_New(request, twilioResponse=None):
	"""
	This function process callers response - set up practice greeting based on practice hours and
	callgroups and specialties (via create_dynamic_greeting)
	"""
	request.session['ivr2_state'] = 'PracticeIVR_CallerResponse_New'
	practice = PracticeLocation.objects.get(id=request.session['practice_id'])
	logger.debug('%s: PracticeIVR_CallerResponse_New state %s practice %s' % (
		request.session.session_key, request.session['ivr2_state'], practice))

	r = twilioResponse or twilio.Response()
	gather = twilio.Gather(action=reverse('PracticeIVR_CallerResponse_Action'),
		finishOnKey='', numDigits=1, timeout=60)
	if (not 'practice_greeting' in request.session):
		if (practice.is_open()):
			request.session['practice_greeting'] = practice.greeting_lunch
		else:
			request.session['practice_greeting'] = practice.greeting_closed

	if(practice.skip_to_rmsg and practice.is_open()):
		request.session['ivr2_state'] = 'PracticeIVR_LeaveRegularMsg_New'
		r.append(twilio.Play(request.session['practice_greeting']))
		r.append(twilio.Redirect(reverse('PracticeIVR_LeaveRegularMsg_New')))
		logger.debug('%s: PracticeIVR_CallerResponse_New skip to leave msg for %s open greeting' % (
			request.session.session_key, practice))
	else:
		if practice.uses_original_answering_serice():
			gather.append(twilio.Play(request.session['practice_greeting']))
			r.append(gather)
			logger.debug('%s: PracticeIVR_CallerResponse_New practice %s orig greeting' % (
				request.session.session_key, practice))
		else:
			#layer 1 greeting, it recites call group lists,
			#populates  request.session['call_groups_map'] and request.session['specialty_map']
			dynamic_greeting = create_dynamic_greeting(request, practice)
			request.session['last_played'] = dynamic_greeting
			gather.append(twilio.Play(request.session['practice_greeting']))
			gather.append(tts(_('%s.') % (''.join(request.session['last_played']))))
			r.append(gather)
			logger.debug('%s: PracticeIVR_CallerResponse_New practice %s greeting %s' % (
				request.session.session_key, practice, request.session['last_played']))

	return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
コード例 #12
0
ファイル: views_generic.py プロジェクト: cnzhuran/mdcom
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)
コード例 #13
0
 def testAddAttribute(self):
     """ add attribute """
     r = twiml.Redirect("", foo="bar")
     r = self.strip(r)
     assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Redirect foo="bar" />')
コード例 #14
0
ファイル: views_generic.py プロジェクト: cnzhuran/mdcom
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)
コード例 #15
0
ファイル: views_generic.py プロジェクト: cnzhuran/mdcom
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)
コード例 #16
0
ファイル: views_provider_v2.py プロジェクト: cnzhuran/mdcom
def ProviderIVR_ForwardCall_New(request, provider=None, twilioResponse=None):
    """
	new version of ProviderIVR_ForwardCall - forward call to dialed user as per user preference
	called by ProviderIVR_Main_New
	Steps:
	1. get name
	2. Dial - based on provider.forward_voicemail state to Mobile, office, other (VM already handled)
	3. After dialed: handle failure by going to LeaveMsg or hangup?
	"""
    assert (request.session['provider_id'])
    provider = Provider.objects.get(id=request.session['provider_id'])
    logger.debug(
        '%s: ProviderIVR_ForwardCall_New is initiated provider %s state %s substate %s POST %s'
        % (request.session.session_key, provider,
           request.session.get('ivr2_state', None),
           request.session.get('ivr2_sub_state', None), str(request.POST)))
    callEnded = _checkCallbackDuration(request, False)

    # check user forwarding preference
    forward = provider.forward_voicemail
    if (forward == 'VM'):
        # go to voicemail
        request.session['ivr2_state'] = 'ProviderIVR_LeaveMsg_New'
        logger.debug(
            '%s: ProviderIVR_ForwardCall_New forwarding to voicemail of %s' %
            (request.session.session_key, provider))
        return ProviderIVR_LeaveMsg_New(request)

    # State processing - 1. get caller name or ask for it
    r = twilioResponse or twilio.Response()
    if ('ivr2_sub_state' not in request.session):
        request.session['ivr2_sub_state'] = 'ProviderIVR_ForwardCall_Start'
    else:
        logger.debug(
            '%s: ProviderIVR_ForwardCall_New sub_state %s' %
            (request.session.session_key, request.session['ivr2_sub_state']))
    if (request.session['ivr2_sub_state'] == 'ProviderIVR_ForwardCall_Start'):
        request.session['ivr2_sub_state'] = 'ProviderIVR_ForwardCall_GetName'
        # is this a doctorcom user with recorded name?
        callSID = request.POST['CallSid']
        log = callLog.objects.get(callSID=callSID)
        if (log.mdcom_caller and isinstance(log.mdcom_caller, Provider)):
            if (log.mdcom_caller.vm_config.count()):
                prov_vmconfig = log.mdcom_caller.vm_config.get()
                if (prov_vmconfig.config_complete):
                    logger.debug('%s/%s: Found the caller\'s name!' % (
                        request.session.session_key,
                        request.session['ivr2_state'],
                    ))
                    log.caller_spoken_name = prov_vmconfig.name
                    log.save()
                    # got the recorded name; just go back to the next step - Dial
                    return ProviderIVR_ForwardCall_New(request, provider,
                                                       r)  # next step
                else:
                    logger.debug(
                        '%s/%s: ProviderIVR_ForwardCall_New GetName: Caller\'s '
                        'vm_config incomplete!' %
                        (request.session.session_key,
                         request.session['ivr2_state']))
            else:
                logger.debug(
                    '%s/%s: ProviderIVR_ForwardCall_New GetName: unsuitable '
                    'number of vm_config objects found: %i' %
                    (request.session.session_key,
                     request.session['ivr2_state'],
                     log.mdcom_caller.vm_config.count()))
        else:
            logger.debug(
                '%s/%s: ProviderIVR_ForwardCall_New GetName: mdcom_caller %s '
                'either isn\'t defined or doesn\'t seem to be a Provider' %
                (request.session.session_key, request.session['ivr2_state'],
                 str(log.mdcom_caller)))

        # Not a user with a name recording. Get one.
        # ivr2_state already set to ProviderIVR_ForwardCall_GetName
        request.session[
            'ivr2_Record_prompt_str'] = 'Please say your name after the tone.'
        request.session['ivr2_Record_maxLength'] = 4
        request.session['ivr2_Record_timeout'] = 2
        request.session['ivr2_Record_leadSilence'] = 1
        return getQuickRecordingNew(request)

    elif (request.session['ivr2_sub_state'] ==
          'ProviderIVR_ForwardCall_GetName'):
        request.session['ivr2_sub_state'] = 'ProviderIVR_ForwardCall_Dial'
        # save the caller name
        callSID = request.POST['CallSid']
        log = callLog.objects.get(callSID=callSID)
        if (not log.caller_spoken_name):
            log.caller_spoken_name = request.session['ivr2_Record_recording']
            del request.session['ivr2_Record_recording']
            log.save()
        # Okay, let's find number to dial!
        user_number = None
        if (forward == 'MO'):
            user_number = provider.user.mobile_phone
        elif (forward == 'OF'):
            user_number = provider.office_phone
        elif (forward == 'OT'):
            user_number = provider.user.phone
        logger.debug(
            '%s/%s: ProviderIVR_ForwardCall_New Dial user number is \'%s\' forward %s'
            % (request.session.session_key, request.session['ivr2_state'],
               user_number, forward))

        if (not user_number):
            # no flags were set.
            if (provider.user.mobile_phone):
                user_number = provider.user.mobile_phone
            else:
                return ProviderIVR_LeaveMsg_New(request, r)
        # when dial action is done, we go back to its actionurl - which is here with state Dial
        dial = twilio.Dial(
            action=reverse('ProviderIVR_ForwardCall_New'),
            timeout=22,
            timeLimit=14400,  # 4 hours
            callerId=_makeUSNumber(request.session['Caller']))
        # we also want to allow call vetting
        dial.append(
            twilio.Number(user_number,
                          url=reverse('ProviderIVR_ForwardCall_Vet')))
        r.append(dial)
        # If the call did not connect, we go to LeaveMsg
        r.append(twilio.Redirect(reverse('ProviderIVR_LeaveMsg_New')))
        return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)

    elif (request.session['ivr2_sub_state'] == 'ProviderIVR_ForwardCall_Dial'):
        # done with forward call
        del request.session['ivr2_sub_state']
        # need to get parent call log for caller and connected; also update child log for duration
        (log, plog) = _getCallLogOrParent(request)
        if log:
            logger.debug(
                '%s/%s: ProviderIVR_ForwardCall_New state connected %s' %
                (request.session.session_key, request.session['ivr2_state'],
                 str(log.call_connected)))
        else:
            logger.debug(
                '%s/%s: ProviderIVR_ForwardCall_New state no log SID %s' %
                (request.session.session_key, request.session['ivr2_state'],
                 request.POST['CallSid']))
        if ('DialCallStatus' in request.POST):
            if (request.POST['DialCallStatus'] == 'completed'):
                # update child log call duration
                diallog = callLog.objects.get(
                    callSID=request.POST['DialCallSid'])
                if diallog:
                    diallog.call_duration = request.POST['DialCallDuration']
                    diallog.save()
                    logger.debug(
                        '%s: ProviderIVR_ForwardCall_New update child diallog '
                        'dialSid %s duration %s' %
                        (request.session.session_key,
                         request.POST['DialCallSid'],
                         request.POST['DialCallDuration']))
                else:
                    logger.debug(
                        '%s: ProviderIVR_ForwardCall_New diallog not found: dialSid %s duration %s'
                        % (request.session.session_key,
                           request.POST['DialCallSid'],
                           request.POST['DialCallDuration']))
                # Do nothing so that the second leg call continues un-interrupted
                return HttpResponse(str(r),
                                    mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
            else:
                # (request.POST['DialCallStatus'] != 'completed'):
                logger.debug(
                    '%s/%s: ProviderIVR_ForwardCall_New DialStatus not answered'
                    % (request.session.session_key,
                       request.session['ivr2_state']))
                if (request.POST['DialCallStatus'] == 'failed'):
                    # TODO: Figure out how to deal with connection problems. Most
                    # likely, send an email to the user and administrators.
                    logger.debug(
                        '%s/%s: ProviderIVR_ForwardCall_New DialStatus failed'
                        % (request.session.session_key,
                           request.session['ivr2_state']))
                    subject = 'ProviderIVR_ForwardCall Call Forward DialStatus Fail'
                    message = 'ProviderIVR_ForwardCall got DialStatus failed. Post data: %s' \
                     % (str(request.POST),)
                    mail_admins(subject=subject,
                                message=message,
                                fail_silently=False)
                # else request.POST['DialStatus'] == 'busy' or request.POST['DialStatus'] == 'no-answer'
                return ProviderIVR_LeaveMsg_New(request, r)
        # if we connected (in Vet), we hang up here
        if (log.call_connected):
            r.append(twilio.Hangup())
            return HttpResponse(str(r),
                                mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
        # if not connected, we go to LeaveMsg
        return ProviderIVR_LeaveMsg_New(request, r)
コード例 #17
0
ファイル: views_provider_v2.py プロジェクト: cnzhuran/mdcom
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)
コード例 #18
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)
コード例 #19
0
ファイル: views_generic.py プロジェクト: cnzhuran/mdcom
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)
コード例 #20
0
ファイル: views_provider.py プロジェクト: cnzhuran/mdcom
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.')
コード例 #21
0
ファイル: views_provider.py プロジェクト: cnzhuran/mdcom
def ProviderIVR_ForwardCall(request):
    """Forward the call to the dialed user, as per the user's preferences.

	Uses the following session variables:
		ProviderIVR_ForwardCall_state: The most recent "state" of execution. May
			have the following values:
				- None/Undefined/Empty String: First execution of this function.
				- Getting_Name: Getting the caller's name, if one hasn't been
						defined.
				- Dialing: Phone(s) have been dialed, and waiting for a response Caller
	"""
    r = twilio.Response()
    request.session.modified = True
    provider = Provider.objects.get(id=request.session['provider_id'])

    if ('CallStatus' in request.POST
            and request.POST['CallStatus'] == 'completed'):
        if ('Duration' in request.POST):
            callSID = request.POST['CallSid']
            log = callLog.objects.get(callSID=callSID)
            log.call_duration = request.POST['Duration']
            log.save()

    if (not 'ProviderIVR_ForwardCall_forward' in request.session):
        request.session[
            'ProviderIVR_ForwardCall_forward'] = provider.forward_voicemail
    forward = provider.forward_voicemail
    if (forward == 'VM'):
        return ProviderIVR_LeaveMsg(request)

    if (not 'ProviderIVR_ForwardCall_state' in request.session
            or not request.session['ProviderIVR_ForwardCall_state']):
        # New call. First, check to see if we should go straight to voicemail

        # Okay, the call isn't going to voicemail directly. Now, set state.
        request.session['ProviderIVR_ForwardCall_state'] = 'Getting_Name'

        # Now, get the caller's name

        # Is the user a DoctorCom user with a recorded name?
        callSID = request.POST['CallSid']
        log = callLog.objects.get(callSID=callSID)

        if (log.mdcom_caller and isinstance(log.mdcom_caller, Provider)):
            if (log.mdcom_caller.vm_config.count()):
                prov_vmconfig = log.mdcom_caller.vm_config.get()
                if (prov_vmconfig.config_complete):
                    logger.debug('%s/%s: Found the caller\'s name!' % (
                        request.session.session_key,
                        request.session['ProviderIVR_ForwardCall_state'],
                    ))
                    log.caller_spoken_name = prov_vmconfig.name
                    log.save()
                    return ProviderIVR_ForwardCall(
                        request)  # restart execution of this function
                else:
                    logger.debug('%s/%s: Caller\'s vm_config incomplete!' % (
                        request.session.session_key,
                        request.session['ProviderIVR_ForwardCall_state'],
                    ))
            else:
                logger.debug(
                    '%s/%s: An unsuitable number of vm_config objects found: %i'
                    % (
                        request.session.session_key,
                        request.session['ProviderIVR_ForwardCall_state'],
                        log.mdcom_caller.vm_config.count(),
                    ))
        else:
            logger.debug(
                '%s/%s: mdcom_caller %s either isn\'t defined or doesn\'t '
                'seem to be a Provider' % (
                    request.session.session_key,
                    request.session['ProviderIVR_ForwardCall_state'],
                    str(log.mdcom_caller),
                ))

        # Okay, it's not a user with a name recording. Get one.
        request.session['ivr_call_stack'].append('ProviderIVR_ForwardCall')
        request.session['ivr_makeRecording_prompt'] = \
         tts('Please say your name after the tone.')
        request.session['ivr_makeRecording_maxLength'] = 4
        request.session['ivr_makeRecording_timeout'] = 2
        request.session['ivr_makeRecording_leadSilence'] = 1
        return getQuickRecording(request)

    if (request.session['ProviderIVR_ForwardCall_state'] == 'Getting_Name'):
        request.session['ProviderIVR_ForwardCall_state'] = 'Dialed'

        logger.debug('%s/%s: Set session to %s' % (
            request.session.session_key,
            request.session['ProviderIVR_ForwardCall_state'],
            request.session['ProviderIVR_ForwardCall_state'],
        ))

        callSID = request.POST['CallSid']
        log = callLog.objects.get(callSID=callSID)
        if (not log.caller_spoken_name):
            log.caller_spoken_name = request.session.pop(
                'ivr_makeRecording_recording')
            log.save()

        logger.debug('%s/%s: got provider \'%s\' \'%s\' with id %s' % (
            request.session.session_key,
            request.session['ProviderIVR_ForwardCall_state'],
            provider.first_name,
            provider.last_name,
            provider.pk,
        ))
        logger.debug(
            '%s/%s: Provider phone is \'%s\' and forward_other is \'%s\'' % (
                request.session.session_key,
                request.session['ProviderIVR_ForwardCall_state'],
                provider.user.phone,
                str(provider.forward_other),
            ))

        # Okay, let's dial!
        user_number = None
        if (forward == 'MO'):
            logger.debug('%s/%s: provider.forward_mobile True' % (
                request.session.session_key,
                request.session['ProviderIVR_ForwardCall_state'],
            ))
            user_number = provider.user.mobile_phone
            logger.debug('%s/%s: Setting user_number to \'%s\'' % (
                request.session.session_key,
                request.session['ProviderIVR_ForwardCall_state'],
                provider.user.mobile_phone,
            ))
        elif (forward == 'OF'):
            logger.debug('%s/%s: provider.forward_office True' % (
                request.session.session_key,
                request.session['ProviderIVR_ForwardCall_state'],
            ))
            user_number = provider.office_phone
            logger.debug('%s/%s: Setting user_number to \'%s\'' % (
                request.session.session_key,
                request.session['ProviderIVR_ForwardCall_state'],
                provider.office_phone,
            ))
        elif (forward == 'OT'):
            logger.debug('%s/%s: provider.forward_other True' % (
                request.session.session_key,
                request.session['ProviderIVR_ForwardCall_state'],
            ))
            user_number = provider.user.phone
            logger.debug('%s/%s: Setting user_number to \'%s\'' % (
                request.session.session_key,
                request.session['ProviderIVR_ForwardCall_state'],
                provider.user.phone,
            ))

        logger.debug('%s/%s: Tried to get called\'s number. Got \'%s\'' % (
            request.session.session_key,
            request.session['ProviderIVR_ForwardCall_state'],
            user_number,
        ))
        logger.debug(
            '%s/%s: Provider phone is \'%s\' and forward_other is \'%s\'' % (
                request.session.session_key,
                request.session['ProviderIVR_ForwardCall_state'],
                provider.user.phone,
                str(provider.forward_other),
            ))

        if (not user_number):
            # no flags were set.
            if (provider.user.mobile_phone):
                user_number = provider.user.mobile_phone
            else:
                return ProviderIVR_LeaveMsg(request)

        dial = twilio.Dial(
            action=reverse('ProviderIVR_ForwardCall'),
            timeout=22,
            timeLimit=14400,  # 4 hours
            callerId=request.session['Caller'])
        dial.append(
            twilio.Number(user_number,
                          url=reverse('ProviderIVR_ForwardCall_VetAnswer')))
        r.append(dial)
        r.append(twilio.Redirect(reverse('ProviderIVR_LeaveMsg')))
        return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)

    if (request.session['ProviderIVR_ForwardCall_state'] == 'Dialed'):
        callSID = request.POST['CallSid']
        log = callLog.objects.get(callSID=callSID)

        if (log.call_connected):
            r.append(twilio.Hangup())
            return HttpResponse(str(r),
                                mimetype=settings.TWILIO_RESPONSE_MIMETYPE)

        return ProviderIVR_LeaveMsg(request)

    r = twilio.Response()
    if (request.POST['DialStatus'] != 'answered'):
        if (request.POST['DialStatus'] == 'failed'):
            # TODO: Figure out how to deal with connection problems. Most
            # likely, send an email to the user and administrators.
            subject = 'ProviderIVR_ForwardCall Call Forward DialStatus Fail'
            message = 'ProviderIVR_ForwardCall got DialStatus failed. Post data: %s' % \
             (str(request.POST),)
            mail_admins(subject=subject, message=message, fail_silently=False)
        # else request.POST['DialStatus'] == 'busy' or request.POST['DialStatus'] == 'no-answer'
        return ProviderIVR_LeaveMsg(request)
    # else: Do nothing so that the call continues un-interrupted
    return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
コード例 #22
0
ファイル: views_generic.py プロジェクト: cnzhuran/mdcom
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)
コード例 #23
0
def PracticeIVR_ForwardCall_New(request, twilioResponse=None):
	"""
	Forward the call to the dialed user, there are no preferences
	for office managers, just call their cell phone
	Done in 3 steps:
	1. get caller name
	2. forward call
	3. if connected, done; if fail to connect, go to LeaveUrgentMsg_New
	"""
	provider = None
	forward = None
	try:
		provider = Provider.objects.get(id=request.session['provider_id'])
		if(not 'ProviderIVR_ForwardCall_forward' in request.session):
			request.session['ProviderIVR_ForwardCall_forward'] = provider.forward_anssvc
		forward = provider.forward_anssvc
	except Provider.DoesNotExist:
		pass
	logger.debug('%s: PracticeIVR_ForwardCall_New provider %s practice %s state %s substate %s' % (
		request.session.session_key, provider, request.session.get('practice_id', None), 
		request.session.get('ivr2_state', None), request.session.get('ivr2_sub_state', None)))

	callSID = request.POST['CallSid']
	# TODO - what if we don't get the callLog?
	log = callLog.objects.get(callSID=callSID)
	log.call_source = 'AS'
	log.save()

	if('click2call' in request.session):
		forward = 'MO'  # hack to keep click2call working

	if(forward == 'VM'):
		request.session['ivr2_state'] = 'PracticeIVR_LeaveUrgentMsg_New'
		logger.debug('%s: PracticeIVR_ForwardCall_New forward to VM - LeaveUrgentMsg_New to %s' % (
			request.session.session_key, provider))
		return PracticeIVR_LeaveUrgentMsg_New(request)

	r = twilioResponse or twilio.Response()
	if ('ivr2_sub_state' not in request.session):
		request.session['ivr2_sub_state'] = 'PracticeIVR_ForwardCall_Start'
	else:
		logger.debug('%s: PracticeIVR_ForwardCall_New sub_state %s' % (
			request.session.session_key, request.session['ivr2_sub_state']))
	# now we get caller name, dial and handle failure to connect by going to leave urgent message
	if (request.session['ivr2_sub_state'] == 'PracticeIVR_ForwardCall_Start'):
		request.session['ivr2_sub_state'] = 'PracticeIVR_ForwardCall_GetName'

		# Is the user a DoctorCom user with a recorded name?
		if (log.mdcom_caller and isinstance(log.mdcom_caller, Provider)):
			if (log.mdcom_caller.vm_config.count()):
				prov_vmconfig = log.mdcom_caller.vm_config.get()
				if (prov_vmconfig.config_complete):
					logger.debug('%s/%s sub %s: Found the caller\'s name! Forwarding call' % (
							request.session.session_key, request.session['ivr2_state'],
							request.session['ivr2_sub_state'],
						))
					log.caller_spoken_name = prov_vmconfig.name
					log.save()
					return PracticeIVR_ForwardCall_New(request, r)  # restart execution of this function
				else:
					logger.debug('%s/%s sub %s: Caller\'s vm_config incomplete!' % (
							request.session.session_key, request.session['ivr2_state'],
							request.session['ivr2_sub_state'],
						))
			else:
				logger.debug('%s/%s sub %s: An unsuitable number of vm_config objects found: %i' % (
						request.session.session_key, request.session['ivr2_state'],
						request.session['ivr2_sub_state'],
						log.mdcom_caller.vm_config.count(),
					))
		else:
			logger.debug('%s/%s sub %s: mdcom_caller %s either isn\'t defined or doesn\'t seem to be a Provider' % (
					request.session.session_key, request.session['ivr2_state'],
					request.session['ivr2_sub_state'],
					str(log.mdcom_caller),
				))

		# Okay, it's not a user with a name recording. Get one.
		request.session['ivr2_Record_prompt_str'] = 'Please say your name after the tone.'
		request.session['ivr2_Record_maxLength'] = 4
		request.session['ivr2_Record_timeout'] = 2
		request.session['ivr2_Record_leadSilence'] = 1
		return getQuickRecordingNew(request)

	elif (request.session['ivr2_sub_state'] == 'PracticeIVR_ForwardCall_GetName'):
		request.session['ivr2_sub_state'] = 'PracticeIVR_ForwardCall_Dial'
		# save caller name
		logger.debug('%s/%s: Set session to %s' % (
				request.session.session_key, request.session['ivr2_state'],
				request.session['ivr2_sub_state']
			))
		if (not log.caller_spoken_name):
			log.caller_spoken_name = request.session['ivr2_Record_recording']
			del request.session['ivr2_Record_recording']
			log.save()
		# now find the number to dial
		user_number = ''
		try:
			office_staff = OfficeStaff.objects.get(user=request.session['provider_id'])  # manager being called
			logger.debug('%s/%s: got office staff \'%s\' \'%s\' with id %s office phone \'%s\'.' % (
					request.session.session_key,
					request.session['ivr2_state'],
					office_staff.user.first_name,
					office_staff.user.last_name,
					office_staff.pk,
					office_staff.user.mobile_phone,
				))
			user_number = office_staff.user.mobile_phone
		except OfficeStaff.DoesNotExist:
			#it's a provider
			if(forward == 'MO'):
				user_number = provider.mobile_phone
			elif(forward == 'OF'):
				user_number = provider.office_phone
			elif(forward == 'OT'):
				user_number = provider.phone

		logger.debug('%s/%s: Setting user_number to \'%s\'' % (
					request.session.session_key,
					request.session['ivr2_state'],
					user_number,
				))

		logger.debug('%s/%s: Tried to get called\'s number. Got \'%s\'' % (
				request.session.session_key,
				request.session['ivr2_state'],
				user_number,
			))

		dial = twilio.Dial(
				action=reverse('PracticeIVR_ForwardCall_New'),
				timeout=22,
				timeLimit=14400,  # 4 hours
				callerId=request.session['Caller'],
			)
		dial.append(twilio.Number(user_number,
				url=reverse('PracticeIVR_ForwardCall_Vet')
			))
		r.append(dial)
		r.append(twilio.Redirect(reverse('PracticeIVR_LeaveUrgentMsg_New')))
		return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)

	elif (request.session['ivr2_sub_state'] == 'PracticeIVR_ForwardCall_Dial'):
		del request.session['ivr2_sub_state']
		(clog, plog) = _getCallLogOrParent(request)
		if clog:
			logger.debug('%s/%s: PracticeIVR_ForwardCall_New state connected %s' % (
				request.session.session_key, request.session['ivr2_state'],
				str(clog.call_connected)))
		else:
			logger.debug('%s/%s: ProviderIVR_ForwardCall_New state no log SID %s' % (
				request.session.session_key, request.session['ivr2_state'],
				request.POST['CallSid']))
		if ('DialCallStatus' in request.POST):
			if (request.POST['DialCallStatus'] == 'completed'):
				# update child log call duration
				diallog = callLog.objects.get(callSID=request.POST['DialCallSid'])
				if diallog:
					diallog.call_duration = request.POST['DialCallDuration']
					diallog.save()
					logger.debug('%s: PracticeIVR_ForwardCall_New update child diallog dialSid %s duration %s' % (
						request.session.session_key, request.POST['DialCallSid'], request.POST['DialCallDuration']))
				else:
					logger.debug('%s: PracticeIVR_ForwardCall_New diallog not found: dialSid %s duration %s' % (
						request.session.session_key, request.POST['DialCallSid'], request.POST['DialCallDuration']))
				# Do nothing so that the second leg call continues un-interrupted
				return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
		if (clog.call_connected):
			r.append(twilio.Hangup())
			return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
		r.append(tts("The provider is not available right now."))
		r.append(twilio.Redirect(reverse('PracticeIVR_LeaveUrgentMsg_New')))
		# redirecting to LeaveUrgentMsg_New
		request.session['ivr2_state'] = 'PracticeIVR_LeaveUrgentMsg_New'
		return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)

	else:
		# else: Do nothing so that the call continues un-interrupted
		return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
コード例 #24
0
 def testBadAppend(self):
     """ should raise exceptions for wrong appending """
     self.improperAppend(twiml.Redirect())
コード例 #25
0
ファイル: views_generic.py プロジェクト: cnzhuran/mdcom
def getCallBackNumber(request, twilioResponse=None):
	"""
	Gets call back number from users input, verifies number, sends it back to 
	be used in msg or sms
	"""
	if 'CallStatus' in request.POST:
		logger.debug('%s: Into getCallBackNumber with call status %s' % (
			request.session.session_key, request.POST['CallStatus']))

	r = twilioResponse or twilio.Response() 
	request.session.modified = True

	if ('CallStatus' in request.POST and request.POST['CallStatus'] == 'completed'):
		# First, check to see if the caller has hung up.
		if ('ivr_has_number' in request.session and 'ivr_callback_returnOnHangup' in
			request.session and 'ivr_makeRecording_callbacknumber' in request.session):
			#call caller function, just to send empty msg or sms
			request.session['ivr_only_callbacknumber'] = True
			view = request.session.get('ivr_callback_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 getCallBackNumber", str(e))

		return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)

	# after hung up we need to clear first time < 10 digit numbers for urgent calls
	if ('ivr_urgent_second_time' in request.session):
		request.session.pop('ivr_makeRecording_callbacknumber', None)
		request.session.pop('ivr_caller_id_area_code', None)

	if 'Digits' in request.POST:
		digits = request.POST['Digits']

		if ('ivr_makeRecording_callbacknumber' in request.session):
			p = re.compile('[0-9]$')
			if (not p.match(digits)):
				del request.session['ivr_makeRecording_callbacknumber']
				del request.session['ivr_has_number']
				request.session.pop('ivr_caller_id_area_code', None)
				r.append(tts('I\'m sorry, I didn\'t understand that.'))
				r.append(twilio.Redirect(reverse('getCallBackNumber')))
			elif (digits == '1'):
				# correct number - leave function, and get voice recordng
				r.append(twilio.Redirect(reverse(request.session['ivr_call_stack'].pop())))
				request.session.modified = True
				#r.append(twilio.Redirect(reverse('getCallBackNumber')))
			elif (digits == '3'):
				#user said, bad number, reinit and enter number again
				del request.session['ivr_makeRecording_callbacknumber']
				del request.session['ivr_has_number']
				request.session.pop('ivr_caller_id_area_code', None)
				r.append(twilio.Redirect(reverse('getCallBackNumber')))
			else:
				r.append(tts('I\'m sorry, I didn\'t understand that.'))
				gather = twilio.Gather(finishOnKey='', numDigits=1, 
									action=reverse('getCallBackNumber'))
				spoken_number = []
				[spoken_number.extend([i, ' ']) for i in 
					request.session['ivr_makeRecording_callbacknumber']]
				spoken_number.pop()  # drop the last element
				gather.append(tts(_('Eye got %s. If this is correct, press one. Or'
					'press three to enter eh different number') % (''.join(spoken_number),)))
				r.append(gather)
				#r.append(twilio.Redirect(reverse('getCallBackNumber')))

			return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)

		if ('ivr_has_number' in request.session):
			#first time thru phone was entered ivr_makeRecording_callbacknumber does 
			# not have phone number in it yet.
			if (not 'ivr_makeRecording_callbacknumber' in request.session or
					'ivr_urgent_second_time' in request.session):
				if(re.match(r'[0-9]+', digits)):
					spoken_number = []
					[spoken_number.extend([i, ' ']) for i in digits]
					spoken_number.pop()  # drop the last element
					#spoken_number.insert(5, ',')
					#spoken_number.insert(12, ',')
					request.session['ivr_makeRecording_callbacknumber'] = digits
					#take first three digits from caller, in case less than 10 digits are
					# entered, we do this for ALL calls where call back number is < 10 digits
					if (len(digits) < 10 and 'Caller' in request.session and 
							len(request.session['Caller']) > 2):
						request.session['ivr_caller_id_area_code'] = request.session['Caller'][0:3]

					# for bug 829, ONLY on FIRST pass, we need to make sure its at least 
					# 10 digits, if not say please make sure you entered area code
					# only if this is URGENT call, rest of callers are free to leave any 
					# number of digits also, if after first try, users still enters < 10 
					# digits, let it go thru (ivr_urgent_second_time var is used for that)
					view = request.session.get('ivr_callback_returnOnHangup', None)
					if (not 'ivr_urgent_second_time' in request.session and len(digits) < 10 
							and view and view.split('.')[-1] == 'PracticeIVR_LeaveUrgentMsg'): 
						gather = twilio.Gather(finishOnKey='#', numDigits=12, timeout=30,
												action=reverse('getCallBackNumber'))
						gather.append(tts('I\'m sorry, It appears your call back number '
									'is less than ten digits. Please enter your call back '
									'number including area code now. Then press pound.'))
						r.append(gather)
						r.append(twilio.Redirect(reverse('getCallBackNumber')))
						request.session['ivr_urgent_second_time'] = True

						return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
					#========= end of bug 829 =======================
					else:
						gather = twilio.Gather(finishOnKey='', numDigits=1,
											action=reverse('getCallBackNumber'))
						gather.append(tts('Eye got %s . If this is correct, press one. '
										'Or press three to enter eh different number' % \
											(''.join(spoken_number),)))
						r.append(gather)
						r.append(twilio.Redirect(reverse('getCallBackNumber')))
						request.session.pop('ivr_urgent_second_time', None)

						return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
				else:
					r.append(tts(_('I\'m sorry, I didn\'t understand that.')))
					r.append(twilio.Redirect(reverse('getCallBackNumber')))

					request.session.pop('ivr_has_number', None)
					request.session.pop('ivr_makeRecording_callbacknumber', None)
					return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)

	if (not 'ivr_has_number' in request.session):
		# This is the code that gets executed on the first run of this function.
		#'digits' get posted for next itteration
		# It also gets run if the call back number verification fails
		gather = twilio.Gather(finishOnKey='#', numDigits=12, timeout=30,
							action=reverse('getCallBackNumber'))
		gather.append(tts(_('On the keypad, please enter your call back number '
									'including area code now, then press pound.')))
		r.append(gather)
		r.append(twilio.Redirect(reverse('getCallBackNumber')))
		request.session['ivr_has_number'] = True

		return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)

	#this is the case of user pressing just pound at call back number, there are no digits.
	if ('ivr_has_number' in request.session and 'Digits' not in request.POST):
		del request.session['ivr_has_number']
		request.session.pop('ivr_makeRecording_callbacknumber', None)
		r.append(tts(_('I\'m sorry, I didn\'t understand that.')))
		r.append(twilio.Redirect(reverse('getCallBackNumber')))
		return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)

	raise Exception(_('should never get here'))
コード例 #26
0
ファイル: views_generic.py プロジェクト: cnzhuran/mdcom
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)