diff --git a/.env.sample b/.env.sample index 4697ead..5731ff5 100644 --- a/.env.sample +++ b/.env.sample @@ -1 +1,3 @@ -DISCORD_TOKEN='' \ No newline at end of file +DISCORD_TOKEN='' + +GUILD_ID='' \ No newline at end of file diff --git a/discord-bot/main.py b/discord-bot/main.py index 6ac2c95..9c8977d 100644 --- a/discord-bot/main.py +++ b/discord-bot/main.py @@ -1,34 +1,67 @@ -import os import time +import datetime import discord -from discord.ext import commands -from dotenv import load_dotenv +from discord import app_commands +from utility import get_env_variable + + +# Code inpired from: https://github.com/therealOri/TheAdministrator/blob/c2e74191eef7cf20960e23cb27e5b6004145045c/admin.py#L122 +# +++++++++++ Client Setup +++++++++++ # +class Bot(discord.Client): + def __init__(self, *, intents: discord.Intents): + guild_id = get_env_variable('GUILD_ID', required=True) + + super().__init__(intents=intents) + self.tree = app_commands.CommandTree(self) + self.guild = discord.Object(id=guild_id) + + async def setup_hook(self): + # This copies the global commands over to your guild. + self.tree.copy_global_to(guild=self.guild) + await self.tree.sync(guild=self.guild) + -load_dotenv() -def load_discord_token(): - try: - return os.environ["DISCORD_TOKEN"] - except KeyError: - raise NameError("DISCORD_TOKEN env does not exist. Unable to proceed.") intents = discord.Intents.default() -intents.messages = True intents.message_content = True +bot = Bot(intents=intents) +# +++++++++++ Client Setup +++++++++++ # + +@bot.tree.command(description='Shows you what commands you can use.') +async def help(interaction: discord.Interaction): + gold_colour = 0xFFD700 + PREFIX = '\u200B\n' # 'Zero Width Space' & 'New Line' + embed = discord.Embed(title='Commands | Help\n-=-=-=-=-=-=-=-=-=-=-=-=-=-', colour=gold_colour) + embed.set_thumbnail(url=bot.user.display_avatar.url) + embed.add_field(name=PREFIX + '/message ', value="Order me to send a message", inline=False) + embed.add_field(name=PREFIX + '/thread ', value="Order me to create a thread in current channel", inline=False) + embed.add_field(name=PREFIX + '/ping', value="Check my reflexes.", inline=True) + embed.add_field(name=PREFIX + '/github', value="I'll give a link to my source code.", inline=True) + await interaction.response.send_message(embed=embed, ephemeral=True) + +@bot.tree.command(description='Check the latency of the bot.') +async def ping(interaction: discord.Interaction): + await interaction.response.send_message(f"⏱️ Pong! ⏱️\nConnection speed is {round(bot.latency * 1000)}ms", ephemeral=True) + +@bot.tree.command(description='Get link to the GitHub repository.') +async def github(interaction: discord.Interaction): + github_url = 'https://github.com/SERLatBTH/discord' + view = discord.ui.View() + button = discord.ui.Button(label='GitHub Repository', url=github_url, style=discord.ButtonStyle.link) + view.add_item(button) + await interaction.response.send_message(view=view, ephemeral=True) -# Define the command prefix -bot = commands.Bot(command_prefix='$', intents=intents) -tree = bot.tree +@bot.tree.command(description='Send a message to the channel.') +async def message(interaction: discord.Interaction, content: str): + await interaction.response.send_message(content, ephemeral=True) -@bot.event -async def on_ready(): - print(f'Bot is ready. Logged in as {bot.user}') - await tree.sync() +@bot.tree.command(description='Create a thread in the current channel.') +async def thread(interaction: discord.Interaction, name: str): + thread = await interaction.channel.create_thread(name=name, auto_archive_duration=60) + await interaction.response.send_message(f"Thread created: {thread.mention} or {thread.jump_url}", ephemeral=True) -@tree.command(name='test', description='Test command') -async def test(interaction: discord.Integration): - await interaction.response.send_message('Test command works!') if __name__ == '__main__': - token = load_discord_token() - bot.run(token) + token = get_env_variable('DISCORD_TOKEN', required=True) + bot.run(token, reconnect=True) print('Bot exited on ' + time.strftime('%Y-%m-%d %H:%M:%S')) \ No newline at end of file diff --git a/discord-bot/utility.py b/discord-bot/utility.py new file mode 100644 index 0000000..4d88549 --- /dev/null +++ b/discord-bot/utility.py @@ -0,0 +1,26 @@ +import os +from dotenv import load_dotenv + +load_dotenv() + + +def get_env_variable(name, default=None, required=False): + """Get an environment variable or raise an error if required and missing. + + Args: + name (str): The name of the environment variable. + default (any, optional): The default value to return if the variable is not set. Defaults to None. + required (bool, optional): If True, raises an error if the variable is missing. Defaults to False. + + Returns: + str: The value of the environment variable. + + Raises: + NameError: If the required variable is missing. + """ + try: + return os.environ[name] + except KeyError: + if required: + raise NameError(f"{name} environment variable is missing and is required.") + return default