Пример #1
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(""))
Пример #2
0
def PracticeIVR_TreeRoot_New(request):
	"""
	will be called if it is practice manager calling and set up was done already
	update set up option only, we have no msgs on this number
	"""
	r = twilio.Response()
	#practice = PracticeLocation.objects.get(id=request.session['practice_id'])
	if ('Digits' in request.POST):
		logger.debug('%s: PracticeIVR_TreeRoot_New digits %s' % (
			request.session.session_key, request.POST['Digits']))
		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 == '3'):
			request.session['ivr2_state'] = 'PracticeIVR_Options_New'
			request.session.modified = True
			return PracticeIVR_Options_New(request, r)
		elif (digits == '*'):
			pass
		else:
			r.append(tts(_('I\'m sorry, I didn\'t understand that.')))

	gather = twilio.Gather(finishOnKey='', numDigits=1, timeout=30)

	r.append(tts(_("Wecome to you voice mail account. Your set up is "
						"complete. This account does not have mail box.")))
	gather.append(tts(_('To manage your settings, press 3')))
	gather.append(tts(_('To repeat this menu, press star')))
	r.append(gather)

	return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
Пример #3
0
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())
Пример #4
0
 def testEmpty(self):
     """ a gather with nothing inside"""
     r = Response()
     r.append(twiml.Gather())
     r = self.strip(r)
     self.assertEquals(
         r,
         '<?xml version="1.0" encoding="UTF-8"?><Response><Gather /></Response>'
     )
Пример #5
0
 def testNestedSayPlayPause(self):
     """ a gather with a say, play, and pause """
     r = Response()
     g = twiml.Gather()
     g.append(twiml.Say("Hey"))
     g.append(twiml.Play("hey.mp3"))
     g.append(twiml.Pause())
     r.append(g)
     r = self.strip(r)
     assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Gather><Say>Hey</Say><Play>hey.mp3</Play><Pause /></Gather></Response>')
Пример #6
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)
Пример #7
0
 def improperAppend(self, verb):
     self.assertRaises(TwimlException, verb.append, twiml.Say(""))
     self.assertRaises(TwimlException, verb.append, twiml.Gather())
     self.assertRaises(TwimlException, verb.append, twiml.Play(""))
     self.assertRaises(TwimlException, verb.append, twiml.Record())
     self.assertRaises(TwimlException, verb.append, twiml.Hangup())
     self.assertRaises(TwimlException, verb.append, twiml.Reject())
     self.assertRaises(TwimlException, verb.append, twiml.Redirect())
     self.assertRaises(TwimlException, verb.append, twiml.Dial())
     self.assertRaises(TwimlException, verb.append, twiml.Conference(""))
     self.assertRaises(TwimlException, verb.append, twiml.Sms(""))
     self.assertRaises(TwimlException, verb.append, twiml.Pause())
Пример #8
0
def PracticeIVR_Options_New(request, twilioResponse=None):
	"""
	Options Menu to change practice pin, name, greetings
	"""
	r = twilioResponse or twilio.Response()
	gather = twilio.Gather(finishOnKey='', numDigits=1, action=reverse('PracticeIVR_Options_Actions'))
	gather.append(tts(_('Options menu')))
	gather.append(tts(_('To re-record your name, press 1')))
	gather.append(tts(_('To record a new closed office greeting, press 3')))
	gather.append(tts(_('To record a new greeting while the office is open, press 5')))
	gather.append(tts(_('To change your pin, press 7')))
	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)
Пример #9
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)
Пример #10
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)
Пример #11
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)
Пример #12
0
def ProviderIVR_Options_New(request, twilioResponse=None):
    """
	Options Menu to change VM settings
	Sets up what we say to user for options choices
	"""
    r = twilioResponse or twilio.Response()
    request.session['ivr2_state'] = 'ProviderIVR_Options_New'
    # reset sub_state
    if ('ivr2_sub_state' in request.session):
        del request.session['ivr2_sub_state']
    gather = twilio.Gather(finishOnKey='',
                           numDigits=1,
                           action=reverse('ProviderIVR_Options_Actions'))
    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)
Пример #13
0
def Twilio_callGather(request):
	import cPickle

	# Save debugging data
	sid = request.POST['CallSid']
	status = request.POST['CallStatus']

	log = TwilioCallGatherTest.objects.get(callid=sid)

	if (not log.debug_data):
		debugData = []
	else:
		debugData = cPickle.loads(log.debug_data.encode('ascii'))
	newEntry = ['Twilio_callGather', cPickle.dumps(request.POST)]
	debugData.append(newEntry)
	log.debug_data = cPickle.dumps(debugData)

	log.save()

	# We don't care about which session this is associated with as all
	# verification is the same across all sessions.
	r = twilio.Response()
	if (status != 'completed'):
		abs_uri = '://'.join([settings.SERVER_PROTOCOL, settings.SERVER_ADDRESS])
		url = reverse('MHLogin.tests.views.Twilio_callGather_complete')

		gather = twilio.Gather(action=urljoin(abs_uri, url),
					numDigits=1, finishOnKey='', timeout=10)
		gather.append(twilio.Say("Please press the number one.", 
					voice=twilio.Say.MAN, language=twilio.Say.ENGLISH))
		r.append(gather)

	log.success = log.success + '1'  # should be 11 or 101 here
	debugData.append(str(r))
	log.debug_data = cPickle.dumps(debugData)
	log.save()

	return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
Пример #14
0
 def testAddAttribute(self):
     """ add attribute """
     r = twiml.Gather(foo="bar")
     r = self.strip(r)
     assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Gather foo="bar" />')
Пример #15
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)
Пример #16
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)
Пример #17
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)
Пример #18
0
def ProviderIVR_TreeRoot_New(request, provider=None, twilioResponse=None):
    """
	call tree of a provider:
	1 to listen to all msgs;
	2 to listen to urgent msgs
	3 to listen to voice mail
	4 to manage voicemail settings
	* to repeat menu
	Require: session variable: provider_id to be set
	Require: request.session['ivr2_state'] == ProviderIVR_TreeRoot_New
	sets up twilio response with message and url to go to ProviderIVR_TreeRoot_Actions
	"""
    if (provider == None):
        provider = Provider.objects.get(id=request.session['provider_id'])
    logger.debug('%s: ProviderIVR_TreeRoot_New prov %s' %
                 (request.session.session_key, provider))
    request.session['ivr2_state'] = 'ProviderIVR_TreeRoot_New'
    unread_anssvc_msg_count = MessageBodyUserStatus.objects.filter(
        user=provider.user,
        read_flag=False,
        delete_flag=False,
        msg_body__message___resolved_by=None,
        msg_body__message__message_type='ANS').count()
    unread_msg_count = MessageBodyUserStatus.objects.filter(
        user=provider.user,
        read_flag=False,
        delete_flag=False,
        msg_body__message___resolved_by=None,
        msg_body__message__message_type='VM').count()
    saved_msg_count = MessageBodyUserStatus.objects.filter(
        user=provider.user,
        read_flag=True,
        delete_flag=False,
        msg_body__message___resolved_by=None,
        msg_body__message__message_type='VM').count()
    saved_anssvc_msg_count = MessageBodyUserStatus.objects.filter(
        user=provider.user,
        read_flag=True,
        delete_flag=False,
        msg_body__message___resolved_by=None,
        msg_body__message__message_type='ANS').count()
    logger.debug('%s: ProviderIVR_TreeRoot_New msg counts %d, %d, %d, %d' %
                 (request.session.session_key, unread_anssvc_msg_count,
                  unread_msg_count, saved_msg_count, saved_anssvc_msg_count))

    say_str = []
    say_str.append('You have %i new, and %i saved urgent messages,' %
                   (unread_anssvc_msg_count, saved_anssvc_msg_count))
    say_str.append(' ')
    say_str.append('and %i new, and %i saved voice messages,' %
                   (unread_msg_count, saved_msg_count))

    if (any((unread_msg_count, unread_anssvc_msg_count, saved_msg_count,
             saved_anssvc_msg_count))):
        say_str.append('To listen to all your messages, press one. ')
        say_str.append('To listen to your urgent messages, press two. ')
        say_str.append('To listen to your voice mail, press three. ')

    r = twilioResponse or twilio.Response()
    gather = twilio.Gather(action=reverse('ProviderIVR_TreeRoot_Actions'),
                           finishOnKey='',
                           numDigits=1)
    gather.append(tts(''.join(say_str)))
    gather.append(tts('To manage your voicemail settings, press four.'))
    gather.append(tts('To repeat this menu, press star.'))
    r.append(gather)
    return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
Пример #19
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)
Пример #20
0
 def testNoDeclaration(self):
     """ add attribute """
     r = twiml.Gather(foo="bar")
     assert_equal(r.toxml(xml_declaration=False), '<Gather foo="bar" />')
Пример #21
0
def PracticeIVR_CallerResponse_Action(request, twilioResponse=None):
	"""
	This function process callers response in 2 ways:
	old way (original answering service):
		1=leave msg in doc com  mailbox via PracticeIVR_LeaveRegularMsg_New (to all practice managers)
		2=page doctor on call (LeaveUrgentMsg_New)
	new way (dynamic greeting already called):
		create greeting based on call_groups info in db
		if 1 call group  for THIS practice, take message via PracticeIVR_LeaveRegularMsg_New
		if > 1 call group, add a layer to first pick call group, then pick type of message
		PracticeIVR_ForwardCall_New
	"""
	practice = PracticeLocation.objects.get(id=request.session['practice_id'])
	logger.debug('%s: PracticeIVR_CallerResponse_Action practice %s POST data is %s' % (
		request.session.session_key, practice, str(request.POST)))

	r = twilioResponse or twilio.Response()
	if (request.method == 'POST' and 'Digits' in request.POST):
		digits = request.POST['Digits']
		if practice.uses_original_answering_serice():  # old way
			logger.debug('%s: PracticeIVR_CallerResponse_Action via old ans svc' % (
				request.session.session_key))
			p = re.compile('[0-9#*]$')
			if (not p.match(digits)):
				r.append(tts(_('I\'m sorry, I didn\'t understand that.')))
			elif (digits == '1'):
				# leave msg in doctor com mailbox
				request.session['ivr2_state'] = 'PracticeIVR_LeaveRegularMsg_New'
				request.session.modified = True
				return PracticeIVR_LeaveRegularMsg_New(request)
			elif (digits == '2'):
				# forward the call
				request.session['ivr2_state'] = 'PracticeIVR_ForwardCall_New'
				request.session.modified = True
				request.session['provider_id'] = _getRecentOncallProviderId(request)
				logger.debug('%s: PracticeIVR_CallerResponse_Action old ans svc NO oncall provider' %
					(request.session.session_key))
				if(not request.session['provider_id']):
					r.append(tts(_('We\'re sorry, an application error has occurred. Goodbye.',
						voice='woman')))
					r.append(twilio.Hangup())
					# return r
					return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
				return PracticeIVR_ForwardCall_New(request)
			elif (digits == '*'):
				pass
			else:
				r.append(tts(_('I\'m sorry, I didn\'t understand that.')))
			return PracticeIVR_CallerResponse_New(request, r)
		else:
			# new V2 dynamic greeting and call groups
			call_groups_map = request.session['call_groups_map']
			specialties_map = request.session['specialties_map']
			logger.debug('%s: PracticeIVR_CallerResponse_Action via new ans svc cg %s sp %s' % (
				request.session.session_key, call_groups_map, specialties_map))
			gather = twilio.Gather(action=reverse('PracticeIVR_CallerResponse_Action'),
				finishOnKey='', numDigits=1, timeout=60)

			p = re.compile('[0-9]$')
			if (not p.match(digits)):
				r.append(tts(_('I\'m sorry, I didn\'t understand that.')))
				r.append(tts(_('%s.') % (''.join(request.session['last_played']),)))
				r.append(gather)

			elif (digits == '1' and request.session['one_ok'] == '1'):  # one_ok is set in create_dynamic_greeting
				# leave msg in doctor com mailbox
				request.session['ivr2_state'] = 'PracticeIVR_LeaveRegularMsg_New'
				request.session.modified = True
				return PracticeIVR_LeaveRegularMsg_New(request)

			elif (digits in call_groups_map):
				#Call Group reached, get provider on call
				request.session['callgroup_id'] = call_groups_map.get(digits)
				request.session['ivr2_state'] = 'PracticeIVR_ForwardCall_New'
				request.session.modified = True
				request.session['provider_id'] = _getRecentOncallProviderId(request)
				logger.debug('%s: PracticeIVR_CallerResponse_Action new ans svc NO oncall provider' %
					(request.session.session_key))
				if(not request.session['provider_id']):
					r.append(tts(_('We\'re sorry, an application error has occurred. Goodbye.',
						voice='woman')))
					r.append(twilio.Hangup())
					# return r
					return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
				return PracticeIVR_ForwardCall_New(request)
			elif (digits in specialties_map):
				#specialty reached, get list of call groups,
				#populates request.session['call_groups_map'] and blanks out request.session['specialty_map']
				call_groups_greeting = create_call_group_list(request, specialties_map.get(digits))
				gather.append(tts(_('%s.') % (''.join(call_groups_greeting),)))
				request.session['last_played'] = call_groups_greeting
				r.append(gather)
			#elif (digits == '*'): treat * as invalid input
				#pass
			else:
				gather.append(tts(_('I\'m sorry, I didn\'t understand that.')))
				gather.append(tts(_('%s.') % (''.join(request.session['last_played']),)))
				r.append(gather)
			return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
	else:
		# should never happen - but if we get here without Digits, we log and go back to Main
		logger.debug('%s: PracticeIVR_CallerResponse_Action is called with no post or digits' %
			(request.session.session_key))
		request.session['ivr2_state'] = 'PracticeIVR_Main_New'
		return PracticeIVR_Main_New(request)
Пример #22
0
def ProviderIVR_TreeRoot(request):

    r = twilio.Response()
    provider = Provider.objects.get(id=request.session['provider_id'])

    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'):
            # play messages
            request.session['ivr_call_stack'].append('ProviderIVR_TreeRoot')
            request.session.modified = True
            messages = MessageBodyUserStatus.objects.filter(
                user=provider.user,
                delete_flag=False,
                msg_body__message___resolved_by=None,
                msg_body__message__message_type__in=('ANS', 'VM'))
            return playMessages(request, messages, r)
        elif (digits == '2'):
            request.session['ivr_call_stack'].append('ProviderIVR_TreeRoot')
            request.session.modified = True
            messages = MessageBodyUserStatus.objects.filter(
                user=provider.user,
                delete_flag=False,
                msg_body__message___resolved_by=None,
                msg_body__message__message_type__in=('ANS', ))
            return playMessages(request, messages, r)
        elif (digits == '3'):
            request.session['ivr_call_stack'].append('ProviderIVR_TreeRoot')
            request.session.modified = True
            messages = MessageBodyUserStatus.objects.filter(
                user=provider.user,
                delete_flag=False,
                msg_body__message___resolved_by=None,
                msg_body__message__message_type__in=('VM', ))
            # fix for issue 2257 - if we go to playMessages, it will use 3 in its digit and try to replay
            # current message which fails if there are no messages
            if (messages == [] or len(messages) == 0):
                pass
            else:
                request.session['ivr_call_stack'].append(
                    'ProviderIVR_TreeRoot')
                return playMessages(request, messages, r)

        elif (digits == '4'):
            request.session['ivr_call_stack'].append('ProviderIVR_TreeRoot')
            request.session.modified = True
            return ProviderIVR_Options(request, True)
        elif (digits == '*'):
            pass
        else:
            r.append(tts('I\'m sorry, I didn\'t understand that.'))

    gather = twilio.Gather(finishOnKey='', numDigits=1)
    #	messages = MessageBodyUserStatus
    unread_anssvc_msg_count = MessageBodyUserStatus.objects.filter(
        user=provider.user,
        read_flag=False,
        delete_flag=False,
        msg_body__message___resolved_by=None,
        msg_body__message__message_type='ANS').count()
    unread_msg_count = MessageBodyUserStatus.objects.filter(
        user=provider.user,
        read_flag=False,
        delete_flag=False,
        msg_body__message___resolved_by=None,
        msg_body__message__message_type='VM').count()

    saved_msg_count = MessageBodyUserStatus.objects.filter(
        user=provider.user,
        read_flag=True,
        delete_flag=False,
        msg_body__message___resolved_by=None,
        msg_body__message__message_type='VM').count()
    saved_anssvc_msg_count = MessageBodyUserStatus.objects.filter(
        user=provider.user,
        read_flag=True,
        delete_flag=False,
        msg_body__message___resolved_by=None,
        msg_body__message__message_type='ANS').count()

    say_str = []

    say_str.append('You have %i new, and %i saved urgent messages,' %
                   (unread_anssvc_msg_count, saved_anssvc_msg_count))
    say_str.append(' ')
    say_str.append('and %i new, and %i saved voice messages,' %
                   (unread_msg_count, saved_msg_count))

    if (any((unread_msg_count, unread_anssvc_msg_count, saved_msg_count,
             saved_anssvc_msg_count))):
        say_str.append('To listen to all your messages, press one. ')
        say_str.append('To listen to your urgent messages, press two. ')
        say_str.append('To listen to your voice mail, press three. ')
    gather.append(tts(''.join(say_str)))

    gather.append(tts('To manage your voicemail settings, press four.'))
    gather.append(tts('To repeat this menu, press star.'))
    r.append(gather)

    return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)
Пример #23
0
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'))