import discord import io import re import sys SPOILER_REGEX = re.compile(r'spoil|\bcw\b', re.IGNORECASE) intents = discord.Intents.default() intents.message_content = True client = discord.Client(intents=intents) def mentions_me(message): return client.user in message.mentions or [client.user] in [role.members for role in message.role_mentions] @client.event async def on_ready(): print('logged in as {0.user}'.format(client), file=sys.stderr) @client.event async def on_message(message): if message.author == client.user: return if ((SPOILER_REGEX.search(message.content) or mentions_me(message)) and message.attachments and not any(a.is_spoiler() for a in message.attachments)): pluralkit = False if message.webhook_id is not None: try: webhook = await client.fetch_webhook(message.webhook_id) except discord.Forbidden as e: print('error fetching message webhook: {0}'.format(e), file=sys.stderr) await message.channel.send("I can't inspect the webhook on this message because I don't have the permissions I need. This is important so I can interact properly with messages sent by PluralKit. Admins, please make sure I have the Manage Webhooks permission in all channels where people want to use me.") return except discord.DiscordException as e: print('error fetching message webhook: {0}'.format(e), file=sys.stderr) return if webhook.user is not None and webhook.user.name == "PluralKit": pluralkit = True # If this is a message that's being reposted by PluralKit, # assume we already caught and reposted the original, and # just delete this one without reposting a spoilered version if not pluralkit: attachments = [] try: for a in message.attachments: f = await a.to_file() f.filename = 'SPOILER_' + f.filename attachments.append(f) except discord.DiscordException as e: print('error reading attachments: {0}'.format(e), file=sys.stderr) return try: spoilered_message = await message.channel.send("{0} says: {1}".format(message.author.mention, message.content), files=attachments) try: await spoilered_message.add_reaction('❌') except discord.DiscordException as e: print('error reacting to message: {0}'.format(e)) except discord.DiscordException as e: print('error sending message: {0}'.format(e), file=sys.stderr) return try: await message.delete() except discord.Forbidden as e: print('error deleting message: {0}'.format(e)) await message.channel.send("I can't delete the original unspoiled message because I don't have the permissions I need. Admins, please make sure I have the Manage Messages permission in all channels where people want to use me.") return except discord.DiscordException as e: print('error deleting message: {0}'.format(e)) return elif mentions_me(message): await message.channel.send("upload an image and put 'spoil' or 'cw' (doesn't have to be lowercase) anywhere in the description, and I'll spoiler it for you. to delete your post, add a :x: react to it.") @client.event async def on_reaction_add(reaction, user): if (reaction.message.author == client.user and str(reaction.emoji) == '❌' and reaction.message.content.startswith('{0} says: '.format(user.mention))): try: await reaction.message.delete() except discord.DiscordException as e: print('error deleting my own message: {0}'.format(e)) with open('token') as f: token = f.read().strip() client.run(token)