def queue_status(): MANAGER = Manager(loop=asyncio.get_event_loop(), host='127.0.0.1', username='******', secret='password') yield from MANAGER.connect() queues_details = yield from MANAGER.send_action({'Action': 'QueueStatus', 'Queue': 'queue_name'}) pprint(queues_details)
class Bridge: def __init__(self, options, filters, push_configs): self.loop = asyncio.get_event_loop() max_queues = options.pop("max_size", DEFAULT_MAX_QUEUES) max_queue_size = options.pop("max_queue_size", DEFAULT_MAX_QUEUE_SIZE) self.controller = Controller(self.loop, max_queues, max_queue_size) self.controller.load_configs(filters, push_configs) options.pop("loop", None) # discard invalid argument self.manager = Manager(loop=self.loop, **options) self.manager.log.addHandler(logging.NullHandler()) self.manager.register_event("*", self.handle_events) @asyncio.coroutine def handle_events(self, manager, message): wrapper = MessageWrapper(message) yield from self.controller.handle(wrapper) @asyncio.coroutine def connect(self): yield from self.manager.connect() def run(self): try: self.loop.run_until_complete(self.connect()) self.loop.run_forever() finally: self.loop.close()
def extension_status(): manager = Manager(loop=asyncio.get_event_loop(), host='127.0.0.1', username='******', secret='password') yield from manager.connect() extension = yield from manager.send_action_via_manager({'Action': 'ExtensionState', 'Exten': '2001', 'Context': 'default'}) pprint(extension)
def __init__(self, bot): self.bot = bot self.bot.asterirc = self self.config = config = dict( host='127.0.0.1', port=5038, http_port='8088', protocol='http', debug=True, ) config.update(bot.config.get('asterisk', {})) self.log = logging.getLogger('irc3.ast') self.ilog = logging.getLogger('irc.asterirc') self.ilog.set_irc_targets(bot, self.config['channel']) self.log.info('Channel is set to {channel}'.format(**config)) self.rooms = defaultdict(dict) self.http = None self.resolver = irc3.utils.maybedotted(self.config['resolver']) self.manager = Manager(log=logging.getLogger('irc3.ast.manager'), **config) self.manager.register_event('Shutdown', self.handle_shutdown) self.manager.register_event('Meet*', self.handle_meetme) if config.get('debug'): self.manager.register_event('*', self.handle_event) if isinstance(self.resolver, type): self.resolver = self.resolver(bot)
def main(): """Função principal da aplicação.""" manager = Manager( loop=asyncio.get_event_loop(), host=ASTERISK_IP, port=ASTERISK_PORT, username=ASTERISK_USER, secret=ASTERISK_PASSWORD, ) @manager.register_event("QueueCallerLeave") @manager.register_event("AgentCalled") @manager.register_event("AgentConnect") @manager.register_event("AgentComplete") @manager.register_event("AgentDump") # @manager.register_event("AgentRingNoAnswer") @manager.register_event("MessageWaiting") # @manager.register_event('UserEvent') async def callback_agent(manager, message): fire(message) @manager.register_event("Hangup") async def callback_hangup(manager, message): # hangup from queue, external only if message.context == "ext-queues": fire(message) manager.connect() try: manager.loop.run_forever() except KeyboardInterrupt: manager.loop.close()
def attach(self, amihost): """ attach amihost to a ChannelManager. Args: amihost (dict): A dictionary containing the connection settings for an AMI host. """ # Create Panoramisk asterisk AMI manager. amimgr = Manager(loop=self.loop, host=amihost['host'], port=amihost['port'], username=amihost['username'], secret=amihost['password'], ssl=False, encoding='utf8', log=self.logger) # Create our own channel manager. channel_manager = self.channel_manager(reporter=self.reporter, ) # Tell Panoramisk to which events we want to listen. for event_name in channel_manager.INTERESTING_EVENTS: amimgr.register_event(event_name, self.on_event) # Record them for later use. self.amimgrs[amimgr] = channel_manager # Tell asyncio what to work on. asyncio.ensure_future(amimgr.connect())
async def start(self): # Set process name salt.utils.process.appendproctitle(self.__class__.__name__) manager_disconnected = asyncio.Event() # Ok let's connect to Asterisk and process events. self.loop = asyncio.get_event_loop() # Create event loop to receive actions as events. self.loop.create_task(self.action_event_loop()) host = __salt__['config.get']('ami_host', 'localhost') port = int(__salt__['config.get']('ami_port', '5038')) login = __salt__['config.get']('ami_login', 'salt') self.manager = Manager( loop=self.loop, host=host, port=port, username=login, secret=__salt__['config.get']('ami_secret', 'stack'), forgetable_actions=('ping', 'login'), ) log.info('AMI connecting to %s@%s:%s...', login, host, port) # Register events for ev_name in __salt__['config.get']('ami_register_events', []): log.info('Registering for AMI event %s', ev_name) self.manager.register_event(ev_name, self.on_asterisk_event) try: await self.manager.connect() log.info('Connected to AMI.') except Exception as e: log.error('Cannot connect to Asterisk AMI: %s', e) await manager_disconnected.wait()
def attach(self, amihost): """ attach amihost to a ChannelManager. Args: amihost (dict): A dictionary containing the connection settings for an AMI host. """ # Create Panoramisk asterisk AMI manager. amimgr = Manager( loop=self.loop, host=amihost['host'], port=amihost['port'], username=amihost['username'], secret=amihost['password'], ssl=False, encoding='utf8') # Create our own channel manager. channel_manager = self.channel_manager( reporter=self.reporter, ) # Tell Panoramisk to which events we want to listen. channel_manager._pre_connect(amimgr) # Record them for later use. self.amimgrs.append(amimgr) self.channel_managers.append(channel_manager) # Tell asyncio what to work on. asyncio.async(amimgr.connect())
def queue_status(): manager = Manager(loop=asyncio.get_event_loop(), host='127.0.0.1', port=5039, username='******', secret='mysecret') yield from manager.connect() queues_details = yield from manager.send_action({'Action': 'QueueStatus', 'Queue': 'queue_name'}) manager.close() pprint(queues_details)
async def extension_status(): manager = Manager(loop=asyncio.get_event_loop(), host='127.0.0.1', port=5039, username='******', secret='password') await manager.connect() extension = await manager.send_action({'Action': 'ExtensionState', 'Exten': '2001', 'Context': 'default'}) manager.close() pprint(extension)
def originate(): manager = Manager(loop=asyncio.get_event_loop(), host='127.0.0.1', username='******', secret='password') yield from manager.connect() result = yield from manager.send_action_via_manager({'Action': 'Originate', 'Channel': 'SIP/gawel', 'WaitTime': 20, 'CallerID': 'gawel', 'Exten': '0299999999', 'Context': 'default', 'Priority': 1,}) pprint(result)
def extension_status(): manager = Manager(loop=asyncio.get_event_loop(), host='127.0.0.1', username='******', secret='password') yield from manager.connect() extension = yield from manager.send_action_via_manager({ 'Action': 'ExtensionState', 'Exten': '2001', 'Context': 'default' }) pprint(extension)
def ping(lp, username, secret): manager = Manager(loop=lp, host='127.0.0.1', port=5038, username=username, secret=secret, forgetable_actions=('login',)) yield from manager.connect() while True: p = yield from manager.send_action({'Action': 'ping'}) # p = yield from manager.send_action({'Action': 'SIPpeers'}) pprint(p) yield from asyncio.sleep(1) manager.close()
async def queue_status(): manager = Manager(loop=asyncio.get_event_loop(), host='127.0.0.1', port=5039, username='******', secret='mysecret') await manager.connect() queues_details = await manager.send_action({ 'Action': 'QueueStatus', 'Queue': 'queue_name' }) manager.close() pprint(queues_details)
def queue_status(): MANAGER = Manager(loop=asyncio.get_event_loop(), host='127.0.0.1', username='******', secret='password') yield from MANAGER.connect() queues_details = yield from MANAGER.send_action_via_manager({ 'Action': 'QueueStatus', 'Queue': 'queue_name' }) pprint(queues_details)
async def ping(lp, username, secret): manager = Manager(loop=lp, host='127.0.0.1', port=5038, username=username, secret=secret) await manager.connect() while True: p = await manager.send_action({'Action': 'ping'}) # p = await manager.send_action({'Action': 'SIPpeers'}) pprint(p) await asyncio.sleep(1) manager.close()
def __init__(self, loop): self.manager = Manager(loop=loop, host='178.248.87.116', port=1709, username='******', secret='100') self.callManager = CallBaseManager() self.httpclient = HttpClientTornado() self.manager.register_event('FullyBooted', self.FullyBooted) self.manager.register_event('BridgeEnter', self.BridgeEnter) self.manager.register_event('Hangup', self.Hangup) self.manager.connect() try: self.manager.loop.run_forever() except KeyboardInterrupt: self.manager.loop.close()
def __init__(self, options, filters, push_configs): self.loop = asyncio.get_event_loop() max_queues = options.pop("max_size", DEFAULT_MAX_QUEUES) max_queue_size = options.pop("max_queue_size", DEFAULT_MAX_QUEUE_SIZE) self.controller = Controller(self.loop, max_queues, max_queue_size) self.controller.load_configs(filters, push_configs) options.pop("loop", None) # discard invalid argument self.manager = Manager(loop=self.loop, **options) self.manager.log.addHandler(logging.NullHandler()) self.manager.register_event("*", self.handle_events)
def test_reconnection_without_lost(event_loop): unused_tcp_port = unused_tcp_port_factory() print('Start server on %s' % unused_tcp_port) manager = Manager(loop=event_loop, host='127.0.0.1', port=unused_tcp_port, username='******', secret='secret') server = Asterisk(event_loop, unused_tcp_port) yield from server.start() yield from manager.connect() yield from server.data_received() login = server.actions[0] assert login['action'] == 'Login' unused_tcp_port = unused_tcp_port_factory() print('Restart server on %s' % unused_tcp_port) server.port = unused_tcp_port manager.config['port'] = unused_tcp_port yield from server.stop() manager.send_action({'Action': 'Ping'}) f = manager.send_action({'Action': 'Test', 'Command': 'test'}) fully_booted = Event('FullyBooted') yield from asyncio.sleep(.1) assert manager.awaiting_actions yield from server.start() yield from asyncio.sleep(2) assert manager.awaiting_actions manager.dispatch(fully_booted) yield from asyncio.sleep(.5) assert not manager.awaiting_actions resp = yield from f yield from server.stop() login2 = server.actions[0] assert login2['action'] == 'Login' assert login['actionid'] != login2['actionid'] test_action = server.actions[-1] assert test_action.id == resp.id assert test_action['action'] == 'Test'
def test_reconnection_without_lost(event_loop, unused_tcp_port_factory): unused_tcp_port = unused_tcp_port_factory() print('Start server on %s' % unused_tcp_port) manager = Manager(loop=event_loop, host='127.0.0.1', port=unused_tcp_port, username='******', secret='secret') server = Asterisk(event_loop, unused_tcp_port) yield from server.start() yield from manager.connect() yield from server.data_received() login = server.actions[0] assert login['action'] == 'Login' unused_tcp_port = unused_tcp_port_factory() print('Restart server on %s' % unused_tcp_port) server.port = unused_tcp_port manager.config['port'] = unused_tcp_port yield from server.stop() manager.send_action({'Action': 'Ping'}) f = manager.send_action({'Action': 'Test', 'Command': 'test'}) fully_booted = Event('FullyBooted') yield from asyncio.sleep(.1) assert manager.awaiting_actions yield from server.start() yield from asyncio.sleep(2) assert manager.awaiting_actions manager.dispatch(fully_booted) yield from asyncio.sleep(.5) assert not manager.awaiting_actions resp = yield from f yield from server.stop() login2 = server.actions[0] assert login2['action'] == 'Login' assert login['actionid'] != login2['actionid'] test_action = server.actions[-1] assert test_action.id == resp.id assert test_action['action'] == 'Test'
def ping(lp, username, secret): manager = Manager(loop=lp, host='127.0.0.1', port=5038, username=username, secret=secret, forgetable_actions=('login', )) yield from manager.connect() while True: p = yield from manager.send_action({'Action': 'ping'}) # p = yield from manager.send_action({'Action': 'SIPpeers'}) pprint(p) yield from asyncio.sleep(1) manager.close()
def attach(self, asterisk): """ Set up a connection to the specified Asterisk Args: asterisk (str): A connection string """ ami_host = urlparse(asterisk) # Create Panoramisk asterisk AMI manager. manager = Manager(loop=self.loop, host=ami_host.hostname, port=ami_host.port, username=ami_host.username, secret=ami_host.password, ssl=ami_host.scheme in ('ssl', 'tls'), encoding='utf8', log=self.logger) # Create our own channel manager. event_handler = self.event_handler( reporter=self.reporter, hostname=ami_host.hostname, logger=self.logger, ) # Tell Panoramisk to which events we want to listen. if event_handler.FILTER_EVENTS: for event_name in event_handler.event_handlers().keys(): manager.register_event(event_name, self.on_event) else: manager.register_event('*', self.on_event) # Record them for later use. self.ami_managers[manager] = event_handler # Tell asyncio what to work on. asyncio.ensure_future(manager.connect())
def putCids(lp, args, config): auth = HTTPBasicAuth(config['carddav']['user'], config['carddav']['pass']) url = config['carddav']['url'] # connect to asterisk ami = Manager(host=config['ami']['host'], port=config['ami']['port'], username=config['ami']['user'], secret=config['ami']['pass']) yield from ami.connect() # get phone numbers from vcard for vurl in getAllVcardLinks(url, auth): r = requests.request("GET", vurl, auth=auth) try: vcard = vobject.readOne(r.text) except ParseError as e: print(e) continue if "tel" in vcard.contents: for telno in vcard.contents['tel']: num = tidyPhoneNumber(config, telno.value) if num and "fn" in vcard.contents: name = vcard.fn.value print("Adding/updating Number: %s Name: %s" % (num, name), end="... ") if not args.no_update: ami_result = yield from ami.send_action({ "Action": "DBPut", "Family": "cidname", "Key": num, "Val": name }) print(ami_result.Response) else: print("no-update") ami.close()
class AmiClient: events_map = [] async def start(self): # Set process name salt.utils.process.appendproctitle(self.__class__.__name__) manager_disconnected = asyncio.Event() # Ok let's connect to Asterisk and process events. self.loop = asyncio.get_event_loop() # Create event loop to receive actions as events. self.loop.create_task(self.action_event_loop()) host = __salt__['config.get']('ami_host', 'localhost') port = int(__salt__['config.get']('ami_port', '5038')) login = __salt__['config.get']('ami_login', 'salt') self.manager = Manager( loop=self.loop, host=host, port=port, username=login, secret=__salt__['config.get']('ami_secret', 'stack'), forgetable_actions=('ping', 'login'), ) log.info('AMI connecting to %s@%s:%s...', login, host, port) # Register events for ev_name in __salt__['config.get']('ami_register_events', []): log.info('Registering for AMI event %s', ev_name) self.manager.register_event(ev_name, self.on_asterisk_event) try: await self.manager.connect() log.info('Connected to AMI.') except Exception as e: log.error('Cannot connect to Asterisk AMI: %s', e) await manager_disconnected.wait() async def on_asterisk_event(self, manager, event): event = dict(event) trace_events = __opts__.get('ami_trace_events') if trace_events: if isinstance(trace_events, bool): log.info('AMI event: %s', json.dumps(event, indent=2)) elif isinstance(trace_events, list) and event['Event'] in trace_events: log.info('AMI event: %s', json.dumps(event, indent=2)) # Inject system name in every message event['SystemName'] = __grains__['id'] # Send event to Salt's event map __salt__['event.fire'](event, 'AMI/{}'.format(event['Event'])) async def action_event_loop(self): log.debug('AMI action event loop started.') event = salt.utils.event.MinionEvent(__opts__) trace_actions = __opts__.get('ami_trace_actions') while True: try: evdata = event.get_event(tag='ami_action', no_block=True) # TODO: Connect to Salt's tornado eventloop. try: await asyncio.sleep(0.01) except concurrent.futures._base.CancelledError: return if evdata: # Remove salt's event item evdata.pop('_stamp', False) reply_channel = evdata.pop('reply_channel', False) # Trace the request if set. if trace_actions and isinstance(trace_actions, bool): log.info('Action request: %s', evdata) elif isinstance( trace_actions, list) and evdata['Action'] in trace_actions: log.info('Action request: %s', evdata) else: log.debug('Action request: %s', evdata) try: # Send action and get action result. res = await asyncio.wait_for( self.manager.send_action(evdata), timeout=1.0) if trace_actions and isinstance(trace_actions, bool): log.info('Action result: %s', res) elif isinstance( trace_actions, list) and evdata['Action'] in trace_actions: log.info('Action result: %s', res) else: log.debug('Action result: %s', res) except asyncio.TimeoutError: log.error('Send action timeout: %s', evdata) res = { 'Message': 'Action Timeout', 'Response': 'Error' } except concurrent.futures._base.CancelledError: log.info('AMI action event loop quitting.') return except Exception as e: log.exception('Send action error:') res = str(e) # Make a list of results to unify. if not isinstance(res, list): res = [res] if reply_channel: # Send back the result. __salt__['event.fire']({ 'Reply': [dict(k) for k in res] }, 'ami_reply/{}'.format(reply_channel)) except Exception as e: if "'int' object is not callable" in str(e): # Reaction on CTRL+C :-) log.info('AMI events action lister quitting.') return else: log.exception('AMI action event loop error:') await asyncio.sleep(1) # Protect log flood.
class Asterisk(object): requires = ['irc3.plugins.command'] def __init__(self, bot): self.bot = bot self.bot.asterirc = self self.config = config = dict( host='127.0.0.1', port=5038, http_port='8088', protocol='http', debug=True, ) config.update(bot.config.get('asterisk', {})) self.log = logging.getLogger('irc3.ast') self.ilog = logging.getLogger('irc.asterirc') self.ilog.set_irc_targets(bot, self.config['channel']) self.log.info('Channel is set to {channel}'.format(**config)) self.rooms = defaultdict(dict) self.http = None self.resolver = irc3.utils.maybedotted(self.config['resolver']) self.manager = Manager(log=logging.getLogger('irc3.ast.manager'), **config) self.manager.register_event('Shutdown', self.handle_shutdown) self.manager.register_event('Meet*', self.handle_meetme) if config.get('debug'): self.manager.register_event('*', self.handle_event) if isinstance(self.resolver, type): self.resolver = self.resolver(bot) def connection_made(self): self.bot.loop.call_later(1, self.connect) def post_connect(self): self.log.debug('post_connect') resp = self.send_action({'Action': 'Status'}) if resp.success: self.update_meetme() else: # pragma: no cover self.log.error(resp.text) self.bot.loop.call_later(1, self.post_connect) def update_meetme(self): resp = self.send_command('meetme list') if resp.success: if 'No active MeetMe conferences.' in resp.text: self.rooms = defaultdict(dict) for line in resp.lines[1:-2]: room = line.split(' ', 1)[0] if not room or not room.isdigit(): continue resp = self.send_command('meetme list ' + room) if resp.success and resp.iter_lines(): room = self.rooms[room] for line in resp.lines: if not line.startswith('User '): continue line = line.split('Channel:')[0] splited = [s for s in line.split() if s][2:] uid = splited.pop(0) caller = ' '.join(splited[1:]) if 'external call ' in caller.lower(): e, c, n = caller.split(' ')[:4] caller = ' '.join([e, c, n[:6]]) room[caller] = uid def connect(self): if self.manager is not None: self.manager.close() self.bot.loop.call_later(5, self.post_connect) try: self.manager.connect() except Exception as e: self.log.exception(e) self.log.info('connect retry in 5s') self.bot.loop.call_later(1, self.connect) return False else: return True def handle_shutdown(self, event, manager): self.manager.close() self.bot.loop.call_later(2, self.connect) def handle_event(self, event, manager): self.log.debug('handle_event %s %s', event, '') # , event.headers) def handle_meetme(self, event, manager): self.log.debug('handle_meetme %s %s', event, event.headers) lower_header_keys(event) name = event.name.lower() room = event['meetme'] if name == 'meetmeend': if room in self.rooms: # pragma: no cover del self.rooms[room] self.ilog.info('room {} is closed.'.format(room)) return action = None caller = event['calleridname'] if 'external call ' in caller.lower(): e, c, n = caller.split(' ')[:4] caller = ' '.join([e, c, n[:6]]) elif 'external call' in caller.lower(): # pragma: no cover caller += event['calleridnum'][:6] if 'join' in name: action = 'join' self.rooms[room][caller] = event['usernum'] elif 'leave' in name: action = 'leave' if caller in self.rooms.get(room, []): del self.rooms[room][caller] if action: # log args = dict(caller=caller, action=action, room=room, total=len(self.rooms[room])) self.ilog.info(( '{caller} has {action} room {room} ' '(total in this room: {total})').format(**args)) def send_action(self, *args, **kwargs): try: res = self.manager.send_action(*args, **kwargs) return res except Exception as e: self.log.error('send_action(%r, **%r)', args, kwargs) self.log.exception(e) return Message('response', 'Sorry an error occured. ({})'.format(repr(e)), headers={'Response': 'Failed'}) def send_command(self, command, debug=False): resp = self.send_action({'Action': 'Command', 'Command': command}) if debug: # pragma: no cover self.log.debug('Command "%s" => Succeed: %s, Data:\n%s', command, resp.success, getattr(resp, 'text', resp)) if resp.success: resp.lines = [] if resp['response'].lower() == 'follows': resp.lines = resp.text.split('\n') return resp @command(permission='voip') def call(self, mask, target, args): """Call someone. Destination and from can't contains spaces. %%call <destination> [<from>] """ if 'nick' not in args: args['nick'] = mask.nick callee = self.resolver(mask, args['<destination>']) if args['<from>']: caller = self.resolver(mask, args['<from>']) else: caller = self.resolver(mask, mask.nick) if caller is None or caller.get('channel') is None: return '{nick}: Your caller is invalid.'.format(**args) if callee is None or callee.get('exten') is None: return '{nick}: Your destination is invalid.'.format(**args) action = { 'Action': 'Originate', 'Channel': caller['channel'], 'WaitTime': 20, 'CallerID': caller.get('fullname', caller['channel']), 'Exten': callee['exten'], 'Context': caller.get('context', 'default'), 'Priority': 1, } resp = self.send_action(action) if resp.success: return '{nick}: Call to {<destination>} done.'.format(**args) else: return resp.text @command(permission='voip') def room(self, mask, target, args): """Invite/kick someone in a room. You can use more than one destination. Destinations can't contains spaces. %%room (list|invite|kick) [<room>] [<destination>...] """ args['nick'] = mask.nick room = args['<room>'] if args['invite']: callees = args['<destination>'] message = '{nick}: {<from>} has been invited to room {<room>}.' if not callees: # self invite callees = [mask.nick] message = '{nick}: You have been invited to room {<room>}.' resolved = [self.resolver(mask, c) for c in callees] if None in resolved: # show invalid arguments and quit callees = zip(resolved, callees) invalid = [c for r, c in callees if r is None] yield ( "{0}: I'm not able to resolve {1}. Please fix it!" ).format(mask.nick, ', '.join(invalid)) raise StopIteration() for callee in callees: # call each args['<destination>'] = args['<room>'] args['<from>'] = callee msg = self.call(mask, target, args) if 'Call to' in msg: yield message.format(**args) else: yield msg if room and room not in self.rooms: yield 'Invalid room' raise StopIteration() if args['list']: def fmt(room, users): amount = len(users) users = ', '.join([u for u in sorted(users)]) return 'Room {0} ({1}): {2}'.format(room, amount, users) if room: yield fmt(room, self.rooms[room]) elif self.rooms: for room, users in self.rooms.items(): yield fmt(room, self.rooms[room]) else: yield 'Nobody here.' elif args['kick']: users = self.rooms[room] commands = [] for victim in args['<destination>']: for user in users: if victim.lower() in user.lower(): peer = users[user] commands.append(( user, 'meetme kick {0} {1}'.format(room, peer))) if not commands: yield 'No user matching query' raise StopIteration() for user, cmd in commands: resp = self.send_command(cmd) if resp.success: del self.rooms[room][user] if not self.rooms[room]: del self.rooms[room] yield '{0} kicked from {1}.'.format(user, room) else: # pragma: no cover yield 'Failed to kick {0} from {1}.'.format(user, room) @command(permission='voip') def asterisk(self, mask, target, args): """Show voip status %%asterisk status [<id>] """ self.log.info('voip %s %s %s', mask, target, args) args['nick'] = mask.nick if args['<id>']: peer = self.resolver(mask.nick, args['<id>']) else: peer = self.resolver(mask, mask.nick) if peer is None: return '{nick}: Your id is invalid.'.format(**args) action = {'Action': 'SIPshowpeer', 'peer': peer['login']} resp = self.send_action(action) if resp.success: print(resp.lheaders) return ('{nick}: Your VoIP phone is registered. ' '(User Agent: {sip-useragent} on {address-ip})' ).format(nick=mask.nick, **resp.lheaders) @command(permission='admin', venusian_category='irc3.debug') def asterisk_command(self, mask, target, args): # pragma: no cover """Send a raw command to asterisk. Use "help" to list core commands. %%asterisk_command <command>... """ cmd = ' '.join(args['<command>']) cmd = dict( help='core show help', ).get(cmd, cmd) resp = self.send_command(cmd, debug=True) return resp.success @command(permission='admin', venusian_category='irc3.debug') def asterisk_originate(self, mask, target, args): # pragma: no cover """Send raw originate %%asterisk_originate <Channel> <CallerID> <Exten> <Context> """ action = { 'Action': 'Originate', 'WaitTime': 20, 'Priority': 1, } for k, v in list(args.items()): if k.startswith('<'): action[k.strip('<>')] = v self.send_action(action) return 'Action {} sent'.format(repr(action)) def SIGINT(self): if self.manager is not None: self.manager.close() self.log.info('SIGINT: connection closed')
import asyncio from panoramisk import Manager import json from pprint import pprint sipLog = 'sipLog.txt' manager = Manager(loop=asyncio.get_event_loop(), host='192.168.2.62', username='', secret='') # This will print NewChannel Events. # AppData='hangupcall, CallerIDName='test2' CallerIDNum='112' Channel='PJSIP/112-0000004a' ChannelState='6', # ChannelState='6' ChannelStateDesc='Up' ConnectedLineName='Test1' ConnectedLineNum='111' Context='ext-local' Event='Newexten' # # @manager.register_event('Newexten') def callback(manager, message): # resp = yield from manager.send_action({'Action': 'Status'}) # print(resp) state = int(message.get('ChannelState')) if message.get('Application') != 'Hangup' and message.get('Application') != 'Finished' else message.get('Application') callStateSwitcher = { 4: 'Incoming', 5: 'Ringing', 6: 'Answered', 7: 'Busy', 'Hangup': 'Hangup', 'Finished': 'NoAnswer', }
import asyncio from panoramisk import Manager manager = Manager(loop=asyncio.get_event_loop(), host='ip', username='******', secret='secret') @manager.register_event('*') def callback(event, manager): if "FullyBooted" not in manager.event: """This will print every event, but the FullyBooted events as these will continuously spam your screen""" print(manager) """ # This will print NewChannel Events @manager.register_event('NewChannel') def callback(event, manager): print(manager) # This will print Hangup Events @manager.register_event('Hangup') def callback(event, manager): print(manager) """
class Asterisk(object): requires = ['irc3.plugins.command'] def __init__(self, bot): self.bot = bot self.bot.asterirc = self self.config = config = dict( host='127.0.0.1', port=5038, http_port='8088', protocol='http', debug=True, ) config.update(bot.config.get('asterisk', {})) self.log = logging.getLogger('irc3.ast') self.ilog = logging.getLogger('irc.asterirc') self.ilog.set_irc_targets(bot, self.config['channel']) self.log.info('Channel is set to {channel}'.format(**config)) self.rooms = defaultdict(dict) self.http = None self.resolver = irc3.utils.maybedotted(self.config['resolver']) self.manager = Manager(log=logging.getLogger('irc3.ast.manager'), **config) self.manager.register_event('Shutdown', self.handle_shutdown) self.manager.register_event('Meet*', self.handle_meetme) if config.get('debug'): self.manager.register_event('*', self.handle_event) if isinstance(self.resolver, type): self.resolver = self.resolver(bot) def connection_made(self): self.bot.loop.call_later(1, self.connect) def post_connect(self): self.log.debug('post_connect') resp = self.send_action({'Action': 'Status'}) if resp.success: self.update_meetme() else: # pragma: no cover self.log.error(resp.text) self.bot.loop.call_later(1, self.post_connect) def update_meetme(self): resp = self.send_command('meetme list') if resp.success: if 'No active MeetMe conferences.' in resp.text: self.rooms = defaultdict(dict) for line in resp.lines[1:-2]: room = line.split(' ', 1)[0] if not room or not room.isdigit(): continue resp = self.send_command('meetme list ' + room) if resp.success and resp.iter_lines(): room = self.rooms[room] for line in resp.lines: if not line.startswith('User '): continue line = line.split('Channel:')[0] splited = [s for s in line.split() if s][2:] uid = splited.pop(0) caller = ' '.join(splited[1:]) if 'external call ' in caller.lower(): e, c, n = caller.split(' ')[:4] caller = ' '.join([e, c, n[:6]]) room[caller] = uid def connect(self): if self.manager is not None: self.manager.close() self.bot.loop.call_later(5, self.post_connect) try: self.manager.connect() except Exception as e: self.log.exception(e) self.log.info('connect retry in 5s') self.bot.loop.call_later(1, self.connect) return False else: return True def handle_shutdown(self, event, manager): self.manager.close() self.bot.loop.call_later(2, self.connect) def handle_event(self, event, manager): self.log.debug('handle_event %s %s', event, '') # , event.headers) def handle_meetme(self, event, manager): self.log.debug('handle_meetme %s %s', event, event.headers) lower_header_keys(event) name = event.name.lower() room = event['meetme'] if name == 'meetmeend': if room in self.rooms: # pragma: no cover del self.rooms[room] self.ilog.info('room {} is closed.'.format(room)) return action = None caller = event['calleridname'] if 'external call ' in caller.lower(): e, c, n = caller.split(' ')[:4] caller = ' '.join([e, c, n[:6]]) elif 'external call' in caller.lower(): # pragma: no cover caller += event['calleridnum'][:6] if 'join' in name: action = 'join' self.rooms[room][caller] = event['usernum'] elif 'leave' in name: action = 'leave' if caller in self.rooms.get(room, []): del self.rooms[room][caller] if action: # log args = dict(caller=caller, action=action, room=room, total=len(self.rooms[room])) self.ilog.info(('{caller} has {action} room {room} ' '(total in this room: {total})').format(**args)) def send_action(self, *args, **kwargs): try: res = self.manager.send_action(*args, **kwargs) return res except Exception as e: self.log.error('send_action(%r, **%r)', args, kwargs) self.log.exception(e) return Message('response', 'Sorry an error occured. ({})'.format(repr(e)), headers={'Response': 'Failed'}) def send_command(self, command, debug=False): resp = self.send_action({'Action': 'Command', 'Command': command}) if debug: # pragma: no cover self.log.debug('Command "%s" => Succeed: %s, Data:\n%s', command, resp.success, getattr(resp, 'text', resp)) if resp.success: resp.lines = [] if resp['response'].lower() == 'follows': resp.lines = resp.text.split('\n') return resp @command(permission='voip') def call(self, mask, target, args): """Call someone. Destination and from can't contains spaces. %%call <destination> [<from>] """ if 'nick' not in args: args['nick'] = mask.nick callee = self.resolver(mask, args['<destination>']) if args['<from>']: caller = self.resolver(mask, args['<from>']) else: caller = self.resolver(mask, mask.nick) if caller is None or caller.get('channel') is None: return '{nick}: Your caller is invalid.'.format(**args) if callee is None or callee.get('exten') is None: return '{nick}: Your destination is invalid.'.format(**args) action = { 'Action': 'Originate', 'Channel': caller['channel'], 'WaitTime': 20, 'CallerID': caller.get('fullname', caller['channel']), 'Exten': callee['exten'], 'Context': caller.get('context', 'default'), 'Priority': 1, } resp = self.send_action(action) if resp.success: return '{nick}: Call to {<destination>} done.'.format(**args) else: return resp.text @command(permission='voip') def room(self, mask, target, args): """Invite/kick someone in a room. You can use more than one destination. Destinations can't contains spaces. %%room (list|invite|kick) [<room>] [<destination>...] """ args['nick'] = mask.nick room = args['<room>'] if args['invite']: callees = args['<destination>'] message = '{nick}: {<from>} has been invited to room {<room>}.' if not callees: # self invite callees = [mask.nick] message = '{nick}: You have been invited to room {<room>}.' resolved = [self.resolver(mask, c) for c in callees] if None in resolved: # show invalid arguments and quit callees = zip(resolved, callees) invalid = [c for r, c in callees if r is None] yield ( "{0}: I'm not able to resolve {1}. Please fix it!").format( mask.nick, ', '.join(invalid)) raise StopIteration() for callee in callees: # call each args['<destination>'] = args['<room>'] args['<from>'] = callee msg = self.call(mask, target, args) if 'Call to' in msg: yield message.format(**args) else: yield msg if room and room not in self.rooms: yield 'Invalid room' raise StopIteration() if args['list']: def fmt(room, users): amount = len(users) users = ', '.join([u for u in sorted(users)]) return 'Room {0} ({1}): {2}'.format(room, amount, users) if room: yield fmt(room, self.rooms[room]) elif self.rooms: for room, users in self.rooms.items(): yield fmt(room, self.rooms[room]) else: yield 'Nobody here.' elif args['kick']: users = self.rooms[room] commands = [] for victim in args['<destination>']: for user in users: if victim.lower() in user.lower(): peer = users[user] commands.append( (user, 'meetme kick {0} {1}'.format(room, peer))) if not commands: yield 'No user matching query' raise StopIteration() for user, command in commands: resp = self.send_command(command) if resp.success: del self.rooms[room][user] if not self.rooms[room]: del self.rooms[room] yield '{0} kicked from {1}.'.format(user, room) else: # pragma: no cover yield 'Failed to kick {0} from {1}.'.format(user, room) @command(permission='voip') def asterisk(self, mask, target, args): """Show voip status %%asterisk status [<id>] """ self.log.info('voip %s %s %s', mask, target, args) args['nick'] = mask.nick if args['<id>']: peer = self.resolver(mask.nick, args['<id>']) else: peer = self.resolver(mask, mask.nick) if peer is None: return '{nick}: Your id is invalid.'.format(**args) action = {'Action': 'SIPshowpeer', 'peer': peer['login']} resp = self.send_action(action) if resp.success: print(resp.lheaders) return ('{nick}: Your VoIP phone is registered. ' '(User Agent: {sip-useragent} on {address-ip})').format( nick=mask.nick, **resp.lheaders) @command(permission='admin', venusian_category='irc3.debug') def asterisk_command(self, mask, target, args): # pragma: no cover """Send a raw command to asterisk. Use "help" to list core commands. %%asterisk_command <command>... """ cmd = ' '.join(args['<command>']) cmd = dict(help='core show help', ).get(cmd, cmd) resp = self.send_command(cmd, debug=True) return resp.success @command(permission='admin', venusian_category='irc3.debug') def asterisk_originate(self, mask, target, args): # pragma: no cover """Send raw originate %%asterisk_originate <Channel> <CallerID> <Exten> <Context> """ action = { 'Action': 'Originate', 'WaitTime': 20, 'Priority': 1, } for k, v in list(args.items()): if k.startswith('<'): action[k.strip('<>')] = v self.send_action(action) return 'Action {} sent'.format(repr(action)) def SIGINT(self): if self.manager is not None: self.manager.close() self.log.info('SIGINT: connection closed')
'call_posted_time': '', 'call_finished': False, 'call_registred': False, 'call_record_attached': False } } if not DEBUG: logging.config.dictConfig(LOGGING) logger = logging.getLogger('ParkLogger') manager = Manager( host=os.getenv('AMI_HOST', '127.0.0.1'), port=os.getenv('AMI_PORT', 5038), username=os.getenv('AMI_USERNAME', 'user'), secret=os.getenv('AMI_SECRET', 'password'), ping_delay=10, # Delay after start ping_interval=10, # Periodically ping AMI (dead or alive) reconnect_timeout=2, # Timeout reconnect if connection lost ) def grab_bx_users(bx24): return { user['UF_PHONE_INNER']: user['ID'] for user in bx24.callMethod('user.get') if user['UF_PHONE_INNER'] } def on_connect(mngr: Manager): logging.info('Connected to %s:%s AMI socket successfully' %
import os import django os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'call_center.settings') django.setup() from django.conf import settings from crm.models import Call, Client from django.utils import timezone import asyncio import pytz import requests from datetime import datetime, timedelta from panoramisk import Manager manager = Manager(loop=asyncio.get_event_loop(), host=settings.IP, username=settings.ASTER_USER, secret=settings.ASTER_PASS) # Получение необходимой группы номеров. def groups_phone_numbers(): url = settings.GROUP_PHONE_NUMBER_URL phones_json = requests.get(url, verify=False).json() return phones_json[settings.NAME_GROUP_PHONE_NUMBER].split('-') numbers = groups_phone_numbers() @manager.register_event('Hangup')
# # AMI CONF in ASTERISK # # add this below, adapting permit and deny accordingly # to /etc/asterisk/manager_custom.conf # [queue_alert_user] # secret=queue_alert_pwd # deny=0.0.0.0/0.0.0.0 # permit=0.0.0.0/0.0.0.0 # read = all # eventfilter=Event: QueueCallerAbandon manager = Manager( loop=asyncio.get_event_loop(), host="localhost", username="******", secret="queue_alert_pwd", ) # # you need to create the above webhook in Rocket.Chat # and paste the Script from incoming.webhook.Rocket.Chat.js # this is the webhook url incoming_endpoint = ( "http://localhost:3000/hooks/" + "620e9615701ffe000986a1c8/8fRecuRk5Muyf3mtsGtDGFgJDkZ8wuEjm5qNqNFqxuCLaErE" ) # this is an example. # you can filter the callback by different method # or inside the method, using message.event # you can also duplicate the code below, and send different
AMI_USER = os.environ.get('AMI_USER', 'asterisk') AMI_SECRET = os.environ.get('AMI_SECRET', 'secret') stats = statsd.StatsClient(*STATSD_HOST.split(':')) loop = asyncio.get_event_loop() logging.basicConfig() logger = logging.getLogger(__name__) logger.setLevel(level=logging.DEBUG) # Asterisk AMI manager client manager = Manager(loop=loop, host=AMI_HOST, port=AMI_PORT, username=AMI_USER, secret=AMI_SECRET, ping_interval=10, # Periodically ping AMI (dead or alive) reconnect_timeout=2, # Timeout reconnect if connection lost ) manager.loop.set_debug(True) channels_current = {} # Current channels gauge sip_reachable_peers = set() iax_reachable_peers = set() sip_total_peers = 0 iax_total_peers = 0 def main(): logger.info('Connecting to {}:{}.'.format(AMI_HOST, AMI_PORT))
class AsteriskClient: def __init__(self, loop): self.manager = Manager(loop=loop, host='178.248.87.116', port=1709, username='******', secret='100') self.callManager = CallBaseManager() self.httpclient = HttpClientTornado() self.manager.register_event('FullyBooted', self.FullyBooted) self.manager.register_event('BridgeEnter', self.BridgeEnter) self.manager.register_event('Hangup', self.Hangup) self.manager.connect() try: self.manager.loop.run_forever() except KeyboardInterrupt: self.manager.loop.close() def FullyBooted(self, manager, message): print(message) resp = yield from manager.send_action({'Action': 'SIPpeers'}) self.callManager.FillSIPpeers(resp) resp = yield from manager.send_action({'Action': 'QueueStatus'}) pprint(resp) result = self.httpclient.QueueStatus(resp, method='connect') self.httpclient.SendRequest(result) def BridgeEnter(self, manager, message): # global isDial # isDial=False print(message) Bridge = self.callManager.CallBegin( CallerNumber=message.CallerIDNum, ConnectedNumber=message.ConnectedLineNum) if isinstance(Bridge, dict): resp = yield from manager.send_action({'Action': 'QueueStatus'}) pprint(resp) result = self.httpclient.QueueStatus(resp, method='call_begin', call=Bridge) self.httpclient.SendRequest(result) def Hangup(self, manager, message): print(message) Call = self.callManager.CallEnd(CallerNumber=message.CallerIDNum) if isinstance(Call, dict): resp = yield from manager.send_action({'Action': 'QueueStatus'}) pprint(resp) result = self.httpclient.QueueStatus(resp, method='call_end', call=Call) self.httpclient.SendRequest(result) def ChanSpy(self, channel_from: str, channel_to: str, type: str): call = yield from self.manager.send_action({ 'Action': 'Originate', 'Channel': 'SIP/' + channel_from, 'Application': 'ChanSpy', 'Data': 'SIP/' + channel_to + ',' + type, 'Priority': 1, 'Callerid': 'Spy-{%s} <{%s}>'.format(channel_to), 'Variable': 'SIPADDHEADER="Call-Info:\;answer-after=0"', }) pprint(call) def PickUp(self, channel: str): call = yield from self.manager.send_action({ 'Action': 'Originate', 'Channel': 'SIP/' + channel, 'Application': 'PickupChan', 'Data': 'SIP/' + channel, 'Priority': 1, 'Callerid': channel, 'Variable': 'SIPADDHEADER="Call-Info:\;answer-after=0"', }) pprint(call) def Originate(self, channel_from, channel_to): call = yield from self.manager.send_action({ 'Action': 'Originate', 'Channel': 'SIP/' + channel_from, 'Exten': channel_to, 'Priority': 1, 'Callerid': channel_from, 'Variable': 'SIPADDHEADER="Call-Info:\;answer-after=0"', }) pprint(call) def Redirect(self, channel_from, channel_to): call = yield from self.manager.send_action({ 'Action': 'Redirect', # 'Channel': 'SIP/' + channel_from, # 'Exten': channel_to, 'Priority': 1, 'Context': 'from-internal', }) pprint(call) def QueueAdd(self, channel): call = yield from self.manager.send_action({ 'Action': 'QueueAdd', 'Queue': 'operator', 'Interface': 'SIP/' + channel, 'Penalty': 0, }) pprint(call) def QueueRemove(self, channel): call = yield from self.manager.send_action({ 'Action': 'QueueRemove', 'Queue': 'operator', 'Interface': 'SIP/' + channel, }) pprint(call) def Queue(self, worker: str, action: int): if action == 1: self.QueueAdd(worker) else: self.QueueRemove(worker) def Parse(self, message: dict): method = message['method'] if method == 'call_abonent': self.Originate(message['from'], message['to']) elif method == 'transfer_call': self.Redirect(message['from'], message['to']) elif method == 'connect_with_abonent': self.ChanSpy(message['from'], message['to'], 'qBx') elif method == 'connect_without_abonent': self.ChanSpy(message['from'], message['to'], 'wx') elif method == 'connect_without_microphone': self.ChanSpy(message['from'], message['to'], 'qx') elif method == 'queue': self.Queue(message['worker'], message['action']) # if __name__ == '__main__': # main()
maxNumTries = int(config['attacker']['maxNumTries']) maxNumInvitesWithoutAuth = int(config['attacker']['maxNumInvites']) BLExpireTime = int(config['attacker']['BLExpireTime']) WLExpireTime = int(config['attacker']['WLExpireTime']) TLExpireTime = int(config['attacker']['TLExpireTime']) iptablesChain = config['attacker']['iptablesChain'] else: maxNumTries = 5 BLExpireTime = 86400 WLExpireTime = 21600 TLExpireTime = 3600 iptablesChain = "INPUT" # We connect into a Asterisk Manager (Asterisk 11 or newer with Security permissions to read) manager = Manager(loop=asyncio.get_event_loop(), host=managerHost, port=managerPort, username=managerUser, secret=managerPass) # Set the logging system to dump everything we do logging.basicConfig(filename=logFile,level=logging.DEBUG,format='%(asctime)s %(levelname)s: %(message)s') Log = logging.getLogger() level = logging.getLevelName(logLevel) Log.setLevel(level) logging.debug("Configured Blacklist expire time: "+str(BLExpireTime)) logging.debug("Configured Whitelist expire time: "+str(WLExpireTime)) logging.debug("Configured Templist expire time: "+str(TLExpireTime)) # We set the lists where we storage the addresses. templist={} # Suspected addresses whitelist={} # Trusted addresses blacklist={} # Attackers addresses
AMI_HOST = os.environ.get('AMI_HOST', 'localhost') AMI_PORT = os.environ.get('AMI_PORT', '5038') AMI_USER = os.environ.get('AMI_USER', 'asterisk') AMI_SECRET = os.environ.get('AMI_SECRET', 'secret') stats = statsd.StatsClient(*STATSD_HOST.split(':')) loop = asyncio.get_event_loop() logging.basicConfig() logger = logging.getLogger(__name__) logger.setLevel(level=logging.DEBUG) # Asterisk AMI manager client manager = Manager(loop=loop, host=AMI_HOST, port=AMI_PORT, username=AMI_USER, secret=AMI_SECRET) manager.loop.set_debug(True) channels_current = {} # Current channels gauge sip_reachable_peers = set() def main(): logger.info('Connecting to {}:{}.'.format(AMI_HOST, AMI_PORT)) manager.connect() try: loop.run_forever() except KeyboardInterrupt: loop.close()
def register(manager: Manager, events: Tuple[str]): for event in events: manager.register_event(event, capture_message)