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