Add Discord bot skeleton framework.

This commit is contained in:
Jack Hadrill 2020-06-01 18:45:55 +01:00
parent 4817ec2021
commit 8a89367e88
9 changed files with 159 additions and 0 deletions

0
CalBot/__init__.py Normal file
View File

View File

@ -0,0 +1,3 @@
from .discord_client import DiscordClient
__all__ = ["DiscordClient"]

View File

@ -0,0 +1,85 @@
import discord
from asyncio import Queue, create_task
import concurrent.futures
"""
Abstraction around the Discord client library
"""
class DiscordClient(discord.Client):
def __init__(self):
super().__init__()
self._commands = {}
self._queue = Queue()
self.bg_task = self.loop.create_task(self._send_loop())
def add_command(self, command, responder):
"""
Add a command.
:param command: The command prefix. For example, '!command'.
:param responder: The function that responds to the message. This can return either a string, an embed or None.
"""
self._commands[command] = responder
async def on_message(self, message):
"""
Called whenever a message is sent to a Discord channel that ButlerBot can read.
This overrides on_message() from discord.py.
:param message: The message sent by the user.
"""
# Don't listen to messages coming from ButlerBot.
if message.author == self.user:
return
# Check if message matches any of the supported command prefixes.
for command, responder in self._commands.items():
command_prefix = message.content.split(' ')[0]
if command_prefix == command:
await self._do_command(responder, message)
async def _do_command(self, responder, message):
"""
Respond to a command.
:param responder: The function that responds to the message.
:param message: The message sent by the user.
"""
# Some commands take a while. Let users know by showing the Discord typing indicator.
with concurrent.futures.ThreadPoolExecutor() as pool:
response_placeholder = await message.channel.send(content=":hourglass: **Command in progress...**")
await message.channel.trigger_typing()
response = await self.loop.run_in_executor(pool, responder, message)
await response_placeholder.delete()
if response is None:
pass
elif isinstance(response, discord.Embed):
await message.channel.send(embed=response)
else:
await message.channel.send(content=response)
def queue_message(self, channel, message):
"""
Queues a message to be sent.
:param channel: The channel in which the message will be sent.
:param message: The message to be sent. This can be eiher a string or an embed.
"""
self._queue.put_nowait((channel, message))
async def _send_loop(self):
"""
Sends queued messages.
"""
await self.wait_until_ready()
while True:
channel, message = await self._queue.get()
if channel is not None and message is not None:
if isinstance(message, discord.Embed):
await channel.send(embed=message)
else:
await channel.send(content=message)
self._queue.task_done()

14
CalBot/main.py Normal file
View File

@ -0,0 +1,14 @@
from CalBot.discord import DiscordClient
from CalBot.reminder import Reminder
def main():
client = DiscordClient()
Reminder(client)
client.run("YOURDISCORDBOTTOKENYy.XlQ5bA.PvDElVz0dzxiSfMHb693WBuOb2E")
if __name__ == "__main__":
main()

View File

@ -0,0 +1 @@
from .reminder import *

View File

@ -0,0 +1,15 @@
import discord
import socket
from CalBot.discord import DiscordClient
class Reminder():
def __init__(self, client):
self._discord = client
self._discord.add_command('!reminder', self._parse_command)
def _parse_command(self, command):
embed = discord.Embed(color=0x00ff00)
embed.set_image(url='https://media.discordapp.net/attachments/506852356898422797/715690132883111996/Capture.PNG')
return embed

View File

@ -1,2 +1,13 @@
# CalBot
Use a Python 3.8 venv. Install using...
```bash
python38 -m venv venv
source venv/bin/activate
pip install .
```
Run using...
```
calbot
```

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
.

29
setup.py Normal file
View File

@ -0,0 +1,29 @@
#!/usr/bin/env python3
from setuptools import setup, find_packages
with open('LICENSE') as f:
license = f.read()
setup(
name='calbot',
version='0.1',
description='A Discord bot for Callum',
author='Jack Hadrill',
author_email='',
url='https://git.jacknet.io/jackhadrill/CalBot',
license=license,
packages=[
'CalBot',
'CalBot.discord',
'CalBot.reminder',
],
entry_points={
'console_scripts' : [
'calbot = CalBot.main:main'
]
},
install_requires=[
'discord.py>=1.3.1',
]
)