Esempio n. 1
0
    async def test_botAssignment(self):
        with self.assertRaises(ValueError):
            # noinspection PyTypeChecker
            AntiSpamHandler(None)

        with self.assertRaises(ValueError):
            # noinspection PyTypeChecker
            AntiSpamHandler(1)

        with self.assertRaises(ValueError):
            # noinspection PyTypeChecker
            AntiSpamHandler("1")

        with self.assertRaises(ValueError):
            # noinspection PyTypeChecker
            AntiSpamHandler({1: 2})

        with self.assertRaises(ValueError):
            # noinspection PyTypeChecker
            AntiSpamHandler([1, None])

        with self.assertRaises(ValueError):
            # noinspection PyTypeChecker
            AntiSpamHandler(True)

        with self.assertRaises(ValueError):
            # noinspection PyTypeChecker
            AntiSpamHandler(False)

        AntiSpamHandler(commands.Bot(command_prefix="!"))
        AntiSpamHandler(commands.AutoShardedBot(command_prefix="!"))
        AntiSpamHandler(discord.Client())
        AntiSpamHandler(discord.AutoShardedClient())
Esempio n. 2
0
def main():
    token = get_token()
    if len(sys.argv) > 2 and sys.argv[2] in ['-s', '-shard']:
        client = discord.AutoShardedClient()
    else:
        client = discord.Client()
    client.loop.create_task(run_debugger(client))
    client.run(token)
Esempio n. 3
0
def start(loop: asyncio.AbstractEventLoop) -> None:
    """Starts the Discord client and logs Modis into Discord.

    Args:
        loop (asyncio.AbstractEventLoop): An asyncio event loop for the bot to run on.
    """

    logger.info("Loading Modis...")

    from modis.tools import config, data, moduledb, version

    # Update data.json cache
    data.pull()

    # Check the current version
    # TODO implement version check and display
    # logger.info(version.infostr())

    # Create client
    logger.debug("Creating Discord client")
    asyncio.set_event_loop(loop)
    global client
    client = discord.AutoShardedClient()

    # Import event handlers
    logger.info("Importing modules...")
    eh_lib = moduledb.get_imports(config.EH_TYPES)

    # Register event handlers
    logger.debug("Registering event handlers")
    for eh_type in config.EH_TYPES:
        eh_list = []
        for module_name in eh_lib.keys():
            if eh_type in eh_lib[module_name].keys():
                eh_list.append(eh_lib[module_name][eh_type])
        if eh_list:
            client.event(_eh_create(eh_type, eh_list))

    # CONNECTION STACK
    logger.info("Logging in...")
    try:
        # Attempt login
        token = data.cache["keys"]["discord_token"]
        client.loop.run_until_complete(client.login(token))
    except Exception as e:
        # Login failed
        logger.critical("Login failed")
        logger.exception(e)
        statuslog.info("3")
        client.loop.close()
    else:
        # Login successful
        logger.info("Connecting...")
        client.loop.run_until_complete(client.connect(reconnect=True))
Esempio n. 4
0
def run(config: Config):
    """runs everything"""
    print("Welcome to Mandrake!")

    print("Connecting to database...")
    pool = connect_to_database(config.database_uri)
    print("Connected to database!")

    async def create_tables():
        async with pool.acquire() as conn:
            await database.create_tables(conn)

    asyncio.get_event_loop().run_until_complete(create_tables())

    client = discord.AutoShardedClient()

    @client.event
    async def on_ready():
        """when bot is connected"""
        print("Connected to Discord!\n")
        print(f"Connected as: {str(client.user)} ({str(client.user.id)})")
        print()
        await client.change_presence(activity=discord.Game(
            name="mn;help \u2014 in {} servers".format(len(client.guilds))))

    @client.event
    async def on_message(message: discord.Message):
        """when a message is received"""
        if message.author.bot:
            return

        # Grab a database connection from the pool
        async with pool.acquire() as conn:
            did_run_command = await commands.command_dispatch(
                client, message, conn, config)
            if did_run_command:
                return

    @client.event
    async def on_error(event_name, *args, **kwargs):
        """when a error occurs"""
        if not config.log_channel:
            return
        log_channel = client.get_channel(int(config.log_channel))

        traceback_str = "```python\n{}```".format(traceback.format_exc())
        if len(traceback.format_exc()) >= (2000 - len("```python\n```")):
            traceback_str = "```python\n...{}```".format(
                traceback.format_exc()[-(2000 - len("```python\n...```")):])
        await log_channel.send(content=traceback_str)

    print("Connecting to Discord. Please wait...")
    client.run(config.token)
Esempio n. 5
0
    def __init__(self, channel_name, bot_token, database):
        """
        Initialize the bot using the Discord token and channel name to chat in.

        :param channel_name: Only chats in this channel. No hashtag included.
        :param bot_token: Full secret bot token
        :param database: Path for sqlite file to use
        """
        # Store configuration values
        self.channel_name = channel_name
        self.token = bot_token
        self.database = database
        self.message_count = 0
        self.last_reset_time = datetime.now()

        logging.info("[*] Setting up signal handlers")
        signal(SIGINT, self.exit_handler)
        signal(SIGTERM, self.exit_handler)

        # Setup database
        logging.info("[*] Initializing database...")
        self.db = sqlite3.connect(self.database)
        self.cursor = self.db.cursor()
        self.setup_database_schema()
        logging.info('[+] Database initialized')

        # Load AIML kernel
        logging.info("[*] Initializing AIML kernel...")
        start_time = datetime.now()
        self.aiml_kernel = aiml.Kernel()
        self.setup_aiml()
        end_time = datetime.now()
        logging.info(
            f"[+] Done initializing AIML kernel. Took {end_time - start_time}")

        # Set up Discord
        logging.info("[*] Initializing Discord bot...")
        self.discord_bot = discord.AutoShardedClient()
        self.setup_discord_events()
        logging.info("[+] Done initializing Discord bot.")
        logging.info("[+] Exiting __init__ function.")
Esempio n. 6
0
import json
from pymongo import MongoClient
import pymongo
import random
import asyncio
import time
import os
import datetime

palavra = ["a", "b", "c"]

forms = []
prefix = ["d."]
cor = 0x32363C
client = commands.Bot(command_prefix=prefix, case_insensitive=True)
shared = discord.AutoShardedClient(shard_count=2, shard_ids=(1, 2))
client.remove_command("help")


@client.event
async def on_ready():
    print("BOT ONLINE")
    while True:
        await client.change_presence(activity=discord.Activity(
            type=discord.ActivityType.watching,
            name=f"{str(len(set(client.get_all_members())))} seres humanos!"))
        await asyncio.sleep(300)
        await client.change_presence(activity=discord.Activity(
            type=discord.ActivityType.watching,
            name=f"{str(len(set(client.guilds)))} servidores!"))
        await asyncio.sleep(300)
Esempio n. 7
0
logging.basicConfig(level=logging.INFO)
log = logging.getLogger(__name__)

# Set logging levels for external modules
logging.getLogger("requests").setLevel(logging.WARNING)
logging.getLogger("discord").setLevel(logging.INFO)
logging.getLogger("websockets.protocol").setLevel(logging.INFO)

# Config parser setup
parser = get_settings_parser()

# Loop, discord.py and Nano core modules initialization
loop = asyncio.get_event_loop()

# NOW USES AUTOSHARDING
client = discord.AutoShardedClient(loop=loop)

log.info("Initializing ServerHandler and NanoStats...")

# Setup the server data and stats
handler = ServerHandler.get_handler(loop)
stats = NanoStats(loop, *ServerHandler.get_redis_credentials())
trans = TranslationManager()


class PluginObject:
    def __init__(self, lib, instance):
        self.plugin = lib
        self.handler = getattr(lib, "NanoPlugin")

        self.instance = instance
Esempio n. 8
0
import os

import discord
import dotenv

dotenv.load_dotenv()

client = discord.AutoShardedClient(
    intents=discord.Intents(guilds=True, guild_messages=True),
    member_cache_flags=discord.MemberCacheFlags.none(),
    max_messages=0,
    activity=discord.Activity(type=discord.ActivityType.watching,
                              name="announcements"),
)


@client.event
async def on_message(message: discord.Message):
    if message.channel.type != discord.ChannelType.news:
        if message.content in {
                f"<@!{client.user.id}>", f"<@{client.user.id}>"
        }:
            app_info = await client.application_info()

            embed = discord.Embed(
                title="Printer",
                description="Auto publish bot for Discord.",
            )
            embed.add_field(
                name="Bot Owner",
                value=
Esempio n. 9
0
 def __init__(self, token, channel):
     self.token = token
     self.channel = channel
     self.discord_bot = discord.AutoShardedClient()
     self.setup_discord_events()
Esempio n. 10
0
            else:
                return io.BytesIO(await r.read())


def trim(txt, l):
    return txt[:l] + ("…" if len(txt) > l else "")


def setLength(txt, l):
    return txt[:l - 1] + ("…" if len(txt) > l else "_" * (l - len(txt)))


timedGuilds = []
timedUsers = []

bot = discord.AutoShardedClient(status=discord.Game(name=TAGLINE))
botIsReady = False


#Why the hell does this use a database? It's pointless
def getTier(id, SET="SUBSCRIBERS"):
    cur.execute(f"SELECT (teir) FROM {SET} where id = {id}")
    return j[0][0] if (j := cur.fetchall()) else False


def removeID(id, c=True, SET="SUBSCRIBERS"):
    cur.execute(f"DELETE FROM {SET} where id = {id}")
    if c:
        con.commit()

Esempio n. 11
0
import discord

client = discord.AutoShardedClient(shard_count=3)
'''
@client.event
async def on_shard_ready(shard):
    print(client.guilds)
    await client.change_presence(game=discord.Game(name=str(shard)), shard_id=shard)
'''


@client.event
async def on_ready():
    print(client.guilds)
    await client.change_presence(game=discord.Game(name='HTSTEM'), shard_id=0)
    try:
        await client.change_presence(game=discord.Game(name='HTC'), shard_id=2)
    except KeyError:
        print('Failed')


client.run('token')
Esempio n. 12
0
File: bot.py Progetto: Brayconn/Miza
import discord, os, sys, datetime, json
from smath import *

sys.path.insert(1, "commands")
sys.path.insert(1, "misc")

client = discord.AutoShardedClient(
    max_messages=4096,
    heartbeat_timeout=30,
)


class main_data:
    
    timeout = 24
    min_suspend = 3
    website = "https://github.com/thomas-xin/Miza"
    heartbeat = "heartbeat.json"
    restart = "restart.json"
    shutdown = "shutdown.json"
    suspected = "suspected.json"
    savedata = "data.json"
    authdata = "auth.json"
    client = client
    cache = {
        "guilds": {},
        "channels": {},
        "users": {},
        "messages": {},
        "deleted": {},
    }
Esempio n. 13
0
import asyncio
import discord
from src.response import ResponseGenerator
import json
from concurrent.futures import ThreadPoolExecutor
from datetime import datetime
import time

intents = discord.Intents(messages=True, guilds=True, typing = False, presences = False, members=False)
config_general=json.loads(open("config-bot.json","r").read())
client = discord.AutoShardedClient(intents=intents, chunk_guilds_at_startup=False,command_prefix=str(config_general["prefix"]))


model=ResponseGenerator("https://woz-model.herokuapp.com/v1/models/jade:predict","https://discord.com/api/webhooks/806950915449683970/-8IG5UkdBGf7jgfQ36XlfRSIUjt2V-rt-RNn9NdC3zDgfvjzMS2SEMj-XlozsXH9Ovju")

@client.event
async def on_ready():
    print('Logged in as '+client.user.name+' (ID:'+str(client.user.id)+') | Connected to '+str(len(client.guilds))+' servers')
    print('--------')
    print("Discord.py verison: " + discord.__version__)
    print('--------')
    print(str(len(client.shards))+" shard(s)")
    
@client.event
async def on_message(message):
    loop = asyncio.get_event_loop()
    
    if message.author.bot == False and message.guild != None:
        try:
            bot.process_commands(message)
        except:
def convertjson(ctx, cogs):
    """This migrates our older JSON files to PostgreSQL

    Note, this deletes all previous entries in the table
    so you can consider this to be a destructive decision.

    Do not pass in cog names with "cogs." as a prefix.

    This also connects us to Discord itself so we can
    use the cache for our migrations.

    The point of this is just to do some migration of the
    data from v3 -> v4 once and call it a day.
    """

    import data_migrators

    run = asyncio.get_event_loop().run_until_complete

    if not cogs:
        to_run = [(getattr(data_migrators, attr), attr.replace('migrate_', ''))
                  for attr in dir(data_migrators)
                  if attr.startswith('migrate_')]
    else:
        to_run = []
        for cog in cogs:
            try:
                elem = getattr(data_migrators, 'migrate_' + cog)
            except AttributeError:
                click.echo(f'invalid cog name given, {cog}.', err=True)
                return

            to_run.append((elem, cog))

    async def make_pool():
        return await asyncpg.create_pool(config.postgresql)

    try:
        pool = run(make_pool())
    except Exception:
        click.echo(
            f'Could not create PostgreSQL connection pool.\n{traceback.format_exc()}',
            err=True)
        return

    client = discord.AutoShardedClient()

    @client.event
    async def on_ready():
        click.echo(
            f'successfully booted up bot {client.user} (ID: {client.user.id})')
        await client.logout()

    try:
        run(client.login(config.token))
        run(client.connect(reconnect=False))
    except:
        pass

    extensions = ['cogs.' + name for _, name in to_run]
    ctx.invoke(init, cogs=extensions)

    for migrator, _ in to_run:
        try:
            run(migrator(pool, client))
        except Exception:
            click.echo(
                f'[error] {migrator.__name__} has failed, terminating\n{traceback.format_exc()}',
                err=True)
            return
        else:
            click.echo(f'[{migrator.__name__}] completed successfully')
Esempio n. 15
0
from io import BytesIO
import io
import datetime
import aiohttp
import copy
import sys
import time
import logging

from resizeimage import resizeimage
# pip install python-resize-image

import math

bot = discord.AutoShardedClient(shard_count=5, loop=loop)

logging.basicConfig(level=logging.INFO)

blurple = (114, 137, 218)
bluplehex = 0x7289da
darkblurple = (78, 93, 148)
white = (255, 255, 255)

allowedusers = {204778476102877187, 226595531844091904, 191602259904167936}
# put your user id here, and it will allow you to use the 'hidden' commands
# (and shutdown command)

approved_channels = {418987056111550464, 436300339273269278}

commands = dict()
Esempio n. 16
0
    send_on_member_leave,
)
from music import functions

if not variables.DEV_MODE:
    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
    logging.basicConfig(level=logging.INFO)
else:
    logging.basicConfig(level=logging.DEBUG)

loop = asyncio.get_event_loop()

client = discord.AutoShardedClient(
    loop=loop,
    proxy=variables.PROXY,
    proxy_auth=variables.PROXY_AUTH,
    activity=discord.Game(
        name=f"{variables.PREFIX}help | Playing around in 100 servers"),
)

loop.create_task(database.prepare_tables())

ONE_TIME_DONE = False


async def on_start(client):
    global ONE_TIME_DONE
    if ONE_TIME_DONE:
        return
    ONE_TIME_DONE = True
Esempio n. 17
0
def run(config: Config):
    pool = connect_to_database(config.database_uri)

    async def create_tables():
        async with pool.acquire() as conn:
            await db.create_tables(conn)

    asyncio.get_event_loop().run_until_complete(create_tables())

    client = discord.AutoShardedClient()
    logger = channel_logger.ChannelLogger(client)

    @client.event
    async def on_ready():
        print("PluralKit started.")
        print("User: {}#{} (ID: {})".format(client.user.name, client.user.discriminator, client.user.id))
        print("{} servers".format(len(client.guilds)))
        print("{} shards".format(client.shard_count or 1))

        await client.change_presence(activity=discord.Game(name="pk;help \u2014 in {} servers".format(len(client.guilds))))

    @client.event
    async def on_message(message: discord.Message):
        # Ignore messages from bots
        if message.author.bot:
            return

        # Grab a database connection from the pool
        async with pool.acquire() as conn:
            # First pass: do command handling
            did_run_command = await commands.command_dispatch(client, message, conn)
            if did_run_command:
                return

            # Second pass: do proxy matching
            await proxy.try_proxy_message(conn, message, logger, client.user)

    @client.event
    async def on_raw_message_delete(payload: discord.RawMessageDeleteEvent):
        async with pool.acquire() as conn:
            await proxy.handle_deleted_message(conn, client, payload.message_id, None, logger)

    @client.event
    async def on_raw_bulk_message_delete(payload: discord.RawBulkMessageDeleteEvent):
        async with pool.acquire() as conn:
            for message_id in payload.message_ids:
                await proxy.handle_deleted_message(conn, client, message_id, None, logger)

    @client.event
    async def on_raw_reaction_add(payload: discord.RawReactionActionEvent):
        if payload.emoji.name == "\u274c":  # Red X
            async with pool.acquire() as conn:
                await proxy.try_delete_by_reaction(conn, client, payload.message_id, payload.user_id, logger)
        if payload.emoji.name in "\u2753\u2754":  # Question mark
            async with pool.acquire() as conn:
                await proxy.do_query_message(conn, client, payload.user_id, payload.message_id)

    @client.event
    async def on_error(event_name, *args, **kwargs):
        # Print it to stderr
        logging.getLogger("pluralkit").exception("Exception while handling event {}".format(event_name))

        # Then log it to the given log channel
        # TODO: replace this with Sentry or something
        if not config.log_channel:
            return
        log_channel = client.get_channel(int(config.log_channel))

        # If this is a message event, we can attach additional information in an event
        # ie. username, channel, content, etc
        if args and isinstance(args[0], discord.Message):
            message: discord.Message = args[0]
            embed = embeds.exception_log(
                message.content,
                message.author.name,
                message.author.discriminator,
                message.author.id,
                message.guild.id if message.guild else None,
                message.channel.id
            )
        else:
            # If not, just post the string itself
            embed = None

        traceback_str = "```python\n{}```".format(traceback.format_exc())
        if len(traceback.format_exc()) >= (2000 - len("```python\n```")):
            traceback_str = "```python\n...{}```".format(traceback.format_exc()[- (2000 - len("```python\n...```")):])
        await log_channel.send(content=traceback_str, embed=embed)
    client.run(config.token)
Esempio n. 18
0
config = FileManipulator(AbstractFile("config.json"))
base_conf = {}

if getenv("TEST_ENV") != "yes":
    try:
        base_conf = config.load_from_json()
    except:
        TextCommandsUtil.noop()

g = Github(base_conf.get("tokens", {}).get("github"))
wordsapi_token = base_conf.get("tokens", {}).get("wordsapi", None)

intents = discord.Intents.default()
intents.members = True
client = discord.AutoShardedClient(intents=intents)


@client.event
async def on_ready():
    await client.change_presence(activity=discord.Game(
        name=base_conf["status"]))
    secho(
        "\nReady to roll, I'll see you on Discord: @" + str(client.user),
        fg="green",
    )


@client.event
async def on_message(message):
    BOT_PREFIX = "+"
Esempio n. 19
0
                    continue
                if msg['type'] == "file":
                    try:
                        await channel.send(msg['message'] + f' [{NAME}]',
                                           files=[discord.File(msg['file'])])
                    except Exception as e:
                        fixPrint("Couldn't send file.", e)
                    tryToDeleteFile(msg['file'])
                elif msg['type'] == "error":
                    await channel.send(msg['message'] + f' [{NAME}]')
            except Exception as e:
                print("Error in queMessages()!:", e)


while botKey == None:
    pass

bot = discord.AutoShardedClient(intents=discord.Intents())


@bot.event
async def on_ready():
    global isReady, w
    if not isReady:
        isReady = True
        await w.send(pickle.dumps({'type': 'ready'}))
        fixPrint("Sent ready.")
        await bot.loop.create_task(queMessages())


bot.run(botKey)
Esempio n. 20
0
    UserUtil,
)

config = FileManipulator(AbstractFile("config.json"))
base_conf = {}

if getenv("TEST_ENV") != "yes":
    try:
        base_conf = config.load_from_json()
    except:
        TextCommandsUtil.noop()

g = Github(base_conf.get("tokens", {}).get("github"))
wordsapi_token = base_conf.get("tokens", {}).get("wordsapi", None)

client = discord.AutoShardedClient()


@client.event
async def on_ready():
    await client.change_presence(activity=discord.Game(
        name=base_conf["status"]))
    secho(
        "\nReady to roll, I'll see you on Discord: @" + str(client.user),
        fg="green",
    )


@client.event
async def on_message(message):
    BOT_PREFIX = "+"
Esempio n. 21
0
File: start.py Progetto: PaPiix/Cube
class Application:
    def __init__(self, using_uvloop, loop):
        self.using_uvloop = using_uvloop
        self.loop = loop

    # Sets the loop info.

    def pass_user(self, server, user_string):
        try:
            if isinstance(user_string, str):
                uid = ''.join(re.findall("[0-9]", user_string))
            else:
                uid = user_string
            return server.get_member(int(uid))
        except:
            return None

    # Attempts to pass a user.

    def pass_channel(self, channel_string, server=None):
        try:
            if isinstance(channel_string, str):
                cid = int(''.join(re.findall("[0-9]", channel_string)))
            else:
                cid = channel_string
            if server is None:
                return self.dclient.get_channel(cid)
            else:
                return server.get_channel(cid)
        except:
            return None

    # Attempts to pass a channel.

    message = None
    # Sets the message to a Nonetype.

    cube_root = os.path.dirname(os.path.abspath(__file__))
    # The exact path of Cube's root folder.

    config = json.load(open(os.path.join(cube_root, "config.json"), "r"))

    # Loads the config.

    def create_embed(self, title, description="", success=False, error=False):
        if success:
            c = 0x00ff00
        elif error:
            c = 0xff0000
        else:
            c = 0x000000
        e = discord.Embed(title=title, description=description, color=c)
        e.set_footer(
            text=f'{self.config["bot_name"]} v{self.config["version"]}')
        return e

    # Creates a branded embed.

    logger = logging.getLogger(config["bot_name"].lower())

    # Sets the logger.
    async def load_mysql(self):
        self.mysql_pool = await aiomysql.create_pool(
            host=self.config["mysql_hostname"],
            user=self.config["mysql_username"],
            password=self.config["mysql_password"],
            db=self.config["mysql_db"],
            charset='utf8mb4')
        self.logger.info("Initialised MySQL. Ready to accept connections!")

    # Loads MySQL on boot.

    async def run_mysql(self, *args, **kwargs):
        async with self.mysql_pool.acquire() as conn:
            async with conn.cursor() as c:
                await c.execute(*args)
                r = None
                if kwargs.get('get_one', False):
                    r = await c.fetchone()
                elif kwargs.get('get_many', False):
                    r = await c.fetchall()
                if kwargs.get('commit', False):
                    await conn.commit()
        return r

    # Runs any MySQL scripts.

    async def attempt_log(self, server_id, *args, **kwargs):
        logging_channel = await self.run_mysql(
            "SELECT * FROM `logging_channels` WHERE `server_id` = %s",
            (server_id, ),
            get_one=True)
        if not logging_channel is None:
            c = self.dclient.get_channel(logging_channel[1])
            try:
                await c.send(*args, **kwargs)
            except:
                pass

    # Attempts to send a message to the logging channel.

    async def get_prefix(self, server_id):
        prefix_sql = await self.run_mysql(
            "SELECT * FROM `custom_prefixes` WHERE `server_id` = %s",
            (server_id, ),
            get_one=True)
        if prefix_sql is None:
            return self.config["default_prefix"]
        else:
            return prefix_sql[1]

    # Gets the prefix.

    discord_callbacks = dict()
    discord_commands = dict()
    plugins = dict()
    # Defines the dictionarys.

    dclient = discord.AutoShardedClient(loop=loop)

    # Sets the Discord client.

    def command(self,
                description="No description given.",
                requires_staff=False,
                requires_management=False,
                requires_bot_admin=False,
                name=None,
                usage=None):
        def deco(func):
            cmd_attr = {
                "description": description,
                "requires_staff": requires_staff,
                "requires_management": requires_management,
                "requires_bot_admin": requires_bot_admin,
                "usage": usage
            }
            func.cmd_attr = cmd_attr
            if name is None:
                func_name = func.__name__
            else:
                func_name = name
            if not inspect.iscoroutinefunction(func):
                raise Exception("Command not async.")
            self.discord_commands[func_name] = func

        return deco

    # The command decorator.

    async def say(self, *args, **kwargs):
        if not self.message == None:
            msg = await self.message.channel.send(*args, **kwargs)
            return msg
        else:
            raise Exception(
                "Message not found. Is this a message based command?")

    # The say function for message based commands.

    async def whisper(self, *args, **kwargs):
        if not self.message == None:
            msg = await self.message.author.send(*args, **kwargs)
            return msg
        else:
            raise Exception(
                "Message not found. Is this a message based command?")

    # The whisper function for message based commands.

    def event(self, func):
        if func.__name__ not in self.discord_callbacks:
            self.discord_callbacks[func.__name__] = []
        if not inspect.iscoroutinefunction(func):
            raise Exception("Event not async.")
        self.discord_callbacks[func.__name__].append(func)

    # The event decorator.

    def load_plugins(self):
        self.discord_callbacks = dict()
        self.discord_commands = dict()
        self.plugins = dict()
        self.plugin_base = PluginBase(package='__main__.plugins')
        self.plugin_source = self.plugin_base.make_plugin_source(
            searchpath=[os.path.join(self.cube_root, "./plugins")])
        for plugin in self.plugin_source.list_plugins():
            self.plugins[plugin] = self.plugin_source.load_plugin(plugin)
            self.plugins[plugin].Plugin(self)
            self.logger.info(f'Loaded "{plugin}" into the plugin cache.')

    # Loads the plugins.

    def run(self):
        if isinstance(self.config["owner_server_id"], str):
            self.config["owner_server_id"] = int(
                self.config["owner_server_id"])
        if isinstance(self.config["owner_user_id"], str):
            self.config["owner_user_id"] = int(self.config["owner_user_id"])
        logging.basicConfig(level=logging.INFO)
        self.load_plugins()
        self.dclient.loop.create_task(self.load_mysql())
        self.dclient.run(self.config["token"])