async def slack_client(app: web.Application) -> AsyncGenerator[None, None]: slack = SlackAPI(token=app["SLACK_TOKEN"], session=app["client_session"]) _register_in_app(app, "slack_client", slack) slack_legacy = SlackAPI(token=app["SLACK_INVITE_TOKEN"], session=app["client_session"]) _register_in_app(app, "slack_client_legacy", slack_legacy) yield
async def _cleanup_user(app, user): try: async with app["plugins"]["pg"].connection() as pg_con: messages = await pg_con.fetch( """SELECT id, channel FROM slack.messages WHERE "user" = $1""", user) api = SlackAPI(session=app["http_session"], token=os.environ["SLACK_ADMIN_TOKEN"]) for message in messages: try: data = {"channel": message["channel"], "ts": message["id"]} await api.query(url=methods.CHAT_DELETE, data=data) except SlackAPIError as e: if e.error == "message_not_found": continue else: LOG.exception( "Failed to cleanup message %s in channel %s", message["id"], message["channel"], ) except Exception: LOG.exception( "Failed to cleanup message %s in channel %s", message["id"], message["channel"], ) except Exception: LOG.exception("Unexpected exception cleaning up user %s", user)
def __init__(self, loop, config_file: str = "config.yaml"): self.loop = loop self.config = Config.from_file(config_file) self.session = ClientSession() self.slack_client = SlackAPI(token=self.config.bot_token, session=self.session) self.waiters = [] self.commands = self.config.commands self.prefix = self.config.prefix self.command_types = { "get_id": self.get_id, "read_web": self.read_web, "run_cmd": self.run_cmd }
def load(self, sirbot): LOG.info("Loading slack plugin") self.api = SlackAPI(session=sirbot.http_session, token=self.token) sirbot.router.add_route("POST", "/slack/events", endpoints.incoming_event) sirbot.router.add_route("POST", "/slack/commands", endpoints.incoming_command) sirbot.router.add_route("POST", "/slack/actions", endpoints.incoming_action) if self.bot_user_id and not self.bot_id: sirbot.on_startup.append(self.find_bot_id)
async def iterate(client): async for channel in client.iter(slack.methods.CHANNELS_LIST, limit=4): pprint.pprint(channel) if __name__ == "__main__": if len(sys.argv) > 1: TOKEN = sys.argv[1] else: TOKEN = os.environ.get("SLACK_TOKEN") if not TOKEN: raise ValueError("No slack token provided !") loop = asyncio.get_event_loop() session = aiohttp.ClientSession(loop=loop) slack_client = SlackAPI(token=TOKEN, session=session, raise_on_rate_limit=True) try: loop.run_until_complete(iterate(slack_client)) except KeyboardInterrupt: pass loop.run_until_complete(session.close())
asyncio.ensure_future(respond_to_message(event, client)) async def respond_to_message(message, client): response = message.response() response['text'] = 'Hello world !' await client.query(slack.methods.CHAT_POST_MESSAGE, data=response.serialize()) if __name__ == '__main__': if len(sys.argv) > 1: TOKEN = sys.argv[1] else: TOKEN = os.environ.get('SLACK_TOKEN') if not TOKEN: raise ValueError('No slack token provided !') loop = asyncio.get_event_loop() session = aiohttp.ClientSession(loop=loop) slack_client = SlackAPI(token=TOKEN, session=session) try: loop.run_until_complete(rtm(slack_client)) except KeyboardInterrupt: pass loop.run_until_complete(session.close())
async def slack_client(app: web.Application) -> AsyncGenerator[None, None]: app["slack_client"] = SlackAPI(token=app["slack_token"], session=app["client_session"]) app["slack_client_legacy"] = SlackAPI(token=app["slack_invite_token"], session=app["client_session"]) yield
class SlackBot: def __init__(self, loop, config_file: str = "config.yaml"): self.loop = loop self.config = Config.from_file(config_file) self.session = ClientSession() self.slack_client = SlackAPI(token=self.config.bot_token, session=self.session) self.waiters = [] self.commands = self.config.commands self.prefix = self.config.prefix self.command_types = { "get_id": self.get_id, "read_web": self.read_web, "run_cmd": self.run_cmd } async def run(self): print("Running") await self.rtm() async def get_id(self, command, message: Message): text = message["text"] mentioned_ids = re.findall(mention, text) await self.send_message(message["channel"], " ".join(mentioned_ids)) async def read_web(self, command, message: Message): async with self.session.get(command["url"]) as resp: resp = await resp.text() await self.send_message(message["channel"], resp) async def run_cmd(self, command, message: Message): output = subprocess.run(command["cmd"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if command["display_output"]: resp = (f"```\n{output.stdout.decode().strip()}\n```" if output.stdout else "") + \ (f"```\n{output.stderr.decode().strip()}\n```" if output.stderr else "") await self.send_message(message["channel"], resp) async def run_command(self, command, message: Message): """ Run a command after checking permissions. """ channel = message["channel"] if "acl1" in command: if not command["acl1"] or message["user"] not in command["acl1"]: return await self.send_message( channel, "You are not in the acl list for this command.") if "reply1" in command: await self.send_message(channel, command["reply1"]) if "acl2" in command and command["acl2"]: message2 = await self.wait_for_message( f"{self.prefix}{command['trigger2']}", timeout=command["timeout"]) if message2 is None: return await self.send_message(channel, "Timed out.") if message2["user"] not in command["acl2"]: return await self.send_message( channel, "You are not in the acl list for this command.") if message2["user"] == message["user"]: return await self.send_message( channel, "The authorising user cannot be the initiating user.") if "reply2" in command: await self.send_message(channel, command["reply2"]) await self.command_types[command["type"]](command, message) if "complete" in command: await self.send_message(channel, command["complete"]) async def wait_for_message(self, text: str, timeout: int) -> Message: """ Wait until receive a message `text` within `timeout`. Returns None if timed out or the message. """ future = loop.create_future() check = lambda event: event.event["text"] == text self.waiters.append((future, check)) try: event = await asyncio.wait_for(future, timeout=timeout) except asyncio.TimeoutError: return None return event async def send_message(self, channel: str, message: str): """ Send `message` to `channel` """ await self.slack_client.query(slack.methods.CHAT_POST_MESSAGE, data={ "channel": channel, "text": message, }) async def rtm(self): """ Main loop, parses Slack messages and runs them """ async for event in self.slack_client.rtm(): if isinstance(event, Message): for future, check in self.waiters: if check(event): future.set_result(event) if not event.event["text"].startswith(self.prefix): continue command = event.event["text"].replace(self.prefix, "", 1).split(" ", 1)[0] if command in self.commands: asyncio.ensure_future( self.run_command(self.commands[command], event.event))
def __init__(self): super(SlackHandler, self).__init__() session = ClientSession() self.slack_client = SlackAPI(token=None, session=session) self.channels = WeakValueDictionary()
class SlackHandler(GenericHandler): def __init__(self): super(SlackHandler, self).__init__() session = ClientSession() self.slack_client = SlackAPI(token=None, session=session) self.channels = WeakValueDictionary() async def setup(self, token): self.slack_client._token = token await self.update_team_info() await self.update_channels() asyncio.ensure_future(self.rtm()) print("Logged into Slack") def get_channel(self, serialised) -> Optional[SlackChannel]: channel_id = serialised["id"] try: return self.channels[channel_id] except KeyError: pass rtn = SlackChannel(channel_id, self.slack_client) self.channels[channel_id] = rtn return rtn async def rtm(self): async for event in self.slack_client.rtm(): if isinstance(event, Message): await asyncio.gather(*[channel.on_message_handler(event) for channel in self.channels.values()]) if isinstance(event, Event): if event["type"].startswith("channel_"): await self.update_channels() @property def serialised_channels(self): return self._serialised_channels async def update_channels(self): channels = await self.slack_client.query( slack.methods.CONVERSATIONS_LIST, data={ "exclude_archived": True } ) self._serialised_channels = [ { "type": "slack", "id": channel["id"], "name": channel["name"], "server": self.team_info } for channel in channels["channels"] if channel["is_member"] ] async def update_team_info(self): team_info = await self.slack_client.query("https://slack.com/api/team.info") self.team_info = { "id": team_info["team"]["id"], "name": team_info["team"]["name"], "icon": team_info["team"]["icon"]["image_132"] }
def initBot(self, bot: BotType, token: str) -> Deferred: self.slack_client[bot] = SlackAPI(token=token, session=self.session) return as_deferred(self._setup(bot))