Exemple #1
0
    def testCallSync(self):
        self.deleteAllLogs()
        self.assertEqual(self.getCallLogCount(), 0)
        self.assertEqual(self.getCallCount(), 0)

        # Test Create
        call = Call()
        self.setRandomCallValues(call)
        call.save()

        sleep(1)
        self.assertEqual(self.getCallLogCount(), 1)
        self.assertEqual(self.getCallCount(), 1)

        calllog = CallLog.get(call.couch_id)
        self.checkFieldValues(calllog, call, Call._migration_get_fields())
        self.assertTrue(CallLog.get_db().get_rev(calllog._id).startswith('2-'))

        # Test Update
        self.setRandomCallValues(call)
        call.save()

        sleep(1)
        self.assertEqual(self.getCallLogCount(), 1)
        self.assertEqual(self.getCallCount(), 1)
        callog = CallLog.get(call.couch_id)
        self.checkFieldValues(callog, call, Call._migration_get_fields())
        self.assertTrue(CallLog.get_db().get_rev(callog._id).startswith('3-'))
Exemple #2
0
def ivr_in(request):
    """
    Handles tropo call requests
    """
    if request.method == "POST":
        data = json.loads(request.body)
        phone_number = data["session"]["from"]["id"]
        # TODO: Implement tropo as an ivr backend. In the meantime, just log the call.

        if phone_number:
            cleaned_number = strip_plus(phone_number)
            v = PhoneNumber.by_extensive_search(cleaned_number)
        else:
            v = None

        # Save the call entry
        msg = Call(
            phone_number=cleaned_number,
            direction=INCOMING,
            date=datetime.utcnow(),
            backend_api=SQLTropoBackend.get_api_id(),
        )
        if v is not None:
            msg.domain = v.domain
            msg.couch_recipient_doc_type = v.owner_doc_type
            msg.couch_recipient = v.owner_id
        msg.save()

        t = Tropo()
        t.reject()
        return HttpResponse(t.RenderJson())
    else:
        return HttpResponseBadRequest("Bad Request")
Exemple #3
0
def ivr_in(request):
    """
    Handles tropo call requests
    """
    if request.method == "POST":
        data = json.loads(request.body)
        phone_number = data["session"]["from"]["id"]
        # TODO: Implement tropo as an ivr backend. In the meantime, just log the call.

        if phone_number:
            cleaned_number = strip_plus(phone_number)
            v = VerifiedNumber.by_extensive_search(cleaned_number)
        else:
            v = None

        # Save the call entry
        msg = Call(
            phone_number=cleaned_number,
            direction=INCOMING,
            date=datetime.utcnow(),
            backend_api=SQLTropoBackend.get_api_id(),
        )
        if v is not None:
            msg.domain = v.domain
            msg.couch_recipient_doc_type = v.owner_doc_type
            msg.couch_recipient = v.owner_id
        msg.save()

        t = Tropo()
        t.reject()
        return HttpResponse(t.RenderJson())
    else:
        return HttpResponseBadRequest("Bad Request")
Exemple #4
0
def log_call(phone_number, gateway_session_id, backend=None):
    cleaned_number = strip_plus(phone_number)
    v = PhoneNumber.by_extensive_search(cleaned_number)

    call = Call(
        phone_number=cleaned_number,
        direction=INCOMING,
        date=datetime.utcnow(),
        backend_api=backend.get_api_id() if backend else None,
        backend_id=backend.couch_id if backend else None,
        gateway_session_id=gateway_session_id,
    )
    if v:
        call.domain = v.domain
        call.couch_recipient_doc_type = v.owner_doc_type
        call.couch_recipient = v.owner_id
    call.save()
Exemple #5
0
def log_call(phone_number, gateway_session_id, backend=None):
    cleaned_number = strip_plus(phone_number)
    v = PhoneNumber.by_extensive_search(cleaned_number)

    call = Call(
        phone_number=cleaned_number,
        direction=INCOMING,
        date=datetime.utcnow(),
        backend_api=backend.get_api_id() if backend else None,
        backend_id=backend.couch_id if backend else None,
        gateway_session_id=gateway_session_id,
    )
    if v:
        call.domain = v.domain
        call.couch_recipient_doc_type = v.owner_doc_type
        call.couch_recipient = v.owner_id
    call.save()
Exemple #6
0
def initiate_outbound_call(recipient, form_unique_id, submit_partial_form,
        include_case_side_effects, max_question_retries, messaging_event_id,
        verified_number=None, unverified_number=None, case_id=None,
        case_for_case_submission=False, timestamp=None):
    """
    Returns False if an error occurred and the call should be retried.
    Returns True if the call should not be retried (either because it was
    queued successfully or because an unrecoverable error occurred).
    """
    call = None
    logged_event = MessagingEvent.objects.get(pk=messaging_event_id)
    logged_subevent = logged_event.create_ivr_subevent(recipient,
        form_unique_id, case_id=case_id)

    if not verified_number and not unverified_number:
        log_error(MessagingEvent.ERROR_NO_PHONE_NUMBER,
            logged_subevent=logged_subevent)
        return True

    backend = get_ivr_backend(recipient, verified_number, unverified_number)
    if not backend:
        log_error(MessagingEvent.ERROR_NO_SUITABLE_GATEWAY,
            logged_subevent=logged_subevent)
        return True

    phone_number = (verified_number.phone_number if verified_number
        else unverified_number)

    call = Call(
        couch_recipient_doc_type=recipient.doc_type,
        couch_recipient=recipient.get_id,
        phone_number='+%s' % str(phone_number),
        direction=OUTGOING,
        date=timestamp or datetime.utcnow(),
        domain=recipient.domain,
        form_unique_id=form_unique_id,
        submit_partial_form=submit_partial_form,
        include_case_side_effects=include_case_side_effects,
        max_question_retries=max_question_retries,
        current_question_retry_count=0,
        case_id=case_id,
        case_for_case_submission=case_for_case_submission,
        messaging_subevent_id=logged_subevent.pk,
    )

    ivr_data = None
    if backend.cache_first_ivr_response():
        ivr_data, error = get_first_ivr_response_data(recipient,
            call, logged_subevent)
        if error:
            return True

    if ivr_data:
        logged_subevent.xforms_session = ivr_data.session
        logged_subevent.save()

    try:
        call.backend_api = backend.get_api_id()
        call.backend_id = backend.couch_id
        result = backend.initiate_outbound_call(call, logged_subevent)
        if ivr_data and not call.error:
            backend.set_first_ivr_response(call, call.gateway_session_id, ivr_data)
        call.save()
        logged_subevent.completed()
        return result
    except GatewayConnectionError:
        log_error(MessagingEvent.ERROR_GATEWAY_ERROR, call, logged_subevent)
        raise
    except Exception:
        log_error(MessagingEvent.ERROR_INTERNAL_SERVER_ERROR, call, logged_subevent)
        raise
Exemple #7
0
def initiate_outbound_call(recipient,
                           form_unique_id,
                           submit_partial_form,
                           include_case_side_effects,
                           max_question_retries,
                           messaging_event_id,
                           verified_number=None,
                           unverified_number=None,
                           case_id=None,
                           case_for_case_submission=False,
                           timestamp=None):
    """
    Returns False if an error occurred and the call should be retried.
    Returns True if the call should not be retried (either because it was
    queued successfully or because an unrecoverable error occurred).
    """
    call = None
    logged_event = MessagingEvent.objects.get(pk=messaging_event_id)
    logged_subevent = logged_event.create_ivr_subevent(recipient,
                                                       form_unique_id,
                                                       case_id=case_id)

    if not verified_number and not unverified_number:
        log_error(MessagingEvent.ERROR_NO_PHONE_NUMBER,
                  logged_subevent=logged_subevent)
        return True

    backend = get_ivr_backend(recipient, verified_number, unverified_number)
    if not backend:
        log_error(MessagingEvent.ERROR_NO_SUITABLE_GATEWAY,
                  logged_subevent=logged_subevent)
        return True

    phone_number = (verified_number.phone_number
                    if verified_number else unverified_number)

    call = Call(
        couch_recipient_doc_type=recipient.doc_type,
        couch_recipient=recipient.get_id,
        phone_number='+%s' % str(phone_number),
        direction=OUTGOING,
        date=timestamp or datetime.utcnow(),
        domain=recipient.domain,
        form_unique_id=form_unique_id,
        submit_partial_form=submit_partial_form,
        include_case_side_effects=include_case_side_effects,
        max_question_retries=max_question_retries,
        current_question_retry_count=0,
        case_id=case_id,
        case_for_case_submission=case_for_case_submission,
        messaging_subevent_id=logged_subevent.pk,
    )

    ivr_data = None
    if backend.cache_first_ivr_response():
        ivr_data, error = get_first_ivr_response_data(recipient, call,
                                                      logged_subevent)
        if error:
            return True

    if ivr_data:
        logged_subevent.xforms_session = ivr_data.session
        logged_subevent.save()

    try:
        call.backend_api = backend.get_api_id()
        call.backend_id = backend.couch_id
        result = backend.initiate_outbound_call(call, logged_subevent)
        if ivr_data and not call.error:
            backend.set_first_ivr_response(call, call.gateway_session_id,
                                           ivr_data)
        call.save()
        logged_subevent.completed()
        return result
    except GatewayConnectionError:
        log_error(MessagingEvent.ERROR_GATEWAY_ERROR, call, logged_subevent)
        raise
    except Exception:
        log_error(MessagingEvent.ERROR_INTERNAL_SERVER_ERROR, call,
                  logged_subevent)
        raise