From 7cb2d1aa9c2467398b8bdd884202b3b97253b043 Mon Sep 17 00:00:00 2001 From: kmmiio99o Date: Sat, 3 Jan 2026 13:32:34 +0100 Subject: [PATCH] fix: sending second non existing message --- .zed/settings.json | 3 ++ plugins/Commands/src/commands/facts.ts | 32 +++++++++++----- plugins/Commands/src/commands/firstmessage.ts | 12 ++++-- .../Commands/src/commands/friendinvites.ts | 31 +++++++-------- plugins/Commands/src/commands/gary.ts | 16 ++++---- plugins/Commands/src/commands/ip.ts | 14 +++---- plugins/Commands/src/commands/konochan.ts | 18 ++++----- plugins/Commands/src/commands/lists.ts | 30 +++++++-------- plugins/Commands/src/commands/lovefemboys.ts | 2 +- plugins/Commands/src/commands/nekoslife.ts | 38 +++++++++---------- plugins/Commands/src/commands/petpet.ts | 8 ++-- plugins/Commands/src/commands/spotify.ts | 22 +++++------ plugins/Commands/src/commands/sysinfo.ts | 8 ++-- plugins/Commands/src/utils/messages.ts | 12 +++--- 14 files changed, 130 insertions(+), 116 deletions(-) create mode 100644 .zed/settings.json diff --git a/.zed/settings.json b/.zed/settings.json new file mode 100644 index 0000000..d8a1fe6 --- /dev/null +++ b/.zed/settings.json @@ -0,0 +1,3 @@ +{ + "format_on_save": "off", +} diff --git a/plugins/Commands/src/commands/facts.ts b/plugins/Commands/src/commands/facts.ts index d2f1188..dea1a63 100644 --- a/plugins/Commands/src/commands/facts.ts +++ b/plugins/Commands/src/commands/facts.ts @@ -1,11 +1,12 @@ import { findByProps } from "@vendetta/metro"; +import { showToast } from "@vendetta/ui/toasts"; import { storage } from "@vendetta/plugin"; import { catFact, dogFact, uselessFact } from "../utils/api"; const MessageActions = findByProps("sendMessage"); // Helper function to format fact response -const formatFactResponse = (fact: { text: string; source?: string }) => { +const formatFactResponse = (fact: { text: string; source?: string; length?: number }) => { let response = fact.text; if (storage.factSettings?.includeCitation && fact.source) { response += `\n\nSource: ${fact.source}`; @@ -25,17 +26,22 @@ export const catFactCommand = { try { const fact = await catFact(); const fixNonce = Date.now().toString(); + MessageActions.sendMessage( ctx.channel.id, { content: formatFactResponse(fact) }, void 0, { nonce: fixNonce } ); - return { type: 4 }; + + // return NOTHING - let client handle the acknowledgement + return null; } catch (error) { console.error("[CatFact] Error:", error); - // Silent fail - no error message in chat - return { type: 4 }; + // Show toast on error + showToast("Failed to fetch cat fact", 3000); + // Return nothing on error too + return null; } }, }; @@ -52,17 +58,20 @@ export const dogFactCommand = { try { const fact = await dogFact(); const fixNonce = Date.now().toString(); + MessageActions.sendMessage( ctx.channel.id, { content: formatFactResponse(fact) }, void 0, { nonce: fixNonce } ); - return { type: 4 }; + + return null; } catch (error) { console.error("[DogFact] Error:", error); - // Silent fail - no error message in chat - return { type: 4 }; + // Show toast on error + showToast("Failed to fetch dog fact", 3000); + return null; } }, }; @@ -79,17 +88,20 @@ export const uselessFactCommand = { try { const fact = await uselessFact(); const fixNonce = Date.now().toString(); + MessageActions.sendMessage( ctx.channel.id, { content: formatFactResponse(fact) }, void 0, { nonce: fixNonce } ); - return { type: 4 }; + + return null; } catch (error) { console.error("[UselessFact] Error:", error); - // Silent fail - no error message in chat - return { type: 4 }; + // Show toast on error + showToast("Failed to fetch useless fact", 3000); + return null; } }, }; diff --git a/plugins/Commands/src/commands/firstmessage.ts b/plugins/Commands/src/commands/firstmessage.ts index 266ae55..8dad2cf 100644 --- a/plugins/Commands/src/commands/firstmessage.ts +++ b/plugins/Commands/src/commands/firstmessage.ts @@ -1,4 +1,5 @@ import { findByProps } from "@vendetta/metro"; +import { showToast } from "@vendetta/ui/toasts"; import { ReactNative as RN } from "@vendetta/metro/common"; interface CommandOption { @@ -84,7 +85,8 @@ export const firstMessageCommand = { // Channel option is not valid in DMs if (isDM && channel) { - return { type: 4 }; + showToast("Channel option cannot be used in DMs", 3000); + return null; } let result = "https://discord.com/channels/"; @@ -114,11 +116,13 @@ export const firstMessageCommand = { RN.Linking.openURL(result); } - return { type: 4 }; + return null; } catch (error) { console.error("[FirstMessage] Error:", error); - // Silent fail - no error message in chat - return { type: 4 }; + // Show toast on error + showToast("Failed to fetch first message", 3000); + // Silent fail + return null; } }, applicationId: "-1", diff --git a/plugins/Commands/src/commands/friendinvites.ts b/plugins/Commands/src/commands/friendinvites.ts index daec685..1866332 100644 --- a/plugins/Commands/src/commands/friendinvites.ts +++ b/plugins/Commands/src/commands/friendinvites.ts @@ -8,7 +8,6 @@ const inviteModule = findByProps( "createFriendInvite", "revokeFriendInvites", ); -const api = findByProps("get", "post"); const getCurrentUser = findByProps("getCurrentUser")?.getCurrentUser; function send(ctx, content) { @@ -33,7 +32,7 @@ export const friendInviteCreateCommand = { "You need a phone number connected to your account!", getAssetIDByName("Small"), ); - return { type: 4 }; + return null; } // Main method: Create friend invite directly @@ -56,11 +55,11 @@ export const friendInviteCreateCommand = { throw new Error("No invite code generated"); } - return { type: 4 }; + return null; } catch (e) { console.error("[FriendInvite] Create error:", e); showToast("Error creating friend invite", getAssetIDByName("Small")); - return { type: 4 }; + return null; } }, }; @@ -77,7 +76,7 @@ export const friendInviteViewCommand = { const invites = await inviteModule.getAllFriendInvites(); if (!invites?.length) { showToast("No active friend invites found", getAssetIDByName("Info")); - return { type: 4 }; + return null; } const friendInviteList = invites.map((i) => { @@ -89,11 +88,12 @@ export const friendInviteViewCommand = { ctx, `**Your Active Friend Invites:**\n${friendInviteList.join("\n")}`, ); - return { type: 4 }; + + return null; } catch (e) { console.error("[FriendInvite] View error:", e); showToast("Error viewing friend invites", getAssetIDByName("Small")); - return { type: 4 }; + return null; } }, }; @@ -115,7 +115,7 @@ export const friendInviteRevokeCommand = { "No active friend invites to revoke", getAssetIDByName("Info"), ); - return { type: 4 }; + return null; } await inviteModule.revokeFriendInvites(); @@ -124,27 +124,22 @@ export const friendInviteRevokeCommand = { const invitesAfter = await inviteModule.getAllFriendInvites(); if (invitesAfter.length === 0) { - send( - ctx, - `✅ Successfully revoked all ${invitesBefore.length} friend invite(s)!`, - ); showToast( - `Revoked ${invitesBefore.length} invite(s)`, + `Successfully revoked all ${invitesBefore.length} friend invite(s)!`, getAssetIDByName("Check"), ); } else { - send( - ctx, + showToast( `⚠️ Partially revoked invites. ${invitesAfter.length} invite(s) remain active.`, + getAssetIDByName("Warning"), ); - showToast("Partial revocation", getAssetIDByName("Warning")); } - return { type: 4 }; + return null; } catch (e) { console.error("[FriendInvite] Revoke error:", e); showToast("Error revoking friend invites", getAssetIDByName("Small")); - return { type: 4 }; + return null; } }, }; diff --git a/plugins/Commands/src/commands/gary.ts b/plugins/Commands/src/commands/gary.ts index 989c30a..3736dec 100644 --- a/plugins/Commands/src/commands/gary.ts +++ b/plugins/Commands/src/commands/gary.ts @@ -16,19 +16,19 @@ export const garyCommand = { if (!storage.garySettings) { storage.garySettings = { imageSource: "gary" }; } - + const source = storage.garySettings.imageSource || "gary"; - console.log(`[Gary Command] Using image source: ${source}`); // Debug log - + console.log(`[Gary Command] Using image source: ${source}`); + const imageUrl = await getGaryUrl(source); if (!imageUrl) { console.log("[Gary Command] No image URL received"); - // Silent fail - no error message - return { type: 4 }; + // Silent fail + return null; } - console.log(`[Gary Command] Sending image: ${imageUrl}`); // Debug log + console.log(`[Gary Command] Sending image: ${imageUrl}`); const fixNonce = Date.now().toString(); MessageActions.sendMessage(ctx.channel.id, { content: imageUrl }, void 0, { nonce: fixNonce, @@ -36,8 +36,8 @@ export const garyCommand = { return { type: 4 }; } catch (error) { console.error("[Gary] Error:", error); - // Silent fail - no error message in chat - return { type: 4 }; + // Silent fail + return null; } }, applicationId: "-1", diff --git a/plugins/Commands/src/commands/ip.ts b/plugins/Commands/src/commands/ip.ts index 0ab38c3..ce2bec7 100644 --- a/plugins/Commands/src/commands/ip.ts +++ b/plugins/Commands/src/commands/ip.ts @@ -74,7 +74,7 @@ export const ipCommand = { }; } showToast(errorMsg, getAssetIDByName("CircleXIcon")); - return { type: 4 }; + return null; } // Show loading toast @@ -88,7 +88,7 @@ export const ipCommand = { "country_phone,latitude,longitude,timezone,currency,completed_requests"; const response = await fetch(url); - + if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } @@ -107,7 +107,7 @@ export const ipCommand = { }; } showToast(errorMsg, getAssetIDByName("CircleXIcon")); - return { type: 4 }; + return null; } // Format the response as code block @@ -129,14 +129,14 @@ export const ipCommand = { } else { // Send as bot message (ephemeral-like) messageUtil.sendBotMessage(ctx.channel.id, content); - return { type: 4 }; + return null; } } catch (error) { console.error("[IP] Command error:", error); const errorMessage = `❌ An error occurred while looking up IP information: ${error.message || "Unknown error"}`; - + const isEphemeral = args?.find?.((arg: any) => arg.name === "ephemeral")?.value ?? false; - + if (isEphemeral) { return { type: 4, @@ -147,7 +147,7 @@ export const ipCommand = { }; } showToast(errorMessage, getAssetIDByName("CircleXIcon")); - return { type: 4 }; + return null; } }, applicationId: "-1", diff --git a/plugins/Commands/src/commands/konochan.ts b/plugins/Commands/src/commands/konochan.ts index ece61aa..1c9a591 100644 --- a/plugins/Commands/src/commands/konochan.ts +++ b/plugins/Commands/src/commands/konochan.ts @@ -85,25 +85,25 @@ export const konoSelfCommand = { if (isNSFW && !ctx.channel.nsfw && !bypassEnabled) { showNSFWWarning(); - return { type: 4 }; + return null; } const imageUrl = await fetchImage(isNSFW); if (!imageUrl) { - // Silent fail - no error message - return { type: 4 }; + // Silent fail + return null; } messageUtil.sendBotMessage( ctx.channel.id, `Here's your random image: ${imageUrl}`, ); - return { type: 4 }; + return null; } catch (error) { console.error("[KonoSelf] Error:", error); // Silent fail - no error message in chat - return { type: 4 }; + return null; } }, applicationId: "-1", @@ -136,14 +136,14 @@ export const konoSendCommand = { if (isNSFW && !ctx.channel.nsfw && !bypassEnabled) { showNSFWWarning(); - return { type: 4 }; + return null; } const imageUrl = await fetchImage(isNSFW); if (!imageUrl) { - // Silent fail - no error message - return { type: 4 }; + // Silent fail + return null; } const fixNonce = Date.now().toString(); @@ -155,7 +155,7 @@ export const konoSendCommand = { nonce: fixNonce, }, ); - return { type: 4 }; + return null; } catch (error) { console.error("[KonoSend] Error:", error); // Silent fail - no error message in chat diff --git a/plugins/Commands/src/commands/lists.ts b/plugins/Commands/src/commands/lists.ts index 71f8cf9..4dba67d 100644 --- a/plugins/Commands/src/commands/lists.ts +++ b/plugins/Commands/src/commands/lists.ts @@ -73,7 +73,7 @@ const addonAuthors = (authors: any) => { if (!authors) return "Unknown"; if (!Array.isArray(authors)) return "Unknown"; if (authors.length === 0) return "Unknown"; - + return authors .filter(author => author && (typeof author === "string" || (typeof author === "object" && author.name))) .map(author => typeof author === "string" ? author : (author.name || "Unknown")) @@ -108,11 +108,11 @@ export async function themeList(args: any[], ctx: any) { if (!themes || typeof themes !== "object") { const channelID: string = ctx.channel.id; Clyde.sendBotMessage(channelID, "No themes found or themes not loaded yet."); - return { type: 4 }; + return null; } const objectValues = Object.values(themes); - + const channelID: string = ctx.channel.id; const themeList = baseListHeader("Theme", Object.keys(themes).length); @@ -120,14 +120,14 @@ export async function themeList(args: any[], ctx: any) { if (objectValues.length) { for (const theme of objectValues) { if (!theme || typeof theme !== "object") continue; - + const { selected, data, id } = theme; - + // Safe destructuring with fallbacks const name = data?.name || "Unknown Theme"; const description = data?.description || "No description"; const authors = data?.authors; - + if (detailed || alwaysDetailed) themeList.push( `> **Name**: ${name}`, @@ -157,12 +157,12 @@ export async function themeList(args: any[], ctx: any) { cancelText: ALERT.CANCEL, onConfirm: async () => await sendList(channelID, themeList) }); - + await sendList(channelID, themeList); } } catch (error) { console.error("[ThemeList] Error:", error); - return { type: 4 }; + return null; } } @@ -176,16 +176,16 @@ export async function pluginList(args: any[], ctx: any) { // Ensure plugins is valid if (!plugins || typeof plugins !== "object") { Clyde.sendBotMessage(channelID, "No plugins found or plugins not loaded yet."); - return { type: 4 }; + return null; } const pluginList = baseListHeader("Plugin", Object.keys(plugins).length); for (const plugin of Object.values(plugins)) { if (!plugin || typeof plugin !== "object") continue; - + const { enabled, manifest, id } = plugin; - + // Safe destructuring with fallbacks const name = manifest?.name || "Unknown Plugin"; const description = manifest?.description || "No description"; @@ -223,14 +223,14 @@ export async function pluginList(args: any[], ctx: any) { } } catch (error) { console.error("[PluginList] Error:", error); - return { type: 4 }; + return null; } } // Export commands for your existing structure export const pluginListCommand = { name: "plugin-list", - displayName: "plugin list", + displayName: "plugin list", description: "Send your plugin list to the current channel", displayDescription: "Send your plugin list to the current channel", options: [ @@ -252,7 +252,7 @@ export const pluginListCommand = { export const themeListCommand = { name: "theme-list", displayName: "theme list", - description: "Send your theme list to the current channel", + description: "Send your theme list to the current channel", displayDescription: "Send your theme list to the current channel", options: [ { @@ -265,7 +265,7 @@ export const themeListCommand = { }, ], execute: themeList, - applicationId: "-1", + applicationId: "-1", inputType: 1, type: 1, }; diff --git a/plugins/Commands/src/commands/lovefemboys.ts b/plugins/Commands/src/commands/lovefemboys.ts index 7a23050..d00ee9c 100644 --- a/plugins/Commands/src/commands/lovefemboys.ts +++ b/plugins/Commands/src/commands/lovefemboys.ts @@ -95,7 +95,7 @@ export const lovefemboysCommand = { }); if (!shouldProceed) { - return { type: 4 }; + return null; } } diff --git a/plugins/Commands/src/commands/nekoslife.ts b/plugins/Commands/src/commands/nekoslife.ts index ef0ecc7..786a071 100644 --- a/plugins/Commands/src/commands/nekoslife.ts +++ b/plugins/Commands/src/commands/nekoslife.ts @@ -11,27 +11,27 @@ interface NekosLifeResult { // Valid SFW categories for validation const validSfwCategories = [ - "avatar", "classic", "cuddle", "fox_girl", "gecg", "holo", - "kemonomimi", "kiss", "neko", "ngif", "smug", "spank", + "avatar", "classic", "cuddle", "fox_girl", "gecg", "holo", + "kemonomimi", "kiss", "neko", "ngif", "smug", "spank", "tickle", "waifu", "wallpaper", "woof" ]; async function fetchNekosLifeImages(category: string, count: number): Promise { const urls: string[] = []; - + for (let i = 0; i < count; i++) { try { // Add delay between requests to avoid rate limiting if (i > 0) { await new Promise(resolve => setTimeout(resolve, 1000)); } - + const response = await fetch(`https://nekos.life/api/v2/img/${category}`); if (!response.ok) { console.error(`[NekosLife] API request failed: ${response.status}`); continue; } - + const data: NekosLifeResult = await response.json(); if (data.url) { urls.push(data.url); @@ -40,7 +40,7 @@ async function fetchNekosLifeImages(category: string, count: number): Promise { try { console.log("[NekosLife] Command executed with args:", args); - + // Parse arguments const categoryInput = args.find((arg: any) => arg.name === "category")?.value; const limitInput = args.find((arg: any) => arg.name === "limit")?.value; @@ -99,11 +99,11 @@ export const nekoslifeCommand = { const isEphemeral = args.find((arg: any) => arg.name === "ephemeral")?.value || false; console.log("[NekosLife] Parsed values:", { categoryInput, limitInput, shouldSend, isEphemeral }); - + if (!categoryInput || typeof categoryInput !== "string") { const errorMsg = "❌ Category is required! Examples: neko, waifu, cuddle, kiss"; console.error("[NekosLife] No category provided"); - + if (isEphemeral) { return { type: 4, @@ -114,15 +114,15 @@ export const nekoslifeCommand = { }; } showToast(errorMsg, getAssetIDByName("CircleXIcon")); - return { type: 4 }; + return null; } // Clean and validate category const category = categoryInput.toLowerCase().trim(); - + if (!isValidSfwCategory(category)) { const errorMsg = `❌ Invalid SFW category "${categoryInput}". Valid: neko, waifu, cuddle, kiss, holo, etc.`; - + if (isEphemeral) { return { type: 4, @@ -133,7 +133,7 @@ export const nekoslifeCommand = { }; } showToast(errorMsg, getAssetIDByName("CircleXIcon")); - return { type: 4 }; + return null; } // Parse and validate limit @@ -164,7 +164,7 @@ export const nekoslifeCommand = { }; } showToast(errorMsg, getAssetIDByName("CircleXIcon")); - return { type: 4 }; + return null; } const content = urls.join("\n"); @@ -182,18 +182,18 @@ export const nekoslifeCommand = { console.log("[NekosLife] Sending to chat"); const fixNonce = Date.now().toString(); MessageActions.sendMessage(ctx.channel.id, { content }, void 0, { nonce: fixNonce }); - return { type: 4 }; + return null; } else { console.log("[NekosLife] Sending as bot message"); messageUtil.sendBotMessage(ctx.channel.id, content); - return { type: 4 }; + return null; } } catch (error) { console.error("[NekosLife] Command error:", error); const errorMessage = "❌ An error occurred while fetching images."; - + const isEphemeral = args?.find?.((arg: any) => arg.name === "ephemeral")?.value ?? false; - + if (isEphemeral) { return { type: 4, @@ -204,7 +204,7 @@ export const nekoslifeCommand = { }; } showToast(errorMessage, getAssetIDByName("CircleXIcon")); - return { type: 4 }; + return null; } }, applicationId: "-1", diff --git a/plugins/Commands/src/commands/petpet.ts b/plugins/Commands/src/commands/petpet.ts index 91d0340..6c55881 100644 --- a/plugins/Commands/src/commands/petpet.ts +++ b/plugins/Commands/src/commands/petpet.ts @@ -24,7 +24,7 @@ export const petPetCommand = { const user = await UserStore.getUser(args[0].value); const image = user.getAvatarURL(512); const data = await getPetPetData(image); - + const fixNonce = Date.now().toString(); MessageActions.sendMessage( ctx.channel.id, @@ -32,11 +32,11 @@ export const petPetCommand = { void 0, { nonce: fixNonce } ); - return { type: 4 }; + return null; } catch (error) { console.error("[PetPet] Error:", error); - // Silent fail - no error message in chat - return { type: 4 }; + // Silent fail + return null; } }, applicationId: "-1", diff --git a/plugins/Commands/src/commands/spotify.ts b/plugins/Commands/src/commands/spotify.ts index 5009e7c..8672eb4 100644 --- a/plugins/Commands/src/commands/spotify.ts +++ b/plugins/Commands/src/commands/spotify.ts @@ -6,30 +6,30 @@ const SpotifyStore = findByStoreName("SpotifyStore"); // Individual command functions async function spotifyTrackExecute(args: any[], ctx: any) { - if (!storage.enabledCommands?.spotifyTrack) return { type: 4 }; - return handleSpotifyCommand(ctx, (track: any) => + if (!storage.enabledCommands?.spotifyTrack) return null;; + return handleSpotifyCommand(ctx, (track: any) => `https://open.spotify.com/track/${track.id}` ); } async function spotifyAlbumExecute(args: any[], ctx: any) { - if (!storage.enabledCommands?.spotifyAlbum) return { type: 4 }; + if (!storage.enabledCommands?.spotifyAlbum) return null; return handleSpotifyCommand(ctx, (track: any) => `https://open.spotify.com/album/${track.album.id}` ); } async function spotifyArtistsExecute(args: any[], ctx: any) { - if (!storage.enabledCommands?.spotifyArtists) return { type: 4 }; + if (!storage.enabledCommands?.spotifyArtists) return null; return handleSpotifyCommand(ctx, (track: any) => - track.artists.map((artist: any) => + track.artists.map((artist: any) => `[${artist.name}](${artist.external_urls.spotify})` ).join("\n") ); } async function spotifyCoverExecute(args: any[], ctx: any) { - if (!storage.enabledCommands?.spotifyCover) return { type: 4 }; + if (!storage.enabledCommands?.spotifyCover) return null; return handleSpotifyCommand(ctx, (track: any) => track.album.image.url ); @@ -49,23 +49,23 @@ async function handleSpotifyCommand(ctx: any, contentGenerator: (track: any) => void 0, { nonce: fixNonce } ); - return { type: 4 }; + return null; } const content = contentGenerator(track); const fixNonce = Date.now().toString(); - + MessageActions.sendMessage( channelId, { content }, void 0, { nonce: fixNonce } ); - - return { type: 4 }; + + return null; } catch (error) { console.error("[Spotify Command] Error:", error); - return { type: 4 }; + return null; } } diff --git a/plugins/Commands/src/commands/sysinfo.ts b/plugins/Commands/src/commands/sysinfo.ts index 164f5bc..0e478d0 100644 --- a/plugins/Commands/src/commands/sysinfo.ts +++ b/plugins/Commands/src/commands/sysinfo.ts @@ -181,7 +181,7 @@ function executeSysinfoCommand(args: any[], ctx: any) { if ((ephemeral || epermit) && !(epermit && !ephemeral)) { messageUtil.sendBotMessage(ctx.channel.id, output.join("\n")); - return { type: 4 }; + return null; } else { const fixNonce = Date.now().toString(); MessageActions.sendMessage( @@ -190,12 +190,12 @@ function executeSysinfoCommand(args: any[], ctx: any) { void 0, { nonce: fixNonce }, ); - return { type: 4 }; + return null; } } catch (e) { console.error("[Sysinfo] Error:", e); - // Silent fail - no chat message - return { type: 4 }; + // Silent fail + return null; } } diff --git a/plugins/Commands/src/utils/messages.ts b/plugins/Commands/src/utils/messages.ts index be75871..4912012 100644 --- a/plugins/Commands/src/utils/messages.ts +++ b/plugins/Commands/src/utils/messages.ts @@ -18,7 +18,7 @@ export const sendMessage = ( ephemeral?: boolean, ) => { // If no content, just acknowledge the command - if (!content) return { type: 4 }; + if (!content) return null; // For ephemeral messages, return special format if (ephemeral) { @@ -45,20 +45,20 @@ export const sendMessage = ( MessageActions.sendMessage(channelId, message, void 0, { nonce }); - return { type: 4 }; // Acknowledge the command + return null; } catch (error) { console.error("[Commands] Message send failed:", error); - // Silent fail - no error message in chat - return { type: 4 }; + // Silent fail + return null; } }; // Helper function to validate channel types in commands export const validateChannelForCommand = (ctx: any) => { if (!isValidChannel(ctx.channel.type)) { - return { + return { type: 4, - data: { + data: { content: "This command cannot be used in threads, forum channels, or voice channels.", flags: 64 // Ephemeral }