import json import re import discord from discord.ext import commands from dotenv import load_dotenv from os import getenv from github_connector import create_or_update_file, delete_file load_dotenv("./.env") CHANNEL_ID = int(getenv("CHANNEL_ID")) MAINTAINERS = json.loads(getenv("MAINTAINERS")) DISCORD_TOKEN = getenv("DISCORD_TOKEN") print(MAINTAINERS) # Intents are required to listen to events like messages intents = discord.Intents.default() intents.message_content = True intents.members = True intents.reactions = True intents.dm_messages = True # Create an instance of the Bot bot = commands.Bot(command_prefix="!", intents=intents) def getFileName(event): return f"{event.start_time.strftime("%Y-%m-%d")}_{event.name}" def getFilePath(event): return f"_events/{event.start_time.strftime("%Y")}/discord-event-{event.id}.md" def getEventYML(event): return f'# event imported from discord manual changes may be overwritten\n---\n \nlayout: event\ntitle: "{event.name}"\nauthor: "Netz39 e.V." \nevent:\n start: {event.start_time.strftime("%Y-%m-%d %H:%M:%S")} \n end: {event.end_time.strftime("%Y-%m-%d %H:%M:%S")} \n organizer: "Netz39 Team <kontakt@netz39.de>" \n location: "Leibnizstr. 18, 39104 Magdeburg"\n---' def addMaintainer(maintainer): MAINTAINERS.append(maintainer) with open(".env", "r") as fileR: # read a list of lines into data data = fileR.readlines() data[6] = f"MAINTAINERS='{json.dumps(MAINTAINERS)}'" with open(".env", "w") as fileW: fileW.writelines(data) async def handleEvent(event): eventYML = getEventYML(event) if "netz39" in event.location.lower() or ( "leibniz" in event.location.lower() and "18" in event.location ): if event.creator_id in MAINTAINERS: create_or_update_file( getFilePath(event), eventYML, f"new event: {getFileName(event)}", ) channel = bot.get_channel(CHANNEL_ID) await channel.send( f"📅 New event '{event.name}' on {event.start_time.strftime("%Y-%m-%d")}." ) else: eventJSON = json.dumps( { "yml": eventYML, "path": getFilePath(event), "fileName": getFileName(event), "name": event.name, "date": event.start_time.strftime("%Y-%m-%d"), }, indent=2, ) for maintainer in MAINTAINERS: user = await bot.fetch_user(event.creator_id) await sendDm( maintainer, f"{user.name} added a new Event on {event.start_time.strftime("%Y")}: {event.name}. Like this message to approve.\n\n\n```json\n{eventJSON}```", ) # Event: When the bot is ready @bot.event async def on_ready(): print(f"Logged in as {discord.user}") # Command: !hello @bot.command() async def hello(ctx): await ctx.send( "Hello, I am a bot to add events from discord to the Netz39 calendar on the website!" ) @bot.event async def on_ready(): print(f"Logged in as {bot.user}") channel = bot.get_channel(CHANNEL_ID) await channel.send("Hello everyone! I'm online and ready to go! 📅") @bot.event async def on_scheduled_event_update(event): await handleEvent(event) @bot.event async def on_scheduled_event_create(event): await handleEvent(event) async def sendDm(userID, message): user = await bot.fetch_user(userID) await user.send(message) @bot.event async def on_reaction_add(reaction, user): if not user.id in MAINTAINERS: return # Ignore non-maintainers if user.bot: return # Ignore bot reactions if ( isinstance(reaction.message.channel, discord.DMChannel) and reaction.message.author.bot ): # Check if it's a DM and from the bot if reaction.emoji == "👍": messageJSON = json.loads( re.search( "(?s)(?<=```json).*?(?=```)", reaction.message.content ).group() ) create_or_update_file( messageJSON["path"], messageJSON["yml"], f"new event: {messageJSON["fileName"]}", ) channel = bot.get_channel(CHANNEL_ID) await channel.send( f"📅 New event '{messageJSON["name"]}' on {messageJSON["date"]}." ) @bot.event async def on_message(message): if isinstance(message.channel, discord.DMChannel): global MAINTAINERS author = message.author if "add maintainer" in message.content.lower() and author.id in MAINTAINERS: newMaintainer = message.content.lower().replace("add maintainer ", "") if not newMaintainer in MAINTAINERS: addMaintainer(int(newMaintainer)) await sendDm( newMaintainer, "You are now a Maintainer for posthorn! Create an event located at 'Netz39 e.V.' and it will be added to the calendar.", ) await message.channel.send("Maintainer added!") await bot.process_commands(message) @bot.event async def on_scheduled_event_delete(event): delete_file(getFilePath(event)) channel = bot.get_channel(CHANNEL_ID) await channel.send(f"❌ Event has been canceled: {event.name}") bot.run(DISCORD_TOKEN)