Skip to content

Commit

Permalink
Merge pull request #1 from compsci-adl/slash-command
Browse files Browse the repository at this point in the history
feat: Use slash commands
  • Loading branch information
rayokamoto authored May 19, 2024
2 parents 26dc179 + 155371b commit 8c328d9
Show file tree
Hide file tree
Showing 15 changed files with 800 additions and 205 deletions.
2 changes: 2 additions & 0 deletions .example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
GUILD_ID=GUILD_ID
BOT_TOKEN="BOT_TOKEN"
34 changes: 34 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Format Code

on:
pull_request:
branches:
- '*'
push:
branches: [main]

jobs:
black:
name: Black
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install poetry
poetry install
- name: Format code with Black
run: poetry run black .

- name: Check for changes
run: git diff --exit-code
48 changes: 41 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,47 @@
# DuckBot

## Running
DuckBot is a Discord bot written in Python using the discord.py library for the CS Club's Discord Server. It provides various commands and functionality to enhance your Discord server experience.

Add the Discord bot token in the `.env` file.
## Getting Started

```
BOT_TOKEN="YOUR_TOKEN_HERE"
```
To get started, please follow these steps:

Make sure you have the dependencies installed as well. They are listed in `requirements.txt`. Copy `example.config.json` and rename to `config.json`. Edit the values in the config file accordingly.
1. Install Poetry if not already installed:

The entry point of the bot is `main.py`.
Linux, macOS, Windows (WSL)
```bash
curl -sSL https://install.python-poetry.org | python3 -
```
Windows (Powershell)
```bash
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -
```

2. Install the dependencies.

```bash
poetry install
```

3. Copy `.env.example` to a new file `.env` and set required environment variables.

4. Navigate to the src directory

```bash
cd src
```

5. Run the bot.

```bash
poetry run python main.py
```

## Contributing

We welcome contributions to enhance Duckbot! If you find any issues, have suggestions, or want to request a feature, please follow our [Contributing Guidelines](https://github.com/compsci-adl/.github/blob/main/CONTRIBUTING.md).

## License

This project is licensed under the MIT License.
See [LICENSE](LICENSE) for details.
601 changes: 601 additions & 0 deletions poetry.lock

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[tool.poetry]
name = "duckbot"
version = "0.1.0"
description = "DuckBot is the CS Club's Discord Bot, created by the CS Club Open Source Team."
authors = ["CS Club Open Source Team <[email protected]>"]
license = "MIT"
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"
"discord.py" = "2.3.2"
python-dotenv = "1.0.0"
black = "^24.4.2"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

2 changes: 0 additions & 2 deletions requirements.txt

This file was deleted.

18 changes: 18 additions & 0 deletions src/commands/hi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from discord import app_commands, Interaction


class HiGroup(app_commands.Group):
def __init__(self):
super().__init__(name="hi", description="Commands to greet users")

@app_commands.command(name="me", description="Say hi to you.")
async def me(self, interaction: Interaction):
user = interaction.user
await interaction.response.send_message(f"Hi {user.mention}!")

@app_commands.command(name="there", description="Say hi.")
async def there(self, interaction: Interaction):
await interaction.response.send_message("Hi there!")


hi_group = HiGroup()
91 changes: 0 additions & 91 deletions src/duckbot.py

This file was deleted.

5 changes: 0 additions & 5 deletions src/example.config.json

This file was deleted.

92 changes: 86 additions & 6 deletions src/main.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,88 @@
"""
Entrypoint for the bot
"""
import os
import importlib
import pkgutil
from discord import Intents, app_commands, Object, Interaction, Embed, Message, Color
from discord.ext import commands
from dotenv import load_dotenv

import duckbot
# Load environment variables from .env file
load_dotenv()

if __name__ == "__main__":
duckbot.run()
# Retrieve guild ID and bot token from environment variables
GUILD_ID = os.getenv("GUILD_ID")
BOT_TOKEN = os.getenv("BOT_TOKEN")

# Load the permissions the bot has been granted in the previous configuration
intents = Intents.default()
intents.message_content = True


class DuckBot(commands.Bot):
def __init__(self):
super().__init__(command_prefix="", intents=intents)
self.synced = False # Make sure that the command tree will be synced only once

async def setup_hook(self):
# Dynamically load all command groups from the commands directory
for _, module_name, _ in pkgutil.iter_modules(["commands"]):
module = importlib.import_module(f"commands.{module_name}")
for attribute_name in dir(module):
attribute = getattr(module, attribute_name)
if isinstance(attribute, app_commands.Group):
self.tree.add_command(attribute, guild=Object(GUILD_ID))

if not self.synced: # Check if slash commands have been synced
await self.tree.sync(guild=Object(GUILD_ID))
self.synced = True

async def on_ready(self):
print(f"Say hi to {self.user}!")


client = DuckBot()


@client.tree.command(description="Pong!", guild=Object(GUILD_ID))
async def ping(interaction: Interaction):
await interaction.response.send_message("Pong!")


@client.tree.command(
description="View useful information about using the bot.",
guild=Object(GUILD_ID),
)
async def help(interaction: Interaction):
commands = list(client.tree.get_commands(guild=Object(GUILD_ID)))
embed = Embed(
title="DuckBot",
description="DuckBot is the CS Club's Discord bot, created by the CS Club Open Source Team.",
color=Color.yellow(),
)
for command in commands:
if isinstance(command, app_commands.Group):
# Add the group name
embed.add_field(
name=f"/{command.name}", value=f"{command.description}", inline=False
)
# Add each subcommand in the group
for subcommand in command.commands:
embed.add_field(
name=f"/{command.name} {subcommand.name}",
value=subcommand.description,
inline=True,
)
else:
embed.add_field(
name=f"/{command.name}", value=command.description, inline=False
)
await interaction.response.send_message(embed=embed)


# Ignore non-slash commands
@client.event
async def on_message(message: Message):
pass


# Add the token of bot
client.run(BOT_TOKEN)
14 changes: 0 additions & 14 deletions src/modules/chat.py

This file was deleted.

14 changes: 0 additions & 14 deletions src/modules/info.py

This file was deleted.

27 changes: 0 additions & 27 deletions src/modules/test.py

This file was deleted.

Loading

0 comments on commit 8c328d9

Please sign in to comment.