async def connect(self, url=None): """ Connect to the websocket stream and iterate over the messages dumping them in the Queue. """ logger.debug('Connecting...') try: if not url: url = (await self._negotiate_rtm_url())['url'] async with self._session.ws_connect(url) as self._ws: self._closed.clear() async for data in self._ws: if data.type == aiohttp.WSMsgType.TEXT: if data.data == 'close cmd': await self._ws.close() break else: msg = json.loads(data.data) ensure_future(self._callback(msg), loop=self._loop, logger=logger) elif data.type == aiohttp.WSMsgType.CLOSED: logger.warning('WS CLOSED: %s', data) elif data.type == aiohttp.WSMsgType.ERROR: logger.warning('WS ERROR: %s', data) await self.reconnect() except asyncio.CancelledError: pass finally: self._closed.set() self._ws = None
async def _incoming(self, request): data = await request.post() data = {**data} if data['token'] != self._token: return Response(text='Invalid') logger.debug('Command handler received: %s', data['command']) slack = registry.get('slack') func = self._endpoints.get(data['command']) if not func: raise SlackUnknownCommand(data['command']) command = await SlackCommand.from_raw(data, slack) if isinstance(self._save, list) and data['command'] in self._save \ or self._save is True: logger.debug('Saving incoming command %s from %s', command.command, command.frm.id) db = registry.get('database') await database.__dict__[db.type].dispatcher.save_incoming_command( db, command) await db.commit() coroutine = func(command, slack) ensure_future(coroutine=coroutine, loop=self._loop, logger=logger) return Response(status=200)
async def incoming_web(self, request): payload = await request.json() if payload['token'] != self._token: return Response(text='Invalid') if payload['type'] == 'url_verification': body = json.dumps({'challenge': payload['challenge']}) return Response(body=body, status=200) try: if payload['event']['type'] == 'message': ensure_future( self._incoming_message(payload['event']), loop=self._loop, logger=logger ) else: ensure_future( self._incoming(payload['event']), loop=self._loop, logger=logger ) return Response(status=200) except Exception as e: logger.exception(e) return Response(status=500)
async def test_ensure_future(loop, capsys): coro = raise_error(loop=loop) ensure_future(coro, loop=loop) await asyncio.sleep(0.2, loop=loop) out, err = capsys.readouterr() assert 'Task exited with error' in err assert 'ValueError' in err
async def _incoming(self, event): logger.debug('Event handler received: %s', event) slack = registry.get('slack') if isinstance(self._save, list) and event['type'] in self._save \ or self._save is True: db = registry.get('database') await self._store_incoming(event, db) for func in self._endpoints.get(event['type'], list()): f = func(event, slack) ensure_future(coroutine=f, loop=self._loop, logger=logger)
async def _dispatch(self, msg, slack): """ Dispatch an incoming slack message to the correct functions :param msg: incoming message :param slack: slack plugin :return: None """ handlers = list() if msg.thread in self._threads: handlers.extend(self._find_thread_handlers(msg)) handlers.extend(self._find_handlers(msg)) for func in handlers: f = func[0](msg, slack, func[1]) ensure_future(coroutine=f, loop=self._loop, logger=logger)
async def _dispatch(self, msg, slack, registry, db): """ Dispatch an incoming slack message to the correct functions :param msg: incoming message :param slack: slack plugin :param registry: plugin registry :return: None """ handlers = list() if msg.thread in self._threads: if msg.frm.id in self._threads[msg.thread]: logger.debug('Located thread handler for "%s" and "%s"', msg.thread, msg.frm.id) handlers.append((self._threads[msg.thread][msg.frm.id], None)) del self._threads[msg.thread][msg.frm.id] elif 'all' in self._threads[msg.thread]: logger.debug('Located thread handler for "%s"', msg.thread) handlers.append((self._threads[msg.thread]['all'], None)) del self._threads[msg.thread]['all'] if not handlers: for match, commands in self._endpoints.items(): n = match.search(msg.text) if n: for command in commands: if command.get('mention') and not msg.mention: continue elif command.get('admin') and not msg.frm.admin: continue logger.debug( 'Located handler for "{}", invoking'.format( msg.text)) handlers.append((command['func'], n)) for func in handlers: f = func[0](msg, slack, registry, func[1]) ensure_future(coroutine=f, loop=self._loop, logger=logger)
async def _incoming(self, request): data = await request.post() if 'payload' not in data: return Response(text='Invalid', status=400) payload = json.loads(data['payload']) if 'token' not in payload or payload['token'] != self._token: return Response(text='Invalid', status=400) logger.debug('Action handler received: %s', payload) slack = self._registry.get('slack') settings = self._endpoints.get(payload['callback_id']) if not settings: raise SlackUnknownAction(payload) action = await SlackAction.from_raw(payload, slack, settings=settings) if isinstance(self._save, list) and payload['callback_id'] \ in self._save or self._save is True: logger.debug('Saving incoming action %s from %s', action.callback_id, action.frm.id) db = self._registry.get('database') await database.__dict__[db.type].dispatcher.save_incoming_action( db, action) await db.commit() coroutine = settings['func'](action, slack, self._registry) ensure_future(coroutine=coroutine, loop=self._loop, logger=logger) if settings.get('public'): return Response(status=200, body=json.dumps({"response_type": "in_channel"}), content_type='application/json; charset=utf-8') else: return Response(status=200)
async def _incoming(self, request): data = await request.post() data = {**data} if data['token'] != self._token: return Response(text='Invalid') logger.debug('Command handler received: %s', data['command']) slack = self._registry.get('slack') settings = self._endpoints.get(data['command']) if not settings: raise SlackUnknownCommand(data['command']) command = await SlackCommand.from_raw(data, slack, settings=settings) if isinstance(self._save, list) and data['command'] in self._save \ or self._save is True: logger.debug('Saving incoming command %s from %s', command.command, command.frm.id) db = self._registry.get('database') await database.__dict__[db.type].dispatcher.save_incoming_command( db, command) await db.commit() coroutine = settings['func'](command, slack, self._registry) ensure_future(coroutine=coroutine, loop=self._loop, logger=logger) # if settings.get('public'): # return Response( # status=200, # body=json.dumps({"response_type": "in_channel"}), # content_type='application/json' # ) # else: return Response(status=200)
async def test_ensure_future_cancel(loop, capsys): coro = cancel(loop=loop) ensure_future(coro, loop=loop) await asyncio.sleep(0.2, loop=loop) out, err = capsys.readouterr() assert '' in err