WarnSystem

API Reference

class warnsystem.api.API(bot, config)[source]

Interact with WarnSystem from your cog.

To import the cog and use the functions, type this in your code:

warnsystem = bot.get_cog('WarnSystem').api

Warning

If warnsystem is None, the cog is not loaded/installed. You won’t be able to interact with the API at this point.

Tip

You can get the cog version by doing this

version = bot.get_cog('WarnSystem').__version__
await edit_case(guild: discord.guild.Guild, user: Union[discord.user.User, discord.member.Member], index: int, new_reason: str) → bool[source]

Edit the reason of a case.

Parameters
  • guild (discord.Guild) – The guild where you want to get the case from.

  • user (Union[discord.User, discord.Member]) – The user you want to get the case from.

  • index (int) – The number of the case you want to edit.

  • new_reason (str) – The new reason to set.

Returns

True if the action succeeded.

Return type

bool

Raises
  • BadArgument – The reason is above 1024 characters. Due to Discord embed rules, you have to make it shorter.

  • NotFound – The case requested doesn’t exist.

await format_reason(guild: discord.guild.Guild, reason: str = None) → str[source]

Reformat a reason with the substitutions set on the guild.

Parameters
  • guild (discord.Guild) – The guild where the warn is set.

  • reason (str) – The string you want to reformat.

Returns

The reformatted string

Return type

str

await get_all_cases(guild: discord.guild.Guild, user: Union[discord.user.User, discord.member.Member, None] = None) → list[source]

Get all cases for a member of a guild.

Parameters
  • guild (discord.Guild) – The guild where you want to get the cases from.

  • user (Optional[Union[discord.User, discord.Member]]) – The user you want to get the cases from. If this arguments is omitted, all cases of the guild are returned.

Returns

A list of all cases of a user/guild. The cases are sorted from the oldest to the newest.

If you specified a user, you should get something like this:

[
    {  # case #1
        "level"     : int,  # between 1 and 5, the warning level
        "author"    : Union[discord.Member, str],  # the member that warned the user
        "reason"    : Optional[str],  # the reason of the warn, can be None
        "time"      : datetime.datetime,  # the date when the warn was set
    },
    {
        # case #2
    },
    # ...
]

However, if you didn’t specify a user, you got all cases of the guild. As for the user, you will get a list of the cases, with another key for specifying the warned user:

{  # case #1
    "level"     : int,  # between 1 and 5, the warning level
    "author"    : Union[discord.Member, str],  # the member that warned the user
    "reason"    : Optional[str],  # the reason of the warn, can be None
    "time"      : datetime.datetime,  # the date when the warn was set

    "member"    : discord.User,  # the member warned, this key is specific to guild
}

Return type

list

await get_case(guild: discord.guild.Guild, user: Union[discord.user.User, discord.member.Member], index: int) → dict[source]

Get a specific case for a user.

Parameters
Returns

A dict which has the following body:

Return type

dict

Raises

NotFound – The case requested doesn’t exist.

await get_embeds(guild: discord.guild.Guild, member: Union[discord.member.Member, warnsystem.api.UnavailableMember], author: Union[discord.member.Member, str], level: int, reason: Optional[str] = None, time: Optional[datetime.timedelta] = None, message_sent: bool = True) → tuple[source]

Return two embeds, one for the modlog and one for the member.

Warning

Unlike for the warning, the arguments are not checked and won’t raise errors if they are wrong. It is recommanded to call warn() and let it generate the embeds instead.

Parameters
  • guild (discord.Guild) – The Discord guild where the warning takes place.

  • member (Union[discord.Member, UnavailableMember]) – The warned member. Should only be UnavailableMember in case of a hack ban.

  • author (Union[discord.Member, str]) – The moderator that warned the user. If it’s not a Discord user, you can specify a str instead (e.g. “Automod”).

  • level (int) – The level of the warning which should be between 1 and 5.

  • reason (Optional[str]) – The reason of the warning.

  • time (Optional[timedelta]) – The time before the action ends. Only for mute and ban.

  • message_sent (bool) – Set to False if the embed couldn’t be sent to the warned user.

Returns

A tuple with the modlog embed at index 0, and the user embed at index 1.

Return type

tuple

await get_modlog_channel(guild: discord.guild.Guild, level: Union[int, str, None] = None) → discord.channel.TextChannel[source]

Get the WarnSystem’s modlog channel on the current guild.

When you call this, the channel is get with the following order:

  1. Get the modlog channel associated to the type, if provided

  2. Get the defult modlog channel set with WarnSystem

  3. Get the Red’s modlog channel associated to the server

Parameters
  • guild (discord.Guild) – The guild you want to get the modlog from.

  • level (Optional[Union[int, str]]) –

    Can be an int between 1 and 5, a str ("all") or None.

    • If the argument is omitted (or None is provided), the default modlog channel will be returned.

    • If an int is given, the modlog channel associated to this warning level will be returned. If a specific channel was not set for this level, the default modlog channel will be returned instead.

    • If "all" is returned, a dict will be returned. It should be built like this:

      {
          "main"      : 012345678987654321,
          "1"         : None,
          "2"         : None,
          "3"         : None,
          "4"         : 478065433996537900,
          "5"         : 567943553912O46428,
      }
      

      A dict with the possible channels is returned, associated with an int corresponding to the channel ID set, or None if it was not set.

      For technical reasons, the default channel is actually named "main" in the dict.

Returns

channel – The channel requested.

Note

It can be None if the channel doesn’t exist anymore.

Return type

discord.TextChannel

Raises

NotFound – There is no modlog channel set with WarnSystem or Red, ask the user to set one.

await maybe_create_mute_role(guild: discord.guild.Guild) → bool[source]

Create the mod role for WarnSystem if it doesn’t exist.

Parameters

guild (discord.Guild) – The guild you want to set up the mute in.

Returns

  • True if the role was successfully created.

  • False if the role already exists.

  • list of str if some channel updates failed, containing the message explaining the error for each message

Return type

bool

Raises
  • MissingPermissions – The bot lacks the discord.PermissionOverwrite.create_roles permission.

  • discord.errors.HTTPException – Creating the role failed.

await warn(guild: discord.guild.Guild, members: Iterable[Union[discord.member.Member, warnsystem.api.UnavailableMember]], author: Union[discord.member.Member, str], level: int, reason: Optional[str] = None, time: Optional[datetime.timedelta] = None, log_modlog: Optional[bool] = True, log_dm: Optional[bool] = True, take_action: Optional[bool] = True, progress_tracker: Optional[Callable[[int], Awaitable[None]]] = None) → bool[source]

Set a warning on a member of a Discord guild and log it with the WarnSystem system.

Tip

The message that comes with the following exceptions are already translated and ready to be sent to Discord:

Parameters
  • guild (discord.Guild) – The guild of the member to warn

  • member (Iterable[Union[discord.Member, UnavailableMember]]) – The member that will be warned. It can be an instance of warnsystem.api.UnavailableMember if you need to ban someone not in the guild.

  • author (Union[discord.Member, str]) – The member that called the action, which will be associated to the log.

  • level (int) –

    An int between 1 and 5, specifying the warning level:

    1. Simple DM warning

    2. Mute (can be temporary)

    3. Kick

    4. Softban

    5. Ban (can be temporary ban, or hack ban, if the member is not in the server)

  • reason (Optional[str]) – The optional reason of the warning. It is strongly recommanded to set one.

  • time (Optional[timedelta]) – The time before cancelling the action. This only works for a mute or a ban.

  • log_modlog (Optional[bool]) – Specify if an embed should be posted to the modlog channel. Default to True.

  • log_dm (Optional[bool]) – Specify if an embed should be sent to the warned user. Default to True.

  • take_action (Optional[bool]) – Specify if the bot should take action on the member (mute, kick, softban, ban). If set to False, the bot will only send a log embed to the member and in the modlog. Default to True.

  • progress_tracker (Optional[Callable[[int], Awaitable[None]]]) –

    an async callable (function or lambda) which takes one argument to follow the progress of the warn. The argument is the number of warns committed. Here’s an example:

    i = 0
    message = await ctx.send("Mass warn started...")
    
    async def update_count(count):
        i = count
    
    async def update_msg():
        await message.edit(content=f"{i}/{len(members)} members warned.")
        await asyncio.sleep(1)
    
    await api.warn(guild, members, ctx.author, 1, progress_tracker=update_count)
    

Returns

A dict of members which couldn’t be warned associated to the exception related.

Return type

dict

Raises
  • InvalidLevel – The level must be an int between 1 and 5.

  • BadArgument – You need to provide a valid discord.Member object, except for a hackban where a discord.User works.

  • NotFound – You provided an int for a hackban, but the bot couldn’t find it by calling discord.Client.get_user_info().

  • MissingMuteRole – You’re trying to mute someone but the mute role was not setup yet. You can fix this by calling maybe_create_mute_role().

  • LostPermissions – The bot lost a permission to do something (it had the perm before). This can be lost permissions for sending messages to the modlog channel or interacting with the mute role.

  • MemberTooHigh – The bot is trying to take actions on someone but his top role is higher than the bot’s top role in the guild’s hierarchy.

  • NotAllowedByHierarchy – The moderator trying to warn someone is lower than him in the role hierarchy, while the bot still has permissions to act. This is raised only if the hierarchy check is enabled.

  • MissingPermissions – The bot lacks a permissions to do something. Can be adding role, kicking or banning members.

  • discord.errors.HTTPException – Unknown error from Discord API. It’s recommanded to catch this potential error too.

Errors

Custom error handling used for the cog and the API.

If you need to prevent and exception, do it like this:

warnsystem = bot.get_cog('WarnSystem')
api = cog.api
errors = cog.errors

try:
    await api.warn(5, user, "my random reason")
except discord.errors.Forbidden:
    print("Missing permissions")
except errors.InvalidLevel:
    print("Wrong warning level")
except:
    # occurs for any exception
    print("Fatal error")
else:
    # executed if the try succeeded
    print("All good")
finally:
    # always executed
    print("End of function")
exception warnsystem.errors.InvalidLevel[source]

The level argument for warn() is wrong. It must be between 1 and 5.

exception warnsystem.errors.NotFound[source]

Something was not found in the WarnSystem data. The meaning of this exception depends of what you called, it may be a missing WarnSystem channel.

exception warnsystem.errors.MissingMuteRole[source]

You requested a mute warn but the mute role doesn’t exist. Call maybe_create_role() to fix this.

exception warnsystem.errors.BadArgument[source]

The arguments provided for your request are wrong, check the types.

exception warnsystem.errors.MissingPermissions[source]

The bot lacks a permission to do an action.

This is raised instead of discord.errors.Forbidden to prevent a useless API call, we check the bot’s permissions before calling.

exception warnsystem.errors.MemberTooHigh[source]

The member to take action on is above the bot in the guild’s role hierarchy.

To fix this, set the bot’s top role above the member’s top role. For more informations about Discord Permissions, read this: https://support.discordapp.com/hc/en-us/articles/206029707

This is raised instead of discord.errors.Forbidden to prevent a useless API call, we check the bot’s permissions before calling.

exception warnsystem.errors.NotAllowedByHierarchy[source]

The bot is set to respect the role hierarchy; the moderator requested a warn against someone equal or higher than him in the hierarchy, which is not allowed by Discord permissions rules.

The moderator must have a role higher than the warned member to continue.

Note

This cannot be raised if the admins disabled the role hierarchy check.

exception warnsystem.errors.LostPermissions[source]

The bot lost a permission he had.

This can be the permission to send messages in the modlog channel or use the mute role.