Abc Reference
This Protocol simply defines how a Cache
should work. This is going to only be useful if
you either plan on working directly with an existing
cache or wish to build your own.
Any form of internal cache is guranteed to implement this so you can treat it as a source of truth for usage. (Unless you bypass them)
- class antispam.abc.Cache(*args, **kwargs)
A generic Protocol for any Cache to implement
- async add_message(message: Message) None
Adds a Message to the relevant Member, creating the Guild/Member if they don’t exist
- Parameters:
message (Message) – The Message to add to the internal cache
Notes
This should silently create any Guild’s/Member’s required to fulfil this transaction
- async delete_guild(guild_id: int) None
Removes a guild from the cache. This should also remove all members.
- Parameters:
guild_id (int) – The id of the guild we wish to remove
Notes
This fails silently.
- async delete_member(member_id: int, guild_id: int) None
Removes a member from the cache.
- Parameters:
Notes
This fails silently.
- async get_all_guilds() AsyncIterable[Guild]
Returns a generator containing all cached guilds
- Yields:
Guild – A generator of all stored guilds
- async get_all_members(guild_id: int) AsyncIterable[Member]
Fetches all members within a guild and returns them within a generator
- Parameters:
guild_id (int) – The guild we want members in
- Yields:
Member – All members in the given guild
- Raises:
GuildNotFound – The given guild was not found
- async get_guild(guild_id: int) Guild
Fetch a Guild dataclass populated with members
- Parameters:
guild_id (int) – The id of the Guild to retrieve from cache
- Raises:
GuildNotFound – A Guild could not be found in the cache with the given id
- async get_member(member_id: int, guild_id: int) Member
Fetch a Member dataclass populated with messages
- Parameters:
- Raises:
MemberNotFound – This Member could not be found on the associated Guild within the internal cache
GuildNotFound – The relevant guild could not be found
- async initialize(*args, **kwargs) None
This method gets called once when the AntiSpamHandler init() method gets called to allow for setting up connections, etc
Notes
This is not required.
- async reset_member_count(member_id: int, guild_id: int, reset_type: ResetType) None
Reset the chosen enum type back to the default value
- Parameters:
Notes
This shouldn’t raise an error if the member doesn’t exist.
- async set_guild(guild: Guild) None
Stores a Guild in the cache
This is essentially a UPSERT operation
- Parameters:
guild (Guild) – The Guild that needs to be stored
Warning
This method should be idempotent.
The passed guild object should not experience a change to the callee.
- async set_member(member: Member) None
Stores a Member internally and attaches them to a Guild, creating the Guild silently if required
Essentially an UPSERT operation
- Parameters:
member (Member) – The Member we want to cache
Warning
This method should be idempotent.
The passed member object should not experience a change to the callee.
- class antispam.abc.Lib(*args, **kwargs)
A protocol to extend and implement for any libs that wish to hook into this package and work natively.
You also should to subclass
antispam.libs.shared.base.Baseas it implements a lot of shared functionality.- async check_message_can_be_propagated(message) PropagateData
Given a message from the relevant package, run all checks to check if this message should be propagated.
Notes
- Should error on the following:
If not an instance of the library’s message class
If in dm’s
If the message is from yourself (the bot)
If
self.handler.options.ignore_botsisTrueand the message is from a botIf the guild id is in
self.handler.options.ignored_guildsIf the member id is in
self.handler.options.ignored_membersIf the channel id is in
self.handler.options.ignored_channelsIf any of the member’s roles (id) are in
self.handler.options.ignored_roles
PropagateData.has_perms_to_make_guildshould beTrueif the member has permissions to kick and ban members
- Parameters:
message (Union[discord.Message, hikari.messages.Message, pincer.objects.Embed]) – The message to check
- Returns:
The data required within propagate
- Return type:
- Raises:
PropagateFailure – This raises an error with the .data attribute set. .data is what gets returned from within propagate itself.
- async create_message(message) Message
Given a message to extract data from, create and return a Message class.
The following should be dumped together as content. Order doesn’t matter as long as it’s consistent.
All sticker urls for stickers in the message
The actual message content
All embeds cast to a string via
embed_to_string
- Parameters:
message (Union[discord.Message, hikari.messages.Message, pincer.objects.UserMessage]) – The message to extract data from
- Returns:
The flushed out message
- Return type:
- Raises:
InvalidMessage – If it couldn’t create a message, I.e message only contained attachments
Warning
This is REQUIRED to be inline with the end options.
1if self.handler.options.delete_zero_width_chars: 2 content = ( 3 content.replace("u200B", "") 4 .replace("u200C", "") 5 .replace("u200D", "") 6 .replace("u200E", "") 7 .replace("u200F", "") 8 .replace("uFEFF", "") 9 )
- async delete_member_messages(member: Member) None
Given a member, traverse all duplicate messages and delete them.
- Parameters:
member (Member) – The member whose messages should be deleted
Notes
Just call delete_message on each message
If you need to fetch the channel, cache it please.
- async delete_message(message) None
Given a message, call and handle the relevant deletion contexts.
- Parameters:
message (Union[discord.Message, hikari.messages.Message, pincer.objects.UserMessage]) – The message to delete
Notes
This should handle given errors silently.
- async dict_to_embed(data: dict, message, warn_count: int, kick_count: int)
- Parameters:
data (dict) – The data to build an embed from
message (Union[discord.Message, hikari.messages.Message]) – The message to extract data from
warn_count (int) – How many warns this person has
kick_count (int) – How many kicks this person has
- Returns:
The embed
- Return type:
Union[discord.Embed, hikari.embeds.Embed, pincer.objects.Embed]
Notes
This is implemented in
antispam.libs.shared.base.Baseso assuming you subclass it you don’t need to create this.
- async dict_to_lib_embed(data: Dict)
Create an Embed object using a dictionary and return that.
- Parameters:
data (Dict) – The data to create the embed from
- Returns:
The dictionary as an embed
- Return type:
Union[discord.Embed, hikari.embeds.Embed, pincer.objects.Embed]
- async embed_to_string(embed) str
Given an embed, return a string representation.
This string representation should include the following. Ordering does not matter as long as it is consistent.
The embeds title
The embeds description
The embeds footer text
The embeds author name
All names + values for embed fields
- Parameters:
embed (Union[discord.Embed, hikari.embeds.Embed]) – The embed to cast to string
- Returns:
The embed as a string
- Return type:
Notes
This is implemented in
antispam.libs.shared.base.Baseso assuming you subclass it you don’t need to create this.
- async get_channel_from_message(message)
Given a message, return the channel object it was sent in.
- get_file(path: str)
Returns a file object for the given path.
For example, in discord.py this is
discord.File
- async get_member_from_message(message)
Given the message, return the Author’s object
- Parameters:
message (Union[discord.Message, hikari.messages.Message, pincer.objects.Embed]) – The message to extract it from
- Returns:
The member object
- Return type:
Union[discord.Member, hikari.guilds.Member, …]
- async get_message_mentions(message) List[int]
Returns all the mention id’s from a message.
- This should include:
People
Roles
Channels
- async get_substitute_args(message) SubstituteArgs
Given a message, return the relevant class filled with data for usage within
substitute_args- Parameters:
message (Union[discord.Message, hikari.messages.Message, pincer.objects.UserMessage]) – The message we are using for creation
- Returns:
A dataclass with the relevant data for substitution.
- Return type:
- is_dm(message) bool
Returns True if this message occurred in a dm, False otherwise.
- Parameters:
message – The discord message this is called on.
- async is_member_currently_timed_out(member) bool
Given the libraries member object, return True if they are currently timed out or False otherwise.
- Parameters:
member (Union[discord.member, hikari.guilds.Member]) – The member to check agaisnt.
- Returns:
True if timed out, otherwise False
- Return type:
- async lib_embed_as_dict(embed) Dict
Given the relevant Embed object for your library, return it in dictionary form.
- Parameters:
embed (Union[discord.Embed, hikari.embeds.Embed, pincer.objects.Embed]) – The embed
- Returns:
The embed as a dictionary
- Return type:
- async punish_member(original_message, member: Member, internal_guild: Guild, user_message, guild_message, is_kick: bool, user_delete_after: int | None = None, channel_delete_after: int | None = None)
A generic method to handle multiple methods of punishment for a user. Supports: kicking, banning
- Parameters:
member (Member) – A reference to the member we wish to punish
internal_guild (Guild) – A reference to the guild this member is in
original_message (Union[discord.Message, hikari.messages.Message, pincer.objects.UserMessage]) – Where we get everything from :)
user_message (Union[str, discord.Embed, hikari.embeds.Embed, pincer.objects.Embed]) – A message to send to the user who is being punished
guild_message (Union[str, discord.Embed, hikari.embeds.Embed, pincer.objects.Embed]) – A message to send in the guild for whoever is being punished
is_kick (bool) – Is it a kick? Else ban
user_delete_after (int, Optional) – An int value denoting the time to delete user sent messages after
channel_delete_after (int, Optional) – An int value denoting the time to delete channel sent messages after
- Raises:
MissingGuildPermissions – I lack perms to carry out this punishment
- Returns:
Did the punishment succeed?
- Return type:
Notes
Due to early design decisions, this will only ever support kicking or banning. A pain for you and I.
- async send_guild_log(guild, message, delete_after_time: int | None, original_channel, file=None) None
Sends a message to the guilds log channel
- Parameters:
guild (Guild) – The guild we wish to send this too
message (Union[str, discord.Embed, hikari.embeds.Embed, pincer.objects.Embed]) – What to send to the guilds log channel
delete_after_time (Optional[int]) – How long to delete these messages after
original_channel (Union[discord.abc.GuildChannel,discord.abc.PrivateChannel,hikari.channels.GuildTextChannel,pincer.objects.Channel]) – Where to send the message assuming this guild has no guild log channel already set.
file – A file to send
Notes
This should catch any sending errors, log them and then proceed to return None.
If no log channel, don’t send anything.
- async send_message_to_(target, message, mention: str, delete_after_time: int | None = None) None
Send the given message to the target.
- Parameters:
target (Union[discord.abc.Messageable, hikari.channels.TextableChannel]) –
Where to send the message.
Types are unknown for Pincer at this time.
message (Union[str, discord.Embed, hikari.embeds.Embed, pincer.objects.Embed]) – The message to send
mention (str) – A string denoting a raw mention of the punished user
delete_after_time (Optional[int]) – When to delete the message after
Notes
This should implement Options.mention_on_embed
- async substitute_args(message: str, original_message, warn_count: int, kick_count: int) str
Given a message, substitute in relevant arguments and return a valid string
- Parameters:
message (str) – The message to substitute args into
original_message (Union[discord.Message, hikari.messages.Message, pincer.objects.UserMessage]) – The message to extract data from
warn_count (int) – How many warns this person has
kick_count (int) – How many kicks this person has
- Returns:
The message with substituted args
- Return type:
Notes
This is implemented in
antispam.libs.shared.base.Baseso assuming you subclass it you don’t need to create this.
- async timeout_member(member, original_message, until: timedelta) None
Timeout the given member.
- Parameters:
member (Union[discord.Member, hikari.guilds.Member]) – The member to timeout
original_message – The message being propagated
until (datetime.timedelta) – How long to time them out for.
- Raises:
UnsupportedAction – Timing out members is not supported.
MissingGuildPermissions – Can’t time this member out
- async transform_message(item: str | dict, message, warn_count: int, kick_count: int)
- Parameters:
message (Union[discord.Message, hikari.messages.Message, pincer.objects.UserMessage]) – The message to extract data from
warn_count (int) – How many warns this person has
kick_count (int) – How many kicks this person has
- Returns:
A template complete message ready for sending
- Return type:
Union[str, discord.Embed, hikari.embeds.Embed]
Notes
This is implemented in
antispam.libs.shared.base.Baseso assuming you subclass it you don’t need to create this.
- async visualizer(content: str, message, warn_count: int = 1, kick_count: int = 2)
Returns a message transformed as if the handler did it
- Parameters:
content (Union[str, discord.Embed, hikari.embeds.Embed]) – What to transform
message (Union[discord.Message, hikari.messages.Message]) – Where to extract our values from
warn_count (int) – The warns to visualize with
kick_count (int) – The kicks to visualize with
- Returns:
The transformed content
- Return type:
Union[str, discord.Embed]
Notes
This is implemented in
antispam.libs.shared.base.Baseso assuming you subclass it you don’t need to create this.