mirror of
https://github.com/pacnpal/markov-discord.git
synced 2025-12-20 03:01:04 -05:00
Prevent all mentions from message responses. Some other light refactoring.
This commit is contained in:
@@ -23,6 +23,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
* Discord slash command support
|
* Discord slash command support
|
||||||
* Many more config options available at <https://claabs.github.io/markov-discord/classes/AppConfig.html>
|
* Many more config options available at <https://claabs.github.io/markov-discord/classes/AppConfig.html>
|
||||||
* Config file supports [JSON5](https://json5.org/) (comments, trailing commas, etc)
|
* Config file supports [JSON5](https://json5.org/) (comments, trailing commas, etc)
|
||||||
|
* Generated responses will now never ping a user or role, only just highlight their name
|
||||||
|
|
||||||
### 0.7.3
|
### 0.7.3
|
||||||
|
|
||||||
|
|||||||
96
src/index.ts
96
src/index.ts
@@ -1,18 +1,14 @@
|
|||||||
/* eslint-disable no-console */
|
|
||||||
import 'source-map-support/register';
|
import 'source-map-support/register';
|
||||||
import 'reflect-metadata';
|
import 'reflect-metadata';
|
||||||
import * as Discord from 'discord.js';
|
import * as Discord from 'discord.js';
|
||||||
|
|
||||||
import Markov, {
|
import Markov, {
|
||||||
MarkovGenerateOptions,
|
MarkovGenerateOptions,
|
||||||
MarkovConstructorOptions,
|
MarkovConstructorOptions,
|
||||||
AddDataProps,
|
AddDataProps,
|
||||||
} from 'markov-strings-db';
|
} from 'markov-strings-db';
|
||||||
|
|
||||||
import { createConnection } from 'typeorm';
|
import { createConnection } from 'typeorm';
|
||||||
import { MarkovInputData } from 'markov-strings-db/dist/src/entity/MarkovInputData';
|
import { MarkovInputData } from 'markov-strings-db/dist/src/entity/MarkovInputData';
|
||||||
import type { PackageJsonPerson } from 'types-package-json';
|
import type { PackageJsonPerson } from 'types-package-json';
|
||||||
|
|
||||||
import makeEta from 'simple-eta';
|
import makeEta from 'simple-eta';
|
||||||
import formatDistanceToNow from 'date-fns/formatDistanceToNow';
|
import formatDistanceToNow from 'date-fns/formatDistanceToNow';
|
||||||
import addSeconds from 'date-fns/addSeconds';
|
import addSeconds from 'date-fns/addSeconds';
|
||||||
@@ -376,7 +372,10 @@ async function generateResponse(
|
|||||||
const response = await markov.generate<MarkovDataCustom>(markovGenerateOptions);
|
const response = await markov.generate<MarkovDataCustom>(markovGenerateOptions);
|
||||||
L.info({ string: response.string }, 'Generated response text');
|
L.info({ string: response.string }, 'Generated response text');
|
||||||
L.debug({ response }, 'Generated response object');
|
L.debug({ response }, 'Generated response object');
|
||||||
const messageOpts: Discord.MessageOptions = { tts };
|
const messageOpts: Discord.MessageOptions = {
|
||||||
|
tts,
|
||||||
|
allowedMentions: { repliedUser: false, parse: [] },
|
||||||
|
};
|
||||||
const attachmentUrls = response.refs
|
const attachmentUrls = response.refs
|
||||||
.filter((ref) => ref.custom && 'attachments' in ref.custom)
|
.filter((ref) => ref.custom && 'attachments' in ref.custom)
|
||||||
.flatMap((ref) => (ref.custom as MarkovDataCustom).attachments);
|
.flatMap((ref) => (ref.custom as MarkovDataCustom).attachments);
|
||||||
@@ -397,20 +396,26 @@ async function generateResponse(
|
|||||||
messageOpts.files = [{ attachment: getRandomElement(randomMessageAttachmentUrls) }];
|
messageOpts.files = [{ attachment: getRandomElement(randomMessageAttachmentUrls) }];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
response.string = response.string.replace(/@everyone/g, '@everyοne'); // Replace @everyone with a homoglyph 'o'
|
|
||||||
messageOpts.content = response.string;
|
messageOpts.content = response.string;
|
||||||
|
|
||||||
const responseMessages: GenerateResponse = {
|
const responseMessages: GenerateResponse = {
|
||||||
message: messageOpts,
|
message: messageOpts,
|
||||||
};
|
};
|
||||||
if (debug) {
|
if (debug) {
|
||||||
responseMessages.debug = { content: `\`\`\`\n${JSON.stringify(response, null, 2)}\n\`\`\`` };
|
responseMessages.debug = {
|
||||||
|
content: `\`\`\`\n${JSON.stringify(response, null, 2)}\n\`\`\``,
|
||||||
|
allowedMentions: { repliedUser: false, parse: [] },
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return responseMessages;
|
return responseMessages;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
L.error(err);
|
L.error(err);
|
||||||
return { error: { content: `\n\`\`\`\nERROR: ${err}\n\`\`\`` } };
|
return {
|
||||||
|
error: {
|
||||||
|
content: `\n\`\`\`\nERROR: ${err}\n\`\`\``,
|
||||||
|
allowedMentions: { repliedUser: false, parse: [] },
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,6 +503,31 @@ function inviteMessage(): Discord.MessageOptions {
|
|||||||
return { embeds: [embed] };
|
return { embeds: [embed] };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleResponseMessage(
|
||||||
|
generatedResponse: GenerateResponse,
|
||||||
|
message: Discord.Message
|
||||||
|
): Promise<void> {
|
||||||
|
if (generatedResponse.message) await message.reply(generatedResponse.message);
|
||||||
|
if (generatedResponse.debug) await message.reply(generatedResponse.debug);
|
||||||
|
if (generatedResponse.error) await message.reply(generatedResponse.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleUnprivileged(
|
||||||
|
interaction: Discord.CommandInteraction | Discord.SelectMenuInteraction,
|
||||||
|
deleteReply = true
|
||||||
|
): Promise<void> {
|
||||||
|
if (deleteReply) await interaction.deleteReply();
|
||||||
|
await interaction.followUp({ content: INVALID_PERMISSIONS_MESSAGE, ephemeral: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleNoGuild(
|
||||||
|
interaction: Discord.CommandInteraction | Discord.SelectMenuInteraction,
|
||||||
|
deleteReply = true
|
||||||
|
): Promise<void> {
|
||||||
|
if (deleteReply) await interaction.deleteReply();
|
||||||
|
await interaction.followUp({ content: INVALID_GUILD_MESSAGE, ephemeral: true });
|
||||||
|
}
|
||||||
|
|
||||||
client.on('ready', async (readyClient) => {
|
client.on('ready', async (readyClient) => {
|
||||||
L.info({ inviteUrl: generateInviteUrl() }, 'Bot logged in');
|
L.info({ inviteUrl: generateInviteUrl() }, 'Bot logged in');
|
||||||
|
|
||||||
@@ -538,23 +568,17 @@ client.on('messageCreate', async (message) => {
|
|||||||
if (command === 'respond') {
|
if (command === 'respond') {
|
||||||
L.debug('Responding to legacy command');
|
L.debug('Responding to legacy command');
|
||||||
const generatedResponse = await generateResponse(message);
|
const generatedResponse = await generateResponse(message);
|
||||||
if (generatedResponse.message) await message.reply(generatedResponse.message);
|
await handleResponseMessage(generatedResponse, message);
|
||||||
if (generatedResponse.debug) await message.reply(generatedResponse.debug);
|
|
||||||
if (generatedResponse.error) await message.reply(generatedResponse.error);
|
|
||||||
}
|
}
|
||||||
if (command === 'tts') {
|
if (command === 'tts') {
|
||||||
L.debug('Responding to legacy command tts');
|
L.debug('Responding to legacy command tts');
|
||||||
const generatedResponse = await generateResponse(message, { tts: true });
|
const generatedResponse = await generateResponse(message, { tts: true });
|
||||||
if (generatedResponse.message) await message.reply(generatedResponse.message);
|
await handleResponseMessage(generatedResponse, message);
|
||||||
if (generatedResponse.debug) await message.reply(generatedResponse.debug);
|
|
||||||
if (generatedResponse.error) await message.reply(generatedResponse.error);
|
|
||||||
}
|
}
|
||||||
if (command === 'debug') {
|
if (command === 'debug') {
|
||||||
L.debug('Responding to legacy command debug');
|
L.debug('Responding to legacy command debug');
|
||||||
const generatedResponse = await generateResponse(message, { debug: true });
|
const generatedResponse = await generateResponse(message, { debug: true });
|
||||||
if (generatedResponse.message) await message.reply(generatedResponse.message);
|
await handleResponseMessage(generatedResponse, message);
|
||||||
if (generatedResponse.debug) await message.reply(generatedResponse.debug);
|
|
||||||
if (generatedResponse.error) await message.reply(generatedResponse.error);
|
|
||||||
}
|
}
|
||||||
if (command === null) {
|
if (command === null) {
|
||||||
if (!message.author.bot) {
|
if (!message.author.bot) {
|
||||||
@@ -563,9 +587,7 @@ client.on('messageCreate', async (message) => {
|
|||||||
// <@!278354154563567636> how are you doing?
|
// <@!278354154563567636> how are you doing?
|
||||||
const startSeed = message.content.replace(/<@!\d+>/g, '').trim();
|
const startSeed = message.content.replace(/<@!\d+>/g, '').trim();
|
||||||
const generatedResponse = await generateResponse(message, { startSeed });
|
const generatedResponse = await generateResponse(message, { startSeed });
|
||||||
if (generatedResponse.message) await message.reply(generatedResponse.message);
|
await handleResponseMessage(generatedResponse, message);
|
||||||
if (generatedResponse.debug) await message.reply(generatedResponse.debug);
|
|
||||||
if (generatedResponse.error) await message.reply(generatedResponse.error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await isValidChannel(message.channelId)) {
|
if (await isValidChannel(message.channelId)) {
|
||||||
@@ -598,6 +620,7 @@ client.on('messageUpdate', async (oldMessage, newMessage) => {
|
|||||||
await markov.addData([newMessage.content]);
|
await markov.addData([newMessage.content]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line consistent-return
|
||||||
client.on('interactionCreate', async (interaction) => {
|
client.on('interactionCreate', async (interaction) => {
|
||||||
if (interaction.isCommand()) {
|
if (interaction.isCommand()) {
|
||||||
L.info({ command: interaction.commandName }, 'Recieved slash command');
|
L.info({ command: interaction.commandName }, 'Recieved slash command');
|
||||||
@@ -626,14 +649,10 @@ client.on('interactionCreate', async (interaction) => {
|
|||||||
await interaction.editReply(reply);
|
await interaction.editReply(reply);
|
||||||
} else if (subCommand === 'add') {
|
} else if (subCommand === 'add') {
|
||||||
if (!isModerator(interaction.member)) {
|
if (!isModerator(interaction.member)) {
|
||||||
await interaction.deleteReply();
|
return handleUnprivileged(interaction);
|
||||||
await interaction.followUp({ content: INVALID_PERMISSIONS_MESSAGE, ephemeral: true });
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (!interaction.guildId) {
|
if (!interaction.guildId) {
|
||||||
await interaction.deleteReply();
|
return handleNoGuild(interaction);
|
||||||
await interaction.followUp({ content: INVALID_GUILD_MESSAGE, ephemeral: true });
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
const channels = getChannelsFromInteraction(interaction);
|
const channels = getChannelsFromInteraction(interaction);
|
||||||
await addValidChannels(channels, interaction.guildId);
|
await addValidChannels(channels, interaction.guildId);
|
||||||
@@ -642,14 +661,10 @@ client.on('interactionCreate', async (interaction) => {
|
|||||||
);
|
);
|
||||||
} else if (subCommand === 'remove') {
|
} else if (subCommand === 'remove') {
|
||||||
if (!isModerator(interaction.member)) {
|
if (!isModerator(interaction.member)) {
|
||||||
await interaction.deleteReply();
|
return handleUnprivileged(interaction);
|
||||||
await interaction.followUp({ content: INVALID_PERMISSIONS_MESSAGE, ephemeral: true });
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (!interaction.guildId) {
|
if (!interaction.guildId) {
|
||||||
await interaction.deleteReply();
|
return handleNoGuild(interaction);
|
||||||
await interaction.followUp({ content: INVALID_GUILD_MESSAGE, ephemeral: true });
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
const channels = getChannelsFromInteraction(interaction);
|
const channels = getChannelsFromInteraction(interaction);
|
||||||
await removeValidChannels(channels, interaction.guildId);
|
await removeValidChannels(channels, interaction.guildId);
|
||||||
@@ -657,15 +672,13 @@ client.on('interactionCreate', async (interaction) => {
|
|||||||
`Removed ${channels.length} text channels from the list. Use \`/train\` to remove these channels from the past known messages.`
|
`Removed ${channels.length} text channels from the list. Use \`/train\` to remove these channels from the past known messages.`
|
||||||
);
|
);
|
||||||
} else if (subCommand === 'modify') {
|
} else if (subCommand === 'modify') {
|
||||||
await interaction.deleteReply();
|
|
||||||
if (!interaction.guild) {
|
if (!interaction.guild) {
|
||||||
await interaction.followUp({ content: INVALID_GUILD_MESSAGE, ephemeral: true });
|
return handleNoGuild(interaction);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (!isModerator(interaction.member)) {
|
if (!isModerator(interaction.member)) {
|
||||||
await interaction.followUp({ content: INVALID_PERMISSIONS_MESSAGE, ephemeral: true });
|
await handleUnprivileged(interaction);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
await interaction.deleteReply();
|
||||||
const dbTextChannels = await getTextChannels(interaction.guild);
|
const dbTextChannels = await getTextChannels(interaction.guild);
|
||||||
const row = new Discord.MessageActionRow().addComponents(
|
const row = new Discord.MessageActionRow().addComponents(
|
||||||
new Discord.MessageSelectMenu()
|
new Discord.MessageSelectMenu()
|
||||||
@@ -698,13 +711,10 @@ client.on('interactionCreate', async (interaction) => {
|
|||||||
await interaction.deferUpdate();
|
await interaction.deferUpdate();
|
||||||
const { guild } = interaction;
|
const { guild } = interaction;
|
||||||
if (!isModerator(interaction.member)) {
|
if (!isModerator(interaction.member)) {
|
||||||
await interaction.followUp({ content: INVALID_PERMISSIONS_MESSAGE, ephemeral: true });
|
return handleUnprivileged(interaction, false);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (!guild) {
|
if (!guild) {
|
||||||
await interaction.deleteReply();
|
return handleNoGuild(interaction, false);
|
||||||
await interaction.followUp({ content: INVALID_GUILD_MESSAGE, ephemeral: true });
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const allChannels =
|
const allChannels =
|
||||||
|
|||||||
Reference in New Issue
Block a user