feat(bot): add recurring events
This commit is contained in:
parent
99a0a15b9c
commit
bf693dea0e
4 changed files with 64 additions and 37 deletions
|
@ -1,7 +1,5 @@
|
|||
DISCORD_TOKEN="DISCORT_BOT_TOKEN"
|
||||
CHANNEL_ID="DISCORD_CHANNEL_ID"
|
||||
GITHUB_TOKEN="GITHUB_TOKEN_TO_PUSH_TO_MAIN"
|
||||
REPO_OWNER="netz39"
|
||||
REPO_NAME="wwww.netz39.de"
|
||||
BASE_BRANCH="main"
|
||||
MAINTAINERS='[DISCORD_IDS_OF_BRANCH_MAINTAINERS]'
|
||||
BASE_BRANCH="main"
|
11
Dockerfile
Normal file
11
Dockerfile
Normal file
|
@ -0,0 +1,11 @@
|
|||
FROM python:3
|
||||
|
||||
RUN mkdir /source
|
||||
|
||||
COPY ./bot.py ./github_connector.py ./requirements.txt /source/
|
||||
|
||||
WORKDIR /source
|
||||
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
CMD [ "python3", "bot.py" ]
|
75
bot.py
75
bot.py
|
@ -1,7 +1,10 @@
|
|||
import json
|
||||
import re
|
||||
|
||||
# import sys
|
||||
|
||||
# needs the following version of discord.py for recurring events to work: https://github.com/DA-344/d.py/tree/recurrent_events
|
||||
# sys.path.insert(1, path_to_discorpy_version)
|
||||
import discord
|
||||
from discord.ext import commands, tasks
|
||||
from dotenv import load_dotenv
|
||||
|
@ -10,10 +13,6 @@ from github_connector import create_or_update_file, delete_file, similar_exists
|
|||
|
||||
|
||||
load_dotenv("./.env")
|
||||
|
||||
CHANNEL_ID = int(getenv("CHANNEL_ID"))
|
||||
GUILD_ID = int(getenv("GUILD_ID"))
|
||||
MAINTAINERS = json.loads(getenv("MAINTAINERS"))
|
||||
DISCORD_TOKEN = getenv("DISCORD_TOKEN")
|
||||
|
||||
# Intents are required to listen to events like messages
|
||||
|
@ -36,44 +35,45 @@ def getFilePath(event):
|
|||
|
||||
|
||||
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 frequency: "{event.recurrence_rule.frequency}"\n interval: {event.recurrence_rule.interval} ---'
|
||||
if hasattr(event.recurrence_rule, "frequency") and hasattr(
|
||||
event.recurrence_rule, "interval"
|
||||
):
|
||||
return f'---\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 frequency: "{event.recurrence_rule.frequency}"\n interval: {event.recurrence_rule.interval}\n---\n<!-- event imported from discord manual changes may be overwritten -->'
|
||||
else:
|
||||
return f'---\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---\n<!-- event imported from discord manual changes may be overwritten -->'
|
||||
|
||||
|
||||
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)
|
||||
def getAdmins(guild):
|
||||
admins = []
|
||||
for member in guild.members:
|
||||
if member.guild_permissions.administrator:
|
||||
admins.append(member.id)
|
||||
return admins
|
||||
|
||||
|
||||
@tasks.loop(hours=24) # Runs every 7 days
|
||||
async def check_events():
|
||||
await bot.wait_until_ready()
|
||||
guild = bot.get_guild(GUILD_ID)
|
||||
channel = guild.get_channel(CHANNEL_ID)
|
||||
|
||||
if not channel:
|
||||
return
|
||||
|
||||
scheduledEvents = await guild.fetch_scheduled_events()
|
||||
for event in scheduledEvents:
|
||||
await handleEvent(event)
|
||||
for guild in bot.guilds:
|
||||
scheduledEvents = await guild.fetch_scheduled_events()
|
||||
for event in scheduledEvents:
|
||||
await handleEvent(event)
|
||||
|
||||
|
||||
async def handleEvent(event):
|
||||
guild = event.guild
|
||||
channel = guild.system_channel
|
||||
admins = getAdmins(guild)
|
||||
|
||||
eventYML = getEventYML(event)
|
||||
file_path = getFilePath(event)
|
||||
commit_message = getCommitMessage(event)
|
||||
if event.creator_id in MAINTAINERS or similar_exists(event.name):
|
||||
if event.creator_id in admins or similar_exists(event.name):
|
||||
create_or_update_file(
|
||||
file_path,
|
||||
eventYML,
|
||||
f"new event: {commit_message}",
|
||||
)
|
||||
channel = bot.get_channel(CHANNEL_ID)
|
||||
await channel.send(
|
||||
f"📅 New event '{event.name}' on {event.start_time.strftime("%Y-%m-%d")}."
|
||||
)
|
||||
|
@ -88,10 +88,10 @@ async def handleEvent(event):
|
|||
},
|
||||
indent=2,
|
||||
)
|
||||
for maintainer in MAINTAINERS:
|
||||
for admin in admins:
|
||||
user = await bot.fetch_user(event.creator_id)
|
||||
await sendDm(
|
||||
maintainer,
|
||||
admin,
|
||||
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}```",
|
||||
)
|
||||
|
||||
|
@ -113,14 +113,17 @@ async def hello(ctx):
|
|||
@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! 📅")
|
||||
for guild in bot.guilds:
|
||||
system_channel = guild.system_channel
|
||||
if system_channel:
|
||||
await system_channel.send("Hello everyone! I'm online and ready to go! 📅")
|
||||
await check_events()
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_scheduled_event_update(event):
|
||||
await handleEvent(event)
|
||||
if event.status != "canceled":
|
||||
await handleEvent(event)
|
||||
|
||||
|
||||
@bot.event
|
||||
|
@ -135,14 +138,18 @@ async def sendDm(userID, message):
|
|||
|
||||
@bot.event
|
||||
async def on_reaction_add(reaction, user):
|
||||
if not user.id in MAINTAINERS:
|
||||
message = reaction.message
|
||||
channel = message.channel
|
||||
guild = message.guild
|
||||
|
||||
admins = getAdmins(guild)
|
||||
if not user.id in admins:
|
||||
return # Ignore non-maintainers
|
||||
if user.bot:
|
||||
return # Ignore bot reactions
|
||||
|
||||
if (
|
||||
isinstance(reaction.message.channel, discord.DMChannel)
|
||||
and reaction.message.author.bot
|
||||
isinstance(message.channel, discord.DMChannel) and message.author.bot
|
||||
): # Check if it's a DM and from the bot
|
||||
if reaction.emoji == "👍":
|
||||
messageJSON = json.loads(
|
||||
|
@ -155,7 +162,6 @@ async def on_reaction_add(reaction, user):
|
|||
messageJSON["yml"],
|
||||
f"new event: {messageJSON["fileName"]}",
|
||||
)
|
||||
channel = bot.get_channel(CHANNEL_ID)
|
||||
await channel.send(
|
||||
f"📅 New event '{messageJSON["name"]}' on {messageJSON["date"]}."
|
||||
)
|
||||
|
@ -164,7 +170,8 @@ async def on_reaction_add(reaction, user):
|
|||
@bot.event
|
||||
async def on_scheduled_event_delete(event):
|
||||
delete_file(getFilePath(event))
|
||||
channel = bot.get_channel(CHANNEL_ID)
|
||||
guild = event.guild
|
||||
channel = guild.system_channel
|
||||
await channel.send(f"❌ Event has been canceled: {event.name}")
|
||||
|
||||
|
||||
|
|
11
docker-compose.yml
Normal file
11
docker-compose.yml
Normal file
|
@ -0,0 +1,11 @@
|
|||
version: "3.5"
|
||||
|
||||
services:
|
||||
posthorn:
|
||||
image: 0ry5/posthorn:latest
|
||||
environment:
|
||||
- DISCORD_TOKEN=ADD_DISCORD_BOT_TOKEN_ID
|
||||
- GITHUB_TOKEN=GITHUB_REPO_TOKEN
|
||||
- REPO_OWNER=OrysB
|
||||
- REPO_NAME=www.netz39.de
|
||||
- BASE_BRANCH=main
|
Loading…
Add table
Reference in a new issue