Warning

This document is for Red's development version, which can be significantly different from previous releases. If you're a regular user, you should read the Red documentation for the current stable release.

Mod log

Mod log has now been separated from Mod for V3.

Basic Usage

from redbot.core import commands, modlog
import discord

class MyCog(commands.Cog):
    @commands.command()
    @commands.admin_or_permissions(ban_members=True)
    async def ban(self, ctx, user: discord.Member, reason: str = None):
        await ctx.guild.ban(user)
        case = await modlog.create_case(
            ctx.bot, ctx.guild, ctx.message.created_at, action_type="ban",
            user=user, moderator=ctx.author, reason=reason
        )
        await ctx.send("Done. It was about time.")

Registering Case types

To register case types, use a special cog_load() method which is called when you add a cog:

# mycog/mycog.py
from redbot.core import modlog, commands
import discord

class MyCog(commands.Cog):

    async def cog_load(self):
        await self.register_casetypes()

    @staticmethod
    async def register_casetypes():
        # Registering a single casetype
        ban_case = {
            "name": "ban",
            "default_setting": True,
            "image": "\N{HAMMER}",
            "case_str": "Ban",
        }
        try:
            await modlog.register_casetype(**ban_case)
        except RuntimeError:
            pass

        # Registering multiple casetypes
        new_types = [
            {
                "name": "hackban",
                "default_setting": True,
                "image": "\N{BUST IN SILHOUETTE}\N{HAMMER}",
                "case_str": "Hackban",
            },
            {
                "name": "kick",
                "default_setting": True,
                "image": "\N{WOMANS BOOTS}",
                "case_str": "Kick",
            }
        ]
        await modlog.register_casetypes(new_types)
# mycog/__init__.py
from .mycog import MyCog

async def setup(bot):
    cog = MyCog()
    await bot.add_cog(cog)

Important

Image should be the emoji you want to represent your case type with.

API Reference

Mod log

class redbot.core.modlog.Case[source]

Bases: object

A single mod log case

This class should ONLY be instantiated by the modlog itself.

bot

The bot object.

Type:

Red

guild

The guild the action was taken in.

Type:

discord.Guild

created_at

The UNIX time the action occurred at.

Type:

int

action_type

The type of action that was taken.

Type:

str

user

The user target by the action.

Note

This attribute will be of type int if the Discord user can no longer be found.

Type:

Union[discord.abc.User, int]

moderator

The moderator who took the action. None if the moderator is unknown.

Note

This attribute will be of type int if the Discord user can no longer be found.

Type:

Optional[Union[discord.abc.User, int]]

case_number

The case’s number.

Type:

int

reason

The reason the action was taken. None if the reason was not specified.

Type:

Optional[str]

until

The UNIX time the action is in effect until. None if the action is permanent.

Type:

Optional[int]

channel

The channel the action was taken in. None if the action was not related to a channel.

Note

This attribute will be of type int if the channel seems to no longer exist.

Type:

Optional[Union[discord.abc.GuildChannel, discord.Thread, int]]

parent_channel_id

The parent channel ID of the thread in channel. None if the action was not done in a thread.

Type:

Optional[int]

amended_by

The moderator who made the last change to the case. None if the case was never edited.

Note

This attribute will be of type int if the Discord user can no longer be found.

Type:

Optional[Union[discord.abc.User, int]]

modified_at

The UNIX time of the last change to the case. None if the case was never edited.

Type:

Optional[float]

message

The message created by Modlog for this case. Instance of discord.Message if the Case object was returned from modlog.create_case(), otherwise discord.PartialMessage.

None if we know that the message no longer exists (note: it might not exist regardless of whether this attribute is None) or if it has never been created.

Type:

Optional[Union[discord.PartialMessage, discord.Message]]

last_known_username

The last known user handle (username / username#1234) of the user. None if the handle of the user was never saved or if their data had to be anonymized.

Type:

Optional[str]

await edit(data)[source]

Edits a case

Parameters:

data (dict) – The attributes to change

classmethod await from_json(mod_channel, bot, case_number, data, **kwargs)[source]

Get a Case object from the provided information

Parameters:
  • mod_channel (discord.TextChannel or discord.VoiceChannel, discord.StageChannel) – The mod log channel for the guild

  • bot (Red) – The bot’s instance. Needed to get the target user

  • case_number (int) – The case’s number.

  • data (dict) – The JSON representation of the case to be gotten

  • **kwargs – Extra attributes for the Case instance which override values in the data dict. These should be complete objects and not IDs, where possible.

Returns:

The case object for the requested case

Return type:

Case

Raises:
await message_content(embed=True)[source]

Format a case message

Parameters:

embed (bool) – Whether or not to get an embed

Returns:

A rich embed or string representing a case message

Return type:

discord.Embed or str

property parent_channel

The parent text/forum channel of the thread in channel.

This will be None if channel is not a thread and when the parent text/forum channel is not in cache (probably due to removal).

to_json()[source]

Transform the object to a dict

Returns:

The case in the form of a dict

Return type:

dict

class redbot.core.modlog.CaseType(name, default_setting, image, case_str, guild=None, **kwargs)[source]

Bases: object

A single case type

This class should ONLY be instantiated by the modlog itself.

name

The name of the case

Type:

str

default_setting

Whether the case type should be on (if True) or off (if False) by default

Type:

bool

image

The emoji to use for the case type (for example, :boot:)

Type:

str

case_str

The string representation of the case (example: Ban)

Type:

str

classmethod from_json(name, data, **kwargs)[source]
Parameters:
  • name (str) – The casetype’s name.

  • data (dict) – The JSON data to create an instance from

  • **kwargs – Values for other attributes of the instance

Returns:

The case type object created from given data.

Return type:

CaseType

await is_enabled()[source]

Determines if the case is enabled. If the guild is not set, this will always return False

Returns:

True if the guild is set and the casetype is enabled for the guild

False if the guild is not set or if the guild is set and the type is disabled

Return type:

bool

await set_enabled(enabled)[source]

Sets the case as enabled or disabled

Parameters:

enabled (bool) – True if the case should be enabled, otherwise False

await to_json()[source]

Transforms the case type into a dict and saves it

await redbot.core.modlog.create_case(bot, guild, created_at, action_type, user, moderator=None, reason=None, until=None, channel=None, last_known_username=None)[source]

Creates a new case.

This fires an event on_modlog_case_create

Parameters:
  • bot (Red) – The bot object

  • guild (discord.Guild) – The guild the action was taken in

  • created_at (datetime) – The time the action occurred at. If naive datetime object is passed, it’s treated as a local time (similarly to how Python treats naive datetime objects).

  • action_type (str) – The type of action that was taken

  • user (Union[discord.Object, discord.abc.User, int]) – The user target by the action

  • moderator (Optional[Union[discord.Object, discord.abc.User, int]]) – The moderator who took the action

  • reason (Optional[str]) – The reason the action was taken

  • until (Optional[datetime]) – The time the action is in effect until. If naive datetime object is passed, it’s treated as a local time (similarly to how Python treats naive datetime objects).

  • channel (Optional[Union[discord.abc.GuildChannel, discord.Thread]]) – The channel the action was taken in

  • last_known_username (Optional[str]) – The last known user handle (username / username#1234) of the user Note: This is ignored if a Member or User object is provided in the user field

Raises:
await redbot.core.modlog.get_all_cases(guild, bot)[source]

Gets all cases for the specified guild

Parameters:
  • guild (discord.Guild) – The guild to get the cases from

  • bot (Red) – The bot’s instance

Returns:

A list of all cases for the guild

Return type:

list

await redbot.core.modlog.get_all_casetypes(guild=None)[source]

Get all currently registered case types

Returns:

A list of case types

Return type:

list

await redbot.core.modlog.get_case(case_number, guild, bot)[source]

Gets the case with the associated case number

Parameters:
  • case_number (int) – The case number for the case to get

  • guild (discord.Guild) – The guild to get the case from

  • bot (Red) – The bot’s instance

Returns:

The case associated with the case number

Return type:

Case

Raises:

RuntimeError – If there is no case for the specified number

await redbot.core.modlog.get_cases_for_member(guild, bot, *, member=None, member_id=None)[source]

Gets all cases for the specified member or member id in a guild.

Parameters:
  • guild (discord.Guild) – The guild to get the cases from

  • bot (Red) – The bot’s instance

  • member (discord.Member) – The member to get cases about

  • member_id (int) – The id of the member to get cases about

Returns:

A list of all matching cases.

Return type:

list

Raises:
await redbot.core.modlog.get_casetype(name, guild=None)[source]

Gets the case type

Parameters:
  • name (str) – The name of the case type to get

  • guild (Optional[discord.Guild]) – If provided, sets the case type’s guild attribute to this guild

Returns:

Case type with provided name. If such case type doesn’t exist this will be None.

Return type:

Optional[CaseType]

await redbot.core.modlog.get_latest_case(guild, bot)[source]

Get the latest case for the specified guild.

Parameters:
  • guild (discord.Guild) – The guild to get the latest case for.

  • bot (Red) – The bot object.

Returns:

The latest case object. None if it the guild has no cases.

Return type:

Optional[Case]

await redbot.core.modlog.get_modlog_channel(guild)[source]

Get the current modlog channel.

Parameters:

guild (discord.Guild) – The guild to get the modlog channel for.

Returns:

The channel object representing the modlog channel.

Return type:

discord.TextChannel, discord.VoiceChannel, or discord.StageChannel

Raises:

RuntimeError – If the modlog channel is not found.

await redbot.core.modlog.register_casetype(name, default_setting, image, case_str)[source]

Registers a case type. If the case type exists and there are differences between the values passed and what is stored already, the case type will be updated with the new values

Parameters:
  • name (str) – The name of the case

  • default_setting (bool) – Whether the case type should be on (if True) or off (if False) by default

  • image (str) – The emoji to use for the case type (for example, :boot:)

  • case_str (str) – The string representation of the case (example: Ban)

Returns:

The case type that was registered

Return type:

CaseType

Raises:
await redbot.core.modlog.register_casetypes(new_types)[source]

Registers multiple case types

Parameters:

new_types (list) – The new types to register

Returns:

True if all were registered successfully

Return type:

bool

Raises:
await redbot.core.modlog.reset_cases(guild)[source]

Wipes all modlog cases for the specified guild.

Parameters:

guild (discord.Guild) – The guild to reset cases for

await redbot.core.modlog.set_modlog_channel(guild, channel)[source]

Changes the modlog channel

Parameters:
Returns:

True if successful

Return type:

bool