![](assets/banners/hifumi_new.png)
Prefix: $ | Language: Typescript | Library: Discord.js | Hifumi's Website | Invite Me! | Join the Support Server |
-
Moderation: 🚫 Get all your moderators on the same page
- Anti-Spam Hifumi automatically removes messages and mutes people when she detects spamming.
- Invite Filtering Invites are automatically removed and added to a users history, offenders are banned after 5 invites by default or a custom value if needed.
- New Member Tracking To combat raiders, she has an option to track people who have joined in the past 5 minutes more closely. Banning on 2 invites instead of the custom limit (if invites are not allowed) and banning on detecting first spam instead of muting.
$history
- Pull up a user's history with information on their previous strikes, notes, invites, mutes and join dates.$strike
- Warn members when they break rules anonymously, adding to their total strikes (or not with$warn
), strikes are automatically expire after 2 weeks, users who go past the strike limit of the server are banned automatically$note
- Note something about a specific user for a later time, saving it in the members history$mute
- Mute a user for a specific time with a given reason$cleanse
- Remove messages sent by bots in a channel$nuke
- Clean all previous messages in a channel of a given amount$snipe
- Remove messages in a channel from a specific user$ignore
- Stop listening for commands and conversations from a specific user or channel
-
Management: 🛠️ Tools to make server management easier
$suggest
- Suggest something that you would like to see get added in the server$suggestions
- Look through suggestions that are waiting approval, approve the serious ones, deny the jokes by clicking on reactions$accept
- Accept someone's suggestion with a reason. Accepting suggestions DMs the user to let them know they contributed$reject
- Reject someone's suggestion with a reason. Rejecting suggestions also DMs the user to let them know they contributed$addmacro
- Add a new custom command for Hifumi to reply to with a response of your choosing$macros
- List all the macros in the server$deletemacro
- Deletes one of the previous saved macros
-
Customization: ⚙ Change Hifumi to fit your server
$setgreeting
- Customize the message you want Hifumi to greet new members with$log
- Change logging settings by assigning a channel for a specific category of logs or turning it off entirely- Logging options: joins, leaves, mutes, bans, unbans, channel management, suggestions, commands, invites, ping spam
$settings
- Changes bot settings$settings prefix
- Changes the prefix I reply to$settings hints
- Hifumi tries to guess what you meant when you enter incorrect commands$settings reactions
- Reactions are added to certain messages, or not, if you find that annoying$settings tracking
- Enable/disable tracking of new members$settings invites
- Are invites ok to send in this server?$settings invitewarn
- Threshold for warning members for sending invites$settings inviteban
- Threshold for banning members for sending invites$settings strikelimit
- Max number of strikes a user can have before getting banned (3 by default)
-
Fun: 🎉 Time to relax
$anime
- Sends details about a specific anime and the date the next ep comes out on (if still airing)$character
- Sends information about an anime character$whatanime
- Tries to find the name and the episode of an anime from a screenshot or a gif$doggo
- Sends a cute 🐶 and its breed$randomquote
- A quote... that is random$ch
- Random cyanide and happiness comic
Commands are all declared under src/commands/**/*.ts
and are globbed in src/handlers/commands/CommandHandler.ts
.
The addition of a new command only requires that a variable called command
is exported somewhere inside src/commands
Before commands are called, information is parsed in src/parsers/argParse.ts
.
All command requirements like arguments and user/client permissions are declared in the Command object that is exported and parsed before calling the command.
A command is only called if these requirements are met.
All necessary arguments are passed into the run
function's second parameter as a tuple.
Anime information is all taken from AniList using graphql.
"Wait a minute, anilist? How are you getting such accurate anime search results?!"
Heh, as much as I love anilist and their API, unfortunately their search engine soon to be changed™ is really bad.
To get around this we use MAL instead... except not really. MAL's API is still either down or not working properly, also their API is
from the stone ages so instead we only use the search hinting endpoint.
This search function for MAL seems to be operating independently from the rest of their API, you don't need any sort of authorization to make a request to the endpoint AND there's virtually no rate limiting. Plus, due to the nature of the search function, the responses are usually blazing fast.
https://myanimelist.net/search/prefix.json?type=[all|manga|anime]&keyword=[url encoded query here]
The information that's returned is mostly irrelevant except for the order of the items
array which represents the closest match
and the id
property. Because AniList is so awesome, almost all of their entries also contain the MAL id of anime entries, meaning
that all that's left to do is query AniList using the mal_id and that's it!
The only caveat is that sometimesMAL will return results based on popularity and not search match so it's necessary to go through all the results and look for a perfect case-insensitive match before we pull the first result in case a user searches for Sword Art Online or New Game!!.
TypeORM is used for all database transactions.
A Redis cache layer is used to speed up common actions like fetching guild prefixes.
Database information is stored in src/database
including
- Models
- Functions
- Migrations
For now, migrations are created manually for production are handled by TypeORM's CLI.
For database backups, python scripts are used to dump the current production db into Amazon S3 bucket.
This script is set on a cron job of regular intervals, and an X amount of backups are rotated inside the bucket, deleting the oldest version on every backup once X is reached to preserve limited bucket space.
A backup-restoration script is available to restore the latest backup if necessary.
Coming soon...