def send(self, text, contact):
        if 'phone' not in contact:
            return {
                'success': False,
                'message': "User dose not have a phone number"
            }

        try:
            twiml_response = VoiceResponse()
            twiml_response.say(text)
            twiml_response.hangup()
            twiml_xml = twiml_response.to_xml()
            call = self.client.calls.create(to=contact['phone'],
                                            twiml=twiml_xml,
                                            from_=self.from_phone)

        except TwilioRestException as e:
            return {
                'success': False,
                'message': "Error calling Twilio: {}".format(e.msg)
            }

        return {
            'success': True,
            'contact': contact['phone'],
            'call_id': call.sid
        }
Пример #2
0
def voice_four(request):
    """
    Play voice 4 and do actions accordingly
    """
    call_sid = None
    choice = None
    call_from = None
    if request.method == 'POST':
        call_sid = request.POST.get('CallSid', None)
        choice = request.POST.get('Digits', None)
        call_from = request.POST.get('From', None)
    if request.method == 'GET':
        call_sid = request.GET.get('CallSid', None)
        choice = request.GET.get('Digits', None)
        call_from = request.GET.get('From', None)
    twiml = VoiceResponse()
    if choice:
        call_detail = CallDetail.objects.get(call_sid=call_sid)
        call_detail.went_conference = True
        call_detail.save()
        if int(choice) == 1:
            client.calls.create(to=num_sendCallTo, from_=num_sendCallTo, url=BASE_URL + '/Conference/' + call_sid,
                                status_callback=BASE_URL+'/ConferenceStatus/' + call_sid,
                                status_callback_method='POST', status_callback_event=["completed", "no-answer", "busy",
                                                                                      "failed"])
            dial = Dial()
            dial.conference(call_sid, wait_url='http://roelofvandijk.com/mp33/IVR/CallingInformation.mp3',
                            status_callback=BASE_URL+'/AddDrop?CallSid=' + call_sid + '&From='+call_from,
                            status_callback_method='POST', status_callback_event=['start', 'join', 'end'],
                            end_conference_on_exit=True, max_participants=2, start_conference_on_enter=True)
            twiml.append(dial)
            return HttpResponse(str(twiml))
        twiml.hangup()
        return HttpResponse(str(twiml))
    return HttpResponse(str(twiml))
Пример #3
0
def getVoiceMessage(uid):
    # fill in with info from appointmentID
    cursor = db.appointment.find_one({'_id': ObjectId(uid)})
    doctorUID = cursor["doctorUid"]
    sTime = cursor["timeframe"]
    # number from 0 to 24, increments of .5
    startTime = datetime.fromtimestamp(int(sTime), )
    convertedTime = startTime.hour - 4 + startTime.minute / 60
    date = startTime.strftime("%B %d")
    patientID = cursor["userId"]
    cursor2 = db.user.find_one({"_id": ObjectId(patientID)})
    patientFName = cursor2[
        'firstName']  # first and last names may (should?) be combined into one string
    patientLName = cursor2["lastName"]
    doctor = betterdoctor.getDoctor("975eb48667ccb9eb20008d302685981d",
                                    doctorUID)
    doctorName = doctor["data"]["profile"]["last_name"]

    message = (patientFName + " " + patientLName +
               " has an appointment with doctor" + doctorName + " from " +
               stringTime(convertedTime) + " to " +
               stringTime(convertedTime + .5) + "on " + date)

    response = VoiceResponse()
    response.say(message)
    response.hangup()
    xml = response.to_xml()
    return xml
Пример #4
0
    def post(self, request, *args, **kwargs):
        survey_id = request.GET.get('survey')
        survey_phone = request.GET.get('phone')
        survey_model = Survey.objects.get(id=survey_id)
        survey_script_flow = survey_model.script_flow['data']
        survey_response = request.GET.get('response')
        print('Answer CallSid', request.data['CallSid'])

        # Quickly creating the response field just to let react knows that we are working on this response
        response_model = Response.objects.create(
            question_id=str(survey_script_flow[0]['id']))
        response_model.save()
        survey_model = SurveyResponse.objects.get(id=survey_response)
        survey_model.responses.add(response_model.id)

        response = VoiceResponse()
        response.say(survey_script_flow[0]['question'],
                     voice=survey_script_flow[0]['voice_gender'])

        response.record(
            timeout=3,
            max_length=survey_script_flow[0]['record_time'],
            action=WEBSITE_URL + '/next/?counter=1&survey=' + str(survey_id) +
            '&response=' + str(survey_response),
            # maxLength
            recordingStatusCallback=WEBSITE_URL + '/save/?survey=' +
            str(survey_id) + '&question=' + str(survey_script_flow[0]['id']) +
            '&response=' + str(survey_response),
            trim="trim-silence")

        response.say('I did not receive a recording')
        response.hangup()
        print(str(response))
        return HttpResponse(str(response), content_type='text/xml')
Пример #5
0
def answer_incoming_call():
    """
    Receives an incoming call to our Twilio number, which will be missed calls
    from our user's phone number.

    Reads a greeting to the user and gives them a menu of options for what to
    do next.
    """
    # Start our TwiML response
    response = VoiceResponse()

    # If this call wasn't forwarded from our user's phone number, don't answer
    # it
    if request.form['ForwardedFrom'] != app.config['USER_PHONE_NUMBER']:
        response.hangup()
        return str(response)

    # Play a greeting and prompt the user to press a button if they want to
    # leave a voicemail
    gather = Gather(
        num_digits=1,
        timeout=10,  # Wait 10 seconds for them to press a number
        action=url_for('record_message'))
    gather.say(
        "You have reached the voicemail of Andrew Baker. Press 5 to leave a message.",
        voice='Polly.Matthew')
    response.append(gather)

    # If they don't press anything, thank the caller and end the call
    response.say('Thank you for calling. Goodbye.', voice='Polly.Matthew')

    return str(response)
Пример #6
0
def answeredby(request):
    # build validator manually because decorator not working
    logger.info(request.build_absolute_uri())
    twilio_request = decompose(request)
    validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)

    # Validate the request using its URL, POST data,
    # and X-TWILIO-SIGNATURE header
    request_valid = validator.validate(
        request.build_absolute_uri(), request.POST,
        request.META.get('HTTP_X_TWILIO_SIGNATURE', ''))

    if not request_valid:
        return HttpResponseForbidden()

    outbound = Outbound.objects.get(twilio_sid=twilio_request.callsid)
    response = VoiceResponse()

    if twilio_request.answeredby in ['human', 'unknown']:
        response.play(outbound.action.audio_file.url)

    else:
        response.hangup()

    outbound.answered_by = twilio_request.answeredby
    outbound.save()

    return HttpResponse(response)
Пример #7
0
def call_status_update_callback(request):
    call_data = request.GET
    logger.debug(call_data['employee'])
    try:
        user = User.objects.get(pk=call_data['employee'])
    except Exception as e:
        user = User.objects.get(pk=1)
        logger.warn(e)
        Log.objects.create(type="Call Summary Error (Getting User)", 
                           message=e,
                           user=user)

    try:
        call_log = Call.objects.get(twilio_id=call_data.get('ParentCallSid', 0))
    except Exception as e:
        logger.debug(e)
        logger.debug("New Call Created")
        call_log = Call()

    call_log.twilio_id = request.GET.get(u'ParentCallSid', call_log.twilio_id)
    call_log.type = call_log.type or call_data.get('Direction', call_log.type) 
    call_log.incoming_number = call_log.incoming_number or call_data.get('From', call_log.incoming_number)
    call_log.employee = user
    call_log.save()

    resp = VoiceResponse()
    resp.hangup()
    return HttpResponse(resp)
Пример #8
0
def answer_call():
    """Respond to incoming phone calls with a brief message if phone number is not recognized by our database."""
    """If the phone number calling us is in the database, user may merge call and record."""

    # Start TwiML response
    resp = VoiceResponse()
    # Read a message aloud to the caller if caller calls the twilio num
    # If caller number in database, record, otherwise, text to voice message.
    data = request.form
    caller_num = data["Caller"][2:]
    caller = User.query.filter_by(phone_num=caller_num).all()
    user_num = caller[0].phone_num
    if user_num == caller_num:
        resp.record(
            method='GET',
            timeout=24 * 60 * 60,  #24 hours is a nice large upper bound
            finish_on_key='',
            action=BASE_URL + "incoming-call-to-db")
    else:
        resp.say("The person you are trying to reach is unavailable",
                 voice='alice')
        #print("######## request form {}".format(request.form))
        # Recording caller's phone call
        #resp.record()
        #end the call when caller hangsup
        resp.hangup()
    r = str(resp)
    #r = r.replace("finishonkey","finishOnKey")
    print("########## NEW RESP = {}".format(str(r)))
    return r
Пример #9
0
def recordAndSend():
    resp = VoiceResponse()

    if 'Digits' in request.values:
        choice = request.values['Digits']

        if choice == '1':
            resp.say("Hi, how can I help you today?",
                     voice='alice',
                     language="en-US")
            resp.record(maxLength=20,
                        timeout=10,
                        transcribe=True,
                        transcribeCallback="/handleVoiceResponse")

            print(resp)
            return str(resp)

        if choice == '2':
            resp.say("Please stay online.", voice='alice', language="en-US")
            resp.hangup()

    else:
        resp.say("We got your msg. Thank you.",
                 voice='alice',
                 language="en-US")
        resp.hangup()

    return str(resp)
Пример #10
0
def incoming():
    response = VoiceResponse()
    response.say('Please leave a message')
    response.record()
    response.hangup()

    return twiml(response)
Пример #11
0
def end():
    resp = VoiceResponse()
    resp.say(
        "Thank you. Your information has been recorded and you should expect to hear "
        "back soon. In the mean time, we hope you feel better. Goodbye.")
    resp.hangup()
    return str(resp)
Пример #12
0
def end_call():
    """Thank the person for contacting the team."""
    response = VoiceResponse()
    response.say("Thank you for using the PromptConf Code of Conduct Hotline",
                 voice='alice')
    response.hangup()
    return Response(str(response), 200, mimetype="application/xml")
Пример #13
0
    def execute(self):
        resp = self.handle_hours()
        if resp is not None:
            return str(resp)

        resp = VoiceResponse()

        gather = Gather()
        gather.play(self.section_data['play_sample'], digits=1)

        pause = 2
        if 'pause' in self.section_data.keys():
            pause = int(self.section_data['pause'])

        gather.pause(length=pause)

        resp.append(gather)

        if ('no_input_max_loops' in self.section_data.keys()
                and self.loop_count >= int(
                    self.section_data['no_input_max_loops'])):
            if 'no_input_action_on_max_loops' in self.section_data.keys():
                resp.redirect(
                    self.url_of(
                        '/ivr/action/' +
                        self.section_data['no_input_action_on_max_loops']))
            else:
                resp.hangup()

        if 'no_input_sample' in self.section_data.keys():
            resp.play(self.section_data['no_input_sample'])

        resp.redirect(self.url_of(f'/ivr/menu?loop_count={self.loop_count}'))

        return str(resp)
Пример #14
0
def begin_call():
    print "start /begin_call"
    from_number = request.values.get('From', None)
    if from_number in callers:
        session['caller'] = callers[from_number]
    else:
        session['caller'] = "unknown"

    resp = VoiceResponse()
    if session['caller'] != "unknown":
        resp.say("Hey " + session['caller'] + "!")
        gather = Gather(input='dtmf speech',
                        timeout=5,
                        num_digits=4,
                        action='/set_date',
                        method='GET')
        gather.say(
            "Let's record a new " + os.environ['PODCASTNAME'] +
            "!\n First, when will this episode air?\n Say the air date or punch it in using a Month Month Day Day format.\n For example, you could say October 31st or punch in 10 31."
        )
        resp.append(gather)
        resp.say("You didn't give me a date. Bye!")
    else:
        resp.say("Hey, this isn't for you. \nBoy Bye!")
        resp.hangup()
        session.clear()
    return str(resp)
async def answer_backend():
    response = VoiceResponse()
    call_id = request.args["CallSid"]
    try:
        connection_to_communicate = Glob["ws_" + call_id]
    except:
        print("error")
    RecordingUrl = request.args["RecordingUrl"]
    parsed_RecordingUrl = urllib.parse.unquote(RecordingUrl)
    recording = requests.get(parsed_RecordingUrl)
    print("sending response from %s" % parsed_RecordingUrl)
    connection_to_communicate.send(recording.content,
                                   opcode=ABNF.OPCODE_BINARY)
    reply = connection_to_communicate.recv()
    j = json.loads(reply)
    if j['ask_flag'] == False:
        if j['ask_flag'] == False and j['exit_flag'] == False:
            second_response = await get_second_response_from_stephnie(
                connection_to_communicate)
            text = j['text'] + second_response
        else:
            text = j['text']
            response.say(text, voice='alice', language='en-AU')
            response.hangup()
            connection_to_communicate.close()
            return str(response)
    else:
        text = j['text']
    print(text)
    response.say(text + INSTRUCTION, voice='alice', language='en-AU')
    response.record(action="/answer_backend", method='GET', trim="do-not-trim")
    return str(response)
Пример #16
0
def end_call():
    """Thank user & hang up."""
    response = VoiceResponse()
    response.say("Thank you for using Call Congress! " +
                 "Your voice makes a difference. Goodbye.")
    response.hangup()
    return Response(str(response), 200, mimetype="application/xml")
Пример #17
0
def get_cur():
    global index, choice
    response = VoiceResponse()
    n = current
    if n["option"] == "speak":
        response.say(message=n["message"])
    elif n["option"] == "directory":
        response.say(message="Directory: ")
        for key, value in n.items():
            if key != "option":
                response.say(message=key + " at " + value)
    elif n["option"] == "end":
        response.hangup()
    elif n["option"] == "redirect":
        response.dial(n['redirect'])
    elif n["option"] == "choice":
        choice = True
        choices = n['choices']
        with response.gather(numDigits=1, action="/gather") as gather:
            for i in range(len(choices)):
                gather.say(message="Press" + str(i) + " to " + choices[i])
        response.redirect("/cur")

    response.redirect('/next')
    return str(response)
Пример #18
0
 def return_twixml_call(reason, resp):
     r = VoiceResponse()
     r.say(reason, voice='alice', loop=2, language="en-US")
     r.hangup()
     resp.status = falcon.HTTP_200
     resp.body = str(r)
     resp.content_type = 'application/xml'
Пример #19
0
def record():
    client = Client(account_sid, auth_token)
    # Start our TwiML response
    response = VoiceResponse()
    # Use <Say> to give the caller some instructions
    response.say('Hello this is LINC. What would you like to talk about?')
    # Use <Record> to record the caller's message
    response.record(transcribe=True, playBeep=True, timeout=4)
    # response.pause(length=3)
    client = Client(account_sid, auth_token)
    trans_list = client.transcriptions.list()
    for transcription in trans_list:
        latest_transcript = transcription.transcription_text
        status = transcription.status
        if (latest_transcript != None):
            unicodedata.normalize('NFKD',
                                  latest_transcript).encode('ascii', 'ignore')
            print(status)
            print(transcription.sid)
            print(latest_transcript)
            transcription.delete()
            break
        else:
            response.say("I'm sorry. I didn't get that. Can you repeat it?")
    print(latest_transcript != "hello")
    if (latest_transcript != "hello"):
        print("boolean worked")
        response.redirect("http://4b930e15.ngrok.io/voice_response")
    response.hangup()
    return str(response)
Пример #20
0
def example():
    """
    Some example usage of different twilio resources.
    """
    client = Client(ACCOUNT_SID, AUTH_TOKEN)

    # Get all messages
    all_messages = client.messages.list()
    print('There are {} messages in your account.'.format(len(all_messages)))

    # Get only last 10 messages...
    some_messages = client.messages.list(limit=10)
    print('Here are the last 10 messages in your account:')
    for m in some_messages:
        print(m)

    # Get messages in smaller pages...
    all_messages = client.messages.list(page_size=10)
    print('There are {} messages in your account.'.format(len(all_messages)))

    print('Sending a message...')
    new_message = client.messages.create(to='XXXX', from_='YYYY', body='Twilio rocks!')

    print('Making a call...')
    new_call = client.calls.create(to='XXXX', from_='YYYY', method='GET')

    print('Serving TwiML')
    twiml_response = VoiceResponse()
    twiml_response.say('Hello!')
    twiml_response.hangup()
    twiml_xml = twiml_response.to_xml()
    print('Generated twiml: {}'.format(twiml_xml))
def voice():
    # Start our TwiML response
    response = VoiceResponse()
    response.say('Hi! I want to know what do you think about coding.')
    response.record(maxLength="10", action="/recording")
    response.hangup()

    return str(response)
Пример #22
0
def _redirect_hangup():
    response = VoiceResponse()

    response.say(
        "Thank you. We\'ll forward your message and have someone call you back. Goodbye.")
    response.hangup()

    return twiml(response)
Пример #23
0
def call():
	resp = VoiceResponse()
	# Play fake ringing
	resp.play('{}static/mp3/ringing.mp3'.format(os.getenv('BASE_URL')))
	# Start recording
	resp.record(timeout=20, transcribe=True, play_beep=False)
	resp.hangup()
	return str(resp)
Пример #24
0
def callback():
    twiml = VoiceResponse()
    speech_result = request.values.get('SpeechResult', None)
    print('Speech Result: ' + speech_result)

    # print('Speech Result: ' + speech_result)
    twiml.hangup()  # hang up call after gathering speech
    return str(twiml)
Пример #25
0
def voice():
    """Respond to incoming phone calls with '9'"""
    resp = VoiceResponse()

    resp.play('', digits='www9')
    resp.hangup()

    return str(resp)
Пример #26
0
def goodbye_twiml():

    response = VoiceResponse()
    response.say("Thank you for answering our survey. Good bye!")
    response.hangup()
    if 'question_id' in session:
        del session['question_id']
    return str(response)
Пример #27
0
def endCallenglish():
    voicemailUrl = request.values.get("RecordingUrl", None)
    caller = request.values.get("From", None)
    getVoicemail(language='en-GB', audiofile=voicemailUrl, caller=caller)
    resp = VoiceResponse()
    resp.say(text['englishending'])
    resp.hangup()

    return str(resp)
Пример #28
0
def ivrSend_view(request):
    audioID = request.matchdict["audioid"]
    response = VoiceResponse()
    response.play(
        request.url_for_static("static/audio/" + getAudioFileName(request, audioID)),
        loop=0,
    )
    response.hangup()
    return twiml(response)
Пример #29
0
    def test_hangup(self):
        """ convenience: should Hangup to a url via POST """
        r = VoiceResponse()
        r.hangup()

        assert_equal(
            self.strip(r),
            '<?xml version="1.0" encoding="UTF-8"?><Response><Hangup /></Response>'
        )
Пример #30
0
def end_call():
    global call_location
    # Start our TwiML response
    resp = VoiceResponse()
    call_location=request.values['SpeechResult']
    # Start our TwiML response
    resp = VoiceResponse()
    global call_recstr
    resp.say("Thanks for reporting the crime.")
    resp.hangup()
    print(resp)
    
    client = Client(account_sid, auth_token)

    recordings = client.recordings.list(limit=20)
    l=[]

    for record in recordings:
        l.append(record.sid)
    rec = l[0]

    call_recstr = 'https://api.twilio.com/2010-04-01/Accounts/ACfa7fe832b6a75655a5ec2bcde267f231/Recordings/' + str(rec) + '.mp3'
 
    inc_id = generate_id()
    incident_priority = calculate_priority(call_situation_type, call_incident_type)
    print(call_incident_type)
    print(incident_priority)
    print(call_situation_type)
    print(call_location)

    data = { "user_fname": 'anon',
                     "user_lname": '',
                     "user_phone": '',
                     "user_email": '',
                     "user_address": '',
                     "animal": '',
                     "incident_id": inc_id,
                     "incident_type": call_incident_type,
                     "incident_priority": incident_priority,
                     "situation_type": call_situation_type,
                     "incident_location": call_location, # Make one for long_lat and one for address
                     "incident_city": '',
                     "incident_country": '',
                     "incident_zipcode": '',
                     "incident_date": '',
                     "incident_time": '',
                     "image_url": '',
                     "incident_description": '',        
                     "assigned_to": "No one",
                     "incident_result": '' ,
                     "recording": call_recstr,
                     "source": 'Phone Call'  
                    }

    db.child("incident").push(data)

    return str(resp)
Пример #31
0
def record():
    """Returns TwiML which prompts the caller to record a message"""
    # Start our TwiML response
    response = VoiceResponse()

    # Use <Say> to give the caller some instructions
    response.say('Hello. Please leave a message after the beep.')

    # Use <Record> to record the caller's message
    response.record()

    # End the call with <Hangup>
    response.hangup()

    return str(response)
Пример #32
0
def record():
    """Returns TwiML which prompts the caller to record a message"""
    # Start our TwiML response
    response = VoiceResponse()

    # Use <Say> to give the caller some instructions
    response.say('Hello. Please leave a message and I will transcribe it.')

    # Use <Record> to record and transcribe the caller's message
    response.record(transcribe=True, max_length=30)

    # End the call with <Hangup>
    response.hangup()

    return str(response)
Пример #33
0
def recording_callback(request):
    call_data = request.POST
    call_log = Call.objects.get(twilio_id=call_data.get('CallSid', 0))

    call_log.duration = call_data.get('RecordingDuration', call_log.duration)
    call_log.recording_url = call_data.get('RecordingUrl', call_log.recording_url)

    call_log.save()

    resp = VoiceResponse()
    resp.hangup()

    try:
        email_call_summary(call_log.employee.email, call_log)
    except Exception as e:
        logger.warn(e)

        try: 
            employee = call_log.employee
        except AttributeError as f:
            logger.warn(f)
            employee = User.objects.get(pk=1)
            #Error for getting user
            Log.objects.create(type="Call Summary Error (Getting user for sending email)", 
                           message=f,
                           user=employee)

        try:
            Log.objects.create(type="Call Summary Error", 
                            message=e,
                            user=employee)
        except ValueError as e:
            logger.warn(e)
            Log.objects.create(type="Call Summary Error", 
                            message=e,
                            user=User.objects.get(pk=1))
        email_call_summary('*****@*****.**', call_log, 'error call summary')


    return HttpResponse(resp)
Пример #34
0
from twilio.twiml.voice_response import Hangup, VoiceResponse

response = VoiceResponse()
response.hangup()

print(response)
Пример #35
0
    def post(self, request, *args, **kwargs):
        from twilio.request_validator import RequestValidator
        from temba.flows.models import FlowSession

        signature = request.META.get("HTTP_X_TWILIO_SIGNATURE", "")
        url = "https://" + request.get_host() + "%s" % request.get_full_path()

        channel_uuid = kwargs.get("uuid")
        call_sid = self.get_param("CallSid")
        direction = self.get_param("Direction")
        status = self.get_param("CallStatus")
        to_number = self.get_param("To")
        to_country = self.get_param("ToCountry")
        from_number = self.get_param("From")

        # Twilio sometimes sends un-normalized numbers
        if to_number and not to_number.startswith("+") and to_country:  # pragma: no cover
            to_number, valid = URN.normalize_number(to_number, to_country)

        # see if it's a twilio call being initiated
        if to_number and call_sid and direction == "inbound" and status == "ringing":

            # find a channel that knows how to answer twilio calls
            channel = self.get_ringing_channel(uuid=channel_uuid)
            if not channel:
                response = VoiceResponse()
                response.say("Sorry, there is no channel configured to take this call. Goodbye.")
                response.hangup()
                return HttpResponse(str(response))

            org = channel.org

            if self.get_channel_type() == "T" and not org.is_connected_to_twilio():
                return HttpResponse("No Twilio account is connected", status=400)

            client = self.get_client(channel=channel)
            validator = RequestValidator(client.auth[1])
            signature = request.META.get("HTTP_X_TWILIO_SIGNATURE", "")

            url = "https://%s%s" % (request.get_host(), request.get_full_path())

            if validator.validate(url, request.POST, signature):
                from temba.ivr.models import IVRCall

                # find a contact for the one initiating us
                urn = URN.from_tel(from_number)
                contact, urn_obj = Contact.get_or_create(channel.org, urn, channel)

                flow = Trigger.find_flow_for_inbound_call(contact)

                if flow:
                    call = IVRCall.create_incoming(channel, contact, urn_obj, channel.created_by, call_sid)
                    session = FlowSession.create(contact, connection=call)

                    call.update_status(
                        request.POST.get("CallStatus", None), request.POST.get("CallDuration", None), "T"
                    )
                    call.save()

                    FlowRun.create(flow, contact, session=session, connection=call)
                    response = Flow.handle_call(call)
                    return HttpResponse(str(response))

                else:

                    # we don't have an inbound trigger to deal with this call.
                    response = channel.generate_ivr_response()

                    # say nothing and hangup, this is a little rude, but if we reject the call, then
                    # they'll get a non-working number error. We send 'busy' when our server is down
                    # so we don't want to use that here either.
                    response.say("")
                    response.hangup()

                    # if they have a missed call trigger, fire that off
                    Trigger.catch_triggers(contact, Trigger.TYPE_MISSED_CALL, channel)

                    # either way, we need to hangup now
                    return HttpResponse(str(response))

        # check for call progress events, these include post-call hangup notifications
        if request.POST.get("CallbackSource", None) == "call-progress-events":
            if call_sid:
                from temba.ivr.models import IVRCall

                call = IVRCall.objects.filter(external_id=call_sid).first()
                if call:
                    call.update_status(
                        request.POST.get("CallStatus", None), request.POST.get("CallDuration", None), "TW"
                    )
                    call.save()
                    return HttpResponse("Call status updated")
            return HttpResponse("No call found")

        return HttpResponse("Not Handled, unknown action", status=400)  # pragma: no cover