def scrape_server(token: str, server_name: str, messages_number: int = DEFAULT_MESSAGES_NUMBER, timeout: float = DEFAULT_TIMEOUT): loop = asyncio.new_event_loop() client = Client(is_bot=False, loop=loop, max_messages=messages_number) server_data = {} @client.event async def on_ready(): __log__.info("logged in as: {}".format(client.user.id)) for server in client.servers: if server.name != server_name: continue server: Server = server __log__.info("obtained server: name: {} id: {}".format( server.name, server.id)) server_data.update( { "name": server.name, "id": server.id, "channels": [] } ) for channel in server.channels: channel: Channel = channel __log__.info("obtained channel: name: {} id: {}".format( channel.name, channel.id)) channel_data = { "name": channel.name, "id": channel.id, "messages": [] } try: async for message in client.logs_from(channel, limit=messages_number): message: Message = message __log__.info( "obtained message: author: {} content: {}".format( message.author.id, message.content)) author: Member = message.author message_data = { "author": { "name": author.name, "id": author.id }, "server": message.server.name, "channel": message.channel.name, "timestamp": str(message.timestamp), "content": message.content, "mentions": [ dict( name=mentioned_member.name, id=mentioned_member.id ) for mentioned_member in message.mentions ] } channel_data["messages"].append(message_data) except Forbidden: # cant access channel pass except NotFound: # cant find channel pass except HTTPException: # discord likely down pass server_data["channels"].append(channel_data) client.close() loop.run_until_complete(client.login(token, bot=False)) try: loop.run_until_complete( asyncio.wait_for(client.connect(), timeout, loop=loop)) except asyncio.TimeoutError: pass loop.run_until_complete(client.logout()) loop.close() return server_data
class DiscordHandler(GenericHandler): def __init__(self): super(DiscordHandler, self).__init__() self.bot = Client() self.message_handlers = WeakSet() self.channels = WeakValueDictionary() async def setup(self, token, client_secret): await self.bot.login(token=token, bot=True) asyncio.ensure_future(self.bot.connect(reconnect=True)) await self.bot.wait_until_ready() print("Logged into Discord") self.bot.event(self.on_message) self.bot.event(self.on_guild_channel_create) self.bot.event(self.on_guild_channel_delete) self.bot.event(self.on_guild_channel_update) def get_channel(self, serialised) -> Optional[DiscordChannel]: channel_id = serialised.get("id") try: return self.channels[channel_id] except KeyError: pass try: channel = self.bot.get_channel(int(channel_id)) except ValueError: return if not channel: return rtn = DiscordChannel(channel) self.message_handlers.add(rtn.on_message_handler) self.channels[channel_id] = rtn return rtn @property def serialised_channels(self): return [{ "type": "discord", "id": f"{channel.id}", "name": channel.name, "server": { "id": f"{channel.guild.id}", "name": channel.guild.name, "icon": str(channel.guild.icon_url_as(format="png", size=256)) } } for channel in self.bot.get_all_channels() if (channel.permissions_for(channel.guild.me).manage_webhooks and isinstance(channel, TextChannel))] async def on_message(self, message): await asyncio.gather( *[handler(message) for handler in self.message_handlers]) async def on_guild_channel_create(self, channel): await self.process_channel_handlers() async def on_guild_channel_delete(self, channel): await self.process_channel_handlers() async def on_guild_channel_update(self, before, after): await self.process_channel_handlers()