Implemented botlist statistic updates

config.example.ts - added botlist object(s), adjusted emoji default values since the ID won't be the same for anyone who spins this up themselves
deps.ts - added botID
mod.ts - Added calling of new updateListStatistics for non-local bots
README.md - Added support invite link, fixed some tab vs spaces issues, added mention of development plans on the milestones pge, linked Deno and Discordeno
intervals.ts - Added updateListStatistics function
This commit is contained in:
Ean Milligan (Bastion) 2021-03-13 15:10:35 -05:00
parent 2a22dc7b04
commit b4d2d71873
5 changed files with 80 additions and 33 deletions

View File

@ -3,7 +3,7 @@ Version 1.4.2 - 2021/02/14
The Artificer is a Discord bot that specializes in rolling dice. The bot utilizes the compact [Roll20 formatting](https://roll20.zendesk.com/hc/en-us/articles/360037773133-Dice-Reference) for ease of use and will correctly perform any needed math on the roll (limited to basic algebra). The Artificer is a Discord bot that specializes in rolling dice. The bot utilizes the compact [Roll20 formatting](https://roll20.zendesk.com/hc/en-us/articles/360037773133-Dice-Reference) for ease of use and will correctly perform any needed math on the roll (limited to basic algebra).
This bot was developed to replace the Sidekick discord bot after it went offline many times for extended periods. This was also developed to fix some annoyances that were found with Sidekick, specifically its vague error messages (such as `"Tarantallegra!"`, what is that supposed to mean) and its inability to handle implicit multiplication (such as `4(12 + 20)`). This bot was developed to replace the Sidekick discord bot after it went offline many times for extended periods, and is now dead according to their GitHub. This was also developed to fix some annoyances that were found with Sidekick, specifically its vague error messages (such as `"Tarantallegra!"`, what is that supposed to mean) and its inability to handle implicit multiplication (such as `4(12 + 20)`).
## Using The Artificer ## Using The Artificer
I am hosting this bot for public use and you may find its invite link below. If you would like to host this bot yourself, details of how to do so are found at the end of this README, but I do not recommend this unless you are experienced with running Discord bots. I am hosting this bot for public use and you may find its invite link below. If you would like to host this bot yourself, details of how to do so are found at the end of this README, but I do not recommend this unless you are experienced with running Discord bots.
@ -12,6 +12,8 @@ After inviting the bot, if you would like it to remove the message requesting th
[Bot Invite Link](https://discord.com/api/oauth2/authorize?client_id=789045930011656223&permissions=2048&scope=bot) [Bot Invite Link](https://discord.com/api/oauth2/authorize?client_id=789045930011656223&permissions=2048&scope=bot)
[Support Server Invite Link](https://discord.gg/peHASXMZYv)
--- ---
## Available Commands ## Available Commands
@ -28,11 +30,11 @@ The Artificer comes with a few supplemental commands to the main rolling command
* Provides a message similar to this subcommand description. * Provides a message similar to this subcommand description.
* `[[api status` * `[[api status`
* Shows the current status of the API for this guild. * Shows the current status of the API for this guild.
* `[[api allow or [[api enable` * `[[api allow or [[api enable`
* Allows API Rolls to be sent to this guild. * Allows API Rolls to be sent to this guild.
* `[[api block or [[api disable` * `[[api block or [[api disable`
* Blocks API Rolls from being sent to this guild. * Blocks API Rolls from being sent to this guild.
* `[[api delete` * `[[api delete`
* Deletes this guild from The Artificer's database. * Deletes this guild from The Artificer's database.
* `[[ping` * `[[ping`
* Tests the latency between you, Discord, and the bot. * Tests the latency between you, Discord, and the bot.
@ -59,22 +61,22 @@ The Artificer comes with a few supplemental commands to the main rolling command
* PI and e are available for use. * PI and e are available for use.
* Parameters for rolling: * Parameters for rolling:
| Paramater | Required? | Repeatable? | Description | | Paramater | Required? | Repeatable? | Description |
|---------------|-------------|---------------|--------------------------------------------------------------------------------------------------| |---------------|-------------|---------------|--------------------------------------------------------------------------------------------------|
| x | Optional | No | number of dice to roll, if omitted, 1 is used | | x | Optional | No | number of dice to roll, if omitted, 1 is used |
| dy | Required | No | size of dice to roll, d20 = 20 sided die | | dy | Required | No | size of dice to roll, d20 = 20 sided die |
| dz or dlz | Optional | No | drops the lowest z dice, cannot be used any other drop or keep options | | dz or dlz | Optional | No | drops the lowest z dice, cannot be used any other drop or keep options |
| kz or khz | Optional | No | keeps the highest z dice, cannot be used any other drop or keep options | | kz or khz | Optional | No | keeps the highest z dice, cannot be used any other drop or keep options |
| dhz | Optional | No | drops the highest z dice, cannot be used any other drop or keep options | | dhz | Optional | No | drops the highest z dice, cannot be used any other drop or keep options |
| klz | Optional | No | keeps the lowest z dice, cannot be used any other drop or keep options | | klz | Optional | No | keeps the lowest z dice, cannot be used any other drop or keep options |
| ra | Optional | Yes | rerolls any rolls that match a, r3 will reroll any dice that land on 3, throwing out old rolls | | ra | Optional | Yes | rerolls any rolls that match a, r3 will reroll any dice that land on 3, throwing out old rolls |
| csq or cs=q | Optional | Yes | changes crit score to q | | csq or cs=q | Optional | Yes | changes crit score to q |
| cs<q | Optional | Yes | changes crit score to be less than or equal to q | | cs<q | Optional | Yes | changes crit score to be less than or equal to q |
| cs>q | Optional | Yes | changes crit score to be greater than or equal to q | | cs>q | Optional | Yes | changes crit score to be greater than or equal to q |
| cfq or cf=q | Optional | Yes | changes crit fail to q | | cfq or cf=q | Optional | Yes | changes crit fail to q |
| cf<q | Optional | Yes | changes crit fail to be less than or equal to q | | cf<q | Optional | Yes | changes crit fail to be less than or equal to q |
| cf>q | Optional | Yes | changes crit fail to be greater than or equal to q | | cf>q | Optional | Yes | changes crit fail to be greater than or equal to q |
| ! | Optional | No | exploding, rolls another dy for every crit roll | | ! | Optional | No | exploding, rolls another dy for every crit roll |
* If the parameter is Required, it must be provided at all times. * If the parameter is Required, it must be provided at all times.
* If the parameter is Repeatable, it may occur multiple times in the roll configuration. * If the parameter is Repeatable, it may occur multiple times in the roll configuration.
@ -170,7 +172,7 @@ If you run into any errors or problems with the bot, or think you have a good id
--- ---
## Self Hosting The Artificer ## Self Hosting The Artificer
The Artificer was built on Deno `v1.7.0` using Discodeno `v10.0.0`. If you choose to run this yourself, you will need to rename `config.example.ts` to `config.ts` and edit some values. You will need to create a new [Discord Application](https://discord.com/developers/applications) and copy the newly generated token into the `"token"` key. If you want to utilize some of the bots dev features, you will need to fill in the keys `"logChannel"` and `"reportChannel"` with text channel IDs and `"devServer"` with a guild ID. The Artificer was built on [Deno](https://deno.land/) `v1.7.0` using [Discordeno](https://discordeno.mod.land/) `v10.3.0`. If you choose to run this yourself, you will need to rename `config.example.ts` to `config.ts` and edit some values. You will need to create a new [Discord Application](https://discord.com/developers/applications) and copy the newly generated token into the `"token"` key. If you want to utilize some of the bots dev features, you will need to fill in the keys `"logChannel"` and `"reportChannel"` with text channel IDs and `"devServer"` with a guild ID.
You will also need to install and setup a MySQL database with a user for the bot to use to add/modify the database. This user must have the "DB Manager" admin rights and "REFERENCES" Global Privileges. Once the DB is installed and a user is setup, run the provided `db\initialize.ts` to create the schema and tables. After this, run `db\populateDefaults.ts` to insert some needed values into the tables. You will also need to install and setup a MySQL database with a user for the bot to use to add/modify the database. This user must have the "DB Manager" admin rights and "REFERENCES" Global Privileges. Once the DB is installed and a user is setup, run the provided `db\initialize.ts` to create the schema and tables. After this, run `db\populateDefaults.ts` to insert some needed values into the tables.
@ -180,6 +182,11 @@ If you choose to run version `1.1.0` or newer, ensure you disable the API in `co
--- ---
## Development Plans
Current and future plans are listed on [the Milestones page](https://github.com/Burn-E99/TheArtificer/milestones).
---
### Built in memory of my Grandmother, Babka ### Built in memory of my Grandmother, Babka
With much love, Ean With much love, Ean

View File

@ -29,11 +29,27 @@ export const config = {
"devServer": "the_dev_server", // Discord guild ID where testing of indev features/commands will be handled, used in conjuction with the DEVMODE bool in mod.ts "devServer": "the_dev_server", // Discord guild ID where testing of indev features/commands will be handled, used in conjuction with the DEVMODE bool in mod.ts
"emojis": [ // Array of objects containing all emojis that the bot can send on your behalf, empty this array if you don't want any of them "emojis": [ // Array of objects containing all emojis that the bot can send on your behalf, empty this array if you don't want any of them
{ // Emoji object, duplicate for each emoji { // Emoji object, duplicate for each emoji
"name": "popcat", // Name of emoji in discord "name": "emoji_name", // Name of emoji in discord
"aliases": ["popcat", "pop", "p"], // Commands that will activate this emoji "aliases": ["alias_1", "alias_2", "alias_n"], // Commands that will activate this emoji
"id": "796340018377523221", // Discord emoji ID for this emoji "id": "the_emoji_id", // Discord emoji ID for this emoji
"animated": true, // Tells the bot this emoji is animated so it sends correctly "animated": false, // Tells the bot this emoji is animated so it sends correctly
"deleteSender": true // Tells the bot to attempt to delete the sender's message after sending the emoji "deleteSender": false // Tells the bot to attempt to delete the sender's message after sending the emoji
}
],
"botLists": [ // Array of objects containing all bot lists that stats should be posted to
{ // Bot List object, duplicate for each bot list
"name": "Bot List Name", // Name of bot list, not used
"enabled": true, // Should statistics be posted to this list?
"apiUrl": "https://example.com/api/bots/?{bot_id}/stats", // API URL, use ?{bot_id} in place of the bot id so that it can be dynamically replaced
"headers": [ // Array of headers that need to be added to the request
{ // Header Object, duplicate for every header needed
"header": "header_name", // Name of header needed, usually Authorization is needed
"value": "header_value" // Value for the header
}
],
"body": { // Data payload to send to the bot list, will be turned into a string and any ?{} will be replaced with the required value, currently only has ?{server_count}
"param_name": "?{param_value}" // Add more params as needed
}
} }
] ]
}; };

View File

@ -3,7 +3,7 @@ export {
startBot, editBotsStatus, startBot, editBotsStatus,
Intents, StatusTypes, ActivityType, Intents, StatusTypes, ActivityType,
sendMessage, sendDirectMessage, sendMessage, sendDirectMessage,
cache, cache, botID,
memberIDHasPermission memberIDHasPermission
} from "https://deno.land/x/discordeno@10.3.0/mod.ts"; } from "https://deno.land/x/discordeno@10.3.0/mod.ts";

11
mod.ts
View File

@ -8,9 +8,10 @@ import {
// Discordeno deps // Discordeno deps
startBot, editBotsStatus, startBot, editBotsStatus,
Intents, StatusTypes, ActivityType, Intents, StatusTypes, ActivityType,
Message, Guild, sendMessage, sendDirectMessage, sendMessage, sendDirectMessage,
cache, cache, botID,
memberIDHasPermission, memberIDHasPermission,
Message, Guild,
// MySQL Driver deps // MySQL Driver deps
Client Client
@ -55,8 +56,12 @@ startBot({
} }
}, 30000); }, 30000);
// Interval to update bot list stats every 24 hours
LOCALMODE ? console.log("updateListStatistics not running") : setInterval(() => intervals.updateListStatistics(botID, cache.guilds.size), 86400000);
// setTimeout added to make sure the startup message does not error out // setTimeout added to make sure the startup message does not error out
setTimeout(() => { setTimeout(() => {
LOCALMODE ? console.log("updateListStatistics not running") : intervals.updateListStatistics(botID, cache.guilds.size);
editBotsStatus(StatusTypes.Online, `Boot Complete`, ActivityType.Game); editBotsStatus(StatusTypes.Online, `Boot Complete`, ActivityType.Game);
sendMessage(config.logChannel, `${config.name} has started, running version ${config.version}.`).catch(() => { sendMessage(config.logChannel, `${config.name} has started, running version ${config.version}.`).catch(() => {
console.error("Failed to send message 00"); console.error("Failed to send message 00");
@ -69,7 +74,7 @@ startBot({
}); });
}, },
guildDelete: (guild: Guild) => { guildDelete: (guild: Guild) => {
sendMessage(config.logChannel, `I have been removed from: ${guild.name} (id: ${guild.id})`).catch(() => { sendMessage(config.logChannel, `I have been removed from: ${guild.name} (id: ${guild.id}).`).catch(() => {
console.error("Failed to send message 02"); console.error("Failed to send message 02");
}); });
}, },

View File

@ -33,4 +33,23 @@ const getRandomStatus = (cache: CacheData): string => {
return status; return status;
}; };
export default { getRandomStatus }; // updateListStatistics(bot ID, current guild count) returns nothing
// Sends the current server count to all bot list sites we are listed on
const updateListStatistics = (botID: string, serverCount: number): void => {
config.botLists.forEach(async e => {
if (e.enabled) {
const tempHeaders = new Headers();
tempHeaders.append(e.headers[0].header, e.headers[0].value);
tempHeaders.append("Content-Type", "application/json");
// ?{} is a template used in config, just need to replace it with the real value
const response = await fetch(e.apiUrl.replace("?{bot_id}", botID), {
"method": 'POST',
"headers": tempHeaders,
"body": JSON.stringify(e.body).replace('"?{server_count}"', serverCount.toString()) // ?{server_count} needs the "" removed from around it aswell to make sure its sent as a number
});
console.log(response);
}
});
};
export default { getRandomStatus, updateListStatistics };