Skip to content
Snippets Groups Projects
Commit 156fbe7f authored by dnns01's avatar dnns01
Browse files

Use slash commands for appointments

parent 378f49b1
No related branches found
No related tags found
No related merge requests found
# General
DISCORD_TOKEN=<Bot Token you can get at https://discord.com/developers/applications/>
DISCORD_ACTIVITY=<What should be shown, Bot is playing right now>
DISCORD_DATE_TIME_FORMAT=<Date and time format used for commands like %d.%m.%Y %H:%M>
\ No newline at end of file
.gitignore 100644 → 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
.idea/misc.xml 100644 → 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
.idea/vcs.xml 100644 → 100755
File mode changed from 100644 to 100755
......@@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="jdk" jdkName="Python 3.10 (xanathar)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
......@@ -5,7 +5,7 @@ import json
import os
import uuid
import discord
from discord import app_commands, errors, Embed, File, Interaction
from discord.ext import tasks, commands
import utils
......@@ -52,7 +52,8 @@ def get_ics_file(title, date_time, reminder, recurring):
return ics_file
class Appointments(commands.Cog):
@app_commands.guild_only()
class Appointments(commands.GroupCog, name="appointments", description="Handle Appointments in Channels"):
def __init__(self, bot):
self.bot = bot
self.fmt = os.getenv("DISCORD_DATE_TIME_FORMAT")
......@@ -84,15 +85,15 @@ class Appointments(commands.Cog):
message = await channel.fetch_message(int(message_id))
reactions = message.reactions
diff = int(round(((date_time - now).total_seconds() / 60), 0))
answer = f"Benachrichtigung!\nDer Termin \"{appointment['title']}\" ist "
answer = f"Benachrichtigung!\nDer Termin \"{appointment['title']}\" startet "
if appointment["reminder"] > 0 and diff > 0:
answer += f"startet <t:{int(date_time.timestamp())}:R>."
answer += f"<t:{int(date_time.timestamp())}:R>."
if (reminder := appointment.get("reminder")) and appointment.get("recurring"):
appointment["original_reminder"] = str(reminder)
appointment["original_reminder"] = reminder
appointment["reminder"] = 0
else:
answer += f"jetzt fällig. :loudspeaker: "
answer += f"jetzt!!! :loudspeaker: "
delete.append(message_id)
answer += f"\n"
......@@ -106,7 +107,7 @@ class Appointments(commands.Cog):
if str(message.id) in delete:
await message.delete()
except discord.errors.NotFound:
except errors.NotFound:
delete.append(message_id)
if len(delete) > 0:
......@@ -125,7 +126,7 @@ class Appointments(commands.Cog):
await self.add_appointment(channel, channel_appointment["author_id"],
splitted_new_date_time_str[0],
splitted_new_date_time_str[1],
str(reminder),
reminder,
channel_appointment["title"],
channel_appointment["recurring"])
channel_appointments.pop(key)
......@@ -135,9 +136,16 @@ class Appointments(commands.Cog):
async def before_timer(self):
await asyncio.sleep(60 - datetime.datetime.now().second)
@commands.command(name="add-appointment")
async def cmd_add_appointment(self, ctx, date, time, reminder, title, recurring: int = None):
await self.add_appointment(ctx.channel, ctx.author.id, date, time, reminder, title, recurring)
@app_commands.command(name="add", description="Füge dem Kanal einen neuen Termin hinzu.")
@app_commands.describe(date="Tag des Termins", time="Uhrzeit des Termins",
reminder="Wie viele Minuten bevor der Termin startet, soll eine Erinnerung verschickt werden?",
title="Titel des Termins",
recurring="In welchem Intervall (in Tagen) soll der Termin wiederholt werden?")
async def cmd_add_appointment(self, interaction: Interaction, date: str, time: str, reminder: int, title: str,
recurring: int = None):
""" Add an appointment to a channel """
await self.add_appointment(interaction.channel, interaction.user.id, date, time, reminder, title, recurring)
await interaction.response.send_message("Termin erfolgreich erstellt!", ephemeral=True)
async def add_appointment(self, channel, author_id, date, time, reminder, title, recurring: int = None):
""" Add appointment to a channel """
......@@ -148,17 +156,11 @@ class Appointments(commands.Cog):
await channel.send("Fehler! Ungültiges Datums und/oder Zeit Format!")
return
if not utils.is_valid_time(reminder):
await channel.send("Fehler! Benachrichtigung in ungültigem Format!")
return
else:
reminder = utils.to_minutes(reminder)
embed = discord.Embed(title="Neuer Termin hinzugefügt!",
description=f"Wenn du eine Benachrichtigung zum Beginn des Termins"
f"{f', sowie {reminder} Minuten vorher, ' if reminder > 0 else f''} "
f"erhalten möchtest, reagiere mit :thumbsup: auf diese Nachricht.",
color=19607)
embed = Embed(title="Neuer Termin hinzugefügt!",
description=f"Wenn du eine Benachrichtigung zum Beginn des Termins"
f"{f', sowie {reminder} Minuten vorher, ' if reminder > 0 else f''} "
f"erhalten möchtest, reagiere mit :thumbsup: auf diese Nachricht.",
color=19607)
embed.add_field(name="Titel", value=title, inline=False)
embed.add_field(name="Startzeitpunkt", value=f"{date_time.strftime(self.fmt)}", inline=False)
......@@ -167,8 +169,8 @@ class Appointments(commands.Cog):
if recurring:
embed.add_field(name="Wiederholung", value=f"Alle {recurring} Tage", inline=False)
message = await channel.send(embed=embed, file=discord.File(get_ics_file(title, date_time, reminder, recurring),
filename=f"{title}.ics"))
message = await channel.send(embed=embed, file=File(get_ics_file(title, date_time, reminder, recurring),
filename=f"{title}.ics"))
await message.add_reaction("👍")
await message.add_reaction("🗑️")
......@@ -181,21 +183,22 @@ class Appointments(commands.Cog):
self.save_appointments()
@commands.command(name="appointments")
async def cmd_appointments(self, ctx):
@app_commands.command(name="list", description="Listet alle Termine dieses Kanals auf.")
@app_commands.describe(show_all="Zeige die Liste für alle an.")
async def cmd_appointments_list(self, interaction: Interaction, show_all: bool = False):
""" List (and link) all Appointments in the current channel """
if str(ctx.channel.id) in self.appointments:
channel_appointments = self.appointments.get(str(ctx.channel.id))
if str(interaction.channel.id) in self.appointments:
channel_appointments = self.appointments.get(str(interaction.channel.id))
answer = f'Termine dieses Channels:\n'
delete = []
for message_id, appointment in channel_appointments.items():
try:
message = await ctx.channel.fetch_message(int(message_id))
message = await interaction.channel.fetch_message(int(message_id))
answer += f'{appointment["date_time"]}: {appointment["title"]} => ' \
f'{message.jump_url}\n'
except discord.errors.NotFound:
except errors.NotFound:
delete.append(message_id)
if len(delete) > 0:
......@@ -203,9 +206,10 @@ class Appointments(commands.Cog):
channel_appointments.pop(key)
self.save_appointments()
await ctx.channel.send(answer)
await interaction.response.send_message(answer, ephemeral=not show_all)
else:
await ctx.send("Für diesen Channel existieren derzeit keine Termine")
await interaction.response.send_message("Für diesen Channel existieren derzeit keine Termine",
ephemeral=not show_all)
def save_appointments(self):
appointments_file = open(self.app_file, mode='w')
......@@ -234,3 +238,7 @@ class Appointments(commands.Cog):
message = await channel.fetch_message(payload.message_id)
if len(message.embeds) > 0 and message.embeds[0].title == "Neuer Termin hinzugefügt!":
await self.handle_reactions(payload)
async def setup(bot: commands.Bot) -> None:
await bot.add_cog(Appointments(bot))
File mode changed from 100644 to 100755
cogs/polls.py 100644 → 100755
......@@ -11,7 +11,7 @@ class Polls(commands.Cog):
@commands.group(name="poll", pass_context=True, invoke_without_command=True)
async def cmd_poll(self, ctx, question, *answers):
""" Create poll """
""" Create a new poll """
await Poll(self.bot, question, list(answers), ctx.author.id).send_poll(ctx)
......@@ -42,3 +42,7 @@ class Polls(commands.Cog):
await poll.delete_poll()
else:
await poll.close_poll()
async def setup(bot: commands.Bot) -> None:
await bot.add_cog(Polls(bot))
utils.py 100644 → 100755
......@@ -43,11 +43,3 @@ def date_to_string(date: datetime):
def date_from_string(date: str):
return datetime.strptime(date, DATE_TIME_FMT)
async def files_from_attachments(attachments):
files = []
for attachment in attachments:
files.append(await attachment.to_file(spoiler=attachment.is_spoiler()))
return files
xanathar.py 100644 → 100755
import os
from typing import List
import discord
from discord.ext import commands
from dotenv import load_dotenv
from cogs import polls, appointments
# .env file is necessary in the same directory, that contains several strings.
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
ACTIVITY = os.getenv('DISCORD_ACTIVITY')
intents = discord.Intents.all()
bot = commands.Bot(command_prefix='!', help_command=None, activity=discord.Game(ACTIVITY), intents=intents)
help_command = commands.DefaultHelpCommand(dm_help=True)
extensions = ["cogs.appointments", "cogs.polls"]
class Xanathar(commands.Bot):
def __init__(self, *args, initial_extensions: List[str], **kwargs):
super().__init__(*args, **kwargs)
self.initial_extensions = initial_extensions
async def setup_hook(self) -> None:
for extension in self.initial_extensions:
await self.load_extension(extension)
await self.tree.sync()
@bot.event
async def on_ready():
print("Client started!")
await bot.add_cog(polls.Polls(bot))
await bot.add_cog(appointments.Appointments(bot))
bot = Xanathar(command_prefix='!', help_command=help_command, activity=discord.Game(ACTIVITY), intents=intents,
initial_extensions=extensions)
bot.run(TOKEN)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment