make context menu commands ephemeral in DMs

This commit is contained in:
artie 2025-03-17 20:43:32 +01:00
parent 0aa9c09fe7
commit b3c0f5ba40
6 changed files with 36 additions and 9 deletions

View File

@ -2,6 +2,7 @@ import { ApplicationCommandType, ContextMenuCommandBuilder } from "discord.js";
import { defineCommand } from "..";
import { translateImpl } from "./translate";
import { abort } from "../../utils/error";
import { defer } from "../../utils/functions";
export default defineCommand({
data: new ContextMenuCommandBuilder()
@ -14,7 +15,7 @@ export default defineCommand({
const text = interaction.targetMessage.content;
if (!text) abort("No text to translate");
await interaction.deferReply();
await defer(interaction);
const payload = await translateImpl(text, null, "en-US");
await interaction.editReply(payload);

View File

@ -11,6 +11,7 @@ import { defineCommand } from "..";
import { abort } from "../../utils/error";
import { translateImpl } from "./translate";
import { findFuzzyLanguage } from "../../utils/deepl";
import { defer } from "../../utils/functions";
export function buildTranslateModal() {
return new ModalBuilder()
@ -58,7 +59,7 @@ export default defineCommand({
time: 60000 * 5,
})
.then(async interaction => {
await interaction.deferReply();
await defer(interaction);
const sourceField =
interaction.fields.getTextInputValue("source") || "auto";

View File

@ -1,7 +1,7 @@
import { ApplicationCommandType, ContextMenuCommandBuilder } from "discord.js";
import { defineCommand } from "..";
import { buildOcrPayload, ocrImpl } from "./ocr";
import { getImageUrlFromMessage } from "../../utils/functions";
import { defer, getImageUrlFromMessage } from "../../utils/functions";
export default defineCommand({
data: new ContextMenuCommandBuilder()
@ -13,7 +13,7 @@ export default defineCommand({
const imageUrl = getImageUrlFromMessage(interaction.targetMessage);
await interaction.deferReply();
await defer(interaction);
const { text, language, model } = await ocrImpl(imageUrl);
const payload = buildOcrPayload(text, language, model);

View File

@ -2,7 +2,7 @@ import { ApplicationCommandType, ContextMenuCommandBuilder } from "discord.js";
import { defineCommand } from "..";
import { translateImpl } from "../language/translate";
import { ocrImpl } from "./ocr";
import { getImageUrlFromMessage } from "../../utils/functions";
import { defer, getImageUrlFromMessage } from "../../utils/functions";
export default defineCommand({
data: new ContextMenuCommandBuilder()
@ -14,7 +14,7 @@ export default defineCommand({
const imageUrl = getImageUrlFromMessage(interaction.targetMessage);
await interaction.deferReply();
await defer(interaction);
const { text, model } = await ocrImpl(imageUrl);
const payload = await translateImpl(text, null, "en-US", model);

View File

@ -5,7 +5,7 @@ import { ocrImpl } from "./ocr";
import { buildTranslateModal } from "../language/translateMenu";
import { abort } from "../../utils/error";
import { findFuzzyLanguage } from "../../utils/deepl";
import { getImageUrlFromMessage } from "../../utils/functions";
import { defer, getImageUrlFromMessage } from "../../utils/functions";
export default defineCommand({
data: new ContextMenuCommandBuilder()
@ -26,7 +26,7 @@ export default defineCommand({
time: 60000 * 5,
})
.then(async interaction => {
await interaction.deferReply();
await defer(interaction);
const sourceField =
interaction.fields.getTextInputValue("source") || null;

View File

@ -2,7 +2,14 @@ import * as cheerio from "cheerio";
import { execa } from "execa";
import { customAlphabet } from "nanoid";
import { URL_REGEX } from "./constants";
import { Message, type ChatInputCommandInteraction } from "discord.js";
import {
ChannelType,
Message,
MessageContextMenuCommandInteraction,
MessageFlags,
ModalSubmitInteraction,
type ChatInputCommandInteraction,
} from "discord.js";
import { abort } from "./error";
export const nanoid = customAlphabet("1234567890abcdef");
@ -105,3 +112,21 @@ export function languageCodeToName(code: string) {
return undefined;
}
}
// deferReply helper with flag heuristics
export async function defer(
interaction:
| MessageContextMenuCommandInteraction
| ModalSubmitInteraction
| ChatInputCommandInteraction
) {
const isDMBased = interaction.channel?.isDMBased();
const isBotDM =
isDMBased &&
interaction.channel.type === ChannelType.DM &&
interaction.channel.recipientId === interaction.client.user.id;
await interaction.deferReply({
flags: isDMBased && !isBotDM ? MessageFlags.Ephemeral : undefined,
});
}