Add opt-out/opt-in commands
Allows users to be globally ignored by the bot.
This commit is contained in:
parent
7b03f3140e
commit
539616679b
|
@ -1,4 +1,4 @@
|
||||||
# The Artificer - A Dice Rolling Discord Bot | V2.0.3 - 2022/07/09
|
# The Artificer - A Dice Rolling Discord Bot | V2.1.0 - 2022/07/10
|
||||||
[![SonarCloud](https://sonarcloud.io/images/project_badges/sonarcloud-orange.svg)](https://sonarcloud.io/summary/new_code?id=TheArtificer)
|
[![SonarCloud](https://sonarcloud.io/images/project_badges/sonarcloud-orange.svg)](https://sonarcloud.io/summary/new_code?id=TheArtificer)
|
||||||
[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=TheArtificer&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=TheArtificer) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=TheArtificer&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=TheArtificer) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=TheArtificer&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=TheArtificer) [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=TheArtificer&metric=bugs)](https://sonarcloud.io/summary/new_code?id=TheArtificer) [![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=TheArtificer&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=TheArtificer) [![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=TheArtificer&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=TheArtificer)
|
[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=TheArtificer&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=TheArtificer) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=TheArtificer&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=TheArtificer) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=TheArtificer&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=TheArtificer) [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=TheArtificer&metric=bugs)](https://sonarcloud.io/summary/new_code?id=TheArtificer) [![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=TheArtificer&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=TheArtificer) [![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=TheArtificer&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=TheArtificer)
|
||||||
|
|
||||||
|
@ -59,6 +59,10 @@ The Artificer comes with a few supplemental commands to the main rolling command
|
||||||
* If you encounter a command that errors out or returns something unexpected, please use this command to alert the developers of the problem.
|
* If you encounter a command that errors out or returns something unexpected, please use this command to alert the developers of the problem.
|
||||||
* Example:
|
* Example:
|
||||||
* `[[report [[2+2]] returned 5 when I expected it to return 4` will send the entire message after `[[report` to the devs via Discord.
|
* `[[report [[2+2]] returned 5 when I expected it to return 4` will send the entire message after `[[report` to the devs via Discord.
|
||||||
|
* `[[opt-out` or `[[ignore-me`
|
||||||
|
* Adds you to an ignore list so the bot will never respond to you
|
||||||
|
* `[[opt-in`
|
||||||
|
* Removes you from the ignore list
|
||||||
* `[[xdydzracsq!]]`
|
* `[[xdydzracsq!]]`
|
||||||
* This is the command the bot was built specifically for.
|
* This is the command the bot was built specifically for.
|
||||||
* It looks a little complicated at first, but if you are familiar with the [Roll20 formatting](https://artificer.eanm.dev/roll20), this will no different.
|
* It looks a little complicated at first, but if you are familiar with the [Roll20 formatting](https://artificer.eanm.dev/roll20), this will no different.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
export const config = {
|
export const config = {
|
||||||
'name': 'The Artificer', // Name of the bot
|
'name': 'The Artificer', // Name of the bot
|
||||||
'version': '2.0.3', // Version of the bot
|
'version': '2.1.0', // Version of the bot
|
||||||
'token': 'the_bot_token', // Discord API Token for this bot
|
'token': 'the_bot_token', // Discord API Token for this bot
|
||||||
'localtoken': 'local_testing_token', // Discord API Token for a secondary OPTIONAL testing bot, THIS MUST BE DIFFERENT FROM "token"
|
'localtoken': 'local_testing_token', // Discord API Token for a secondary OPTIONAL testing bot, THIS MUST BE DIFFERENT FROM "token"
|
||||||
'prefix': '[[', // Prefix for all commands
|
'prefix': '[[', // Prefix for all commands
|
||||||
|
|
|
@ -19,8 +19,20 @@ await dbClient.execute(`DROP PROCEDURE IF EXISTS INC_HEATMAP;`);
|
||||||
await dbClient.execute(`DROP TABLE IF EXISTS roll_time_heatmap;`);
|
await dbClient.execute(`DROP TABLE IF EXISTS roll_time_heatmap;`);
|
||||||
await dbClient.execute(`DROP PROCEDURE IF EXISTS INC_CNT;`);
|
await dbClient.execute(`DROP PROCEDURE IF EXISTS INC_CNT;`);
|
||||||
await dbClient.execute(`DROP TABLE IF EXISTS command_cnt;`);
|
await dbClient.execute(`DROP TABLE IF EXISTS command_cnt;`);
|
||||||
|
await dbClient.execute(`DROP TABLE IF EXISTS ignore_list;`);
|
||||||
console.log('Tables dropped');
|
console.log('Tables dropped');
|
||||||
|
|
||||||
|
// Table to hold list of users who want to be ignored by the bot
|
||||||
|
console.log('Attempting to create table ignore_list');
|
||||||
|
await dbClient.execute(`
|
||||||
|
CREATE TABLE ignore_list (
|
||||||
|
userid bigint unsigned NOT NULL,
|
||||||
|
PRIMARY KEY (userid),
|
||||||
|
UNIQUE KEY ignore_list_userid_UNIQUE (userid)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
`);
|
||||||
|
console.log('Table created');
|
||||||
|
|
||||||
// Light telemetry on how many commands have been run
|
// Light telemetry on how many commands have been run
|
||||||
console.log('Attempting to create table command_cnt');
|
console.log('Attempting to create table command_cnt');
|
||||||
await dbClient.execute(`
|
await dbClient.execute(`
|
||||||
|
|
|
@ -10,7 +10,7 @@ await dbClient.execute('INSERT INTO all_keys(userid,apiKey) values(?,?)', [confi
|
||||||
console.log('Inesrtion done');
|
console.log('Inesrtion done');
|
||||||
|
|
||||||
console.log('Attempting to insert default commands into command_cnt');
|
console.log('Attempting to insert default commands into command_cnt');
|
||||||
const commands = ['ping', 'rip', 'rollhelp', 'help', 'info', 'version', 'report', 'stats', 'roll', 'emojis', 'api', 'privacy', 'mention', 'audit', 'heatmap', 'rollDecorators'];
|
const commands = ['ping', 'rip', 'rollhelp', 'help', 'info', 'version', 'report', 'stats', 'roll', 'emojis', 'api', 'privacy', 'mention', 'audit', 'heatmap', 'rollDecorators', 'opt-out', 'opt-in'];
|
||||||
for (const command of commands) {
|
for (const command of commands) {
|
||||||
await dbClient.execute('INSERT INTO command_cnt(command) values(?)', [command]).catch((e) => {
|
await dbClient.execute('INSERT INTO command_cnt(command) values(?)', [command]).catch((e) => {
|
||||||
console.log(`Failed to insert ${command} into database`, e);
|
console.log(`Failed to insert ${command} into database`, e);
|
||||||
|
|
16
mod.ts
16
mod.ts
|
@ -25,7 +25,7 @@ import {
|
||||||
startBot,
|
startBot,
|
||||||
} from './deps.ts';
|
} from './deps.ts';
|
||||||
import api from './src/api.ts';
|
import api from './src/api.ts';
|
||||||
import { dbClient } from './src/db.ts';
|
import { dbClient, ignoreList } from './src/db.ts';
|
||||||
import commands from './src/commands/_index.ts';
|
import commands from './src/commands/_index.ts';
|
||||||
import intervals from './src/intervals.ts';
|
import intervals from './src/intervals.ts';
|
||||||
import { successColor, warnColor } from './src/commandUtils.ts';
|
import { successColor, warnColor } from './src/commandUtils.ts';
|
||||||
|
@ -173,6 +173,9 @@ startBot({
|
||||||
// Ignore all other bots
|
// Ignore all other bots
|
||||||
if (message.isBot) return;
|
if (message.isBot) return;
|
||||||
|
|
||||||
|
// Ignore users who requested to be ignored
|
||||||
|
if (ignoreList.includes(message.authorId) && !message.content.startsWith(`${config.prefix}opt-in`)) return;
|
||||||
|
|
||||||
// Ignore all messages that are not commands
|
// Ignore all messages that are not commands
|
||||||
if (message.content.indexOf(config.prefix) !== 0) {
|
if (message.content.indexOf(config.prefix) !== 0) {
|
||||||
// Handle @bot messages
|
// Handle @bot messages
|
||||||
|
@ -193,6 +196,17 @@ startBot({
|
||||||
// All commands below here
|
// All commands below here
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
|
case 'opt-out':
|
||||||
|
case 'ignore-me':
|
||||||
|
// [[opt-out or [[ignore-me
|
||||||
|
// Tells the bot to add you to the ignore list.
|
||||||
|
commands.optOut(message);
|
||||||
|
break;
|
||||||
|
case 'opt-in':
|
||||||
|
// [[opt-in
|
||||||
|
// Tells the bot to remove you from the ignore list.
|
||||||
|
commands.optIn(message);
|
||||||
|
break;
|
||||||
case 'ping':
|
case 'ping':
|
||||||
// [[ping
|
// [[ping
|
||||||
// Its a ping test, what else do you want.
|
// Its a ping test, what else do you want.
|
||||||
|
|
|
@ -14,6 +14,8 @@ import { roll } from './roll.ts';
|
||||||
import { handleMentions } from './handleMentions.ts';
|
import { handleMentions } from './handleMentions.ts';
|
||||||
import { audit } from './audit.ts';
|
import { audit } from './audit.ts';
|
||||||
import { heatmap } from './heatmap.ts';
|
import { heatmap } from './heatmap.ts';
|
||||||
|
import { optOut } from './optOut.ts';
|
||||||
|
import { optIn } from './optIn.ts';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
ping,
|
ping,
|
||||||
|
@ -32,4 +34,6 @@ export default {
|
||||||
handleMentions,
|
handleMentions,
|
||||||
audit,
|
audit,
|
||||||
heatmap,
|
heatmap,
|
||||||
|
optOut,
|
||||||
|
optIn,
|
||||||
};
|
};
|
||||||
|
|
|
@ -76,6 +76,16 @@ export const help = (message: DiscordenoMessage) => {
|
||||||
value: 'Heatmap of when the roll command is run the most',
|
value: 'Heatmap of when the roll command is run the most',
|
||||||
inline: true,
|
inline: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: `\`${config.prefix}opt-out\` or \`${config.prefix}ignore-me\``,
|
||||||
|
value: 'Adds you to an ignore list so the bot will never respond to you',
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: `\`${config.prefix}opt-in\``,
|
||||||
|
value: 'Removes you from the ignore list',
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: `\`${config.prefix}xdydzracsq!${config.postfix}\` ...`,
|
name: `\`${config.prefix}xdydzracsq!${config.postfix}\` ...`,
|
||||||
value:
|
value:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import config from '../../config.ts';
|
||||||
import { dbClient, queries } from '../db.ts';
|
import { dbClient, queries } from '../db.ts';
|
||||||
import {
|
import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
|
@ -8,16 +9,16 @@ import utils from '../utils.ts';
|
||||||
|
|
||||||
export const info = (message: DiscordenoMessage) => {
|
export const info = (message: DiscordenoMessage) => {
|
||||||
// Light telemetry to see how many times a command is being run
|
// Light telemetry to see how many times a command is being run
|
||||||
dbClient.execute(queries.callIncCnt('info')).catch((e) => utils.commonLoggers.dbError('info.ts:14', 'call sproc INC_CNT on', e));
|
dbClient.execute(queries.callIncCnt('info')).catch((e) => utils.commonLoggers.dbError('info.ts:12', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
message.send({
|
message.send({
|
||||||
embeds: [{
|
embeds: [{
|
||||||
color: infoColor2,
|
color: infoColor2,
|
||||||
title: 'The Artificer, a Discord bot that specializing in rolling dice and calculating math',
|
title: `${config.name}, a Discord bot that specializing in rolling dice and calculating math`,
|
||||||
description: `The Artificer is developed by Ean AKA Burn_E99.
|
description: `${config.name} is developed by Ean AKA Burn_E99.
|
||||||
Additional information can be found on my website [here](https://discord.burne99.com/TheArtificer/).
|
Additional information can be found on my website [here](https://discord.burne99.com/TheArtificer/).
|
||||||
Want to check out my source code? Check it out [here](https://github.com/Burn-E99/TheArtificer).
|
Want to check out my source code? Check it out [here](https://github.com/Burn-E99/TheArtificer).
|
||||||
Need help with this bot? Join my support server [here](https://discord.gg/peHASXMZYv).`,
|
Need help with this bot? Join my support server [here](https://discord.gg/peHASXMZYv).`,
|
||||||
}],
|
}],
|
||||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('info.ts:27', message, e));
|
}).catch((e: Error) => utils.commonLoggers.messageSendError('info.ts:23', message, e));
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import config from '../../config.ts';
|
||||||
|
import { dbClient, ignoreList, queries } from '../db.ts';
|
||||||
|
import {
|
||||||
|
// Discordeno deps
|
||||||
|
DiscordenoMessage,
|
||||||
|
} from '../../deps.ts';
|
||||||
|
import { successColor, failColor } from '../commandUtils.ts';
|
||||||
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
|
export const optIn = async (message: DiscordenoMessage) => {
|
||||||
|
// Light telemetry to see how many times a command is being run
|
||||||
|
dbClient.execute(queries.callIncCnt('opt-out')).catch((e) => utils.commonLoggers.dbError('optIn.ts:11', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
|
try {
|
||||||
|
const idIdx = ignoreList.indexOf(message.authorId);
|
||||||
|
if (idIdx !== -1) {
|
||||||
|
ignoreList.splice(idIdx, 1);
|
||||||
|
await dbClient.execute('DELETE FROM ignore_list WHERE userid = ?', [message.authorId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
message.reply({
|
||||||
|
embeds: [{
|
||||||
|
color: successColor,
|
||||||
|
title: `${config.name} will now respond to you again.`,
|
||||||
|
description: `If you want ${config.name} to ignore to you again, please run the following command:
|
||||||
|
|
||||||
|
\`${config.prefix}opt-out\``,
|
||||||
|
}],
|
||||||
|
}).catch((e: Error) => utils.commonLoggers.messageSendError('optIn.ts:27', message, e));
|
||||||
|
} catch (err) {
|
||||||
|
message.reply({
|
||||||
|
embeds: [{
|
||||||
|
color: failColor,
|
||||||
|
title: 'Opt-In failed',
|
||||||
|
description: 'Please try the command again. If the issue persists, please join the support server, linked in my About Me section.',
|
||||||
|
}],
|
||||||
|
}).catch((e: Error) => utils.commonLoggers.messageSendError('optIn.ts:27', message, e));
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,36 @@
|
||||||
|
import config from '../../config.ts';
|
||||||
|
import { dbClient, ignoreList, queries } from '../db.ts';
|
||||||
|
import {
|
||||||
|
// Discordeno deps
|
||||||
|
DiscordenoMessage,
|
||||||
|
} from '../../deps.ts';
|
||||||
|
import { successColor, failColor } from '../commandUtils.ts';
|
||||||
|
import utils from '../utils.ts';
|
||||||
|
|
||||||
|
export const optOut = async (message: DiscordenoMessage) => {
|
||||||
|
// Light telemetry to see how many times a command is being run
|
||||||
|
dbClient.execute(queries.callIncCnt('opt-out')).catch((e) => utils.commonLoggers.dbError('optOut.ts:11', 'call sproc INC_CNT on', e));
|
||||||
|
|
||||||
|
try {
|
||||||
|
ignoreList.push(message.authorId);
|
||||||
|
await dbClient.execute('INSERT INTO ignore_list(userid) values(?)', [message.authorId]);
|
||||||
|
|
||||||
|
message.reply({
|
||||||
|
embeds: [{
|
||||||
|
color: successColor,
|
||||||
|
title: `${config.name} will no longer respond to you.`,
|
||||||
|
description: `If you want ${config.name} to respond to you again, please run the following command:
|
||||||
|
|
||||||
|
\`${config.prefix}opt-in\``,
|
||||||
|
}],
|
||||||
|
}).catch((e: Error) => utils.commonLoggers.messageSendError('optOut.ts:25', message, e));
|
||||||
|
} catch (err) {
|
||||||
|
message.reply({
|
||||||
|
embeds: [{
|
||||||
|
color: failColor,
|
||||||
|
title: 'Opt-Out failed',
|
||||||
|
description: `Please try the command again. If the issue persists, please report this using the \`${config.prefix}report opt-out failed\` command.`,
|
||||||
|
}],
|
||||||
|
}).catch((e: Error) => utils.commonLoggers.messageSendError('optOut.ts:33', message, e));
|
||||||
|
}
|
||||||
|
};
|
11
src/db.ts
11
src/db.ts
|
@ -2,6 +2,10 @@ import config from '../config.ts';
|
||||||
import { Client } from '../deps.ts';
|
import { Client } from '../deps.ts';
|
||||||
import { LOCALMODE } from '../flags.ts';
|
import { LOCALMODE } from '../flags.ts';
|
||||||
|
|
||||||
|
type UserIdObj = {
|
||||||
|
userid: bigint;
|
||||||
|
};
|
||||||
|
|
||||||
export const dbClient = await new Client().connect({
|
export const dbClient = await new Client().connect({
|
||||||
hostname: LOCALMODE ? config.db.localhost : config.db.host,
|
hostname: LOCALMODE ? config.db.localhost : config.db.host,
|
||||||
port: config.db.port,
|
port: config.db.port,
|
||||||
|
@ -10,6 +14,13 @@ export const dbClient = await new Client().connect({
|
||||||
password: config.db.password,
|
password: config.db.password,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// List of userIds who have requested that the bot ignore them
|
||||||
|
export const ignoreList: Array<bigint> = [];
|
||||||
|
const dbIgnoreList = await dbClient.query("SELECT * FROM ignore_list");
|
||||||
|
dbIgnoreList.forEach((userIdObj: UserIdObj) => {
|
||||||
|
ignoreList.push(userIdObj.userid);
|
||||||
|
});
|
||||||
|
|
||||||
export const weekDays = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
|
export const weekDays = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
|
||||||
|
|
||||||
export const queries = {
|
export const queries = {
|
||||||
|
|
Loading…
Reference in New Issue