def send_message(self, message="", **kwargs): """Send an SMS to target users.""" from asterisk.ami import AMIClient from asterisk.ami.action import SimpleAction client = AMIClient(address=self._address, port=self._port) future = client.login(username=self._user, secret=self._password) if future.response.is_error(): _LOGGER.error("Can't connect to Asterisk AMI: %s", " ".join(str(future.response).splitlines())) return targets = kwargs.get(ATTR_TARGET) if targets is None: _LOGGER.error("No SMS targets, as 'target' is not defined") return # TODO: add quota per day for target in targets: _LOGGER.debug("Sending SMS to %s", target) action = SimpleAction( 'DongleSendSMS', Device=self._dongle, Number=target, Message=message, ) client.send_action(action, callback=lambda r: self._on_message(target, r)) _LOGGER.debug("SMS to %s sent", target) client.logoff()
def make_call(): channel = request.args.get('channel', '') exten = request.args.get('exten', '') channel = '304' exten = '8' + exten[1:] user_client = AMIClient(address=ami_ip, port=ami_port) future = user_client.login(username=ami_user, secret=ami_secret) time.sleep(0.5) user_adapter = AMIClientAdapter(user_client) res = user_adapter.Originate(Channel='SIP/' + channel, Context='local', Exten=exten, ActionID=exten, Priority=1, CallerID=exten, CallerIDName=exten, Timeout='') time.sleep(0.2) user_client.logoff() return 'ok', 200, HEADERS
def run_call(ext, to): sip = 'SIP/{}'.format(ext) tel = '9{}'.format(to) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(3) ats1 = 'f1.ats.com' ats2 = 'f2.ats.com' host = ats1 try: sock.connect((ats1, 5038)) except socket.error: host = ats2 sock.close() client = AMIClient(address=host, port=5038) client.login(username='******', secret='pass') action = SimpleAction( 'Originate', Channel=sip, Exten=tel, Priority=1, Context='from-internal', CallerID='crmdancer', ) client.send_action(action, callback=None) client.logoff()
def Listen(request, num): print(request.user.aduser.telephoneNumber) PBXClient = AMIClient(address=settings.JSON_SETTINGS['asteriskServer'], port=5038) PBXClient.login(username=settings.JSON_SETTINGS['AMILogin'], secret=settings.JSON_SETTINGS['AMIPassword']) print(PBXClient) action = SimpleAction( 'Originate', Channel=('SIP/%s' % request.user.aduser.telephoneNumber), CallerID=('Spy%s' % num), #Exten = '6670', #Application = 'Playback', Application='ChanSpy', #Data = '/var/spool/asterisk/monitor/2017/10/03/out-1694-6666-20171003-103712-1507016232.189', Data=('SIP/%s,qx' % num), Timeout='30000', #Priority = '1', #Async = 'yes' ) print(action) ans = PBXClient.send_action(action) print(ans.response) PBXClient.logoff() return HttpResponse(ans.response)
def test_auth(host, port=7777, user='******', secret='admin'): client = AMIClient(address=host, port=port) future = client.login(username=user, secret=secret) response = future.response if response: if response.is_error(): return False else: client.logoff() return True else: return False
def make_call(): client = AMIClient(address=AMI_ADDRESS, port=AMI_PORT) future = client.login(username=AMI_USER, secret=AMI_SECRET) id = request.args.get('id', '') channel = request.args.get('channel', '') exten = request.args.get('exten', '') caller_id = request.args.get('caller_id', '') caller_id_name = request.args.get('caller_id_name', '') user = request.args.get('user', '') action_id = request.args.get('action_id', '') d = {} exten = '8' + exten id_ext = uuid.uuid4() id_ext = str(id_ext) if future.response.is_error(): d['status'] = 'failed' d['error'] = str(future.response) res = json.dumps(d, default=json_serial) return res, 200, HEADERS adapter = AMIClientAdapter(client) res_call = do_call_with_oper(adapter, channel, exten, caller_id, caller_id_name, action_id) client.logoff() d['status'] = 'ok' d['id_ext'] = id_ext res = json.dumps(d, default=json_serial) USER_EVENTS[user] = { 'id_ext': id_ext, 'id': id, 'user': user, 'channel': channel, 'exten': exten, 'caller_id': caller_id } return res, 200, HEADERS
def dev_dial(action): """Function that actually makes the asterisk call.""" try: client = AMIClient(address=AUTH_CREDS['address'], port=AUTH_CREDS['port']) client.login(username=AUTH_CREDS['username'], secret=AUTH_CREDS['secret']) future = client.send_action(action) if VERBOSE: print(future.response or "None") client.logoff() except Exception as e: print("Error: %s" % e.strerror) sys.exit(1)
def make_call_auto(param): tel = kwargs_get(param, 'tel') file = kwargs_get(param, 'file') client = AMIClient(address=AMI_ADDRESS, port=AMI_PORT) future = client.login(username=AMI_USER, secret=AMI_SECRET) if future.response.is_error(): raise Exception(str(future.response)) adapter = AMIClientAdapter(client) channel = f'Local/{tel}@ng_ext_autodial' d['channel'] = channel action_id = tel variable = FILE_NAMES[file] client.add_event_listener(event_listener) #res_call = simple_call_without_oper(channel, data) res_call = simple_call_without_oper(adapter, channel, DATA, APP, action_id, variable, tel) while True: if d['status'] == 'Error': break elif d['status'] == 'ANSWER': break elif d['status'] == 'BUSY': break elif d['status'] == 'Success': break if not res_call.response is None: d['status'] = res_call.response.status time.sleep(0.2) client.logoff() #print(d['DTMF']) #print(d['status']) return d
def call(): call_message = "call in progress" client = AMIClient(address='172.16.1.254', port=5038) client.login(username='******', secret='9787474') action = SimpleAction( 'Originate', Channel='DAHDI/i1/09385255833', Exten='698', Priority=1, Context='from-internal', CallerID="Channel", ) client.send_action(action) client.logoff() flash("success call", 'success') return render_template('home.html', message=call_message)
def ami_event(peer, action): # Part of dialplan to generate AMI UserEvent: # exten => 881,2,UserEvent(Channel: SIP, Peername: ${CALLERID(num)}, DND: enabled) # exten => 882,2,UserEvent(Channel: SIP, Peername: ${CALLERID(num)}, DND: disabled) # channel - just a variable for MonAst channel = 'SIP/'+str(peer) # AMI connection. username and secret create in /etc/asterisk/manager.conf: client = AMIClient(address=aster_server, port=ami_port) client.login(username=ami_user, secret=ami_pass) if action == 'enabled': action = SimpleAction('UserEvent', UserEvent='UserEvent', peername=peer, dnd='enabled', channel=channel, status='DND enabled',) elif action == 'disabled': action = SimpleAction('UserEvent', UserEvent='UserEvent', peername=peer, dnd='disabled', channel=channel, status='DND disabled',) client.send_action(action) client.logoff()
def Originate(Extension, phoneNumber, CallerID='python', Context='from-internal'): client = AMIClient(**config.AMIClientAddress) client.login(**config.AMIClientUser) logger = logging.getLogger("bot.ClinicaWeb") action = SimpleAction( 'Originate', Channel='SIP/' + str(Extension), Exten=phoneNumber, Priority=1, Context=Context, CallerID=CallerID, ) logger.info("Start originate from %s to %s" % (Extension, phoneNumber)) if client.send_action(action).response.status == 'Success': logger.info("Start call from %s to %s" % (Extension, phoneNumber)) else: logger.info("Cancel originate from %s to %s" % (Extension, phoneNumber)) client.logoff()
def ami_action(number, shablon, cursor, db, id): Channel = trunk+number logging.debug("Channel - {}".format(Channel) ) #logging.info("Channel - {}".format(Channel) ) # Variable=id=3 var = "VAR="+str(shablon)+str(id) # Connect to AMI client = AMIClient(address=aster_server, port=ami_port) client.login(username=ami_user, secret=ami_pass) action = SimpleAction( 'Originate', Channel=Channel, Exten=exten, Context=context, Priority=1, CallerID=number, Variable=var,) try: client.send_action(action) client.logoff() except Exception as ex: print(ex)
def make_call_auto(): client = AMIClient(address=AMI_ADDRESS, port=AMI_PORT) future = client.login(username=AMI_USER, secret=AMI_SECRET) id = request.args.get('id', '') exten = request.args.get('exten', '') file = request.args.get('file', '') action_id = request.args.get('action_id', '') exten = '8' + exten d = {} id_ext = uuid.uuid4() id_ext = str(id_ext) if future.response.is_error(): d['status'] = 'failed' d['error'] = str(future.response) res = json.dumps(d, default=json_serial) return res, 200, HEADERS adapter = AMIClientAdapter(client) channel = f'Local/{exten}@ng_ext_autodial_speech_to_text' d['channel'] = channel variable = FILE_NAMES[file] res_call = do_call_without_oper(adapter, channel, DATA, APP, action_id, variable, exten) client.logoff() d = {} d['Действия'] = 'Asterisk_AutoCall_Event' d['Данные'] = {} d['Данные']['name'] = 'init' d['Данные']['id_ext'] = id_ext d['Данные']['event_date'] = datetime.now() d['Данные']['status'] = 'ok' d['Данные']['callerid'] = exten d['Данные']['id'] = id.upper() jdata = json.dumps(d, default=json_serial) auto_call_event(jdata) AUTO_CALLS[channel] = { 'id_ext': id_ext, 'id': id, 'channel': channel, 'exten': exten, 'callerid': exten } #period = datetime.now() #source = id.upper() #status = 'init' #value = id_ext #comment = res #var = Statuses_AutoCall.create(period=period, source=source, status=status, value=value, comment=comment) return jdata, 200, HEADERS
class asterisk_originate: def __init__(self, ami_host, ami_port, ami_username, ami_password): self.__ami_host = ami_host self.__ami_port = int(ami_port) self.___ami_username = ami_username self.__ami_password = ami_password self.__ami_client = AMIClient(address=self.__ami_host, port=self.__ami_port) def _login(self): self.__ami_client = AMIClient(address=self.__ami_host, port=self.__ami_port) try: self.__ami_client.login(username=self.___ami_username, secret=self.__ami_password) print("Successfully logged into AMI") return True except Exception as e: error = self._handle_ami_exception(e) print("Unable to login to AMI: %s" % error) return False def _logoff(self): try: self.__ami_client.logoff() return True except Exception as e: error = self._handle_ami_exception(e) print("Unable to logoff from AMI: %s" % error) return False def _handle_ami_exception(self, exception): try: if exception.errno == errno.ECONNREFUSED: return ("Unable to connect to AMI (Connection Refused)") elif exception.errno == errno.EPIPE: return ("No longer connected to AMI (Broken Pipe)") elif exception.errno == errno.EBADF: return ("No longer connected to AMI (Bad File Descriptor)") else: return (exception) except Exception as e: return (e) def _send_originate_context(self, channel, context, extension, priority, callerid, timeout=60, variables=""): action = SimpleAction('Originate', Channel=channel, Exten=extension, Priority=priority, Context=context, CallerID=callerid, Timeout=timeout * 1000, Variable=variables, Async="true") try: self.__ami_client.send_action(action) return True except Exception as e: error = self._handle_ami_exception(e) print("Unable to connect to %s: %s" % (channel, error)) return False def _send_originate_application(self, channel, application, data, callerid): action = SimpleAction('Originate', Channel=channel, CallerID=callerid, Application=application, Data=data, Async="true") try: self.__ami_client.send_action(action) return True except Exception as e: error = self._handle_ami_exception(e) print("Unable to connect to %s: %s" % (channel, error)) return False def originate_context(self, channels, context, extension, priority, callerid, timeout=60, variables=""): split_channels = channels.split("&") if None not in (channels, extension, priority, context, callerid): if self._login(): for channel in split_channels: self._send_originate_context(channel, context, extension, priority, callerid, timeout, variables) if self._logoff(): return True else: return False else: raise MissingParams("Failed to parse application parameters") def originate_application(self, channels, application, data, callerid): split_channels = channels.split("&") if None not in (channels, application, data, callerid): if self._login(): for channel in split_channels: self._send_originate_application(channel, application, data, callerid) if self._logoff(): return True else: return False else: raise MissingParams("Failed to parse originate parameters")
class Worker(object): events = [] PBXClient = None def waitEvent(self, timewait=5): while not self.events: timewait -= 1 if timewait == 0: break time.sleep(1) def QueryStat(self): self.PBXClient = AMIClient( address=settings.JSON_SETTINGS['asteriskServer'], port=5038) self.PBXClient.login(username=settings.JSON_SETTINGS['AMILogin'], secret=settings.JSON_SETTINGS['AMIPassword']) self.events = [] action = SimpleAction('QueueStatus', ) #print('hi') self.PBXClient.add_event_listener(self.listener, white_list=['QueueParams']) #self.events = ['QueryStat'] self.PBXClient.send_action(action) self.waitEvent() self.PBXClient.logoff() return self.events def QueueAgent(self, Queue): self.PBXClient = AMIClient( address=settings.JSON_SETTINGS['asteriskServer'], port=5038) self.PBXClient.login(username=settings.JSON_SETTINGS['AMILogin'], secret=settings.JSON_SETTINGS['AMIPassword']) self.events = [] action = SimpleAction('QueueStatus', ) #print('hi') #print("Queue: %s" % Queue) #q = "'%s'" % Queue #print(q) self.PBXClient.add_event_listener(self.listener, white_list=['QueueMember'], Queue='%s' % Queue) #self.events = ['QueryStat'] self.PBXClient.send_action(action) self.waitEvent() self.PBXClient.logoff() return self.events def Queue(self): self.PBXClient = AMIClient( address=settings.JSON_SETTINGS['asteriskServer'], port=5038) self.PBXClient.login(username=settings.JSON_SETTINGS['AMILogin'], secret=settings.JSON_SETTINGS['AMIPassword']) self.events = [] action = SimpleAction('Queues', ) #print('hi') self.PBXClient.add_event_listener(self.listener) #self.events = ['QueryStat'] ans = self.PBXClient.send_action(action) self.waitEvent() self.PBXClient.logoff() return (self.events, ans) def GetQuery(self): servers = settings.JSON_SETTINGS['MemcachedServers'] cServers = [] for server in servers: tmp = server.split(':') cServers += [(tmp[0], int(tmp[1]))] cl = HashClient(cServers) q = cl.get('queue') if q is None: self.QueryStat() queue = [] for event in self.events: queue += [event['Queue']] cl.set('queue', ','.join(queue), settings.JSON_SETTINGS['MemcachedExpire']) return queue else: return q.decode("utf-8").split(',') def listener(self, event, **kwargs): #print(event) self.events += [event] def __del__(self): #print("__del__") if not self.PBXClient is None: self.PBXClient.logoff()
data = { 'Response': response.status, 'follows': response.follows, } data.update(response.keys) self.mqtt_client.publish(self.base_topic + '/response', json.dumps(data)) def on_event(self, event, **kwargs): self.mqtt_client.publish(self.base_topic + '/event/%s' % event.name, json.dumps(event.keys)) mqtt_client = mqtt.Client() ami_client = AMIClient(**connection) AutoReconnect(ami_client) bridge = MqttAmiBridge('%s/%s' % (hostname, 'asterisk-ami'), mqtt_client, ami_client) mqtt_client.on_message = bridge.mqtt_on_message mqtt_client.on_connect = bridge.mqtt_on_connect mqtt_client.connect(broker, 1883) mqtt_client.loop_start() f = ami_client.login(**login) ami_client.add_event_listener(bridge) try: while True: time.sleep(10) except (KeyboardInterrupt, SystemExit): mqtt_client.disconnect() ami_client.logoff()
import requests def event_notification(source, event): binado = ( event['ConnectedLineNum'] ) ext = ( event['Exten']) os.system("curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{call: {src: '%s', dst: '%s'}}' http://10.254.254.208:8887/api/voip/events" % (binado, ext)) print (binado, ext) client = AMIClient(address="127.0.0.1") future = client.login(username="******", secret="cxmanager*con") client.add_event_listener(EventListener(on_event=event_notification, black_list='Exten = 100', white_list='Newstate', ChannelStateDesc='Up')) if future.response.is_error(): raise Exception(str(future.response)) try: while True: sleep(10) except (KeyboardInterrupt, SystemExit): client.logoff()
return dst def call_to(dst): call = SimpleAction( 'Originate', Channel="SIP/" + str(agent), Exten=dst, Priority=1, Context='from-internal', CallerID="From CRM<" + dst + ">", ) sip.send_action(call) sip.logoff() if (len(sys.argv) > 1): dst = unidecode(''.join(sys.argv[1:])) dst = normalize(dst) elif (clipboard.paste()): dst = unidecode(clipboard.paste().replace(" ", "")) dst = normalize(dst) else: sip.logoff() print("Error") exit() call_to(dst)
} data.update(response.keys) self.mqtt_client.publish(self.base_topic + '/response', json.dumps(data)) def on_event(self, event, **kwargs): self.mqtt_client.publish(self.base_topic + '/event/%s' % event.name, json.dumps(event.keys)) mqtt_client = mqtt.Client() ami_client = AMIClient(**connection) AutoReconnect(ami_client) bridge = MqttAmiBridge('%s/%s' % (hostname, 'asterisk-ami'), mqtt_client, ami_client) mqtt_client.on_message = bridge.mqtt_on_message mqtt_client.on_connect = bridge.mqtt_on_connect mqtt_client.connect(broker, 1883) mqtt_client.loop_start() f = ami_client.login(**login) ami_client.add_event_listener(bridge) try: while True: time.sleep(10) except (KeyboardInterrupt, SystemExit): mqtt_client.disconnect() ami_client.logoff()
class asterisk_reconnect: def __init__(self, logger, config): self.logger = logger self.config = config self.clients = self.config['clients'] self.check_interval = config['intervals']['check_interval'] self.reconnect_interval = config['intervals']['reconnect_interval'] self.ping_interval = config['intervals']['ping_interval'] self.ami_host = config['ami']['host'] self.ami_port = int(config['ami']['port']) self.ami_username = config['ami']['username'] self.ami_password = config['ami']['password'] self.ami_client = AMIClient(address=self.ami_host, port=self.ami_port) self.channels = [] self.last_check = time.time() self.last_ping = time.time() self.last_login = time.time() self.connected = False self.kill_received = False self.thread = threading.Thread(target=self.reconnect_loop, args=()) self.thread.daemon = True self.thread.start() def login(self): self.last_login = time.time() self.ami_client = AMIClient(address=self.ami_host, port=self.ami_port) try: self.ami_client.login(username=self.ami_username, secret=self.ami_password) self.connected = True self.logger.info("Successfully logged into AMI") return True except Exception as e: error = self.handle_ami_exception(e) self.logger.error("Unable to login to AMI: %s" % error) def logoff(self): try: self.ami_client.logoff() self.connected = True except Exception as e: error = self.handle_ami_exception(e) self.logger.error("Unable to logoff from AMI: %s" % error) def send_ping(self): self.logger.debug("Sending Ping") self.last_ping = time.time() try: action = SimpleAction('ping') self.ami_client.send_action(action) except Exception as e: error = self.handle_ami_exception(e) self.logger.error("Sending Ping Failed: %s" % error) def get_channels(self): command = ("core show channels concise") action = SimpleAction('Command', Command=command) try: future = self.ami_client.send_action(action) response = future.response.follows chan_len = len(response) - 1 response = response[:chan_len] self.channels = [] for channel in response: match = re.match( "((.*?)\/.*?)!(.*?)!(.*?)!(.*?)!(.*?)!(.*?)!(.*?)!(.*?)!(.*?)!(.*?)!(.*?)!(.*?)$", channel) if match: chan_type = match.group(2) chan = match.group(1) context = match.group(3) extension = match.group(4) priority = match.group(5) state = match.group(6) app = match.group(7) data = match.group(8) clid = match.group(9) duration = match.group(12) bridged_to = match.group(13) parsed_chan = { "chan_type": chan_type, "chan": chan, "context": context, "extension": extension, "priority": priority, "state": state, "app": app, "data": data, "clid": clid, "duration": duration, "bridged_to": bridged_to } self.channels.append(parsed_chan) else: self.logger.error("Unable to parse channel: %s " % channel) return self.channels except Exception as e: error = self.handle_ami_exception(e) self.logger.error("Unable to get channels: %s" % error) self.channels = [] def handle_ami_exception(self, exception): if exception.errno == errno.ECONNREFUSED: self.connected = False return ("Unable to connect to AMI (Connection Refused)") elif exception.errno == errno.EPIPE: self.connected = False return ("No longer connected to AMI (Broken Pipe)") elif exception.errno == errno.EBADF: self.connected = False return ("No longer connected to AMI (Bad File Descriptor)") else: self.connected = False raise exception def check_clients(self): for client, params in self.clients.items(): context = params['context'] extension = params['extension'] uri = params['uri'] if not self.chan_connected(context, extension, uri): self.logger.info("Client \'%s\' not connected" % client) self.connect_client(client, context, extension, uri) def chan_connected(self, context, extension, uri): for channel in self.channels: if (context == channel['context'] and extension == channel['extension'] and self.uri_comp(channel['chan'], uri)): return True return False def uri_comp(self, chan_uri, client_uri): chan_match = re.match("(.*?)(?:$|-)", chan_uri) client_match = re.match("(.*?):(?:.*)@(.*)$", client_uri) if chan_match and client_match: chan_parsed = chan_match.group(1) client_scheme = client_match.group(1).upper() client_host = client_match.group(2) client_parsed = ("%s/%s" % (client_scheme, client_host)) # self.logger.debug("Comparing %s and %s" % (client_parsed, # chan_parsed)) if chan_parsed == client_parsed: return True elif chan_match: self.logger.info("Error parsing client URI: %s" % client_uri) return False elif client_match: self.logger.info("Error parsing chan URI: %s" % chan_uri) return False else: self.logger.info("Error parsing client URI: %s" % client_uri) self.logger.info("Error parsing chan URI: %s" % chan_uri) return False def connect_client(self, client, context, extension, uri): match = re.match("(.*?):(.*)$", uri) if match: scheme = match.group(1) uri = match.group(2) if scheme == "sip": scheme = "SIP" elif scheme == "iax": scheme = "IAX" channel = ("%s/%s" % (scheme, uri)) self.logger.info("Connecting to %s (%s)" % (client, channel)) action = SimpleAction( 'Originate', Channel=channel, Exten=extension, Priority=1, Context=context, CallerID='AutoDialler', ) try: self.ami_client.send_action(action) except Exception as e: error = self.handle_ami_exception(e) self.logger.info("Unable to connect to %s: %s" % (client, error)) def run_check(self): self.logger.debug("Checking Connected Clients") self.last_check = time.time() self.last_ping = time.time() self.get_channels() self.check_clients() def reconnect_loop(self): self.login() if self.connected: self.run_check() self.last_check = time.time() self.last_ping = time.time() while not self.kill_received: current_time = time.time() if not self.connected and current_time - self.last_login > self.reconnect_interval: self.logger.info("Reattempting Login") self.login() elif self.connected: if current_time - self.last_check > self.check_interval: self.run_check() if current_time - self.last_ping > self.ping_interval: self.send_ping() time.sleep(1) self.logger.info("Terminating Thread") self.logoff()
#!/usr/bin/python import os import time from settings import login, connection from asterisk.ami import AMIClient def event_notification(source, event): os.system('notify-send "%s" "%s"' % (event.name, str(event))) client = AMIClient(**connection) future = client.login(**login) if future.response.is_error(): raise Exception(str(future.response)) client.add_event_listener(event_notification) try: while True: time.sleep(10) except (KeyboardInterrupt, SystemExit): client.logoff()