API Reference

Event Reference

twitch_stream(data)
Parameters:

data (voxelbotutils.TwitchStream) – The Twitch stream that went live.

Pinged when a Twitch stream goes live. This only occurs if valid Twitch authentication is set inside of the config.

Utils

Bot

class voxelbotutils.MinimalBot(command_prefix, help_command=<default-help-command>, description=None, **options)

A minimal version of the VoxelBotUtils bot that inherits from discord.ext.commands.AutoShardedBot but gives new VBU features.

async create_message_log(messages: List[Message] | HistoryIterator) str

Creates and returns an HTML log of all of the messages provided. This is an API method, and may raise an asyncio HTTP error.

Parameters:

messages (Union[List[discord.Message], discord.iterators.HistoryIterator]) – The messages you want to create into a log.

Returns:

The HTML for a log file.

Return type:

str

class voxelbotutils.Bot(config_file: str = 'config/config.toml', logger: ~logging.Logger | None = None, activity: ~discord.activity.BaseActivity = <Game name='Reconnecting...'>, status: ~discord.enums.Status = <Status.dnd: 'dnd'>, case_insensitive: bool = True, intents: ~discord.flags.Intents | None = None, allowed_mentions: ~discord.mentions.AllowedMentions = AllowedMentions(everyone=False, users=True, roles=True, replied_user=True), *args, **kwargs)

A bot class that inherits from voxelbotutils.MinimalBot, detailing more VoxelBotUtils functions, as well as changing some of the default Discord.py library behaviour.

logger

A logger instance for the bot.

Type:

logging.Logger

config

The config for the bot.

Type:

dict

session

A session instance that you can use to make web requests.

Type:

aiohttp.ClientSession

application_id

The ID of this bot application.

Type:

int

database

The database connector, as connected using the data from your config file.

Type:

DatabaseWrapper

redis

The redis connector, as connected using the data from your config file.

Type:

RedisConnection

stats

The stats connector, as connected using the data from your config file. May not be authenticated, but will fail silently if not.

Type:

StatsdConnection

startup_method

The task that’s run when the bot is starting up.

Type:

asyncio.Task

guild_settings

A dictionary from the guild_settings Postgres table.

Type:

dict

user_settings

A dictionary from the user_settings Postgres table.

Type:

dict

user_agent

The user agent that the bot should use for web requests as set in the config file. This isn’t used automatically anywhere, so it just here as a provided convenience.

Type:

str

upgrade_chat

An UpgradeChat connector instance using the oauth information provided in your config file.

Type:

upgradechat.UpgradeChat

clean_prefix

The default prefix for the bot.

Type:

str

owner_ids

A list of the owners from the config file.

Type:

List[int]

embeddify

Whether or not messages should be embedded by default, as set in the config file.

Type:

bool

__init__(config_file: str = 'config/config.toml', logger: ~logging.Logger | None = None, activity: ~discord.activity.BaseActivity = <Game name='Reconnecting...'>, status: ~discord.enums.Status = <Status.dnd: 'dnd'>, case_insensitive: bool = True, intents: ~discord.flags.Intents | None = None, allowed_mentions: ~discord.mentions.AllowedMentions = AllowedMentions(everyone=False, users=True, roles=True, replied_user=True), *args, **kwargs)
Parameters:
async startup()

Clears the custom caches for the bot (guild_settings and user_settings), re-reads the database tables for each of those items, and calls the voxelbotutils.Cog.cache_setup() method in each of the cogs again.

async fetch_support_guild() Guild | None

Get the support guild as set in the bot’s config file.

Returns:

The guild instance. Will be None if a guild ID has not been

provided, or cannot be found.

Return type:

Optional[discord.Guild]

Generate an invite link for the bot.

Parameters:
  • client_id (int, optional) – The client ID that the invite command should use. Uses the passed argument, then the config's set client ID, and then the bot’s ID if nothing is found.

  • scope (str, optional) – The scope for the invite link.

  • response_type (str, optional) – The response type of the invite link.

  • redirect_uri (str, optional) – The redirect URI for the invite link.

  • guild_id (int, optional) – The guild ID that the invite link should default to.

  • permissions (discord.Permissions, optional) – A permissions object that should be used to make the permissions on the invite.

Returns:

The URL for the invite.

Return type:

str

async get_user_topgg_vote(user_id: int) bool

Returns whether or not the user has voted on Top.gg. If there’s no Top.gg token provided in your config file then this will always return False. This method doesn’t handle timeouts or errors in their API (such as outages); you are expected to handle them yourself.

Parameters:

user_id (int) – The ID of the user you want to check.

Returns:

Whether or not that user has registered a vote on Top.gg.

Return type:

bool

get_event_webhook(event_name: str) Webhook | None

Get a discord.Webhook object based on the keys in the bot's config.

Parameters:

event_name (str) – The name of the event you want to get a webhook for.

Returns:

A webhook instance pointing to the URL as given.

Return type:

Optional[discord.Webhook]

async add_delete_reaction(message: Message, valid_users: Tuple[User | Member] | None = None, *, delete: Tuple[Message] | None = None, timeout: float = 60.0, wait: bool = False) None

Adds a delete reaction to the given message.

Parameters:
  • message (discord.Message) – The message you want to add a delete reaction to.

  • valid_users (List[discord.User], optional) – The users who have permission to use the message’s delete reaction.

  • delete (List[discord.Message], optional) – The messages that should be deleted on clicking the delete reaction.

  • timeout (float, optional) – How long the delete reaction should persist for.

  • wait (bool, optional) – Whether or not to block (via async) until the delete reaction is pressed.

Raises:

discord.HTTPException – The bot was unable to add a delete reaction to the message.

Sets a footer on the given embed based on the items in the bot's config.

Parameters:

embed (discord.Embed) – The embed that you want to set a footer on.

get_extensions() List[str]

Gets a list of filenames of all the loadable cogs.

Returns:

A list of the extensions found in the cogs/ folder,

as well as the cogs included with VoxelBotUtils.

Return type:

List[str]

load_all_extensions() None

Loads all the given extensions from voxelbotutils.Bot.get_extensions().

async set_default_presence(shard_id: int | None = None) None

Sets the default presence for the bot as appears in the config file.

reload_config() None

Re-reads the config file into cache.

Cog

class voxelbotutils.Cog(*args: Any, **kwargs: Any)

A slightly modified cog class to allow for the cache_setup method and for the class’ logger instance.

bot

The bot instance that the cog was added to.

Type:

Bot

logger

The logger that’s assigned to the cog instance. This will be used for logging command calls, even if you choose not to use it yourself.

Type:

logging.Logger

qualified_name

The human-readable name for the cog.

class MyCog(voxelbotutils.Cog): pass
c = MyCog(bot)
c.qualified_name  # "My Cog"

class APICommands(voxelbotutils.Cog): pass
c = APICommands(bot)
c.qualified_name  # "API Commands"
Type:

str

get_logger_name(*prefixes, sep: str = '.') str

Gets the name of the class with any given prefixes, with sep as a seperator. You tend to not need this yourself, but it is instead called internally by the bot when generating the logger instance.

async cache_setup(database: DatabaseWrapper)

A method that gets run when the bot’s startup method is run - intended for setting up cached information in the bot object that aren’t in the voxelbotutils.Bot.guild_settings or voxelbotutils.Bot.user_settings tables. This setup should clear your caches before setting them, as the voxelbotutils.Bot.startup() method may be called multiple times.

Context

class voxelbotutils.Context(*args, **kwargs)

A modified version of the default discord.ext.commands.Context.

original_author_id

The ID of the original person to run the command. Persists through the bot’s sudo command, if you want to check the original author.

Type:

int

async okay() None

Adds the okay hand reaction to a message.

AbstractMentionable

class voxelbotutils.AbstractMentionable(id: int, mention: str = 'null', name: str = 'null')

A fake mentionable object for use anywhere that you can’t catch an error on a .mention being None.

id

The ID of the mentionable.

Type:

int

mention

The mention string for the object.

Type:

str

name

The name of the object.

Type:

str

__init__(id: int, mention: str = 'null', name: str = 'null')
Parameters:
  • id (int) – The ID of the mentionable.

  • mention (str) – The string to be returned when .mention is run.

  • name (str) – The string to be returned when .name is run.

DatabaseWrapper

class voxelbotutils.DatabaseWrapper(conn=None, *, cursor: DriverConnection = None)

A wrapper around your preferred database driver.

async classmethod create_pool(config: UserDatabaseConfig) None

Create the database pool and store its instance in pool.

Parameters:

config (dict) – The config that the pool should be created with.

async classmethod get_connection() DatabaseWrapper

Acquires a connection to the database from the pool.

Using this method does not automatically call the .disconnect() method - if you want this to be handled automaticall you can use this class in a context manager.

Examples

>>> db = await vbu.Database.get_connection()
>>> rows = await db("SELECT 1")
>>> await db.disconnect()
Returns:

The connection that was aquired from the pool.

Return type:

DatabaseWrapper

async disconnect() None

Releases a connection from the pool back to the mix. This should be called after you’re done with a database connection.

transaction(*args, **kwargs) DatabaseTransaction

Start a database transaction.

Parameters:

commit_on_exit (bool) – Whether or not you want to commit automatically when you exit the context manager. Defaults to True.

Examples

>>> # This will commit automatically on exit
>>> async with db.transaction() as transaction:
>>>     await transaction("DROP TABLE example")
>>> # This needs to be committed manually
>>> async with db.transaction(commit_on_exit=False) as transaction:
>>>     await transaction("DROP TABLE example")
>>>     await transaction.commit()
>>> # You can rollback a transaction with `.rollback()`
>>> async with db.transaction() as transaction:
>>>     await transaction("DROP TABLE example")
>>>     await transaction.rollback()
>>> # Rollbacks will happen automatically if any error is hit in the
>>> # transaction context
>>> async with db.transaction() as transaction:
>>>     await transaction("DROP TABLE example")
>>>     raise Exception()
>>> # If you have `commit_on_exit` set to `False` and you don't commit then
>>> # your changes will be automatically rolled back on exiting the context
>>> async with db.transaction(commit_on_exit=False) as transaction:
>>>     await transaction("DROP TABLE example")
Returns:

A handler for your transaction instance.

Return type:

DatabaseTransaction

async call(sql: str, *args) List[Any]

Run a line of SQL against your database driver.

This method can also be run as __call__.

Parameters:
  • sql (str) – The SQL that you want to run. This will be parsed as a prepared or parameterized statement. For PostgreSQL, arguments will be in form $1 numbered for each of your arguments; in SQLite they’ll be ? and inserted in the order of your given arguments; and in MySQL they’ll be in format %s and inserted in the order of your given arguments.

  • *args (Any) – The arguments that are passed to your database call.

Examples

>>> sql = "INSERT INTO example (a, b) VALUES ($1, $2)"
>>> await db.executemany(sql, 1, 2)
Returns:

The list of rows that were returned from the database.

Return type:

typing.List[dict]

async executemany(sql: str, *args_list: Iterable[Any]) None

Run a line of SQL with a multitude of arguments.

Parameters:
  • sql (str) – The SQL that you want to run. This will be parsed as a prepared or parameterized statement. For PostgreSQL, arguments will be in form $1 numbered for each of your arguments; in SQLite they’ll be ? and inserted in the order of your given arguments; and in MySQL they’ll be in format %s and inserted in the order of your given arguments.

  • *args_list (Iterable[Any]) – A list of arguments that should be passed into your database call.

Examples

>>> sql = "INSERT INTO example (a, b) VALUES ($1, $2)"
>>> await db.executemany(sql, (1, 2), (3, 4), (5, 6), (7, 8))
Returns:

The list of rows that were returned from the database.

Return type:

typing.List[dict]

DatabaseTransaction

class voxelbotutils.DatabaseTransaction(driver: Type[DriverWrapper], parent: DatabaseWrapper, *, commit_on_exit: bool = True)

A wrapper around a transaction for your database.

Parameters:

commit_on_exit (bool) – Whether or not your changes should be automatically committed when the transaction context is left.

parent

The connection that spawned this transaction.

Type:

DatabaseWrapper

async call(*args, **kwargs)

Run some SQL, returning it’s data. See DatabaseWrapper.call().

async execute_many(*args, **kwargs)

Run some SQL, returning it’s data. See DatabaseWrapper.execute_many().

async commit()

Commit the changes made to the database in this transaction context.

async rollback()

Roll back the changes made to the database in this transaction context.

RedisConnection

class voxelbotutils.RedisConnection(connection: RedisConnection | None = None)

A wrapper for an aioredis.Redis object, provided in your bot object at Bot.redis for your convenience. Implemented are setter and getter methods for the redis database, as well as publish and subscribe via a decorator.

Examples

# In a command
async with RedisConnection() as re:
    await re.publish("channel_name", {"foo": "bar"})
    await re.publish_str("channel_two", "baz")

# In a cog
@voxelbotutils.redis_channel_handler("channel_name")
async def handler(self, payload):
    self.logger.info(payload)
async classmethod create_pool(config: dict) None

Creates and connects the pool object.

Parameters:

config (dict) – The config dictionary that should be passed directly to aioredis.create_redis_pool() directly as kwargs.

async classmethod get_connection() RedisConnection

Acquires a connection from the connection pool.

async disconnect() None

Releases a connection back into the connection pool.

async publish(channel: str, json: dict) None

Publishes some JSON to a given redis channel.

Parameters:
  • channel (str) – The name of the channel that you want to publish redis to.

  • json (dict) – The JSON that you want to publish.

async publish_str(channel: str, message: str) None

Publishes a message to a given redis channel.

Parameters:
  • channel (str) – The name of the channel that you want to publish redis to.

  • message (str) – The message that you want to publish.

async set(key: str, value: str) None

Sets a key/value pair in the redis DB.

Parameters:
  • key (str) – The key you want to set the value of

  • value (str) – The data you want to set the key to

async get(key: str) str

Gets a value from the Redis DB given a key.

Parameters:

key (str) – The key that you want to get from the Redis database.

Returns:

The key from the database.

Return type:

str

async mget(*keys) List[str]

Gets multiple values from the Redis DB given a list of keys.

Parameters:

keys (str) – The keys that you want to get from the database.

Returns:

The values from the Redis database associated with the given keys.

Return type:

List[str]

StatsdConnection

class voxelbotutils.StatsdConnection(connection: Client | None = None)

A helper class to wrap around an aiodogstatsd.Client object so as to make it a little easier to use. Statsd is unique in my wrapper utils in that it’ll fail silently if there’s no connection to be made.

async classmethod get_connection() StatsdConnection

Acquires a connection to the database from the pool.

Returns:

The connection that was aquired from the pool.

Return type:

StatsdConnection

async disconnect() None

Releases a connection from the pool back to the mix.

Embed

class voxelbotutils.Embed(*args, use_random_colour: bool = False, **kwargs)

A modification for Discord.py’s discord.Embed class to allow for args where D.py uses kwargs, as well as inbuilt random colour generation and setting the author field to an instance of a user.

Examples

embed = voxelbotutils.Embed(use_random_colour=True)
embed.set_author_to_user(bot.get_user(141231597155385344))

# You can also use a with statement if you want to have your
# IDE fold the embed code.
# There is no other use for the with statement.
with embed:
    embed.set_image("https://example.com/image.png")
__init__(*args, use_random_colour: bool = False, **kwargs)
Parameters:
  • use_random_colour (bool, optional) – Whether or not to automatically use a random colour.

  • **kwargs – Default args that go do discord.Embed.

use_random_colour() Embed

Sets the colour for the embed to a random one.

Returns:

The embed instance.

Return type:

Embed

Sets the footer of the embed.

Parameters:
  • text (str) – The text to use in the footer.

  • *args – Default args that go do discord.Embed.set_footer.

  • **kwargs – Default args that go do discord.Embed.set_footer.

Returns:

The embed instance.

Return type:

Embed

set_image(url: str) Embed

Sets the image of the embed.

Parameters:

url (str) – The URL to set the image to.

Returns:

The embed instance.

Return type:

Embed

set_thumbnail(url: str) Embed

Sets the thumbnail of the embed.

Parameters:

url (str) – The URL to set the thumbnail to.

Returns:

The embed instance.

Return type:

Embed

set_author_to_user(user: User, use_nick: bool = False) Embed

Sets the author of the embed to a given Discord user.

Parameters:
  • user (discord.User) – The user you want to set the author to.

  • use_nick (bool) – Whether to use the guild nickname or regular username.

Returns:

The embed instance.

Return type:

Embed

add_field(name: str, value: str, inline: bool = True) Embed

Adds a field to the embed without using kwargs.

Parameters:
  • name (str) – The name of the field.

  • value (str) – The value of the field.

  • inline (bool, optional) – Whether or not to set the field as inline.

Returns:

The embed instance.

Return type:

Embed

get_field_by_key(key: str) dict

Return the data from a field given its key

Parameters:

key (str) – The name of the field you want to get the data for

Returns:

A dictionary of the attrs for that field

Return type:

dict

Raises:

KeyError – If the given key doesn’t exist in the embed

edit_field_by_index(index: int, *, name: str | None = None, value: str | None = None, inline: bool | None = None) Embed

Edit a field in the embed using its index.

Parameters:
  • index (int) – The index of the field you want to edit.

  • name (str, optional) – What you want to set the name to.

  • value (str, optional) – What you want to set the value to.

  • inline (bool, optional) – Whether or not the field should be inline.

Returns:

The embed instance.

Return type:

Embed

edit_field_by_key(key: str, *, name: str | None = None, value: str | None = None, inline: bool | None = None) Embed

Edit a field in the embed using its name as a key.

Parameters:
  • key (str) – The key of the field to edit, based on its name.

  • name (str, optional) – What you want to set the name to.

  • value (str, optional) – What you want to set the value to.

  • inline (bool, optional) – Whether or not the field should be inline.

Returns:

The embed instance.

Return type:

Embed

Raises:

KeyError – If the given key isn’t present in the embed.

classmethod from_native(embed: Embed) Embed

Upgrade a native embed into a VoxelBotUtils embed.

Parameters:

embed (discord.Embed) – The embed that you want to upgrade.

Returns:

The upgraded embed instance.

Return type:

Embed

Paginator

class voxelbotutils.Paginator(data: Sequence | Generator | Callable[[int], Any], *, per_page: int = 10, formatter: Callable[[Paginator, Sequence[Any]], str | Embed | dict] | None = None)

An automatic paginator util that takes a list and listens for reactions on a message to change the content.

# Items will automatically be cast to strings and joined
my_list = list(range(30))
p = vbu.Paginator(my_list, per_page=5)
await p.start(ctx, timeout=15)

# Alternatively you can give a function, which can return a string, an embed, or a dict
# that gets unpacked directly into the message's edit method
def my_formatter(menu, items):
    output = []
    for i in items:
        output.append(f"The {i}th item")
    output_string = "\n".join(output)
    embed = vbu.Embed(description=output_string)
    embed.set_footer(f"Page {menu.current_page + 1}/{menu.max_pages}")

p = vbu.Paginator(my_list, formatter=my_formatter)
await p.start(ctx)
__init__(data: Sequence | Generator | Callable[[int], Any], *, per_page: int = 10, formatter: Callable[[Paginator, Sequence[Any]], str | Embed | dict] | None = None)
Parameters:
  • data (Union[Sequence, Generator, Callable[[int], Any]]) – The data that you want to paginate. If a generator or function is given then the max_pages will start as the string “?”, and the per_page parameter will be ignored - the formatter will be passed the content of whatever your generator returns. If a function is given, then you will be passed the page number as an argument - raising StopIteration from this function will cause the max_pages attribute to be set, and the page will go back to what it was previously.

  • per_page (int, optional) – The number of items that appear on each page. This argument only works for sequences

  • formatter (Callable[[Paginator, Sequence[Any]], Union[str, discord.Embed, dict]], optional) – A function taking the paginator instance and a list of things to display, returning a dictionary of kwargs that get passed directly into a discord.Message.edit().

async start(ctx: Context, *, timeout: float = 120)

Start and handle a paginator instance.

Parameters:
  • ctx (discord.ext.commands.Context) – The context instance for the called command.

  • timeout (float, optional) – How long you should wait between getting a reaction and timing out.

async get_page(page_number: int) List[Any]

Get a list of items that appear for a given page.

Parameters:

page_number (int) – The page number to get.

Returns:

The list of items that would be on the page.

Return type:

List[Any]

static default_list_formatter(m: Paginator, d: List[str | Embed])

The default list formatter for embeds. Takes the paginator instance and the list of data to be displayed, and returns a dictionary of kwargs for a Message.edit.

static default_ranked_list_formatter(m: Paginator, d: List[str])

The default list formatter for embeds. Takes the paginator instance and the list of strings to be displayed, and returns a dictionary of kwargs for a Message.edit.

TimeValue

class voxelbotutils.TimeValue(duration: float)

An object that nicely converts an integer value into an easily readable string. This util is also available as an argument converter for your commands, though it can be used outide of being a converter as well via use of the parse() method.

Examples

>>> value = voxelbotutils.TimeValue(606)
>>> value.clean
'10m6s'
>>> value.clean_spaced
'10m 6s'
>>> value = voxelbotutils.TimeValue.parse('10m6s')
>>> value.duration
606

Note

This does not support partial seconds, and can only support a max of about 68 years (2^31 seconds).

duration

The entire duration, in seconds, of the timevalue object.

Type:

int

years

The number of years that the object represents.

Type:

int

days

The number of days that the object represents.

Type:

int

hours

The number of hours that the object represents.

Type:

int

minutes

The number of minutes that the object represents.

Type:

int

seconds

The number of seconds that the object represents.

Type:

int

clean_full

A string form of the object in form “10 hours 3 minutes”.

Type:

str

clean_spaced

A string form of the object in form “10h 3m”.

Type:

str

clean

A string form of the object in form “10h3m”.

Type:

str

delta

A timedelta for the entire timevalue object.

Type:

datetime.timedelta

__init__(duration: float)
Parameters:

duration (float) – The duration to be converted.

Warning

Provided values will be rounded up to the nearest integer.

Raises:

InvalidTimeDuration – If the provided time duration was invalid.

async classmethod convert(ctx: Context, value: str) TimeValue

Takes a value (1h/30m/10s/2d etc) and returns a TimeValue instance with the duration. Provided for use of the Discord.py module.

Parameters:
Returns:

A time value instance.

Return type:

voxelbotutils.TimeValue

Raises:

voxelbotutils.errors.InvalidTimeDuration – If the time could not be successfully converted.

classmethod parse(value: str) TimeValue

Takes a value (1h/30m/10s/2d etc) and returns a TimeValue instance with the duration.

Parameters:

value (str) – The value string to be converted.

Returns:

A time value instance.

Return type:

voxelbotutils.TimeValue

Raises:

voxelbotutils.errors.InvalidTimeDuration – If the time could not be successfully converted.

TwitchStream

class voxelbotutils.TwitchStream(*, data: dict)

A container class for parts of a Twitch stream.

id

The ID of the stream.

Type:

str

user_id

The ID of the user who’s streaming.

Type:

str

user_login

The login name of the user who’s streaming.

Type:

str

user_name

The display name of the user who’s streaming.

Type:

str

game_id

The ID of the game that the user is playing.

Type:

str

game_name

The name of the game that the user is playing.

Type:

str

type

The stream status. Will only be “live”.

Type:

str

title

The title of the stream.

Type:

str

viewer_count

The viewer count for the stream.

Type:

int

started_at

An ISO 8601 timestamp for the stream’s start time.

Type:

datetime.datetime

language

The language code for the stream’s language.

Type:

str

thumbnail_url

A URL for the stream’s thumbnail, with placeholder “{width}” and “{height}” format string placeholders.

Type:

str

tag_ids

The IDs of the tags assigned to the stream.

Type:

List[str]

is_mature

Whether or not the stream is set to mature.

Type:

bool

__init__(*, data: dict)

component_check

voxelbotutils.component_check(user: User | Member, message: Message, no_interact_message: str | None = ...) Callable[[Interaction], bool]

A check for a wait_for that allows only a user to interact with the given button, outputting the no interaction message.

New in version 0.6.6.

Parameters:
  • user (Union[discord.User, discord.Member]) – The user who’s allowed to interact with the message.

  • message (discord.Message) – The message that the user is allowed to interact with.

  • no_interact_message (Optional[str]) –

    The content that’s output when a non-valid user interacts with the button.

    Changed in version 0.7.0.

    You can now disable a response being sent by passing None to this parameter. If you do, a deferred update will still be sent.

Returns:

A callable check for interaction events where only the supplied user is allowed to interact.

Return type:

Callable[[discord.Interaction], bool]

format

voxelbotutils.format(*args, **kwargs)

A modified version of the normal str.format method to have some slightly more useful utilities in it.

Examples

# Saying how many of a given item you have can be a pain.
# Using the plural formatter, you can easily format a string to have
# plural nouns.
vbu.format("{0:plural,single,plural}", 1)  # "single"
vbu.format("{0:plural,single,plural}", 2)  # "plural"
vbu.format("{0} {0:plural,item,items}", 1)  # "1 item"
vbu.format("{0} {0:plural,item,items}", 2)  # "2 items"

# You have a command `inventory` - runnable as `inventory @user` defaulting the user
# to yourself.
# Pronouns for this can be a pain to update in strings. In this example, we set the
# pronouns by comparing the specified user to `ctx.author`
vbu.format("{0:pronoun,You,{1.mention}} {0:pronoun,have,has} stuff.", ctx.author == user, user.mention)

# The join formatter can "human" join a list strings.
items = ["a", "b", "c", "d"]
vbu.format("{0:humanjoin}", items)  # "a, b, c, and d"

translation

voxelbotutils.translation(ctx: Context | Interaction | str, domain: str, *, use_guild: bool = False, **kwargs) GNUTranslations | NullTranslations

Get a translation table for a given domain with the locale stored in a context.

Examples

>>> # This will get the locale from your context,
>>> # and will get the translation from the "errors" file.
>>> vbu.translation(ctx, "errors").gettext("This command is currently unavailable")
Parameters:
  • ctx (Union[discord.ext.commands.Context, discord.Interaction, str]) – The context that you want to get the translation within, or the name of the locale that you want to get anyway.

  • domain (str) – The domain of the translation.

  • use_guild (bool) – Whether or not to prioritize the guild locale over the user locale.

Returns:

The transation table object that you want to .gettext for.

Return type:

Union[gettext.GNUTranslations, gettext.NullTranslations]

Checks

checks.is_config_set

voxelbotutils.checks.is_config_set(*config_keys)

Checks that your config has been set given the keys for the item. Items are run as __getitem__`s for the following item. So for a config where you want to check that `config[“api_keys”][“example”] has been set, you would write your check as is_config_set(“api_keys”, “example”).

Raises:

ConfigNotSet – If the config item hasn’t been set for the bot.

checks.meta_command

voxelbotutils.checks.meta_command()

Stops users from being able to run this command. Should be caught and then reinvoked, or should have Context.invoke_meta set to True.

Examples

@voxelbotutils.command()
@voxelbotutils.checks.meta_command()
async def notrunnable(self, ctx, *args):
    '''This command can't be run by normal users, and will fail silently...'''

    await ctx.send('uwu time gamers')

@voxelbotutils.command()
async def runnable(self, ctx):
    '''But you can still run the command like this.'''

    ctx.invoke_meta = True
    await ctx.invoke(ctx.bot.get_command('notrunnable'))
Raises:

InvokedMetaCommand – If the command was run without the meta tag being set.

checks.bot_is_ready

voxelbotutils.checks.bot_is_ready()

The check for whether or not the bot has processed all of its startup methods (as defined by the Bot.startup_method task being completed), as well as having populated the cache (as defined by Discord.py having set discord.ext.commands.Bot.is_ready to true).

Raises:

BotNotReady – If the bot isn’t yet marked as ready.

checks.is_bot_support

voxelbotutils.checks.is_bot_support()

Checks whether or not the calling user has the bot support role, as defined in the bot’s configuration file (config.bot_support_role_id). As it checks a role ID, this will only work it the command in quesiton is called in a guild where the calling user has the given role.

Raises:

NotBotSupport – If the given user isn’t a member of the bot’s support team.

checks.is_voter

voxelbotutils.checks.is_voter(timeout: float = 3.0)

A check to make sure the author of a given command is a voter on your bot’s Top.gg page. This only works if a Top.gg token is provided in your config (BotConfig.bot_listing_api_keys.topgg_token) and is valid. If one isn’t provided, the command will always raise voxelbotutils.errors.IsNotVoter.

Parameters:

timeout (float, optional) – The amount of time to wait before considering their API to be down.

Raises:
  • IsNotVoter – If the user is has not voted for the bot on Top.gg, or the bot doesn’t have a Top.gg token defined.

  • commands.CheckFailure – Top.gg’s API is unable to process our API request within the given time.

checks.is_upgrade_chat_subscriber

voxelbotutils.checks.is_upgrade_chat_subscriber(*any_item_names)

A check to see whether a given user is an UpgradeChat subscriber for any of the given item names, adding an upgrade_chat_items attribute to the context object with the given purchases. For example, if you wanted a command to only be runnable if someone is subscribed to an item called command_access via UpgradeChat, your check would be is_upgrade_chat_subscriber(“command_access”).

Raises:
  • IsNotUpgradeChatSubscriber – If the user isn’t subscribing to the given item.

  • commands.CheckFailure – If the Upgrade.Chat API is unavailable.

checks.is_upgrade_chat_purchaser

voxelbotutils.checks.is_upgrade_chat_purchaser(*any_item_names)

A check to see whether a given user is an UpgradeChat purchaser for any of the given item names, adding an upgrade_chat_items attribute to the context object with the given purchases. For example, if you wanted a command to only be runnable if someone purchased the an item called command_access via UpgradeChat, your check would be is_upgrade_chat_purchaser(“command_access”).

Raises:
  • IsNotUpgradeChatPurchaser – If the user hasn’t purchased the given item.

  • commands.CheckFailure – If the Upgrade.Chat API is unavailable.

Converters

converters.UserID

class voxelbotutils.converters.UserID

A conveter that takes the given value and tries to grab the ID from it. When used, this would provide the ID of the user. This isn’t guarenteed to be a real user, but rather an ID that looks like a user’s.

converters.ChannelID

class voxelbotutils.converters.ChannelID

A conveter that takes the given value and tries to grab the ID from it. When used, this would provide the ID of the channel. This isn’t guarenteed to be a real user, but rather an ID that looks like a user’s.

converters.BooleanConverter

class voxelbotutils.converters.BooleanConverter(*args, **kwargs)

Converts the given input into a boolean yes/no, defaulting to “no” if something couldn’t be properly converted rather than raising an error.

converters.ColourConverter

class voxelbotutils.converters.ColourConverter(*, allow_custom_colour_names: bool = True, allow_default_colours: bool = True)

The normal Discord discord.ext.commands.ColourConverter class but it contains a lot more colour names, as taken from Wikipedia, the CSS colour set, and a couple of extra ones that I thought were cute.

converters.FilteredUser

class voxelbotutils.converters.FilteredUser(*, allow_author: bool = False, allow_bots: bool = False)

A simple discord.ext.commands.UserConverter that doesn’t allow bots or the author to be passed into the function.

converters.FilteredMember

class voxelbotutils.converters.FilteredMember(*, allow_author: bool = False, allow_bots: bool = False)

A simple discord.ext.commands.MemberConverter that doesn’t allow bots or the author to be passed into the function.

Errors

errors.ConfigNotSet

exception voxelbotutils.errors.ConfigNotSet(message: str | None = None, *args: Any)

This is a subclass of discord.ext.commands.DisabledCommand raised exclusively by the is_config_set check. For normal users, this should just say that the command is disabled.

errors.InvokedMetaCommand

exception voxelbotutils.errors.InvokedMetaCommand(message: str | None = None, *args: Any)

Raised on any command decorated with voxelbotutils.checks.meta_command(). This stops users from running commands that you’ve made for internal use only, such as settings subcommands or commands that should only be invoked via discord.ext.commands.Bot.invoke().

errors.BotNotReady

exception voxelbotutils.errors.BotNotReady(message: str | None = None, *args: Any)

The generic error for the bot failing the voxelbotutils.checks.bot_is_ready() check.

errors.IsNotVoter

exception voxelbotutils.errors.IsNotVoter(message: str | None = None, *args: Any)

The error thrown when a particular user is not a voter on Top.gg, or when there’s no valid token set in the bot’s config (BotConfig.bot_listing_api_keys.topgg_token).

errors.NotBotSupport

exception voxelbotutils.errors.NotBotSupport

The generic error for the bot failing the voxelbotutils.checks.is_bot_support() check - is a subclass of discord.ext.commands.MissingRole.

errors.MissingRequiredArgumentString

exception voxelbotutils.errors.MissingRequiredArgumentString(param: str)

This is a version of discord.ext.commands.MissingRequiredArgument that just takes a string as a parameter so you can manually raise it inside commands.

param

The parameter that was missing from the command.

Type:

str

errors.InvalidTimeDuration

exception voxelbotutils.errors.InvalidTimeDuration(value: str)

A conversion error for an invalid input passed to voxelbotutils.TimeValue.

value

The value that was given that failed to parse.

Type:

str

errors.IsNotUpgradeChatPurchaser

exception voxelbotutils.errors.IsNotUpgradeChatPurchaser(item_names: str)

The error raised when the user is missing an UpradeChat purchase.

errors.IsNotUpgradeChatSubscriber

exception voxelbotutils.errors.IsNotUpgradeChatSubscriber

The error raised when the user is missing an UpradeChat subscription.

Websites

web.OauthGuild

class voxelbotutils.web.OauthGuild(bot, guild_data, user)

A guild object from an oauth integration.

id

The ID of the guild.

Type:

int

name

The name of the guild.

Type:

str

icon

The guild’s icon.

Type:

discord.Asset

owner_id

The ID of the owner for the guild. This will either be the ID of the authenticated user or 0.

Type:

int

features

A list of features that the guild has.sa

Type:

List[str]

property icon: Asset | None

Returns the guild’s icon asset, if available.

Type:

Optional[Asset]

async fetch_guild(bot=None) Guild | None

Fetch the original discord.Guild object from the API using the authentication from the bot given.

Parameters:

bot – The bot object that you want to use to fetch the guild.

Returns:

The guild instance.

Return type:

Optional[discord.Guild]

web.OauthUser

class voxelbotutils.web.OauthUser(user_data)

A user object from an oauth integration.

id

The ID of the user.

Type:

int

username

The user’s username.

Type:

str

avatar

The user’s avatar asset.

Type:

discord.Asset

discriminator

The user’s discrimiator.

Type:

str

public_flags

The user’s public flags.

Type:

discord.PublicUserFlags

locale

The locale of the user.

Type:

str

mfa_enabled

Whether or not the user has MFA enabled.

Type:

bool

property avatar: Asset | None

Returns the guild’s icon asset, if available.

Type:

Optional[Asset]

web.OauthMember

class voxelbotutils.web.OauthMember(bot, guild_data, user_data)

A user object from an oauth integration.

id

The ID of the user.

Type:

int

username

The user’s username.

Type:

str

avatar

The user’s avatar hash.

Type:

str

avatar_url

The user’s avatar.

Type:

discord.Asset

discriminator

The user’s discrimiator.

Type:

str

public_flags

The user’s public flags.

Type:

discord.PublicUserFlags

locale

The locale of the user.

Type:

str

mfa_enabled

Whether or not the user has MFA enabled.

Type:

bool

guild

The guild object that this member is a part of.

Type:

OauthGuild

guild_permissions

The permissions that this member has on the guild.

Type:

discord.Permissions

web.add_discord_arguments

voxelbotutils.web.add_discord_arguments(*, redirect_if_logged_out: str | None = None, redirect_if_logged_in: str | None = None)

This function is a wrapper around all routes. It takes the output and adds the user info and request to the returning dictionary It must be applied before the template decorator.

Parameters:
  • redirect_if_logged_out (str, optional) – A location to direct the user to should they be logged out.

  • redirect_if_logged_in (str, optional) – A location to direct the user to if they are logged in already.

web.get_avatar_url

voxelbotutils.web.get_avatar_url(user_info: dict | None = None)

Gets the avatar URL for a user when provided with their user info. If no arguments are provided then the default Discord avatar is given.

web.requires_login

voxelbotutils.web.requires_login()

Using this wrapper on a route means that the user needs to be logged in to see the page. If they’re not logged in then they’ll be redirected to the login URL as set in your website config.

web.is_logged_in

async voxelbotutils.web.is_logged_in(request: Request)

Returns whether or not the user for the given request is logged in.

web.get_discord_login_url

voxelbotutils.web.get_discord_login_url(request: Request, redirect_uri: str | None = None) str

Returns a login URL for your website based on the oauth information given in your website config.

Parameters:
  • request (Request) – The request from which this command call is coming from.

  • redirect_uri (str, optional) – Where the user should be redirected to after pressing authorize.

  • oauth_scopes (list, optional) – The scopes that the login URL will ask for. Does not necessarily mean we’ll get them.

Returns:

The login URL that we want to use.

Return type:

str

web.process_discord_login

async voxelbotutils.web.process_discord_login(request: Request) None

Process a Discord login and store the information in the provided session based off of a callback from your Discord redirect URI.

Parameters:
  • request (Request) – The request from which this command call is coming from.

  • oauth_scopes (list) – The list of oauth scopes that we asked for.

web.get_user_info_from_session

async voxelbotutils.web.get_user_info_from_session(request: Request, *, refresh: bool = False)

Get the user’s info.

web.get_access_token_from_session

async voxelbotutils.web.get_access_token_from_session(request: Request, *, refresh_if_expired: bool = True, refresh: bool = False) str

Get the access token for a given user.

web.get_user_guilds_from_session

async voxelbotutils.web.get_user_guilds_from_session(request: Request, bot_key: str = 'bot') List[OauthMember]

Returns a list of guilds that the user is in based on the request’s logged in user.

web.add_user_to_guild_from_session

async voxelbotutils.web.add_user_to_guild_from_session(request: Request, bot_index: str, guild_id: int) bool

Adds the user to the given guild (if the correct scopes were previously provided). Returns a boolean of whether or not that user was added (or was already in the guild) successfully.