Add Discord bot skeleton framework.
This commit is contained in:
parent
4817ec2021
commit
8a89367e88
|
@ -0,0 +1,3 @@
|
|||
from .discord_client import DiscordClient
|
||||
|
||||
__all__ = ["DiscordClient"]
|
|
@ -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()
|
|
@ -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()
|
|
@ -0,0 +1 @@
|
|||
from .reminder import *
|
|
@ -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
|
11
README.md
11
README.md
|
@ -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
|
||||
```
|
|
@ -0,0 +1 @@
|
|||
.
|
|
@ -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',
|
||||
]
|
||||
)
|
Loading…
Reference in New Issue