Below are verbose instructions for using the various features of Sharkbot. For documentation on commands Sharkbot can use by default, view that readme instead. Most of these features were grown from other project, but all relevant information is below for convenience. All features require a config file in .config/<feature name>.js
, and must have active: true
as an entry.
This widget will send messages (including files, etc.) to the specified channel at the specified time. There are various options to allow for a random message to be sent from an Array, tagging a person or role, and sending random files from a folder or specified Array.
defaultTimezone
: the timezone on which to base the alarms. Find a valid one fromsurpriseFreq
: default frequency to post a surprise-type message
The rules these alarms are created from go in .rules/alarms
as .js
files. These rules must have the following structure (required options where noted):
channelIds
: (*required* either here or in theposts
entry/ies) Array of channel ids to send the scheduled messagecronTime
: (*required*) cron expression specifying the time(s) at which to send the messagementionIds
: Array of mentionable ids to "@" in the messagepolicies
: Object with the following options:content
:random
orstatic
(defaultstatic
).static
sends the first (0th) text from thecontent
Array in a post,random
sends a random textfiles
:random
orstatic
(defaultstatic
). Similar tocontent
, determines how to choose file/s to sendpost
:random
,static
, orweighted
(defaultstatic
). Determines how to choose which post fromposts
to send.random
andstatic
are similar to the above, andweighted
uses theweight
in each post to randomly choose a post by weight (the weights need not sum to any particular number)surprise
: (defaultfalse
) eitherfalse
or a decimal value (0<x<1), where x is the chance to send a message. If a number is given but x<0 or x>1,surpriseFreq
from theconfig
is used
posts
: (*required*) Array of Objects detailing what (and potentially where) to send at a message the specifiedcronTime
. It must contain at least 1 Object, with the following options:channelIds
: (*required* either here or in the main body of the rule) Array of channel ids to send this post specificallycontent
: (*required* unless there is at least one entry infiles
) Array of text to send (chosen according tocontent
policy (see above))delayTime
: amount of time to wait aftercronTime
before sending this postfiles
: (*required* unless there is at least one entry incontent
) Array of Arrays of absolute filepaths to be attached to message (chosen based onfiles
policy (see above)). Note: in the includedEXAMPLE.js
file is a function that grabs all the files from a specified foldermentionIds
: Array of mentionable ids to "@" in the messageweight
: amount to weight this post by (forweighted
post policy (see above))
timezone
: for using a different timezone to schedule this rule
To be included: I do not use embeds, but it would be straightforward to implement this to send embeds as well. Adding a command so any user can add an alarm manually seems easy enough, but will not persist through restarts.
This feature designates a channel as a suggestion box. Messages sent there by non-mod members are deleted by default and copied to a mod-only channel for private discussion. Of course, if the copy-to channel is not a mod-only channel, anyone will be able to read it.
A slash command /ask
has been added so people can send asks privately to the sendToChId
without having a publicly visible post (the slash command is responded to ephemerally).
askChId
: channel ID of "suggestion box" channelsendToChId
: channel ID of mod-only channel which receives copied messages fromaskCh
private
:true
(default) orfalse
. If true, original message from sent toaskCh
will be deletedallowAnon
:false
(default), ortrue
. If true, copied messages will be sent without sender's username for anonymous submissionsanonPrefixes
: Array of allowed prefixes, to be contained in square brackets. E.g., "[anon] mods suck >:(" would send the message anonymously
This feature is loaded automatically, and is the only one that cannot be deactivated (i.e., it does not require active: true
in its config file). This is in part to have better legibility for commands which "belong" to specific features, but also because certain methods are created here which are on occasion used by other features (at this point most of these have probably been removed?). The default commands are detailed in the commands readme.
To add or remove commands, add or delete files from the /<widget>/commands/text
folder in whichever widget the command can be found in, or the /commands/text
folder in root.
Recently, slash commands have been added and implemented in a similar way to what I'm calling text commands. These use Discord.JS's built-in SlashCommandBuilder
, which I've extended slightly in SlashBuilderPlus
. In much the same way to text commands, these can easily be added or removed by adding or deleting files from the respective /commands/slash
folder. Most text commands have a (near) identical slash command, and in cases where they are identical the bulk of the work is in a "shared" file in the co-located /shared
folder. For more information on how these are implemented in Discord.JS, read this guide.
There are still some text commands (e.g., affirm
) that require functionality that slash commands do not provide (or is much easier to do without the inherent limitations of hard-coding options), or have been kept for posterity (or fun, e.g., I like being able to type ?weekend
to see if it's the weekend or not).
If a user sends a message that is a haiku, Sharkbot will reformat and repost it. To keep things sane, Sharkbot will not repost every valid haiku (controlled with frequency
), and he can ignore some channels entirely (listed in ignoredChannels
). If he made a bad haiku (or something that shouldn't have been a haiku for whatever reason), the original author of the haiku is able to react with 🚫
in the first five minutes and the haiku will be deleted. After the time limit, and if a valid channel ID is given, Sharkbot will repost the haiku in the specified archive channel.
allowedForms
: an Array of pattern Arrays. By default, only 5-7-5 haiku will be considered validignoredChannels
: Array of channel IDs to ignore completely when making haiku (also uses the default ignored channels from the.bot.js
config file)alwaysChannels
: only relevant when afrequency
is given. Valid haiku in these channels will always be reposted, regardless of frequencyarchiveChannel
: (optional) channel ID to send copies of haiku tofrequency
: (optional) defines how frequently a valid haiku will be reposted, to reduce clutter/spam
There are some commands for this feature, see the command documentation for more.
To be implemented: this feature functions as intended. I have considered sending the haiku as images, but have not devoted the time to that.
In some ways an extension of member-db
, this widget controls the level progression of users as they spend time in the server. This has taken me a while to figure out how to implement in a way that makes sense and is readable. The widget keeps track of members' various doings, and levels up based on a set of rules in the corresponding /.rules/levels/go##.js
.
levelLogChId
: channel ID to send leveling information tolevelIds
: IDs of level roles, in order from lowest to highest
Each go##.js
has a prep
(what to do/what values to re/set when the user gets to level n), a check
(checking to see if the user can level from n to n+1), an approve
(for if the checked leveling needs mod approval), and a denied
(what happens if the leveling is denied by a mod). When a member is or is eligible for leveling, Sharkbot will post in the specified channel levelLogChId
. Level ids go in /levels-config.js
, and should be ordered from lowest/least privileged to highest/most privileged.
Enables message logging in the shell window. Currently investigating an unobtrusive way to write the console to a file.
ccDM
: whether or not to send copies of messages the bot receives to the owner (specified in the.bot.js
config file)
Another widget that spent a while in development hell, mostly because I didn't understand how to use async functions properly (still don't). This widget gives the ability to write user info to a file, so that in the event of a crash/reboot, not everything is lost. In normal use this is probably not crucial (unless you really care about tracking nicknames?), but is vital for levels
to function, as some functionality it adds is used by levels
. I think it's best to write the files automatically with, say, setInterval()
in /handlers/ready
, but you can also do it manually with the !writedb
command.
Allows reacting and/or replying to messages given specific criteria.
Rules are kept in a separate files for better read- and editability. Examples given in /.rules/message-reacts
.
ifs
: logical expression returning true or false based on the conditions for thereacts
to triggerpriors
: (optional) if anything needs to be created/added in order to achieve the desiredreacts
. Loaded at client startupreacts
: the actions to take ififs
returns true
The bones here are taken from a peterthehan widget, reaction-role-bot. The implementation has been modified to keep the handlers clean, and almost all the functionality is now contained within the ReactTracker
class.
All rules are .json
files in /.rules/reaction-roles
, where an example is given (filenames do not matter, just the extension).
messageId
: ID of the message to trackchannelId
: ID of the channel the message is inisUnique
: if this is set totrue
, users will only be allowed to react with one emoji (other reactions will be removed). Roles will be set in accordance with the most recent reactionreactAgnostic
: if this is set totrue
, any reaction (not just ones in the role map) sent by a user will cause the user to be assigned all roles in the role mapemojiRoleMap
: a Map, of one emoji (or valid emoji ID) to an Array of role IDs. The roles will be added or removed when a user reacts or un-reacts with the corresponding emoji
Based heavily on (the now outdated) scryfall servo bot, but with better functionality and the ability to flip dual-faced cards (thanks to iColtz). Search for any card with [[card name]]
, or use Scryfall's search directly with [[~search terms]]
.
To be included: [[!card]]
to display only the image and [[?card]]
to send the formats in which the card is legal. Refer to Scryfall for search syntax documentation.
Similar to askbox, only the message is copied and sent to the same channel it was sent to originally before being deleted. Any message beginning with !shout
will be copied, resent, and deleted from the channel. The /shout
slash command allows "shouting" to any channel from any channel.
shoutChIds
: Array of channel IDs in which to allow shoutsccToDM
: iftrue
, sends a copy of all shouts to owner(s), with the original author's tag
Go ahead, try it. Smooth thyself. Now in that delicious vintage flavour you know and love (and works...?)
Sends a (hopefully) helpful message whenever someone joins the server.
welcomeText
: text to send to new members