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
|
# 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