diff options
Diffstat (limited to 'bot')
| -rw-r--r-- | bot/eslint.config.js | 3 | ||||
| -rw-r--r-- | bot/package.json | 1 | ||||
| -rw-r--r-- | bot/src/bot.js | 6 | ||||
| -rw-r--r-- | bot/src/commands/about.js | 2 | ||||
| -rw-r--r-- | bot/src/commands/quote.js | 2 | ||||
| -rw-r--r-- | bot/src/commands/rm.js | 2 | ||||
| -rw-r--r-- | bot/src/commands/settings.js | 79 | ||||
| -rw-r--r-- | bot/src/commands/suggest.js | 2 | ||||
| -rw-r--r-- | bot/src/events/ClientReady.js | 3 | ||||
| -rw-r--r-- | bot/src/events/GuildBanAdd.js | 13 | ||||
| -rw-r--r-- | bot/src/events/GuildCreate.js | 3 | ||||
| -rw-r--r-- | bot/src/events/GuildDelete.js | 16 | ||||
| -rw-r--r-- | bot/src/events/GuildMemberRemove.js | 2 | ||||
| -rw-r--r-- | bot/src/events/InteractionCreate.js | 10 | ||||
| -rw-r--r-- | bot/src/events/MessageCreate.js | 10 | ||||
| -rw-r--r-- | bot/src/events/MessageUpdate.js | 18 | ||||
| -rw-r--r-- | bot/src/models/guild-settings.js | 28 | ||||
| -rw-r--r-- | bot/src/storage/consts.js | 2 |
18 files changed, 146 insertions, 56 deletions
diff --git a/bot/eslint.config.js b/bot/eslint.config.js index 6f258fe..e9901f8 100644 --- a/bot/eslint.config.js +++ b/bot/eslint.config.js @@ -20,7 +20,8 @@ export default [ '@stylistic/js/quotes': ['error', 'single'], '@stylistic/js/semi-style': ['error', 'last'], '@stylistic/js/semi': ['error', 'always'], - '@stylistic/js/indent': ['error', 4] + '@stylistic/js/indent': ['error', 4], + 'require-await': 'error' } }, pluginJs.configs.recommended, diff --git a/bot/package.json b/bot/package.json index 75534b4..72568aa 100644 --- a/bot/package.json +++ b/bot/package.json @@ -8,6 +8,7 @@ "scripts": { "start": "node src/bot.js", "dev": "nodemon src/bot.js", + "deploy": "node deploy-command.js", "lint": "eslint ." }, "dependencies": { diff --git a/bot/src/bot.js b/bot/src/bot.js index ff03b06..3236817 100644 --- a/bot/src/bot.js +++ b/bot/src/bot.js @@ -1,11 +1,13 @@ import { Client, GatewayIntentBits } from 'discord.js'; import 'dotenv/config'; import { init } from './init.js'; -const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildMessages] }); +const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildBans ] }); init(client); -client.login(process.env.token).catch(function() { +client.login(process.env.token).then(() => { + console.log('[>] Successfully authenticated.'); +}).catch(() => { console.log('[X] Login failed. The token that you have put in is invalid.'); process.exit(1); }); diff --git a/bot/src/commands/about.js b/bot/src/commands/about.js index 8d3efab..311200e 100644 --- a/bot/src/commands/about.js +++ b/bot/src/commands/about.js @@ -23,7 +23,7 @@ export default { { name: 'License', value: 'GNU General Public License v3.0' }, { name: 'Contributors', value: '- <@297201585090723841> (Uptime command from 2.x)' } ) - .setFooter({ text: '© Copyright 2017-2025 Andrew Lee Projects' }) + .setFooter({ text: '© Copyright 2017-2025 Andrew Lee & contributors' }) .setColor(abEmbedColour); let Buttons = new ActionRowBuilder() diff --git a/bot/src/commands/quote.js b/bot/src/commands/quote.js index 60e35b9..3ae1de3 100644 --- a/bot/src/commands/quote.js +++ b/bot/src/commands/quote.js @@ -97,7 +97,7 @@ export default { return modalInteraction.reply({ content: 'Something went wrong.', flags: MessageFlags.Ephemeral }); }); - return modalInteraction.reply({content: 'Sending this quote for manual approval.', flags: MessageFlags.Ephemeral}); + return await modalInteraction.reply({content: 'Sending this quote for manual approval.', flags: MessageFlags.Ephemeral}); }) .catch((err) => { console.error(err); diff --git a/bot/src/commands/rm.js b/bot/src/commands/rm.js index 7a1351c..9edfdc4 100644 --- a/bot/src/commands/rm.js +++ b/bot/src/commands/rm.js @@ -12,7 +12,7 @@ export default { .setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages), async execute(interaction) { const amount = interaction.options.getNumber('amount'); - if (amount > 100) return interaction.reply({ content: 'Put a number less than 100.', flags: MessageFlags.Ephemeral }); + if (amount > 100) return await interaction.reply({ content: 'Put a number less than 100.', flags: MessageFlags.Ephemeral }); return await interaction.channel.bulkDelete(amount) .then( (messages) => interaction.reply(`Deleted ${messages.size} messages.`)); diff --git a/bot/src/commands/settings.js b/bot/src/commands/settings.js index 00f7caf..5fdf0cd 100644 --- a/bot/src/commands/settings.js +++ b/bot/src/commands/settings.js @@ -1,5 +1,17 @@ -import { EmbedBuilder, MessageFlags, PermissionFlagsBits, SlashCommandBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder, ComponentType } from 'discord.js'; +import { + EmbedBuilder, + MessageFlags, + PermissionFlagsBits, + SlashCommandBuilder, + ButtonBuilder, + ButtonStyle, + ActionRowBuilder, + ComponentType, + ChannelType, + ChannelSelectMenuBuilder +} from 'discord.js'; import { abEmbedColour } from '../storage/consts.js'; +import { guildSettings } from '../models/guild-settings.js'; export default { data: new SlashCommandBuilder() @@ -17,6 +29,17 @@ export default { if (interaction.options.getSubcommand() === 'guild') { //if (!interaction.member.permissions.has(PermissionFlagsBits.ManageGuild)) return await interaction.reply({ content: 'You do not have the permission to manage this guild.', flags: MessageFlags.Ephemeral }); + const guildSetting = await guildSettings.findOne({ where: { guildID: interaction.guild.id } }); + + if (!guildSetting) { + await guildSettings.create({ guildID: interaction.guild.id }); + } + + const logMenu = new ChannelSelectMenuBuilder() + .setCustomId('logMenu') + .setPlaceholder('Select a channel') + .setChannelTypes(ChannelType.GuildText); + const logging = new ButtonBuilder() .setCustomId('logging') .setLabel('Logging') @@ -27,18 +50,41 @@ export default { .setLabel('Suggestions') .setStyle(ButtonStyle.Primary); + const qotdChannel = new ButtonBuilder() + .setCustomId('qotdChannel') + .setLabel('QOTD Channel') + .setStyle(ButtonStyle.Primary); + + const llmChatbot = new ButtonBuilder() + .setCustomId('llmChatbot') + .setLabel('LLM Chatbot') + .setStyle(ButtonStyle.Primary); + + const qotdToggle = new ButtonBuilder() + .setCustomId('qotdToggle') + .setLabel('QOTD Toggle') + .setStyle(ButtonStyle.Primary); + + const done = new ButtonBuilder() + .setCustomId('done') + .setLabel('Suggestions') + .setStyle(ButtonStyle.Success); + const row = new ActionRowBuilder() - .addComponents(logging, suggestions); + .addComponents(logging, suggestions, qotdChannel, llmChatbot, qotdToggle); + + const row2 = new ActionRowBuilder() + .addComponents(logMenu); const guildEmbed = new EmbedBuilder() .setAuthor({ name: 'AleeBot Guild Settings', iconURL: interaction.client.user.avatarURL() }) .setDescription('Select the options') .addFields( - { name: 'Logging', value: 'logchannel', inline: true }, - { name: 'Suggestions', value: 'channel', inline: true }, - { name: 'LLM Chatbot', value: 'Enabled', inline: true }, - { name: 'Quote of the Day', value: 'logchannel', inline: true }, - { name: 'QOTD Channel', value: 'logchannel', inline: true } + { name: 'Logging', value: guildSetting?.logChannelID ? `<#${guildSetting.logChannelID}>` : 'N/A', inline: true }, + { name: 'Suggestions', value: guildSetting?.suggestionsChannelID ? `<#${guildSetting.suggestionsChannelID}>` : 'N/A', inline: true }, + { name: 'QOTD Channel', value: guildSetting?.qotdChannelID ? `<#${guildSetting.qotdChannelID}>` : 'N/A', inline: true }, + { name: 'LLM Chatbot', value: guildSetting?.ollamaEnabled ? 'Enabled' : 'Disabled', inline: true }, + { name: 'Quote of the Day', value: guildSetting?.qotdToggle ? 'Enabled' : 'Disabled', inline: true } ) .setColor(abEmbedColour); @@ -54,7 +100,24 @@ export default { guildCollector.on('collect', async (interaction) => { if (interaction.customId === 'logging') { - await interaction.reply({ content: 'Clicked on logging' }); + await interaction.reply({ components: [row2] }); + + const logMenuInteraction = await interaction.channel.awaitMessageComponent({ + componentType: ComponentType.ChannelSelectMenu, + filter: (i) => i.user.id === interaction.user.id, + time: 1000 * 120 + }); + + if (logMenuInteraction.customId === 'logMenu') { + await logMenuInteraction.reply({ content: `Selected <#${logMenuInteraction.values}>` }); + await guildSettings.update({ logChannelID: logMenuInteraction.values[0] }, { where: { guildID: interaction.guild.id } }); + } + + const logSetting = await guildSettings.findOne({ where: { guildID: interaction.guild.id } }); + guildEmbed.spliceFields(0, 1, { name: 'Logging', value: logSetting?.logChannelID ? `<#${logSetting.logChannelID}>` : 'N/A', inline: true }); + + await interaction.editReply({ embeds: [guildEmbed], components: [row] }); + await interaction.deleteReply(); } if (interaction.customId === 'suggestions') { diff --git a/bot/src/commands/suggest.js b/bot/src/commands/suggest.js index 8f75915..e4bed85 100644 --- a/bot/src/commands/suggest.js +++ b/bot/src/commands/suggest.js @@ -55,7 +55,7 @@ export default { .setFooter({ text: `Sending from ${modalInteraction.guild.name}`, iconURL: modalInteraction.guild.iconURL() }) ]}); - return modalInteraction.reply({content: 'Your suggestion has been sent.', flags: MessageFlags.Ephemeral}); + return await modalInteraction.reply({content: 'Your suggestion has been sent.', flags: MessageFlags.Ephemeral}); }) .catch((err) => { console.error(err); diff --git a/bot/src/events/ClientReady.js b/bot/src/events/ClientReady.js index af03e25..ec22ba6 100644 --- a/bot/src/events/ClientReady.js +++ b/bot/src/events/ClientReady.js @@ -28,7 +28,7 @@ export default { console.log(`[i] Bot ID: ${client.user.id}`); console.log(`[i] Running version ${abVersion} | Serving in ${client.guilds.cache.size} guilds`); - botActivity(client); + await botActivity(client); if (readyMsg) { const readyEmbed = new EmbedBuilder() @@ -41,7 +41,6 @@ export default { ) .setColor(abEmbedColour); - let statusChannel = client.channels.cache.get(process.env.statusChannelID); if (!statusChannel) return console.error('The status channel does not exist! Skipping.'); await statusChannel.send({ embeds: [readyEmbed]}); diff --git a/bot/src/events/GuildBanAdd.js b/bot/src/events/GuildBanAdd.js index 1e52040..e68701d 100644 --- a/bot/src/events/GuildBanAdd.js +++ b/bot/src/events/GuildBanAdd.js @@ -1,9 +1,17 @@ -import { EmbedBuilder, Events } from 'discord.js'; +import { EmbedBuilder, Events, AuditLogEvent } from 'discord.js'; import { guildSettings } from '../models/guild-settings.js'; export default { name: Events.GuildBanAdd, async execute(guild, user) { + + const banLog = await guild.fetchAuditLogs({ + type: AuditLogEvent.MemberBanAdd, + limit: 1, + }); + + const banEntry = banLog.entries.first(); + const guildSetting = await guildSettings.findOne({ where: { guildID: guild.id } }); if (!guildSetting || !guildSetting.logChannelID) return; @@ -12,7 +20,8 @@ export default { .setDescription(`This user got banned from ${guild.name}`) .addFields( { name: 'User:', value: `${user.tag}` }, - { name: 'User ID:', value: `${user.id}`} + { name: 'User ID:', value: `${user.id}`}, + { name: 'Reason:', value: `${banEntry.reason || 'No reason provided'}` } ) .setColor('#ff021b') .setTimestamp(); diff --git a/bot/src/events/GuildCreate.js b/bot/src/events/GuildCreate.js index 7bcd0d1..4d73f08 100644 --- a/bot/src/events/GuildCreate.js +++ b/bot/src/events/GuildCreate.js @@ -1,5 +1,6 @@ import { EmbedBuilder, Events } from 'discord.js'; import { abEmbedColour } from '../storage/consts.js'; +import { guildSettings } from '../models/guild-settings.js'; export default { name: Events.GuildCreate, @@ -16,6 +17,8 @@ export default { .setColor(abEmbedColour) .setFooter({ text: `We now run on ${guild.client.guilds.cache.size} guilds.` }); + await guildSettings.create({ guildID: guild.id }); + let statusChannel = guild.client.channels.cache.get(process.env.statusChannelID); if (!statusChannel) return; await statusChannel.send({ embeds: [logEmbed]}); diff --git a/bot/src/events/GuildDelete.js b/bot/src/events/GuildDelete.js index 2dcba22..5ca1cbe 100644 --- a/bot/src/events/GuildDelete.js +++ b/bot/src/events/GuildDelete.js @@ -6,16 +6,6 @@ export default { name: Events.GuildDelete, async execute(guild) { console.log(`[i] I have been removed from: ${guild.name} (${guild.id})`); - - try { - const guildSetting = await guildSettings.findOne({ where: { guildID: guild.id } }); - if (guildSetting) { - await guildSettings.destroy({ where: { guildID: guild.id } }); - } - } catch (error) { - console.error(`Failed to remove guild settings for ${guild.id}:`, error); - } - const logEmbed = new EmbedBuilder() .setAuthor({ name: 'AleeBot', iconURL: guild.client.user.avatarURL() }) .setDescription('I got removed from a server...') @@ -26,6 +16,12 @@ export default { .setColor(abEmbedColour) .setFooter({ text: `We now run on ${guild.client.guilds.cache.size} guilds.` }); + const guildSetting = await guildSettings.findOne({ where: { guildID: guild.id } }); + + if (guildSetting) { + await guildSettings.destroy({ where: { guildID: guild.id } }); + } + let statusChannel = guild.client.channels.cache.get(process.env.statusChannelID); if (!statusChannel) return; await statusChannel.send({ embeds: [logEmbed]}); diff --git a/bot/src/events/GuildMemberRemove.js b/bot/src/events/GuildMemberRemove.js index 9bf5e9d..aa109b1 100644 --- a/bot/src/events/GuildMemberRemove.js +++ b/bot/src/events/GuildMemberRemove.js @@ -9,7 +9,7 @@ export default { const logEmbed = new EmbedBuilder() .setAuthor({ name: 'AleeBot Logging', iconURL: member.client.user.avatarURL() }) - .setDescription('A user has joined this server!') + .setDescription('A user has left this server!') .addFields( { name: 'Username: ', value: `${member.user.tag}`, inline: true }, { name: 'User ID: ', value: `${member.id}`, inline: true }, diff --git a/bot/src/events/InteractionCreate.js b/bot/src/events/InteractionCreate.js index eadef09..8f1e998 100644 --- a/bot/src/events/InteractionCreate.js +++ b/bot/src/events/InteractionCreate.js @@ -1,5 +1,9 @@ import { Events, MessageFlags } from 'discord.js'; +function error(e) { + return `Something went wrong. [Submit an issue at the AleeBot repository.](<https://github.com/Alee14/AleeBot/issues>)\nMessage:\n\`\`\`${e.stack}\`\`\``; +} + export default { name: Events.InteractionCreate, async execute(interaction) { @@ -12,11 +16,11 @@ export default { try { await command.execute(interaction); } catch (e) { - console.log(e); + console.error(e); if (interaction.replied || interaction.deferred) { - await interaction.followUp({ content: `Something went wrong. The following error message:\n\`\`\`${e}\`\`\``, flags: MessageFlags.Ephemeral }); + await interaction.followUp({ content: error(e), flags: MessageFlags.Ephemeral }); } else { - await interaction.reply({ content: `Something went wrong. The following error message:\n\`\`\`${e}\`\`\``, flags: MessageFlags.Ephemeral }); + await interaction.reply({ content: error(e), flags: MessageFlags.Ephemeral }); } } } diff --git a/bot/src/events/MessageCreate.js b/bot/src/events/MessageCreate.js index 90b517d..e7af3a8 100644 --- a/bot/src/events/MessageCreate.js +++ b/bot/src/events/MessageCreate.js @@ -1,6 +1,7 @@ import { Events } from 'discord.js'; import { ollama } from '../utils/ollama.js'; -import { ollamaEnabled, ollamaModel } from '../storage/consts.js'; +import { ollamaGlobal, ollamaModel } from '../storage/consts.js'; +import { guildSettings } from '../models/guild-settings.js'; export default { name: Events.MessageCreate, @@ -9,10 +10,13 @@ export default { if (msg.author.bot) return; if (!msg.guild) return; + const guildSetting = await guildSettings.findOne({ where: { guildID: msg.guild.id } }); + const args = msg.content.slice(`<@${msg.client.user.id}>`.length).trim(); if (msg.mentions.has(msg.client.user)) { - if (!ollamaEnabled) return msg.reply('Sorry, this feature has been turned off.'); + if (!guildSetting.ollamaEnabled) return; + if (!ollamaGlobal) return msg.reply('Sorry, this feature has been turned off.'); if (!args) return msg.reply('Sorry? What was that?'); try { @@ -35,7 +39,7 @@ export default { } catch (err) { console.error(err); - await msg.reply('Something went wrong.'); + await msg.reply(`Something went wrong. [Submit an issue at the AleeBot repository.](<https://github.com/Alee14/AleeBot/issues>)\nMessage:\n\`\`\`${err.stack}\`\`\``); } } } diff --git a/bot/src/events/MessageUpdate.js b/bot/src/events/MessageUpdate.js index 26f6ab3..118f51d 100644 --- a/bot/src/events/MessageUpdate.js +++ b/bot/src/events/MessageUpdate.js @@ -3,23 +3,23 @@ import { guildSettings } from '../models/guild-settings.js'; export default { name: Events.MessageUpdate, - async execute(oldmsg, newmsg) { - const guildSetting = await guildSettings.findOne({ where: { guildID: oldmsg.guild.id } }); - if (!oldmsg.guild || !guildSetting || !guildSetting.logChannelID) return; - if (oldmsg.content === newmsg.content) return; + async execute(msg, newmsg) { + const guildSetting = await guildSettings.findOne({ where: { guildID: msg.guild.id } }); + if (!msg.guild || !guildSetting || !guildSetting.logChannelID) return; + if (msg.content === newmsg.content) return; const logEmbed = new EmbedBuilder() - .setAuthor({ name: 'AleeBot Logging', iconURL: oldmsg.client.user.avatarURL() }) - .setDescription(`A message from ${oldmsg.author.username} was edited in <#${oldmsg.channel.id}>`) + .setAuthor({ name: 'AleeBot Logging', iconURL: msg.client.user.avatarURL() }) + .setDescription(`A message from ${msg.author.username} was edited in <#${msg.channel.id}>`) .addFields( - { name: 'Before: ', value: `\`\`\`${oldmsg.content}\`\`\`` }, + { name: 'Before: ', value: `\`\`\`${msg.content}\`\`\`` }, { name: 'After: ', value: `\`\`\`${newmsg.content}\`\`\`` } ) .setColor('#ffff1a') .setTimestamp() - .setFooter(`Author ID: ${oldmsg.author.id}`); + .setFooter(`Author ID: ${msg.author.id}`); - let editMessage = oldmsg.client.channels.cache.get(guildSetting.logChannelID); + let editMessage = msg.client.channels.cache.get(guildSetting.logChannelID); if (!editMessage) return; await editMessage.send({ embeds: [logEmbed]}); diff --git a/bot/src/models/guild-settings.js b/bot/src/models/guild-settings.js index 81cfbc2..bb4d30b 100644 --- a/bot/src/models/guild-settings.js +++ b/bot/src/models/guild-settings.js @@ -1,4 +1,4 @@ -import { INTEGER, STRING } from 'sequelize'; +import { INTEGER, STRING, BOOLEAN } from 'sequelize'; import { sequelize } from '../utils/sequelize.js'; export const guildSettings = sequelize.define('guild-settings', { @@ -14,14 +14,22 @@ export const guildSettings = sequelize.define('guild-settings', { logChannelID: { type: STRING, allowNull: true - } - // qotdChannelID: { - // type: Sequelize.STRING, - // allowNull: true - // }, - // qotdToggle: { - // type: Sequelize.BOOLEAN, - // allowNull: true - // } + }, + suggestionsChannelID: { + type: STRING, + allowNull: true + }, + qotdChannelID: { + type: STRING, + allowNull: true + }, + qotdToggle: { + type: BOOLEAN, + allowNull: true + }, + ollamaEnabled: { + type: BOOLEAN, + allowNull: true + }, }); diff --git a/bot/src/storage/consts.js b/bot/src/storage/consts.js index 905ef79..0787528 100644 --- a/bot/src/storage/consts.js +++ b/bot/src/storage/consts.js @@ -1,5 +1,5 @@ export const abEmbedColour = '#0066a6'; export const readyMsg = false; -export const ollamaEnabled = false; +export const ollamaGlobal = false; export const ollamaModel = 'deepseek-r1:14b'; export const featureSuggestChannel = '427495678390960148'; |
