Add friendinvite commands

This commit is contained in:
kmmiio99o 2025-10-07 11:45:12 +02:00
parent 8d38f366ef
commit e8793f437e
3 changed files with 233 additions and 98 deletions

View file

@ -1,9 +1,9 @@
import { registerCommand } from "@vendetta/commands";
import { storage } from "@vendetta/plugin";
import {
catFactCommand,
dogFactCommand,
uselessFactCommand,
catFactCommand,
dogFactCommand,
uselessFactCommand,
} from "./src/commands/facts";
import { pluginListCommand, themeListCommand } from "./src/commands/lists";
import { petPetCommand } from "./src/commands/petpet";
@ -11,116 +11,109 @@ import { konoSelfCommand, konoSendCommand } from "./src/commands/konochan";
import { firstMessageCommand } from "./src/commands/firstmessage";
import { sysinfoCommand } from "./src/commands/sysinfo";
import {
spotifyTrackCommand,
spotifyAlbumCommand,
spotifyArtistsCommand,
spotifyCoverCommand
spotifyTrackCommand,
spotifyAlbumCommand,
spotifyArtistsCommand,
spotifyCoverCommand,
} from "./src/commands/spotify";
import { garyCommand } from "./src/commands/gary";
import { lovefemboysCommand } from "./src/commands/lovefemboys";
import { ipCommand } from "./src/commands/ip";
import { nekoslifeCommand } from "./src/commands/nekoslife";
import {
friendInviteCreateCommand,
friendInviteViewCommand,
friendInviteRevokeCommand,
} from "./src/commands/friendinvites";
import settings from "./settings";
// Initialize storage with default values
if (!storage.factSettings) {
storage.factSettings = {
sendAsReply: true,
includeCitation: false,
};
storage.factSettings = {
sendAsReply: true,
includeCitation: false,
};
}
if (!storage.listSettings) {
storage.listSettings = {
pluginListAlwaysDetailed: false,
themeListAlwaysDetailed: false,
};
storage.listSettings = {
pluginListAlwaysDetailed: false,
themeListAlwaysDetailed: false,
};
}
if (!storage.garySettings) {
storage.garySettings = {
imageSource: "gary",
};
storage.garySettings = {
imageSource: "gary",
};
}
if (!storage.enabledCommands) {
storage.enabledCommands = {
catfact: true,
dogfact: true,
useless: true,
petpet: true,
pluginList: true,
themeList: true,
konoself: true,
konosend: true,
firstmessage: true,
sysinfo: true,
spotifyTrack: true,
spotifyAlbum: true,
spotifyArtists: true,
spotifyCover: true,
gary: true,
ip: true, // IP command - enabled by default
lovefemboys: false, // Hidden command - disabled by default
nekoslife: false, // Hidden command - disabled by default
};
storage.enabledCommands = {
catfact: true,
dogfact: true,
useless: true,
petpet: true,
pluginList: true,
themeList: true,
konoself: true,
konosend: true,
firstmessage: true,
sysinfo: true,
spotifyTrack: true,
spotifyAlbum: true,
spotifyArtists: true,
spotifyCover: true,
gary: true,
ip: true,
lovefemboys: false,
nekoslife: false,
friendInviteCreate: true,
friendInviteView: true,
friendInviteRevoke: true,
};
}
// Initialize hidden settings storage
if (!storage.hiddenSettings) {
storage.hiddenSettings = {
enabled: false,
visible: false,
konochanBypassNsfw: false, // NSFW bypass option
};
storage.hiddenSettings = {
enabled: false,
visible: false,
konochanBypassNsfw: false,
};
}
// Map commands to their storage keys
const commandMap = {
catfact: catFactCommand,
dogfact: dogFactCommand,
useless: uselessFactCommand,
petpet: petPetCommand,
pluginList: pluginListCommand,
themeList: themeListCommand,
konoself: konoSelfCommand,
konosend: konoSendCommand,
firstmessage: firstMessageCommand,
sysinfo: sysinfoCommand,
spotifyTrack: spotifyTrackCommand,
spotifyAlbum: spotifyAlbumCommand,
spotifyArtists: spotifyArtistsCommand,
spotifyCover: spotifyCoverCommand,
gary: garyCommand,
ip: ipCommand, // Add IP command
lovefemboys: lovefemboysCommand, // Add hidden command to map
nekoslife: nekoslifeCommand, // Add NekosLife command
catfact: catFactCommand,
dogfact: dogFactCommand,
useless: uselessFactCommand,
petpet: petPetCommand,
pluginList: pluginListCommand,
themeList: themeListCommand,
konoself: konoSelfCommand,
konosend: konoSendCommand,
firstmessage: firstMessageCommand,
sysinfo: sysinfoCommand,
spotifyTrack: spotifyTrackCommand,
spotifyAlbum: spotifyAlbumCommand,
spotifyArtists: spotifyArtistsCommand,
spotifyCover: spotifyCoverCommand,
gary: garyCommand,
ip: ipCommand,
lovefemboys: lovefemboysCommand,
nekoslife: nekoslifeCommand,
friendInviteCreate: friendInviteCreateCommand,
friendInviteView: friendInviteViewCommand,
friendInviteRevoke: friendInviteRevokeCommand,
};
// Store registered commands for cleanup
let commands: Array<() => void> = [];
export default {
onLoad: () => {
console.log("[All-In-One Commands] Loading plugin...");
// Register only enabled commands
for (const [key, command] of Object.entries(commandMap)) {
if (storage.enabledCommands[key]) {
commands.push(registerCommand(command));
console.log(`[All-In-One Commands] Registered command: ${key}`);
}
}
console.log("[All-In-One Commands] Plugin loaded successfully!");
},
onUnload: () => {
console.log("[All-In-One Commands] Unloading plugin...");
commands.forEach((unregister) => unregister());
commands = [];
console.log("[All-In-One Commands] Plugin unloaded successfully!");
},
settings,
onLoad: () => {
for (const [key, command] of Object.entries(commandMap)) {
if (storage.enabledCommands[key]) {
commands.push(registerCommand(command));
}
}
},
onUnload: () => {
commands.forEach((unregister) => unregister());
commands = [];
},
settings,
};

View file

@ -42,9 +42,12 @@ storage.enabledCommands ??= {
spotifyArtists: true,
spotifyCover: true,
gary: true,
ip: true, // IP command - enabled by default
lovefemboys: false, // Hidden command - disabled by default
nekoslife: false, // Hidden command - disabled by default
ip: true,
lovefemboys: false,
nekoslife: false,
friendInviteCreate: true,
friendInviteView: true,
friendInviteRevoke: true,
};
storage.pendingRestart ??= false;
@ -53,7 +56,7 @@ storage.pendingRestart ??= false;
storage.hiddenSettings ??= {
enabled: false,
visible: false,
konochanBypassNsfw: false, // New bypass option - disabled by default
konochanBypassNsfw: false,
};
// Better Table Row Group Component
@ -287,7 +290,7 @@ function NekosLifeCategoriesPage() {
},
});
// Only SFW nekos.life categories
// nekos.life categories
const sfwCategories = [
{ name: "Avatar", value: "avatar" },
{ name: "Classic", value: "classic" },
@ -447,7 +450,6 @@ function HiddenSettingsPage() {
forceUpdate();
},
onCancel: () => {
// Do nothing - keep it disabled
},
});
} else {
@ -951,7 +953,7 @@ function SpotifySettingsPage() {
);
}
// Other Settings Page - Updated with IP command
// Other Settings Page - Updated with friend invite commands
function OtherSettingsPage() {
useProxy(storage);
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
@ -994,6 +996,42 @@ function OtherSettingsPage() {
}}
/>
</BetterTableRowGroup>
<BetterTableRowGroup
title="Friend Invites"
icon={getAssetIDByName("UserAddIcon")}
>
<FormSwitchRow
label="/invite create"
subLabel="Generate a friend invite link"
value={storage.enabledCommands.friendInviteCreate}
onValueChange={v => {
storage.enabledCommands.friendInviteCreate = v;
storage.pendingRestart = true;
forceUpdate();
}}
/>
<FormSwitchRow
label="/view invites"
subLabel="View your current friend invites"
value={storage.enabledCommands.friendInviteView}
onValueChange={v => {
storage.enabledCommands.friendInviteView = v;
storage.pendingRestart = true;
forceUpdate();
}}
/>
<FormSwitchRow
label="/revoke invites"
subLabel="Revoke all your friend invites"
value={storage.enabledCommands.friendInviteRevoke}
onValueChange={v => {
storage.enabledCommands.friendInviteRevoke = v;
storage.pendingRestart = true;
forceUpdate();
}}
/>
</BetterTableRowGroup>
</RN.View>
</ScrollView>
);

View file

@ -0,0 +1,104 @@
import { findByProps } from "@vendetta/metro";
const ClydeUtils = findByProps("sendBotMessage", "sendMessage");
const inviteModule = findByProps("getAllFriendInvites", "createFriendInvite", "revokeFriendInvites");
const api = findByProps("get", "post");
const getCurrentUser = findByProps("getCurrentUser")?.getCurrentUser;
const uuidv4 = findByProps("v4")?.v4;
function send(ctx, content) {
const fixNonce = Date.now().toString();
ClydeUtils.sendMessage(ctx.channel.id, { content }, void 0, { nonce: fixNonce });
}
export const friendInviteCreateCommand = {
name: "invite create",
displayName: "invite create",
description: "Generates a friend invite link.",
displayDescription: "Generates a friend invite link.",
type: 1,
applicationId: "-1",
inputType: 1,
execute: async (_, ctx) => {
try {
if (!getCurrentUser?.().phone) {
send(ctx, "You need to have a phone number connected to your account to create a friend invite!");
return { type: 4 };
}
const uuid = uuidv4();
const res = await api.post({
url: "/friend-finder/find-friends",
body: { modified_contacts: { [uuid]: [1, "", ""] }, phone_contact_methods_count: 1 },
});
const code = res.body?.invite_suggestions?.[0]?.[3];
if (!code) {
send(ctx, "Failed to generate invite code.");
return { type: 4 };
}
const createInvite = await inviteModule.createFriendInvite({
code,
recipient_phone_number_or_email: uuid,
contact_visibility: 1,
filter_visibilities: [],
filtered_invite_suggestions_index: 1,
});
const expires = Math.floor(new Date(createInvite.expires_at).getTime() / 1000);
const message = `https://discord.gg/${createInvite.code} · Expires: <t:${expires}:R>`;
send(ctx, message);
return { type: 4 };
} catch (e) {
send(ctx, "Error creating invite.");
console.error("[FriendInvite] create error:", e);
return { type: 4 };
}
},
};
export const friendInviteViewCommand = {
name: "view invites",
displayName: "view invites",
description: "View your current friend invite links that you've made.",
displayDescription: "View your current friend invite links that you've made.",
type: 1,
applicationId: "-1",
execute: async (_, ctx) => {
try {
const invites = await inviteModule.getAllFriendInvites();
if (!invites?.length) {
send(ctx, "You have no active friend invites!");
return { type: 4 };
}
const friendInviteList = invites.map(i => {
const expires = Math.floor(new Date(i.expires_at).getTime() / 1000);
return `_https://discord.gg/${i.code}_ · Expires: <t:${expires}:R> · Uses: \`${i.uses}/${i.max_uses}\``;
});
send(ctx, friendInviteList.join("\n"));
return { type: 4 };
} catch (e) {
send(ctx, "Error viewing invites.");
console.error("[FriendInvite] view error:", e);
return { type: 4 };
}
},
};
export const friendInviteRevokeCommand = {
name: "revoke invites",
displayName: "revoke invites",
description: "Revoke all your friend invite links.",
displayDescription: "Revoke all your friend invite links.",
type: 1,
applicationId: "-1",
inputType: 1,
execute: async (_, ctx) => {
try {
await inviteModule.revokeFriendInvites();
send(ctx, "All friend invites have been revoked.");
return { type: 4 };
} catch (e) {
send(ctx, "Error revoking invites.");
console.error("[FriendInvite] revoke error:", e);
return { type: 4 };
}
},
};