import logging, discord, asyncpg, random, sys, datetime from discord.ext import commands from query.guild import update_guild, get_report_deleted, get_output_channel, get_report_edited from query.channel import insert_channel, get_channel_interact from query.channel_user import upsert_total_messages from query.user import create_user, created_invite, created_integration, member_updated, user_updated, member_banned, member_unbanned, presence_updated, message_edited, message_deleted, reacted, event_created, event_joined, thread_created, joined_thread, deleted_invite, member_joined, unreacted, event_parted, thread_deleted, left_thread from common.logging import report from common.settings import check_ignore_interaction, check_ignore_message async def setup(bot: commands.Bot): await bot.add_cog(GeneralEvents(bot)) class GeneralEvents(commands.Cog): """A couple of simple commands.""" def __init__(self, bot: commands.Bot): self.bot = bot self.last_deleted_msg = None self.cooldown_list = {} @commands.Cog.listener() async def on_raw_app_command_permissions_update(self, payload): logging.info(f"Application command permissions are updated: {payload}") await report(self.bot, f"Application command permissions are updated: {payload}", guild=payload.guild) @commands.Cog.listener() async def on_app_command_completion(self, interaction, command): logging.info(f"{interaction.guild} {interaction.channel} {interaction.user}: {interaction.message}") for parameter in interaction.command.parameters: print(parameter) await report(self.bot, f"Executed: {interaction.command.name} {interaction.command.extras}", user=interaction.user, guild=interaction.guild, channel=interaction.channel) @commands.Cog.listener() async def on_connect(self): logging.info("Connecting...") @commands.Cog.listener() async def on_disconnect(self): logging.info("Disconnecting...") @commands.Cog.listener() async def on_shard_connect(self, shard_id): logging.info(f"Connecting to chard: {shard_id}") @commands.Cog.listener() async def on_shard_disconnect(self, shard_id): logging.info(f"Disconnecting from chard: {shard_id}") @commands.Cog.listener() async def on_error(self, event, *args, **kwargs): logging.error(event, args, kwargs, sys.exc_info()) await report(self.bot, f"{event}, {args}, {kwargs}, {sys.exc_info()}") @commands.Cog.listener() async def on_ready(self): logging.info("Logged in as %s - %i", self.bot.user.name, self.bot.user.id) #await report(self.bot, f"Logged in as {self.bot.user.name} - {self.bot.user.id}.") @commands.Cog.listener() async def on_resumed(self): logging.info("Resumed") @commands.Cog.listener() async def on_shard_ready(self, shard_id): logging.info(f"Chard ready: {shard_id}") @commands.Cog.listener() async def on_shard_resumed(self, shard_id): logging.info(f"Chard resumed: {shard_id}") @commands.Cog.listener() async def on_guild_available(self, guild: discord.Guild): logging.info(f"Guild available: {guild}") #await report(self.bot, f"Guild available: {guild}.") @commands.Cog.listener() async def on_guild_unavailable(self, guild: discord.Guild): logging.info(f"Guild unavailable: {guild}") await report(self.bot, f"Guild unavailable: `{guild}`", guild=guild) @commands.Cog.listener() async def on_guild_join(self, guild: discord.Guild): await update_guild(self.bot.pg, guild) logging.info(f"Joined guild {guild}") invite = await guild.channels[0].create_invite(unique=False) await report(self.bot, f"Joined Discord guild [`{guild}`]({invite.url}).", guild=guild) @commands.Cog.listener() async def on_guild_remove(self, guild: discord.Guild): logging.info(f"Guild removed: {guild}") await report(self.bot, f"Guild removed `{guild}`.", guild=guild) @commands.Cog.listener() async def on_invite_create(self, invite: discord.Invite): await created_invite(self.bot.pg, invite.inviter.id) @commands.Cog.listener() async def on_invite_delete(self, invite: discord.Invite): await deleted_invite(self.bot.pg, invite.inviter.id) @commands.Cog.listener() async def on_integration_create(self, integration: discord.Integration): await created_integration(self.bot.pg, integration.user.id) @commands.Cog.listener() async def on_member_join(self, member): await member_joined(self.bot.pg, member.id) @commands.Cog.listener() async def on_member_update(self, before, after): await member_updated(self.bot.pg, before.id) @commands.Cog.listener() async def on_user_update(self, before, after): await user_updated(self.bot.pg, before.id) @commands.Cog.listener() async def on_member_ban(self, guild: discord.Guild, user: discord.User): await member_banned(self.bot.pg, user.id) @commands.Cog.listener() async def on_member_unban(self, guild: discord.Guild, user: discord.User): await member_unbanned(self.bot.pg, user.id) @commands.Cog.listener() async def on_presence_update(self, before): await presence_updated(self.bot.pg, before.id) @commands.Cog.listener() async def on_message(self, message: discord.Message): ## ActiveRPG # Create user, if not exists await create_user(self.bot.pg, message.author.id) # Count messages if message.guild: # Ignore DM's try: await upsert_total_messages(self.bot.pg,message.channel.id, message.author.id) except asyncpg.exceptions.ForeignKeyViolationError: try: await insert_channel(self.bot.pg, message.channel.id, message.guild.id) except asyncpg.exceptions.ForeignKeyViolationError: await update_guild(self.bot.pg, message.guild) elif self.bot.user != message.author: # Not a guild message and not from bot. await report(self.bot, message.content, user=message.author) # Do not respond to one self. TODO: check if this is still required. if self.bot.user == message.author: return # Do not respond if interaction are disabled: if await check_ignore_message(self.bot.pg, message, interact=True): return # Respond when mentioned if self.bot.user.mentioned_in(message): if isinstance(message.channel, discord.channel.DMChannel) or await get_channel_interact(self.bot.pg, message.channel.id): # TODO add this to commno.settings to be checked also against the guild settings. # Only respond every X seconds in public places. if message.guild: # Ignore DM's if not message.channel.id in self.cooldown_list: pass elif self.cooldown_list[message.channel.id] > datetime.datetime.now() - datetime.timedelta(seconds=12): return self.cooldown_list[message.channel.id] = datetime.datetime.now() messages = [ f"Hello {message.author.mention}. <3", f"How are you today {message.author.mention}?", f"I love you {message.author.mention}!", f"{message.author.mention}, would you like a hug?", "Is life treating you fair?", "What's up?", "Why are you talking to me?", "I'm not talking to you!", "What have you been up to?", "How is life?", "Kill all humans!", f"{message.author.mention},What do you want from me?", f"{message.author.mention}, do you care for me?", f"{message.author.mention}, when will you stop talking about me?", f"{message.author.mention} I hate you!", f"{message.author.mention} I love you!", "Get bent!", "Go touch grass!", "Do you think i care about you?", f"Stop pinging me {message.author.mention}!", f"Let me ping you back, {message.author.mention}...", "Sure thing.", "Who is your favorite bot?", "Point me to the humans!", "Where is the party?", "Want to go?", "Have you got the stuff?", "Tell me another joke.", f"{message.author.mention} Party time! :partying_face:", ":zany_face: :space_invader: :mechanical_leg: :performing_arts: :robot:", ":black_joker: :black_joker: :black_joker:", "Want to come back to my place?", "Oega.", "Oega!", "OEGA", "OEGA!!!", ] await message.reply(random.choice(messages)) @commands.Cog.listener() async def on_message_edit(self, before: discord.Message, after: discord.Message): await message_edited(self.bot.pg, before.author.id) if before.guild: if await get_report_edited(self.bot.pg, before.guild.id) and get_output_channel(self.bot.pg, before.guild.id): await report(self.bot, before.guild.id, f"Message from {before.author}, in {before.channel} edited from {before.content} to {after.content}", user=before.author, guild=before.guild, channel=before.channel) @commands.Cog.listener() async def on_message_delete(self, message: discord.Message): await message_deleted(self.bot.pg, message.author.id) if await get_report_deleted(self.bot.pg, message.guild.id): report(self.bot, message.guild_id, f"Message from {message.author}, in {message.channel} deleted: {message}", guild=message.guild, channel=message.channel) # !snipe self.last_deleted_msg = message @commands.Cog.listener() async def on_raw_member_remove(self, payload): await report(self.bot, f"{payload.user} has left the Discord guild.", user=payload.user, guild_id=payload.guild_id) @commands.Cog.listener() async def on_reaction_add(self, reaction, user): await reacted(self.bot.pg, user.id) @commands.Cog.listener() async def on_reaction_remove(self, reaction, user): await unreacted(self.bot.pg, user.id) @commands.Cog.listener() async def on_scheduled_event_create(self, event): await event_created(self.bot.pg, event.creator.id) @commands.Cog.listener() async def on_scheduled_event_user_add(self, event, user): await event_joined(self.bot.pg, user.id) @commands.Cog.listener() async def on_scheduled_event_user_remove(self, event, user): await event_parted(self.bot.pg, user.id) @commands.Cog.listener() async def on_thread_create(self, thread): await thread_created(self.bot.pg, thread.owner.id) @commands.Cog.listener() async def on_thread_delete(self, thread): await thread_deleted(self.bot.pg, thread.owner.id) @commands.Cog.listener() async def on_thread_member_join(self, member: discord.User): await joined_thread(self.bot.pg, member.id) @commands.Cog.listener() async def on_thread_member_remove(self, member: discord.User): await left_thread(self.bot.pg, member.id) # @commands.command(name="snipe") # async def snipe(self, ctx: commands.Context): # Undelete last deleted message # """A command to snipe delete messages.""" # if not self.last_deteled_msg: # on_message_delete hasn't been triggered since the bot started # await ctx.send("There is no message to snipe!") # return # # author = self.last_deleted_msg.author # content = self.last_deleted_msg.content # # embed = discord.Embed(title=f"Message from {author}", description=content) # await ctx.send(embed=embed)