コード例 #1
0
ファイル: tests.py プロジェクト: zoliapjove/newfies-dialer
    def setUp(self):
        self.gateway = Gateway(
            name='test gateway',
            status=2,
            removeprefix='94'
        )
        self.gateway.set_name("MyGateway")
        self.gateway.save()
        self.assertEqual(self.gateway.__unicode__(), u'MyGateway')

        response = prepare_phonenumber('9897525414', '91', '+', self.gateway.status)
        self.assertEqual(response, False)

        response = prepare_phonenumber('', '91', '+', self.gateway.status)
        self.assertEqual(response, False)

        response = prepare_phonenumber('+9897525414', '91', '+', self.gateway.status)
        self.assertEqual(response, False)

        self.gateway.status = 1
        self.gateway.save()
        response = prepare_phonenumber('9897525414', '91', '+', self.gateway.status)
        self.assertEqual(response, '919897525414')
コード例 #2
0
ファイル: tasks.py プロジェクト: sarkartanzil/newfies-dialer
def init_callrequest(callrequest_id,
                     campaign_id,
                     callmaxduration,
                     ms_addtowait=0,
                     alarm_request_id=None):
    """
    This task read the callrequest, update it as 'In Process'
    then proceed on the call outbound, using the different call engine supported

    **Attributes**:

        * ``callrequest_id`` - Callrequest ID
        * ``campaign_id`` - Campaign ID
        * ``callmaxduration`` - Max duration
        * ``ms_addtowait`` - Milliseconds to wait before outbounding the call

    """
    outbound_failure = False
    subscriber_id = None
    contact_id = None
    debug_query(8)

    if ms_addtowait > 0:
        sleep(ms_addtowait)

    # Survey Call or Alarm Call
    if campaign_id:
        # TODO: use only
        # https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.only
        obj_callrequest = Callrequest.objects\
            .select_related('aleg_gateway', 'user__userprofile', 'subscriber', 'campaign').get(id=callrequest_id)
        subscriber_id = obj_callrequest.subscriber_id
        contact_id = obj_callrequest.subscriber.contact_id
    elif alarm_request_id:
        obj_callrequest = Callrequest.objects.select_related(
            'aleg_gateway', 'user__userprofile').get(id=callrequest_id)
        alarm_request_id = obj_callrequest.alarm_request_id
    else:
        logger.info(
            "TASK :: init_callrequest, wrong campaign_id & alarm_request_id")
        return False

    debug_query(9)
    logger.info("TASK :: init_callrequest - status:%s;cmpg:%s;alarm:%s" %
                (obj_callrequest.status, campaign_id, alarm_request_id))

    # TODO: move method prepare_phonenumber into the model gateway
    # Obj_callrequest.aleg_gatewayprepare_phonenumber()
    dialout_phone_number = prepare_phonenumber(
        obj_callrequest.phone_number, obj_callrequest.aleg_gateway.addprefix,
        obj_callrequest.aleg_gateway.removeprefix,
        obj_callrequest.aleg_gateway.status)
    if not dialout_phone_number:
        logger.info("Error with dialout_phone_number - phone_number:%s" %
                    (obj_callrequest.phone_number))
        return False
    else:
        logger.debug("dialout_phone_number : %s" % dialout_phone_number)

    debug_query(10)

    if settings.DIALERDEBUG:
        dialout_phone_number = settings.DIALERDEBUG_PHONENUMBER

    # Retrieve the Gateway for the A-Leg
    gateways = obj_callrequest.aleg_gateway.gateways
    gateway_id = obj_callrequest.aleg_gateway.id
    # Gateway_codecs / gateway_retries

    dialing_timeout = obj_callrequest.timeout
    # fraud protection on short calls
    try:
        dialing_timeout = int(dialing_timeout)
        if dialing_timeout < 10:
            dialing_timeout = 10
    except ValueError:
        dialing_timeout = 45
    originate_dial_string = obj_callrequest.aleg_gateway.originate_dial_string

    debug_query(11)

    # Sanitize gateways
    gateways = gateways.strip()
    if gateways[-1] != '/':
        gateways = gateways + '/'

    originate_dial_string = obj_callrequest.aleg_gateway.originate_dial_string
    if obj_callrequest.user.userprofile and obj_callrequest.user.userprofile.accountcode:
        originate_dial_string = originate_dial_string + ',accountcode=' + \
            str(obj_callrequest.user.userprofile.accountcode)

    debug_query(12)

    if settings.NEWFIES_DIALER_ENGINE.lower() == 'esl':
        try:
            args_list = []
            send_digits = False
            time_limit = callmaxduration

            # To wait before sending DTMF to the extension, you can add leading 'w'
            # characters.
            # Each 'w' character waits 0.5 seconds instead of sending a digit.
            # Each 'W' character waits 1.0 seconds instead of sending a digit.
            # You can also add the tone duration in ms by appending @[duration] after string.
            # Eg. 1w2w3@1000
            check_senddigit = dialout_phone_number.partition('w')
            if check_senddigit[1] == 'w':
                send_digits = check_senddigit[1] + check_senddigit[2]
                dialout_phone_number = check_senddigit[0]

            if obj_callrequest.callerid and len(obj_callrequest.callerid) > 0:
                args_list.append("origination_caller_id_number='%s'" %
                                 obj_callrequest.callerid)
            if obj_callrequest.caller_name and len(
                    obj_callrequest.caller_name) > 0:
                args_list.append("origination_caller_id_name='%s'" %
                                 obj_callrequest.caller_name)

            # Add App Vars
            args_list.append(
                "campaign_id=%s,subscriber_id=%s,alarm_request_id=%s,used_gateway_id=%s,callrequest_id=%s,contact_id=%s,dialout_phone_number=%s"
                %
                (campaign_id, subscriber_id, alarm_request_id, gateway_id,
                 obj_callrequest.id, contact_id, obj_callrequest.phone_number))
            args_list.append(originate_dial_string)

            # Call Vars
            callvars = "bridge_early_media=true,originate_timeout=%d,newfiesdialer=true,leg_type=1" % \
                (dialing_timeout, )
            args_list.append(callvars)

            # Default Test
            hangup_on_ring = ''
            send_preanswer = False
            # set hangup_on_ring
            try:
                hangup_on_ring = int(hangup_on_ring)
            except ValueError:
                hangup_on_ring = -1
            exec_on_media = 1
            if hangup_on_ring >= 10:  # 0->10 fraud protection on short calls
                args_list.append(
                    "execute_on_media_%d='sched_hangup +%d ORIGINATOR_CANCEL'"
                    % (exec_on_media, hangup_on_ring))
                exec_on_media += 1

            # TODO: look and test http://wiki.freeswitch.org/wiki/Misc._Dialplan_Tools_queue_dtmf
            # Send digits
            if send_digits:
                if send_preanswer:
                    args_list.append("execute_on_media_%d='send_dtmf %s'" %
                                     (exec_on_media, send_digits))
                    exec_on_media += 1
                else:
                    args_list.append("execute_on_answer='send_dtmf %s'" %
                                     send_digits)

            # Set time_limit
            try:
                time_limit = int(time_limit)
                if time_limit > 0:
                    args_list.append(
                        "execute_on_answer='sched_hangup +%d ALLOTTED_TIMEOUT'"
                        % time_limit)
            except ValueError:
                logger.error('ValueError time_limit :> %s' % time_limit)

            # build originate string
            args_str = ','.join(args_list)

            # DEBUG
            # settings.ESL_SCRIPT = '&playback(/usr/local/freeswitch/sounds/en/us/callie/voicemail/8000/vm-record_greeting.wav)'
            if settings.DIALERDEBUG:
                dial_command = "originate {%s}user/areski '%s'" % (
                    args_str, settings.ESL_SCRIPT)
            else:
                dial_command = "originate {%s}%s%s '%s'" % \
                    (args_str, gateways, dialout_phone_number, settings.ESL_SCRIPT)

            # originate {bridge_early_media=true,hangup_after_bridge=true,originate_timeout=10}user/areski &playback(/tmp/myfile.wav)
            # dial = "originate {bridge_early_media=true,hangup_after_bridge=true,originate_timeout=,newfiesdialer=true,used_gateway_id=1,callrequest_id=38,leg_type=1,origination_caller_id_number=234234234,origination_caller_id_name=234234,effective_caller_id_number=234234234,effective_caller_id_name=234234,}user//1000 '&lua(/usr/share/newfies-lua/newfies.lua)'"

            # Load balance on testing
            # from random import randint, seed
            # seed()
            # randval = randint(1, 2)
            # if randval == 1:
            #     dial_command = dial_command.replace('88.208.208.244', '88.208.208.209')
            # logger.warn('dial_command (%d): %s' % (randval, dial_command))

            logger.warn('dial_command : %s' % dial_command)
            request_uuid = dial_out(dial_command, obj_callrequest.id)

            debug_query(14)

            if request_uuid and len(
                    request_uuid) > 0 and request_uuid[:5] == 'error':
                outbound_failure = True
            debug_query(13)
        except:
            raise
            logger.error('error : ESL')
            outbound_failure = True
        logger.debug('Received RequestUUID :> %s' % request_uuid)
    else:
        logger.error('No other method supported!')
        obj_callrequest.status = CALLREQUEST_STATUS.FAILURE
        obj_callrequest.save()
        # ADD if alarm_request_id update AlarmRequest
        return False

    # Survey Call or Alarm Call
    if campaign_id:
        # Update Subscriber
        if not obj_callrequest.subscriber.count_attempt:
            obj_callrequest.subscriber.count_attempt = 1
        else:
            obj_callrequest.subscriber.count_attempt = obj_callrequest.subscriber.count_attempt + 1
        obj_callrequest.subscriber.last_attempt = datetime.utcnow().replace(
            tzinfo=utc)
        # check if the outbound call failed then update Subscriber
        if outbound_failure:
            obj_callrequest.subscriber.status = SUBSCRIBER_STATUS.FAIL
        obj_callrequest.subscriber.save()
    elif alarm_request_id:
        if outbound_failure:
            check_retry_alarm(alarm_request_id)

    # Update CallRequest Object
    obj_callrequest.request_uuid = request_uuid
    # check if the outbound call failed
    if outbound_failure:
        obj_callrequest.status = CALLREQUEST_STATUS.FAILURE
    else:
        obj_callrequest.status = CALLREQUEST_STATUS.CALLING
    obj_callrequest.save()

    debug_query(14)

    return True
コード例 #3
0
ファイル: tasks.py プロジェクト: acheraime/newfies-dialer
def init_callrequest(callrequest_id, campaign_id, callmaxduration):
    """
    This task read the callrequest, update it as 'In Process'
    then proceed on the call outbound, using the different call engine supported

    **Attributes**:

        * ``callrequest_id`` - Callrequest ID

    """
    debug_query(8)

    #Get CallRequest object
    # .only('id', 'callerid', 'phone_number', 'status',
    #     'request_uuid', 'campaign__id', 'subscriber__id',
    #     'aleg_gateway__id', 'aleg_gateway__addprefix', 'aleg_gateway__removeprefix', 'aleg_gateway__status',
    #     'aleg_gateway__gateways', 'aleg_gateway__gateway_timeouts', 'aleg_gateway__originate_dial_string',
    #     'user__userprofile__accountcode', 'campaign__caller_name',
    #     'subscriber__id', 'subscriber__contact__id', 'subscriber__count_attempt', 'subscriber__last_attempt')\
    obj_callrequest = Callrequest.objects.select_related('aleg_gateway', 'user__userprofile', 'subscriber', 'campaign').get(id=callrequest_id)

    debug_query(9)

    logger.info("TASK :: init_callrequest - status:%s;cmpg:%d" % (str(obj_callrequest.status), campaign_id))

    debug_query(10)

    if obj_callrequest.aleg_gateway:
        dialout_phone_number = prepare_phonenumber(
            obj_callrequest.phone_number,
            obj_callrequest.aleg_gateway.addprefix,
            obj_callrequest.aleg_gateway.removeprefix,
            obj_callrequest.aleg_gateway.status)
    else:
        dialout_phone_number = obj_callrequest.phone_number
    logger.debug("dialout_phone_number : %s" % dialout_phone_number)

    if not dialout_phone_number:
        logger.info("Error with dialout_phone_number - phone_number:%s;cmpg:%d" % (str(obj_callrequest.phone_number), campaign_id))
        return False

    debug_query(11)

    if settings.DIALERDEBUG:
        dialout_phone_number = settings.DIALERDEBUG_PHONENUMBER

    #Retrieve the Gateway for the A-Leg
    gateways = obj_callrequest.aleg_gateway.gateways
    gateway_id = obj_callrequest.aleg_gateway.id
    #gateway_codecs = obj_callrequest.aleg_gateway.gateway_codecs
    #gateway_retries = obj_callrequest.aleg_gateway.gateway_retries
    gateway_timeouts = obj_callrequest.aleg_gateway.gateway_timeouts
    originate_dial_string = obj_callrequest.aleg_gateway.originate_dial_string

    debug_query(12)

    #Sanitize gateways
    gateways = gateways.strip()
    if gateways[-1] != '/':
        gateways = gateways + '/'

    originate_dial_string = obj_callrequest.aleg_gateway.originate_dial_string
    if (obj_callrequest.user.userprofile.accountcode and
       obj_callrequest.user.userprofile.accountcode > 0):
        originate_dial_string = originate_dial_string + \
            ',accountcode=' + str(obj_callrequest.user.userprofile.accountcode)

    debug_query(13)

    outbound_failure = False

    #Send Call to API
    #http://ask.github.com/celery/userguide/remote-tasks.html

    """
    #this could be needed if we want to call a different API / Twilio
    import httplib, urllib
    params = urllib.urlencode({'From': '900900000', 'To': '1000',})
    headers = {"Content-type": "application/x-www-form-urlencoded",
           "Accept": "text/plain"}
    conn = httplib.HTTPConnection("127.0.0.1:8000")
    conn.request("POST", "/api/dialer_cdr/testcall/", params, headers)
    response = conn.getresponse()
    print response.status, response.reason
    data = response.read()
    conn.close()
    """

    if settings.NEWFIES_DIALER_ENGINE.lower() == 'esl':
        try:
            args_list = []
            send_digits = False
            time_limit = callmaxduration

            # To wait before sending DTMF to the extension, you can add leading 'w'
            # characters.
            # Each 'w' character waits 0.5 seconds instead of sending a digit.
            # Each 'W' character waits 1.0 seconds instead of sending a digit.
            # You can also add the tone duration in ms by appending @[duration] after string.
            # Eg. 1w2w3@1000
            check_senddigit = dialout_phone_number.partition('w')
            if check_senddigit[1] == 'w':
                send_digits = check_senddigit[1] + check_senddigit[2]
                dialout_phone_number = check_senddigit[0]

            args_list.append("origination_caller_id_number=%s" % obj_callrequest.callerid)
            if obj_callrequest.campaign.caller_name:
                args_list.append("origination_caller_id_name='%s'" % obj_callrequest.campaign.caller_name)

            #Add App Vars
            args_list.append("campaign_id=%d,subscriber_id=%d,used_gateway_id=%s,callrequest_id=%s,contact_id=%s" %
                (obj_callrequest.campaign_id, obj_callrequest.subscriber_id, gateway_id, obj_callrequest.id, obj_callrequest.subscriber.contact_id))

            args_list.append(originate_dial_string)

            #Call Vars
            callvars = "bridge_early_media=true,originate_timeout=%s,newfiesdialer=true,leg_type=1" % \
                (gateway_timeouts, )

            args_list.append(callvars)

            #Default Test
            hangup_on_ring = ''
            send_preanswer = False

            # set hangup_on_ring
            try:
                hangup_on_ring = int(hangup_on_ring)
            except ValueError:
                hangup_on_ring = -1
            exec_on_media = 1
            if hangup_on_ring >= 0:
                args_list.append("execute_on_media_%d='sched_hangup +%d ORIGINATOR_CANCEL'"
                    % (exec_on_media, hangup_on_ring))
                exec_on_media += 1

            #TODO: look and test http://wiki.freeswitch.org/wiki/Misc._Dialplan_Tools_queue_dtmf

            # Send digits
            if send_digits:
                if send_preanswer:
                    args_list.append("execute_on_media_%d='send_dtmf %s'"
                        % (exec_on_media, send_digits))
                    exec_on_media += 1
                else:
                    args_list.append("execute_on_answer='send_dtmf %s'" % send_digits)

            # set time_limit
            try:
                time_limit = int(time_limit)
            except ValueError:
                time_limit = -1
            #TODO : Fix time_limit - maybe implement this into Lua
            # if time_limit > 0:
            #     # create sched_hangup_id
            #     sched_hangup_id = str(uuid1())
            #     # create a new request uuid
            #     request_uuid = str(uuid1())
            #     args_list.append("api_on_answer_1='sched_api +%d %s hupall ALLOTTED_TIMEOUT'"
            #         % (time_limit, sched_hangup_id))

            # build originate string
            args_str = ','.join(args_list)

            #DEBUG
            #settings.ESL_SCRIPT = '&playback(/usr/local/freeswitch/sounds/en/us/callie/voicemail/8000/vm-record_greeting.wav)'
            dial = "originate {%s}%s%s '%s'" % \
                (args_str, gateways, dialout_phone_number, settings.ESL_SCRIPT)
            # originate {bridge_early_media=true,hangup_after_bridge=true,originate_timeout=10}user/areski &playback(/tmp/myfile.wav)
            # dial = "originate {bridge_early_media=true,hangup_after_bridge=true,originate_timeout=,newfiesdialer=true,used_gateway_id=1,callrequest_id=38,leg_type=1,origination_caller_id_number=234234234,origination_caller_id_name=234234,effective_caller_id_number=234234234,effective_caller_id_name=234234,}user//1000 '&lua(/usr/share/newfies-lua/newfies.lua)'"
            print dial

            import ESL
            c = ESL.ESLconnection(settings.ESL_HOSTNAME, settings.ESL_PORT, settings.ESL_SECRET)
            c.connected()
            ev = c.api("bgapi", str(dial))
            c.disconnect()

            debug_query(14)

            if ev:
                result = ev.serialize()
                logger.debug(result)
                pos = result.find('Job-UUID:')
                if pos:
                    request_uuid = result[pos + 10:pos + 46]
                else:
                    request_uuid = 'error'
            else:
                request_uuid = 'error'

        except:
            raise
            logger.error('error : ESL')
            outbound_failure = True
            return False
        logger.info('Received RequestUUID :> ' + request_uuid)
    else:
        logger.error('No other method supported!')
        obj_callrequest.status = CALLREQUEST_STATUS.FAILURE
        obj_callrequest.save()
        return False

    #Update Subscriber
    if not obj_callrequest.subscriber.count_attempt:
        obj_callrequest.subscriber.count_attempt = 1
    else:
        obj_callrequest.subscriber.count_attempt = obj_callrequest.subscriber.count_attempt + 1
    obj_callrequest.subscriber.last_attempt = datetime.now()
    #check if the outbound call failed then update Subscriber
    if outbound_failure:
        obj_callrequest.subscriber.status = SUBSCRIBER_STATUS.FAIL
    obj_callrequest.subscriber.save()

    #Update CallRequest Object
    obj_callrequest.request_uuid = request_uuid
    #check if the outbound call failed
    if outbound_failure:
        obj_callrequest.status = CALLREQUEST_STATUS.FAILURE
    else:
        obj_callrequest.status = CALLREQUEST_STATUS.CALLING
    obj_callrequest.save()

    #lock to limit running process, do so per campaign
    #http://ask.github.com/celery/cookbook/tasks.html

    debug_query(15)

    return True
コード例 #4
0
ファイル: tasks.py プロジェクト: nishad89/newfies-dialer
def init_callrequest(callrequest_id, campaign_id, callmaxduration, ms_addtowait=0, alarm_request_id=None):
    """
    This task read the callrequest, update it as 'In Process'
    then proceed on the call outbound, using the different call engine supported

    **Attributes**:

        * ``callrequest_id`` - Callrequest ID
        * ``campaign_id`` - Campaign ID
        * ``callmaxduration`` - Max duration
        * ``ms_addtowait`` - Milliseconds to wait before outbounding the call

    """
    outbound_failure = False
    subscriber_id = None
    contact_id = None
    debug_query(8)

    if ms_addtowait > 0:
        sleep(ms_addtowait)

    #Survey Call or Alarm Call
    if campaign_id:
        #TODO: use only https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.only
        obj_callrequest = Callrequest.objects\
            .select_related('aleg_gateway', 'user__userprofile', 'subscriber', 'campaign').get(id=callrequest_id)
        subscriber_id = obj_callrequest.subscriber_id
        contact_id = obj_callrequest.subscriber.contact_id
    elif alarm_request_id:
        obj_callrequest = Callrequest.objects.select_related('aleg_gateway', 'user__userprofile').get(id=callrequest_id)
        alarm_request_id = obj_callrequest.alarm_request_id
    else:
        logger.info("TASK :: init_callrequest, wrong campaign_id & alarm_request_id")
        return False

    debug_query(9)
    logger.info("TASK :: init_callrequest - status:%s;cmpg:%s;alarm:%s" %
                (obj_callrequest.status, campaign_id, alarm_request_id))

    # TODO: move method prepare_phonenumber into the model gateway
    #obj_callrequest.aleg_gatewayprepare_phonenumber()
    dialout_phone_number = prepare_phonenumber(
        obj_callrequest.phone_number,
        obj_callrequest.aleg_gateway.addprefix,
        obj_callrequest.aleg_gateway.removeprefix,
        obj_callrequest.aleg_gateway.status)
    if not dialout_phone_number:
        logger.info("Error with dialout_phone_number - phone_number:%s" % (obj_callrequest.phone_number))
        return False
    else:
        logger.debug("dialout_phone_number : %s" % dialout_phone_number)

    debug_query(10)

    if settings.DIALERDEBUG:
        dialout_phone_number = settings.DIALERDEBUG_PHONENUMBER

    #Retrieve the Gateway for the A-Leg
    gateways = obj_callrequest.aleg_gateway.gateways
    gateway_id = obj_callrequest.aleg_gateway.id
    #gateway_codecs / gateway_retries
    gateway_timeouts = obj_callrequest.aleg_gateway.gateway_timeouts
    if not gateway_timeouts:
        gateway_timeouts = '60'
    originate_dial_string = obj_callrequest.aleg_gateway.originate_dial_string

    debug_query(11)

    #Sanitize gateways
    gateways = gateways.strip()
    if gateways[-1] != '/':
        gateways = gateways + '/'

    originate_dial_string = obj_callrequest.aleg_gateway.originate_dial_string
    if obj_callrequest.user.userprofile and obj_callrequest.user.userprofile.accountcode:
        originate_dial_string = originate_dial_string + ',accountcode=' + \
            str(obj_callrequest.user.userprofile.accountcode)

    debug_query(12)

    if settings.NEWFIES_DIALER_ENGINE.lower() == 'esl':
        try:
            args_list = []
            send_digits = False
            time_limit = callmaxduration

            # To wait before sending DTMF to the extension, you can add leading 'w'
            # characters.
            # Each 'w' character waits 0.5 seconds instead of sending a digit.
            # Each 'W' character waits 1.0 seconds instead of sending a digit.
            # You can also add the tone duration in ms by appending @[duration] after string.
            # Eg. 1w2w3@1000
            check_senddigit = dialout_phone_number.partition('w')
            if check_senddigit[1] == 'w':
                send_digits = check_senddigit[1] + check_senddigit[2]
                dialout_phone_number = check_senddigit[0]

            args_list.append("origination_caller_id_number=%s" % obj_callrequest.callerid)
            args_list.append("origination_caller_id_name='%s'" % obj_callrequest.caller_name)

            #Add App Vars
            args_list.append("campaign_id=%s,subscriber_id=%s,alarm_request_id=%s,used_gateway_id=%s,callrequest_id=%s,contact_id=%s" %
                (campaign_id, subscriber_id, alarm_request_id, gateway_id, obj_callrequest.id, contact_id))
            args_list.append(originate_dial_string)

            #Call Vars
            callvars = "bridge_early_media=true,originate_timeout=%s,newfiesdialer=true,leg_type=1" % \
                (gateway_timeouts, )
            args_list.append(callvars)

            #Default Test
            hangup_on_ring = ''
            send_preanswer = False
            # set hangup_on_ring
            try:
                hangup_on_ring = int(hangup_on_ring)
            except ValueError:
                hangup_on_ring = -1
            exec_on_media = 1
            if hangup_on_ring >= 0:
                args_list.append("execute_on_media_%d='sched_hangup +%d ORIGINATOR_CANCEL'" %
                                 (exec_on_media, hangup_on_ring))
                exec_on_media += 1

            #TODO: look and test http://wiki.freeswitch.org/wiki/Misc._Dialplan_Tools_queue_dtmf
            # Send digits
            if send_digits:
                if send_preanswer:
                    args_list.append("execute_on_media_%d='send_dtmf %s'" % (exec_on_media, send_digits))
                    exec_on_media += 1
                else:
                    args_list.append("execute_on_answer='send_dtmf %s'" % send_digits)

            # Set time_limit
            try:
                time_limit = int(time_limit)
            except ValueError:
                time_limit = -1
            #TODO : Fix time_limit - maybe implement this into Lua
            # if time_limit > 0:
            #     # create sched_hangup_id
            #     sched_hangup_id = str(uuid1())
            #     # create a new request uuid
            #     request_uuid = str(uuid1())
            #     args_list.append("api_on_answer_1='sched_api +%d %s hupall ALLOTTED_TIMEOUT'"
            #         % (time_limit, sched_hangup_id))

            # build originate string
            args_str = ','.join(args_list)

            #DEBUG
            #settings.ESL_SCRIPT = '&playback(/usr/local/freeswitch/sounds/en/us/callie/voicemail/8000/vm-record_greeting.wav)'
            if settings.DIALERDEBUG:
                dial_command = "originate {%s}user/areski '%s'" % (args_str, settings.ESL_SCRIPT)
            else:
                dial_command = "originate {%s}%s%s '%s'" % \
                    (args_str, gateways, dialout_phone_number, settings.ESL_SCRIPT)

            # originate {bridge_early_media=true,hangup_after_bridge=true,originate_timeout=10}user/areski &playback(/tmp/myfile.wav)
            # dial = "originate {bridge_early_media=true,hangup_after_bridge=true,originate_timeout=,newfiesdialer=true,used_gateway_id=1,callrequest_id=38,leg_type=1,origination_caller_id_number=234234234,origination_caller_id_name=234234,effective_caller_id_number=234234234,effective_caller_id_name=234234,}user//1000 '&lua(/usr/share/newfies-lua/newfies.lua)'"
            logger.warn('dial_command : %s' % dial_command)

            request_uuid = dial_out(dial_command)

            debug_query(14)

            if request_uuid and len(request_uuid) > 0 and request_uuid[:5] == 'error':
                outbound_failure = True
            debug_query(13)
        except:
            raise
            logger.error('error : ESL')
            outbound_failure = True
        logger.debug('Received RequestUUID :> %s' % request_uuid)
    else:
        logger.error('No other method supported!')
        obj_callrequest.status = CALLREQUEST_STATUS.FAILURE
        obj_callrequest.save()
        #ADD if alarm_request_id update AlarmRequest
        return False

    #Survey Call or Alarm Call
    if campaign_id:
        #Update Subscriber
        if not obj_callrequest.subscriber.count_attempt:
            obj_callrequest.subscriber.count_attempt = 1
        else:
            obj_callrequest.subscriber.count_attempt = obj_callrequest.subscriber.count_attempt + 1
        obj_callrequest.subscriber.last_attempt = datetime.utcnow().replace(tzinfo=utc)
        #check if the outbound call failed then update Subscriber
        if outbound_failure:
            obj_callrequest.subscriber.status = SUBSCRIBER_STATUS.FAIL
        obj_callrequest.subscriber.save()
    elif alarm_request_id:
        if outbound_failure:
            check_retry_alarm(alarm_request_id)

    #Update CallRequest Object
    obj_callrequest.request_uuid = request_uuid
    #check if the outbound call failed
    if outbound_failure:
        obj_callrequest.status = CALLREQUEST_STATUS.FAILURE
    else:
        obj_callrequest.status = CALLREQUEST_STATUS.CALLING
    obj_callrequest.save()

    debug_query(14)

    return True
コード例 #5
0
def init_callrequest(callrequest_id,
                     campaign_id,
                     callmaxduration,
                     ms_addtowait=0):
    """
    This task read the callrequest, update it as 'In Process'
    then proceed on the call outbound, using the different call engine supported

    **Attributes**:

        * ``callrequest_id`` - Callrequest ID
        * ``campaign_id`` - Campaign ID
        * ``callmaxduration`` - Max duration
        * ``ms_addtowait`` - Milliseconds to wait before outbounding the call

    """
    debug_query(8)

    if ms_addtowait > 0:
        sleep(ms_addtowait)

    #Get CallRequest object
    #use only https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.only
    # test2 = Callrequest.objects.only('id', 'callerid', 'phone_number', 'status', \
    #     'request_uuid', 'campaign__id', 'subscriber__id', \
    #     'aleg_gateway__id', 'aleg_gateway__addprefix', 'aleg_gateway__removeprefix', 'aleg_gateway__status', \
    #     'aleg_gateway__gateways', 'aleg_gateway__gateway_timeouts', 'aleg_gateway__originate_dial_string', \
    #     'user__userprofile__accountcode', 'campaign__caller_name', \
    #     'subscriber__id', 'subscriber__contact__id', 'subscriber__count_attempt', 'subscriber__last_attempt')\
    #     .select_related('aleg_gateway', 'user__userprofile', 'subscriber', 'campaign').get(id=4767)
    obj_callrequest = Callrequest.objects.select_related(
        'aleg_gateway', 'user__userprofile', 'subscriber',
        'campaign').get(id=callrequest_id)

    debug_query(9)

    logger.info("TASK :: init_callrequest - status:%s;cmpg:%d" %
                (str(obj_callrequest.status), campaign_id))

    debug_query(10)

    if obj_callrequest.aleg_gateway:
        dialout_phone_number = prepare_phonenumber(
            obj_callrequest.phone_number,
            obj_callrequest.aleg_gateway.addprefix,
            obj_callrequest.aleg_gateway.removeprefix,
            obj_callrequest.aleg_gateway.status)
    else:
        dialout_phone_number = obj_callrequest.phone_number
    logger.debug("dialout_phone_number : %s" % dialout_phone_number)

    if not dialout_phone_number:
        logger.info(
            "Error with dialout_phone_number - phone_number:%s;cmpg:%d" %
            (str(obj_callrequest.phone_number), campaign_id))
        return False

    debug_query(11)

    if settings.DIALERDEBUG:
        dialout_phone_number = settings.DIALERDEBUG_PHONENUMBER

    #Retrieve the Gateway for the A-Leg
    gateways = obj_callrequest.aleg_gateway.gateways
    gateway_id = obj_callrequest.aleg_gateway.id
    #gateway_codecs = obj_callrequest.aleg_gateway.gateway_codecs
    #gateway_retries = obj_callrequest.aleg_gateway.gateway_retries
    gateway_timeouts = obj_callrequest.aleg_gateway.gateway_timeouts
    originate_dial_string = obj_callrequest.aleg_gateway.originate_dial_string

    debug_query(12)

    #Sanitize gateways
    gateways = gateways.strip()
    if gateways[-1] != '/':
        gateways = gateways + '/'

    originate_dial_string = obj_callrequest.aleg_gateway.originate_dial_string
    if (obj_callrequest.user.userprofile.accountcode
            and obj_callrequest.user.userprofile.accountcode > 0):
        originate_dial_string = originate_dial_string + \
            ',accountcode=' + str(obj_callrequest.user.userprofile.accountcode)

    debug_query(13)

    outbound_failure = False

    #Send Call to API
    #http://ask.github.com/celery/userguide/remote-tasks.html
    """
    #this could be needed if we want to call a different API / Twilio
    import httplib, urllib
    params = urllib.urlencode({'From': '900900000', 'To': '1000',})
    headers = {"Content-type": "application/x-www-form-urlencoded",
           "Accept": "text/plain"}
    conn = httplib.HTTPConnection("127.0.0.1:8000")
    conn.request("POST", "/api/dialer_cdr/testcall/", params, headers)
    response = conn.getresponse()
    print response.status, response.reason
    data = response.read()
    conn.close()
    """

    if settings.NEWFIES_DIALER_ENGINE.lower() == 'esl':
        try:
            args_list = []
            send_digits = False
            time_limit = callmaxduration

            # To wait before sending DTMF to the extension, you can add leading 'w'
            # characters.
            # Each 'w' character waits 0.5 seconds instead of sending a digit.
            # Each 'W' character waits 1.0 seconds instead of sending a digit.
            # You can also add the tone duration in ms by appending @[duration] after string.
            # Eg. 1w2w3@1000
            check_senddigit = dialout_phone_number.partition('w')
            if check_senddigit[1] == 'w':
                send_digits = check_senddigit[1] + check_senddigit[2]
                dialout_phone_number = check_senddigit[0]

            args_list.append("origination_caller_id_number=%s" %
                             obj_callrequest.callerid)
            if obj_callrequest.campaign.caller_name:
                args_list.append("origination_caller_id_name='%s'" %
                                 obj_callrequest.campaign.caller_name)

            #Add App Vars
            args_list.append(
                "campaign_id=%d,subscriber_id=%d,used_gateway_id=%s,callrequest_id=%s,contact_id=%s"
                % (obj_callrequest.campaign_id, obj_callrequest.subscriber_id,
                   gateway_id, obj_callrequest.id,
                   obj_callrequest.subscriber.contact_id))

            args_list.append(originate_dial_string)

            #Call Vars
            callvars = "bridge_early_media=true,originate_timeout=%s,newfiesdialer=true,leg_type=1" % \
                (gateway_timeouts, )

            args_list.append(callvars)

            #Default Test
            hangup_on_ring = ''
            send_preanswer = False

            # set hangup_on_ring
            try:
                hangup_on_ring = int(hangup_on_ring)
            except ValueError:
                hangup_on_ring = -1
            exec_on_media = 1
            if hangup_on_ring >= 0:
                args_list.append(
                    "execute_on_media_%d='sched_hangup +%d ORIGINATOR_CANCEL'"
                    % (exec_on_media, hangup_on_ring))
                exec_on_media += 1

            #TODO: look and test http://wiki.freeswitch.org/wiki/Misc._Dialplan_Tools_queue_dtmf

            # Send digits
            if send_digits:
                if send_preanswer:
                    args_list.append("execute_on_media_%d='send_dtmf %s'" %
                                     (exec_on_media, send_digits))
                    exec_on_media += 1
                else:
                    args_list.append("execute_on_answer='send_dtmf %s'" %
                                     send_digits)

            # set time_limit
            try:
                time_limit = int(time_limit)
            except ValueError:
                time_limit = -1
            #TODO : Fix time_limit - maybe implement this into Lua
            # if time_limit > 0:
            #     # create sched_hangup_id
            #     sched_hangup_id = str(uuid1())
            #     # create a new request uuid
            #     request_uuid = str(uuid1())
            #     args_list.append("api_on_answer_1='sched_api +%d %s hupall ALLOTTED_TIMEOUT'"
            #         % (time_limit, sched_hangup_id))

            # build originate string
            args_str = ','.join(args_list)

            #DEBUG
            #settings.ESL_SCRIPT = '&playback(/usr/local/freeswitch/sounds/en/us/callie/voicemail/8000/vm-record_greeting.wav)'
            dial_command = "originate {%s}%s%s '%s'" % \
                (args_str, gateways, dialout_phone_number, settings.ESL_SCRIPT)
            # originate {bridge_early_media=true,hangup_after_bridge=true,originate_timeout=10}user/areski &playback(/tmp/myfile.wav)
            # dial = "originate {bridge_early_media=true,hangup_after_bridge=true,originate_timeout=,newfiesdialer=true,used_gateway_id=1,callrequest_id=38,leg_type=1,origination_caller_id_number=234234234,origination_caller_id_name=234234,effective_caller_id_number=234234234,effective_caller_id_name=234234,}user//1000 '&lua(/usr/share/newfies-lua/newfies.lua)'"

            request_uuid = esl_dialout(dial_command)
            debug_query(14)
        except:
            raise
            logger.error('error : ESL')
            outbound_failure = True
            return False
        logger.debug('Received RequestUUID :> ' + request_uuid)
    else:
        logger.error('No other method supported!')
        obj_callrequest.status = CALLREQUEST_STATUS.FAILURE
        obj_callrequest.save()
        return False

    #Update Subscriber
    if not obj_callrequest.subscriber.count_attempt:
        obj_callrequest.subscriber.count_attempt = 1
    else:
        obj_callrequest.subscriber.count_attempt = obj_callrequest.subscriber.count_attempt + 1
    obj_callrequest.subscriber.last_attempt = datetime.now()
    #check if the outbound call failed then update Subscriber
    if outbound_failure:
        obj_callrequest.subscriber.status = SUBSCRIBER_STATUS.FAIL
    obj_callrequest.subscriber.save()

    #Update CallRequest Object
    obj_callrequest.request_uuid = request_uuid
    #check if the outbound call failed
    if outbound_failure:
        obj_callrequest.status = CALLREQUEST_STATUS.FAILURE
    else:
        obj_callrequest.status = CALLREQUEST_STATUS.CALLING
    obj_callrequest.save()

    #lock to limit running process, do so per campaign
    #http://ask.github.com/celery/cookbook/tasks.html

    debug_query(15)

    return True