autobotrobot/src/main.py

124 lines
4.9 KiB
Python
Raw Permalink Normal View History

2019-10-21 20:07:17 +00:00
import discord
import toml
import logging
import discord.ext.commands as commands
2020-05-12 16:08:03 +00:00
import discord.ext.tasks as tasks
2019-10-21 20:07:17 +00:00
import re
import asyncio
import json
2020-06-18 18:43:20 +00:00
import traceback
import random
import collections
2021-01-27 19:38:21 +00:00
import prometheus_client
import prometheus_async.aio
import typing
import sys
2019-10-21 20:07:17 +00:00
import tio
2020-04-18 12:14:31 +00:00
import db
2020-05-12 16:08:03 +00:00
import util
import eventbus
import irc_link
2020-11-01 17:32:02 +00:00
import achievement
2019-10-21 20:07:17 +00:00
config = util.config
2019-10-21 20:07:17 +00:00
logging.basicConfig(level=logging.INFO, format="%(levelname)s %(asctime)s %(message)s", datefmt="%H:%M:%S %d/%m/%Y")
2021-03-25 18:39:45 +00:00
intents = discord.Intents.default()
intents.members = True
2023-07-19 13:51:52 +00:00
intents.presences = True
intents.message_content = True
2020-11-25 19:00:43 +00:00
2024-03-26 23:21:15 +00:00
bot = commands.Bot(command_prefix=commands.when_mentioned_or(config["prefix"]), description="AutoBotRobot, the omniscient, omnipotent, omnibenevolent Discord bot by gollark." + util.config.get("description_suffix", ""),
2021-03-25 18:39:45 +00:00
case_insensitive=True, allowed_mentions=discord.AllowedMentions(everyone=False, users=True, roles=True), intents=intents)
2019-10-21 20:07:17 +00:00
bot._skip_check = lambda x, y: False
async def on_guild_available(guild):
logging.info(f"{guild.name}|{guild.id} became available")
bot.on_guild_available = on_guild_available
2021-01-27 19:38:21 +00:00
messages = prometheus_client.Counter("abr_messages", "Messages seen/handled by bot")
command_invocations = prometheus_client.Counter("abr_command_invocations", "Total commands invoked (includes failed)")
@bot.event
async def on_message(message):
2021-01-27 19:38:21 +00:00
messages.inc()
words = message.content.split(" ")
if len(words) == 10 and message.author.id == 435756251205468160:
await message.channel.send(util.unlyric(message.content))
else:
if message.author == bot.user or message.author.discriminator == "0000": return
ctx = await bot.get_context(message)
if not ctx.valid: return
2021-01-27 19:38:21 +00:00
command_invocations.inc()
await bot.invoke(ctx)
2021-01-27 19:38:21 +00:00
command_errors = prometheus_client.Counter("abr_errors", "Count of errors encountered in executing commands.")
@bot.event
async def on_command_error(ctx, err):
if isinstance(err, (commands.CommandNotFound, commands.CheckFailure)): return
if isinstance(err, commands.CommandInvokeError) and isinstance(err.original, ValueError):
return await ctx.send(embed=util.error_embed(str(err.original), title=f"Error in {ctx.invoked_with}"))
2021-03-08 10:25:11 +00:00
# TODO: really should find a way to detect ALL user errors here?
if isinstance(err, (commands.UserInputError)):
return await ctx.send(embed=util.error_embed(str(err), title=f"Error in {ctx.invoked_with}"))
try:
2021-01-27 19:38:21 +00:00
command_errors.inc()
trace = re.sub("\n\n+", "\n", "\n".join(traceback.format_exception(err, err, err.__traceback__)))
logging.error("Command error occured (in %s)", ctx.invoked_with, exc_info=err)
await ctx.send(embed=util.error_embed(util.gen_codeblock(trace), title=f"Internal error in {ctx.invoked_with}"))
2020-11-01 17:32:02 +00:00
await achievement.achieve(ctx.bot, ctx.message, "error")
except Exception as e:
logging.exception("Error in command error handling.")
@bot.check
async def andrew_bad(ctx):
return ctx.message.author.id != 543131534685765673
2020-05-12 16:08:03 +00:00
@bot.event
async def on_ready():
logging.info("Connected as " + bot.user.name)
2020-11-01 17:07:36 +00:00
await bot.change_presence(status=discord.Status.online,
2021-04-05 18:08:37 +00:00
activity=discord.Activity(name=f"{config['prefix']}help", type=discord.ActivityType.listening))
2020-05-12 16:08:03 +00:00
2021-01-27 20:35:32 +00:00
visible_users = prometheus_client.Gauge("abr_visible_users", "Users the bot can see")
def get_visible_users():
return len(bot.users)
visible_users.set_function(get_visible_users)
heavserver_members = prometheus_client.Gauge("abr_heavserver_members", "Current member count of heavserver")
heavserver_bots = prometheus_client.Gauge("abr_heavserver_bots", "Current bot count of heavserver")
2021-01-27 20:35:32 +00:00
def get_heavserver_members():
if not bot.get_guild(util.config["heavserver"]["id"]): return 0
2021-01-27 20:35:32 +00:00
return len(bot.get_guild(util.config["heavserver"]["id"]).members)
def get_heavserver_bots():
if not bot.get_guild(util.config["heavserver"]["id"]): return 0
return len([ None for member in bot.get_guild(util.config["heavserver"]["id"]).members if member.bot ])
2021-01-27 20:35:32 +00:00
heavserver_members.set_function(get_heavserver_members)
heavserver_bots.set_function(get_heavserver_bots)
2021-01-27 20:35:32 +00:00
guild_count = prometheus_client.Gauge("abr_guilds", "Guilds the bot is in")
def get_guild_count():
return len(bot.guilds)
guild_count.set_function(get_guild_count)
2020-04-18 12:14:31 +00:00
async def run_bot():
bot.database = await db.init(config["database"])
await eventbus.initial_load(bot.database)
2021-01-14 09:38:32 +00:00
for ext in util.extensions:
logging.info("Loaded %s", ext)
bot.load_extension(ext)
2020-04-18 12:14:31 +00:00
await bot.start(config["token"])
if __name__ == "__main__":
2020-04-18 12:14:31 +00:00
loop = asyncio.get_event_loop()
2021-01-27 19:38:21 +00:00
loop.create_task(prometheus_async.aio.web.start_http_server(port=config["metrics_port"]))
loop.create_task(run_bot())
2020-04-18 12:14:31 +00:00
try:
loop.run_forever()
2020-04-18 12:14:31 +00:00
except KeyboardInterrupt:
loop.run_until_complete(bot.close())
sys.exit(0)
2020-04-18 12:14:31 +00:00
finally:
2020-06-18 18:43:20 +00:00
loop.close()