Exemplo n.º 1
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)
Exemplo n.º 2
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())
Exemplo n.º 3
0
 def testPlayHelloLoop(self):
     """should play hello monkey loop"""
     r = Response()
     r.append(twiml.Play("http://hellomonkey.mp3", loop=3))
     r = self.strip(r)
     self.assertEqual(
         r,
         '<?xml version="1.0" encoding="UTF-8"?><Response><Play loop="3">http://hellomonkey.mp3</Play></Response>'
     )
Exemplo n.º 4
0
 def testEmptyPlay(self):
     """should play hello monkey"""
     r = Response()
     r.append(twiml.Play(""))
     r = self.strip(r)
     self.assertEqual(
         r,
         '<?xml version="1.0" encoding="UTF-8"?><Response><Play /></Response>'
     )
Exemplo n.º 5
0
 def testPlayDigits(self):
     """ should play digits """
     r = Response()
     r.append(twiml.Play(digits='w123'))
     r = self.strip(r)
     self.assertEqual(
         r,
         '<?xml version="1.0" encoding="UTF-8"?><Response><Play digits="w123" /></Response>'
     )
Exemplo n.º 6
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>')
Exemplo n.º 7
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)
Exemplo n.º 8
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())
Exemplo n.º 9
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)
Exemplo n.º 10
0
 def testPlayBadAppend(self):
     """ should raise exceptions for wrong appending """
     self.improperAppend(twiml.Play(""))
Exemplo n.º 11
0
 def testPlayAddAttribute(self):
     """ add attribute """
     r = twiml.Play("", foo="bar")
     r = self.strip(r)
     assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Play foo="bar" />')
Exemplo n.º 12
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)
Exemplo n.º 13
0
def ProviderIVR_LeaveMsg(request):
    """
	Records a voicemail message.

	Arguments:
		request - The standard Django request argument

	request.session Keys:
		provider_id - The ID of the Provider user who owns this voicemail box.
	"""
    # TODO: Update this code so that users can hit the pound key to
    # pop back and log into their own voicemail box.
    provider = Provider.objects.get(id=request.session['provider_id'])

    config = None
    config_complete = provider.vm_config.count(
    ) == 1 and provider.vm_config.get().config_complete
    if (config_complete):
        config = provider.vm_config.get()

    if ('CallStatus' in request.POST
            and request.POST['CallStatus'] == 'completed'):
        try:
            callSID = request.POST['CallSid']
            auth, uri, = client.auth, client.account_uri
            resp = make_twilio_request('GET',
                                       uri + '/Calls/%s' % callSID,
                                       auth=auth)
            content = json.loads(resp.content)
            log = callLog.objects.get(callSID=callSID)
            log.call_duration = content['TwilioResponse']['Call']['Duration']
            log.save()
        except:
            pass  # this is really ugly, but letting this exception fall through
            # destroys a message analytics will pick up the duration later on if it's missing

    if ('ivr_makeRecording_recording' in request.session):
        provider_qs = Provider.objects.filter(
            mobile_phone=request.session['Caller'])
        if (provider_qs):
            request.session['ivr_makeRecording_callbacknumber'] = provider_qs[
                0].mdcom_phone
            subject = "Voice Mail from %s %s" % (provider_qs[0].first_name,
                                                 provider_qs[0].last_name)
        else:
            request.session[
                'ivr_makeRecording_callbacknumber'] = request.session['Caller']
            subject = "Voice Mail from %s" % request.session[
                'ivr_makeRecording_callbacknumber']
        save_message(request, subject, [provider.user], None, "VM", False)
        request.session.pop('ivr_makeRecording_recording')

        r = twilio.Response()
        r.append(tts('Good bye'))
        r.append(twilio.Hangup())
        return HttpResponse(str(r), mimetype=settings.TWILIO_RESPONSE_MIMETYPE)

    # Get the configuration file for this Provider
    if (not config_complete):
        # FIXME:
        # Probably not the best way to create the spoken number. We need to
        # break the number down so that there are spaces between each digit, and
        # so that there are commas after the third and sixth digits.
        if (not 'Called' in request.session
                or (not request.session['Called'])):
            # This will occur if click2call calls this function
            request.session['ivr_makeRecording_prompt'] = tts(
                'The user is not available. '
                'Please leave a message after the beep. Press pound when finished for options.'
            )
        else:
            number = request.session['Called']
            spoken_number = []
            [spoken_number.extend([i, ' ']) for i in number]
            spoken_number.pop()  # drop the last element
            spoken_number.insert(5, ',')
            spoken_number.insert(12, ',')
            request.session['ivr_makeRecording_prompt'] = tts(
                'The person at %s '
                'is not available. Please leave a message after the beep. Press pound '
                'when finished for options.' % (''.join(spoken_number), ))
    else:
        p = re.compile('http')
        if (p.match(config.greeting)):
            # This is a Twilio recording.
            request.session['ivr_makeRecording_prompt'] = twilio.Play(
                config.greeting)
        else:
            # TODO:
            raise Exception('Unimplemented playback of local files')

    request.session['ivr_makeRecording_maxLength'] = 120  # 2 minutes
    request.session['ivr_makeRecording_leadSilence'] = 2
    request.session['ivr_makeRecording_promptOnce'] = True
    request.session['ivr_makeRecording_returnOnHangup'] = \
     'MHLogin.DoctorCom.IVR.views_provider.ProviderIVR_LeaveMsg'
    request.session['ivr_call_stack'].append('ProviderIVR_LeaveMsg')
    request.session.modified = True

    # Pass off the recording action to the getRecording function.
    return getRecording(request)
Exemplo n.º 14
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)