diff --git a/labscore/constants.js b/labscore/constants.js index e2dd611..3fe536d 100644 --- a/labscore/constants.js +++ b/labscore/constants.js @@ -34,7 +34,8 @@ module.exports.COLORS = Object.freeze({ warning: 16426522, embed: 2829617, brand: 6809687, - nsfw: 15549056 + nsfw: 15549056, + incognito: 10057726, }) module.exports.BADGE_ICONS = Object.freeze({ diff --git a/labscore/paginator/structures/BasePaginator.js b/labscore/paginator/structures/BasePaginator.js index 5c72d0d..a5b0f28 100644 --- a/labscore/paginator/structures/BasePaginator.js +++ b/labscore/paginator/structures/BasePaginator.js @@ -1,5 +1,6 @@ const EventEmitter = require("eventemitter3"); const { Context } = require("detritus-client/lib/command"); +const { editOrReply } = require("#utils/message"); module.exports = class BasePaginator extends EventEmitter { constructor(client, data) { @@ -10,13 +11,15 @@ module.exports = class BasePaginator extends EventEmitter { this.pages = data.pages; this.index = 0; + this.context = data.context; + this.targetUser = data.targetUser || this.message?.author?.id || data.context?.user?.id; this.isInteractionPaginator = false; this.editOrReply; - if(data.context.editOrReply) this.editOrReply = data.context.editOrReply.bind(data.context); + if(data.context.editOrReply) this.editOrReply = editOrReply.bind(data.context); if(data.context.editOrRespond){ - this.editOrReply = data.context.editOrRespond.bind(data.context); + this.editOrReply = editOrReply.bind(data.context); this.isInteractionPaginator = true; } } @@ -65,7 +68,7 @@ module.exports = class BasePaginator extends EventEmitter { if(!msg.message_reference) msg.reference = true if(!msg.allowedMentions) msg.allowedMentions = {parse: [], repliedUser: false} - return this.commandMessage = await this.editOrReply(msg); + return this.commandMessage = await this.editOrReply(this.context, msg); } async previous() { diff --git a/labscore/utils/message.js b/labscore/utils/message.js index e10a5c9..89c77e0 100644 --- a/labscore/utils/message.js +++ b/labscore/utils/message.js @@ -1,6 +1,15 @@ const { Permissions, MessageFlags } = require("detritus-client/lib/constants") const { basecamp } = require("../logging") const { createEmbed } = require("./embed") +const { COLORS } = require("#constants") + +/** + * These will force the command to become "incognito". + */ +const BLOCK_REASONS = { + 20016: "Slowmode", + 200000: "AutoMod" +} module.exports.editOrReply = function(context, message, disableReference = false){ // Apply message_reference @@ -21,41 +30,42 @@ module.exports.editOrReply = function(context, message, disableReference = false // you can figure out what this does on your own time message.nonce = Math.floor(Math.random() * 9999 + 1000) + message.flags = flags; // Handle responses for interaction context + console.log("responding" + Date.now() + " (flags " + flags + ")") + console.log(context._meta) if(context.editOrRespond){ - return context.editOrRespond(message).catch((e)=>{ - /* - Discord in their infinite wisdom decided that *bots* should - be the one to handle automod errors on their own, deciding - against adding a notice/response type for their frontend. + if(context._meta?.replacementMessageId){ + console.log("responding via hack") + return context.editMessage(context._meta.replacementMessageId, message).catch((e)=>{ + basecamp(`<:ico_w3:1086624963047460874>\`[${process.env.HOSTNAME}]\` **\` SHARD_MESSAGE_ERROR \`** \`[Shard ${context.client.shardId}]\` Command \`${context.command.name}\` failed to respond: @ \`${Date.now()}\`\nGuild: \`${context.guild?.id}\`\nChannel: \`${context.channel?.id}\`\nUser: \`${context.user?.id}\`\`\`\`js\n${e}\`\`\``, message) + }); + } + + return context.editOrRespond(message).catch(async (e)=>{ + const errorData = await e.response.json(); + if(BLOCK_REASONS[errorData.code]){ + // Delete the public response + await context.deleteResponse(); + + message.flags = MessageFlags.EPHEMERAL - This is the awesome solution to this problem, that isn't - actually very awesome and actually sucks a lot. - */ - if(e.code === 200000){ - try{ - let embedResponse = createEmbed("error", context, "Response was filtered by AutoMod.") - embedResponse.description = `Try running the command somewhere else or ask server admins for help.` - return context.editOrRespond({ - allowedMentions: { parse: [], repliedUser: false }, - embeds: [ - embedResponse - ], - flags + // Create a notice + if(message.embeds && message.embeds.length <= 4){ + message.embeds.unshift({ + description: `<:incognito:1250198171859161199> ​ ​ This response has been made incognito due to ${BLOCK_REASONS[errorData.code]}.`, + color: COLORS.incognito }) - }catch(e){ - /* - another error? suck it. - there is genuinely nothing left that we can do. - - create followup message has an awesome 'hack' that prevents - the bot from creating a new ephemeral followup response - if the original one isn't/couldn't be acknowledged. - - https://discord.com/developers/docs/interactions/receiving-and-responding#create-followup-message - */ } + + let replacementMessage = await context.createMessage(message); + + if(!context._meta) context._meta = {} + context._meta.replacementMessageId = replacementMessage.id; + + return replacementMessage; + } basecamp(`<:ico_w3:1086624963047460874>\`[${process.env.HOSTNAME}]\` **\` SHARD_MESSAGE_ERROR \`** \`[Shard ${context.client.shardId}]\` Command \`${context.command.name}\` failed to respond: @ \`${Date.now()}\`\nGuild: \`${context.guild?.id}\`\nChannel: \`${context.channel?.id}\`\nUser: \`${context.user?.id}\`\`\`\`js\n${e}\`\`\``, message) }) @@ -65,5 +75,5 @@ module.exports.editOrReply = function(context, message, disableReference = false if(!context.message.deleted && context.channel.can(Permissions.SEND_MESSAGES)) return context.editOrReply(message).catch((e)=>{ console.log(e.status) basecamp(`<:ico_w3:1086624963047460874>\`[${process.env.HOSTNAME}]\` **\` SHARD_MESSAGE_ERROR \`** \`[Shard ${context.client.shardId}]\` Command \`${context.message?.content}\` failed to reply: @ \`${Date.now()}\`\nGuild: \`${context.guild?.id}\`\nChannel: \`${context.channel?.id}\`\nUser: \`${context.user?.id}\`\`\`\`js\n${e}\`\`\``, message) -}) + }) } \ No newline at end of file