def main():
    agi_inst = agi.AGI()
    agi_inst.verbose("Printing available channel values")
    agi_inst.verbose(str(agi_inst.env))
    callerId = agi_inst.env['agi_callerid']
    agi_inst.verbose("call from %s" % callerId)
    while True:
        agi_inst.stream_file('vm-extension')
        result = agi_inst.wait_for_digit(-1)
        agi_inst.verbose("got digit %s" % result)
        if result.isdigit():
            agi_inst.say_number(result)
        else:
            agi_inst.verbose("bye!")
            agi_inst.hangup()
            agi_inst.exit()
Esempio n. 2
0
    def __init__(self, config_file, group, use_agi=False, use_mgr=False):
        self.config_file = config_file
        self.group = group

        # Validate and parse the config
        config = _Config(self.config_file, self.group)
        (status, self.conf) = config.parse()

        if not status:
            print "[ConfigError] %s" % self.conf
            sys.exit(1)

        self.sql = _SQL(self.conf['sqlite_database'])
        self.log = self._setupLogging(self.conf['log_file'],
                                      self.conf['log_level'])

        if use_agi: self.agi = agi.AGI()
        if use_mgr: self.mgr = manager.Manager()
def main():
    agi_inst = agi.AGI()

    agi_inst.verbose("Connecting to MongoDB")
    mongo_client = pymongo.MongoClient('localhost', 27017)

    agi_inst.verbose("Retrieving Call Data")
    calls = mongo_client.asterisk_data.call_data

    agi_inst.verbose("Got the collection")

    gathered_data = {
        "caller": agi_inst.env['agi_callerid'],
        "called": agi_inst.env['agi_arg_1'],
        "chargeable": agi_inst.env['agi_arg_1'] in chargeable_endpoints
    }

    agi_inst.verbose("Gathered data: " + str(gathered_data))

    calls.insert_one(gathered_data)

    agi_inst.verbose("Inserted data. Time to go!")
Esempio n. 4
0
def main(options, arguments):
    # print 'options = %s' % options
    # print 'arguments = %s' % arguments

    agi = agilib.AGI()

    if options.outgoing:
        phone_number = agi.env['agi_%s' % options.outgoing_agi_var]
        agi.verbose("Dialed phone number is %s" % phone_number)
    else:
        # If we already have a "True" caller ID name
        # i.e. not just digits, but a real name, then we don't try to
        # connect to Odoo or geoloc, we just keep it
        if (
                agi.env.get('agi_calleridname') and
                not agi.env['agi_calleridname'].isdigit() and
                agi.env['agi_calleridname'].lower()
                not in ['asterisk', 'unknown', 'anonymous'] and
                not options.notify):
            agi.verbose(
                "Incoming CallerID name is %s"
                % agi.env['agi_calleridname'])
            agi.verbose("As it is a real name, we do not change it")
            return True

        phone_number = agi.env['agi_callerid']

    if not isinstance(phone_number, str):
        agi.verbose("Phone number is empty")
        exit(0)
    # Match for particular cases and anonymous phone calls
    # To test anonymous call in France, dial 3651 + number
    if not phone_number.isdigit():
        agi.verbose("Phone number (%s) is not a digit" % phone_number)
        exit(0)

    agi.verbose("Phone number = %s" % phone_number)

    if options.notify and not arguments:
        agi.verbose(
            "When using the notify option, you must give arguments "
            "to the script")
        exit(0)

    if options.notify:
        method = 'incall_notify_by_login'
    else:
        method = 'get_name_from_phone_number'

    res = False
    # Yes, this script can be used without "-s odoo_server" !
    if options.server and options.jsonrpc:
        import odoorpc
        proto = options.ssl and 'jsonrpc+ssl' or 'jsonrpc'
        agi.verbose(
            "Starting %s request on Odoo %s:%d database %s username %s" % (
                proto.upper(), options.server, options.port, options.database,
                options.username))
        try:
            odoo = odoorpc.ODOO(options.server, proto, options.port)
            odoo.login(options.database, options.username, options.password)
            if options.notify:
                res = odoo.execute(
                    'phone.common', method, phone_number, arguments)
            else:
                res = odoo.execute('phone.common', method, phone_number)
            agi.verbose("Called method %s" % method)
        except:
            agi.verbose("Could not connect to Odoo in JSON-RPC")
    elif options.server:
        proto = options.ssl and 'https' or 'http'
        agi.verbose(
            "Starting %s XML-RPC request on Odoo %s:%d "
            "database %s user ID %d" % (
                proto, options.server, options.port, options.database,
                options.userid))
        sock = xmlrpclib.ServerProxy(
            '%s://%s:%d/xmlrpc/object'
            % (proto, options.server, options.port))
        try:
            if options.notify:
                res = sock.execute(
                    options.database, options.userid, options.password,
                    'phone.common', method, phone_number, arguments)
            else:
                res = sock.execute(
                    options.database, options.userid, options.password,
                    'phone.common', method, phone_number)
            agi.verbose("Called method %s" % method)
        except:
            agi.verbose("Could not connect to Odoo in XML-RPC")
        # To simulate a long execution of the XML-RPC request
        # import time
        # time.sleep(5)

    # Function to limit the size of the name
    if res:
        if len(res) > options.max_size:
            res = res[0:options.max_size]
    elif options.geoloc:
        # if the number is not found in Odoo, we try to geolocate
        agi.verbose(
            "Trying to geolocate with country %s and lang %s"
            % (options.country, options.lang))
        res = geolocate_phone_number(
            phone_number, options.country, options.lang)
    else:
        # if the number is not found in Odoo and geoloc is off,
        # we put 'not_found_name' as Name
        agi.verbose("Phone number not found in Odoo")
        res = not_found_name

    # All SIP phones should support UTF-8...
    # but in case you have analog phones over TDM
    # or buggy phones, you should use the command line option --ascii
    if options.ascii:
        res = convert_to_ascii(res)

    agi.verbose("Name = %s" % res)
    if res:
        if options.outgoing:
            agi.set_variable('connectedlinename', res)
        else:
            agi.set_callerid('"%s"<%s>' % (res, phone_number))
    return True
Esempio n. 5
0
#!/usr/bin/python3

# NOTE: Remember to add Google's API key with 'export GOOGLE_APPLICATION_CREDENTIALS="/home/vagrant/g_api_key.json"'

import urllib.request
from google.cloud import speech_v1p1beta1
from google.cloud.speech_v1p1beta1 import enums
import sys, os
import asterisk.agi as agi

agi_inst = agi.AGI()


def recognize_voice(voice_file):
    agi_inst.verbose(voice_file)
    w_2_d = {
        'zero': '0',
        'one': '1',
        'two': '2',
        'three': '3',
        'four': '4',
        'five': '5',
        'six': '6',
        'seven': '7',
        'eight': '8',
        'nine': '9'
    }

    client = speech_v1p1beta1.SpeechClient()
    config = {
        "language_code": "en-US",
def main(args):
    agi = agilib.AGI()
    if args.outgoing:
        phone_number = agi.env["agi_%s" % args.outgoing_agi_var]
        agi.verbose("Dialed phone number is %s" % phone_number)
    else:
        # If we already have a "True" caller ID name
        # i.e. not just digits, but a real name, then we don't try to
        # connect to Odoo or geoloc, we just keep it
        phone_chars = [str(d) for d in range(10)]
        phone_chars += ["+"]
        if (agi.env.get("agi_calleridname") and any(
            [x not in phone_chars for x in agi.env["agi_calleridname"]])
                and agi.env["agi_calleridname"].lower()
                not in ["asterisk", "unknown", "anonymous"]
                and not args.notify):
            agi.verbose("Incoming CallerID name is %s" %
                        agi.env["agi_calleridname"])
            agi.verbose("As it is a real name, we do not change it")
            return True

        phone_number = agi.env["agi_callerid"]

    if not isinstance(phone_number, str):
        agi.verbose("Phone number is empty")
        exit(0)
    # Match for particular cases and anonymous phone calls
    # To test anonymous call in France, dial 3651 + number
    if not phone_number.isdigit():
        agi.verbose("Phone number (%s) is not a digit" % phone_number)
        exit(0)

    agi.verbose("Phone number = %s" % phone_number)

    res = False
    # This script can be used without "-s odoo_server" !
    if args.server:
        res = get_callerid_from_odoo(agi, phone_number)

    # Function to limit the size of the name
    if not res:
        if args.geoloc:
            # if the number is not found in Odoo, we try to geolocate
            agi.verbose("Trying to geolocate with country %s and lang %s" %
                        (args.country, args.lang))
            res = geolocate_phone_number(phone_number, args.country, args.lang)
        else:
            # if the number is not found in Odoo and geoloc is off,
            # we put 'not_found_name' as Name
            agi.verbose("Phone number not found in Odoo")
            res = not_found_name

    # All SIP phones should support UTF-8...
    # but in case you have analog phones over TDM
    # or buggy phones, you should use the command line option --ascii
    if args.ascii:
        res = convert_to_ascii(res)

    agi.verbose("Name = %s" % res)
    if res:
        if args.outgoing:
            agi.set_variable("connectedlinename", res)
        else:
            agi.set_callerid('"%s"<%s>' % (res, phone_number))
Esempio n. 7
0
    def run(self, send_email_report=False):
        try:
            self._agi = agi.AGI()

            # XXX 'env' is not in the pyst docs ~Roman Dudin
            project = self._agi.env['agi_arg_1']
            if not project:
                raise ValueError('No project specified')
            warlist = self._agi.get_variable('warlist')

            self._agi.verbose('Processing campaign: {0}'.format(project))

            if use_redis_cache:
                self._model = model.cached.SurveyModelCached(
                    source_db_config, destination_db_config, project, warlist,
                    redis_config, redis_ttl)
            else:
                self._model = model.SurveyModel(source_db_config,
                                                destination_db_config, project,
                                                warlist)

            call_result = CallResult()
            call_result.fields = {'calldate': datetime.now()}

            try:
                self._agi.answer()

                # update("UPDATE `{0}` SET `{1}` = `{1}` + {2} WHERE id = {3}".format(project, 'attempts', 1, warlist))

                project_data = self._model.get_details()

                # set basic project details
                project_start = project_data['intro_id']
                project_finish = project_data['hangup_id']
                project_next = project_data['next']

                try:
                    # Check AMD dialplan variable for affirmative setting.
                    # Variables evaluated in the dialplan are case-insensitive.
                    #
                    # Set(AMD = true)
                    #
                    # True values are y, yes, t, true, on and 1;
                    # false values are n, no, f, false, off and 0.
                    # Raises ValueError if val is anything else.
                    #
                    # When the dialplan variable is not set, ValueError is ignored.
                    if strtobool(self._agi.get_variable('amd')):
                        self._agi.appexec('AMD')
                        amd_status = self._agi.get_variable('AMDSTATUS')
                        amd_cause = self._agi.get_variable('AMDCAUSE')
                        self._agi.verbose('AMD Status: {0} Cause: {1}'.format(
                            amd_status, amd_cause))
                        call_result.fields['amdstatus'] = amd_status
                        call_result.fields['amdreason'] = amd_cause
                        if amd_status == 'MACHINE':
                            self._agi.verbose('Machine detected, hanging up')
                            self._finish(call_result, send_email_report)
                            self._agi.hangup()
                            return
                    else:
                        self._agi.verbose('AMD Disabled')
                except ValueError:
                    self._agi.verbose('NOTICE: AMD Dialplan Variable NOT Set!',
                                      2)

                self.play_file(project_start)
                self.prompt(project, project_next,
                            [project_start, project_finish], warlist,
                            call_result)
                self.play_file(project_finish)
                self._agi.verbose('Done')

                # Keep this BEFORE hangup()
                self._finish(call_result, send_email_report)

                self._agi.hangup()

            except NoAnswerError:
                self._finish(call_result, send_email_report)
                self._agi.hangup()
            except (agi.AGIHangup, agi.AGIAppError,
                    AsteriskConnectionLostError):
                # if the callee hangs up, the results are still written
                self._finish(call_result, send_email_report)
                raise
        except:
            # Perform UPDATE on ANY failure
            self._finish(call_result, send_email_report)
def main(options, arguments):

    agi = agilib.AGI()

    agi.verbose(
            "ENTRA EN EL PHONECALL")    

    if options.port:
        port = options.port
    # default port depends on protocol
    else:
        if options.ssl:
            port = 443
        else:
            port = 8069

    res = False
    # Yes, this script can be used without "-s odoo_server" !
    if options.server and options.jsonrpc:
        import odoorpc
        proto = options.ssl and 'jsonrpc+ssl' or 'jsonrpc'
        agi.verbose(
            "Starting %s request on Odoo %s:%d database %s username %s" % (
                proto.upper(), options.server, port, options.database,
                options.username))
        try:
            odoo = odoorpc.ODOO(options.server, proto, port)
            odoo.login(options.database, options.username, options.password)
            res = odoo.execute('crm.phonecall', 'create_phonecall_from_asterisk', agi)
            agi.verbose("Called method %s" % 'create_phonecall_from_asterisk')
        except:
            agi.verbose("Could not connect to Odoo in JSON-RPC")
    elif options.server:
        proto = options.ssl and 'https' or 'http'
        agi.verbose(
            "Starting %s XML-RPC request on Odoo %s:%d "
            "database %s user ID %d" % (
                proto, options.server, port, options.database,
                options.userid))
        sock = xmlrpclib.ServerProxy(
            '%s://%s:%d/xmlrpc/object' % (proto, options.server, port))
        try:
            res = sock.execute(
                options.database, options.userid, options.password,
                'crm.phonecall', 'create_phonecall_from_asterisk', agi)
            agi.verbose("Called method %s" % 'create_phonecall_from_asterisk')
        except:
            agi.verbose("Could not connect to Odoo in XML-RPC")
        # To simulate a long execution of the XML-RPC request
        # import time
        # time.sleep(5)

    # Function to limit the size of the name
    if res:
        agi.verbose("Data: ".format(data))
    else:
        # if the number is not found in Odoo and geoloc is off,
        # we put 'not_found_name' as Name
        agi.verbose("Data not found in Odoo")
        res = not_found_name

    # All SIP phones should support UTF-8...
    # but in case you have analog phones over TDM
    # or buggy phones, you should use the command line option --ascii
    return True