mirror of
https://github.com/Vendicated/Vencord.git
synced 2024-09-19 22:20:34 +00:00
Compare commits
146 commits
8324f8a015
...
9bf08a3ebf
Author | SHA1 | Date | |
---|---|---|---|
|
9bf08a3ebf | ||
|
b875ebf92d | ||
|
c7e5295da0 | ||
|
4f6e980dc4 | ||
|
e7faf3321e | ||
|
187ca435b5 | ||
|
a3d4c1963f | ||
|
cb4be3d77b | ||
|
ae6290a605 | ||
|
0561b3890a | ||
|
ec4e97b187 | ||
|
3b20759c60 | ||
|
5e52a34205 | ||
|
2cd661f7b6 | ||
|
e88e3b3e13 | ||
|
db4c0d1446 | ||
|
1de442a84b | ||
|
c93f694faf | ||
|
f045554bfe | ||
|
5180df743b | ||
|
f84220eada | ||
|
588a40c43f | ||
|
56be5eb247 | ||
|
9ad6e1b3a2 | ||
|
c0842cb84c | ||
|
fc3618628f | ||
|
2721cd3d47 | ||
|
1da50eb8f4 | ||
|
8696ca0706 | ||
|
070b25e813 | ||
|
90c9dd20bb | ||
|
dcb9402f1c | ||
|
bc3093a41e | ||
|
6c19f52f26 | ||
|
b63becffb6 | ||
|
7a1a9d20e8 | ||
|
ae10deaee4 | ||
|
61eacb2106 | ||
|
b3a9d33411 | ||
|
e764018621 | ||
|
cafe4b19a2 | ||
|
422c18c37c | ||
|
d7036c5886 | ||
|
9ee1b5ba6e | ||
|
0d4ec94203 | ||
|
0df09f2aab | ||
|
2728102fbc | ||
|
249ea30995 | ||
|
8d2fa0e45f | ||
|
adc60648a5 | ||
|
9a9c1b0487 | ||
|
892de53603 | ||
|
c8602ef52b | ||
|
c88ac8d5ca | ||
|
de2598a87a | ||
|
c3af902ace | ||
|
e04225df1a | ||
|
dec282bf50 | ||
|
d29d5e9476 | ||
|
46e4fc664a | ||
|
e9cb2eccec | ||
|
f0483f9c24 | ||
|
13119c0b29 | ||
|
720aaf6f3e | ||
|
f04bd8a7ad | ||
|
acf77127c8 | ||
|
530e19e266 | ||
|
7f36d8569f | ||
|
28f70e2942 | ||
|
6d704d603e | ||
|
65787848c4 | ||
|
73ca8dc776 | ||
|
209c64afc4 | ||
|
b4366bdab6 | ||
|
70ae9eabf4 | ||
|
d739675413 | ||
|
2462544d61 | ||
|
6022317d5e | ||
|
8f0204b4ca | ||
|
f801ab3cb9 | ||
|
8c48731026 | ||
|
31993c0053 | ||
|
1dc98721ee | ||
|
6266d037e7 | ||
|
4c466e9c04 | ||
|
522d2fd35c | ||
|
e24d5d3f93 | ||
|
521647b4e1 | ||
|
23992bd213 | ||
|
bc64dd400a | ||
|
38647087e0 | ||
|
c5d03bab3b | ||
|
abf48db04d | ||
|
2c11a7ad84 | ||
|
570e41b95c | ||
|
b722513662 | ||
|
e608170820 | ||
|
082227301e | ||
|
f87c73685e | ||
|
04c4c85ea7 | ||
|
82cc75ecc8 | ||
|
39b3e747f9 | ||
|
83fedd4df1 | ||
|
9edb4c01f2 | ||
|
c542a81986 | ||
|
1d93a03654 | ||
|
1a106e755b | ||
|
c2a8671f31 | ||
|
3ec9f7cf89 | ||
|
7c71d9f52d | ||
|
2ac335c3f4 | ||
|
1947cedd55 | ||
|
610c48fe92 | ||
|
736fef879e | ||
|
8a09cb533b | ||
|
9c7c3d0c5d | ||
|
f43f404123 | ||
|
73a2f5548a | ||
|
2da6a64748 | ||
|
9fab41449a | ||
|
1225861843 | ||
|
9b600b9dad | ||
|
6df510d9f5 | ||
|
a6c7cb9517 | ||
|
4cb2661ae9 | ||
|
0fd7a59d8a | ||
|
f2b22bc349 | ||
|
2f1c10de3e | ||
|
1c3e33dbbd | ||
|
9060352977 | ||
|
4ea2d1ca5c | ||
|
284a951353 | ||
|
d02a241ff9 | ||
|
cedf10bdd2 | ||
|
4f68631080 | ||
|
278c4f0d60 | ||
|
ba0a9d0696 | ||
|
f41c6f4762 | ||
|
87e86271fe | ||
|
3dd65d520e | ||
|
369f66e810 | ||
|
0207b9fa12 | ||
|
2c20a85871 | ||
|
ff6f24b8c9 | ||
|
bde85e073a | ||
|
ccce4952cc |
11 changed files with 319 additions and 89 deletions
5
src/plugins/fullSearchContext/README.md
Normal file
5
src/plugins/fullSearchContext/README.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# FullSearchContext
|
||||||
|
|
||||||
|
Makes the message context menu in message search results have all options you'd expect.
|
||||||
|
|
||||||
|
![](https://github.com/user-attachments/assets/472d1327-3935-44c7-b7c4-0978b5348550)
|
82
src/plugins/fullSearchContext/index.tsx
Normal file
82
src/plugins/fullSearchContext/index.tsx
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a modification for Discord's desktop app
|
||||||
|
* Copyright (c) 2023 Vendicated and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { migratePluginSettings } from "@api/Settings";
|
||||||
|
import { Devs } from "@utils/constants";
|
||||||
|
import definePlugin from "@utils/types";
|
||||||
|
import { findByPropsLazy } from "@webpack";
|
||||||
|
import { ChannelStore, ContextMenuApi, i18n, UserStore } from "@webpack/common";
|
||||||
|
import { Message } from "discord-types/general";
|
||||||
|
import type { MouseEvent } from "react";
|
||||||
|
|
||||||
|
const { useMessageMenu } = findByPropsLazy("useMessageMenu");
|
||||||
|
|
||||||
|
function MessageMenu({ message, channel, onHeightUpdate }) {
|
||||||
|
const canReport = message.author &&
|
||||||
|
!(message.author.id === UserStore.getCurrentUser().id || message.author.system);
|
||||||
|
|
||||||
|
return useMessageMenu({
|
||||||
|
navId: "message-actions",
|
||||||
|
ariaLabel: i18n.Messages.MESSAGE_UTILITIES_A11Y_LABEL,
|
||||||
|
|
||||||
|
message,
|
||||||
|
channel,
|
||||||
|
canReport,
|
||||||
|
onHeightUpdate,
|
||||||
|
onClose: () => ContextMenuApi.closeContextMenu(),
|
||||||
|
|
||||||
|
textSelection: "",
|
||||||
|
favoriteableType: null,
|
||||||
|
favoriteableId: null,
|
||||||
|
favoriteableName: null,
|
||||||
|
itemHref: void 0,
|
||||||
|
itemSrc: void 0,
|
||||||
|
itemSafeSrc: void 0,
|
||||||
|
itemTextContent: void 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
migratePluginSettings("FullSearchContext", "SearchReply");
|
||||||
|
export default definePlugin({
|
||||||
|
name: "FullSearchContext",
|
||||||
|
description: "Makes the message context menu in message search results have all options you'd expect",
|
||||||
|
authors: [Devs.Ven, Devs.Aria],
|
||||||
|
|
||||||
|
patches: [{
|
||||||
|
find: "onClick:this.handleMessageClick,",
|
||||||
|
replacement: {
|
||||||
|
match: /this(?=\.handleContextMenu\(\i,\i\))/,
|
||||||
|
replace: "$self"
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
|
||||||
|
handleContextMenu(event: MouseEvent, message: Message) {
|
||||||
|
const channel = ChannelStore.getChannel(message.channel_id);
|
||||||
|
if (!channel) return;
|
||||||
|
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
ContextMenuApi.openContextMenu(event, contextMenuProps =>
|
||||||
|
<MessageMenu
|
||||||
|
message={message}
|
||||||
|
channel={channel}
|
||||||
|
onHeightUpdate={contextMenuProps.onHeightUpdate}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,6 +0,0 @@
|
||||||
# SearchReply
|
|
||||||
|
|
||||||
Adds a reply button to search results.
|
|
||||||
|
|
||||||
![the plugin in action](https://github.com/Vendicated/Vencord/assets/45497981/07e741d3-0f97-4e5c-82b0-80712ecf2cbb)
|
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
/*
|
|
||||||
* Vencord, a modification for Discord's desktop app
|
|
||||||
* Copyright (c) 2023 Vendicated and contributors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
|
|
||||||
import { ReplyIcon } from "@components/Icons";
|
|
||||||
import { Devs } from "@utils/constants";
|
|
||||||
import definePlugin from "@utils/types";
|
|
||||||
import { findByCodeLazy } from "@webpack";
|
|
||||||
import { ChannelStore, i18n, Menu, PermissionsBits, PermissionStore, SelectedChannelStore } from "@webpack/common";
|
|
||||||
import { Message } from "discord-types/general";
|
|
||||||
|
|
||||||
|
|
||||||
const replyToMessage = findByCodeLazy(".TEXTAREA_FOCUS)", "showMentionToggle:");
|
|
||||||
|
|
||||||
const messageContextMenuPatch: NavContextMenuPatchCallback = (children, { message }: { message: Message; }) => {
|
|
||||||
// make sure the message is in the selected channel
|
|
||||||
if (SelectedChannelStore.getChannelId() !== message.channel_id) return;
|
|
||||||
const channel = ChannelStore.getChannel(message?.channel_id);
|
|
||||||
if (!channel) return;
|
|
||||||
if (channel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel)) return;
|
|
||||||
|
|
||||||
// dms and group chats
|
|
||||||
const dmGroup = findGroupChildrenByChildId("pin", children);
|
|
||||||
if (dmGroup && !dmGroup.some(child => child?.props?.id === "reply")) {
|
|
||||||
const pinIndex = dmGroup.findIndex(c => c?.props.id === "pin");
|
|
||||||
dmGroup.splice(pinIndex + 1, 0, (
|
|
||||||
<Menu.MenuItem
|
|
||||||
id="reply"
|
|
||||||
label={i18n.Messages.MESSAGE_ACTION_REPLY}
|
|
||||||
icon={ReplyIcon}
|
|
||||||
action={(e: React.MouseEvent) => replyToMessage(channel, message, e)}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// servers
|
|
||||||
const serverGroup = findGroupChildrenByChildId("mark-unread", children);
|
|
||||||
if (serverGroup && !serverGroup.some(child => child?.props?.id === "reply")) {
|
|
||||||
serverGroup.unshift((
|
|
||||||
<Menu.MenuItem
|
|
||||||
id="reply"
|
|
||||||
label={i18n.Messages.MESSAGE_ACTION_REPLY}
|
|
||||||
icon={ReplyIcon}
|
|
||||||
action={(e: React.MouseEvent) => replyToMessage(channel, message, e)}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
export default definePlugin({
|
|
||||||
name: "SearchReply",
|
|
||||||
description: "Adds a reply button to search results",
|
|
||||||
authors: [Devs.Aria],
|
|
||||||
contextMenus: {
|
|
||||||
"message": messageContextMenuPatch
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -103,7 +103,7 @@ function VoiceChannelTooltip({ channel }: VoiceChannelTooltipProps) {
|
||||||
<UserSummaryItem
|
<UserSummaryItem
|
||||||
users={users}
|
users={users}
|
||||||
renderIcon={false}
|
renderIcon={false}
|
||||||
max={7}
|
max={14}
|
||||||
size={18}
|
size={18}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -159,6 +159,7 @@ export const VoiceChannelIndicator = ErrorBoundary.wrap(({ userId }: VoiceChanne
|
||||||
<Tooltip
|
<Tooltip
|
||||||
text={<VoiceChannelTooltip channel={channel} />}
|
text={<VoiceChannelTooltip channel={channel} />}
|
||||||
tooltipClassName={cl("tooltip-container")}
|
tooltipClassName={cl("tooltip-container")}
|
||||||
|
tooltipContentClassName={cl("tooltip-content")}
|
||||||
>
|
>
|
||||||
{props =>
|
{props =>
|
||||||
isLocked ?
|
isLocked ?
|
||||||
|
|
|
@ -32,7 +32,7 @@ const settings = definePluginSettings({
|
||||||
default: true,
|
default: true,
|
||||||
restartNeeded: true
|
restartNeeded: true
|
||||||
},
|
},
|
||||||
showInVoiceMemberList: {
|
showInMemberList: {
|
||||||
type: OptionType.BOOLEAN,
|
type: OptionType.BOOLEAN,
|
||||||
description: "Show a user's Voice Channel indicator in the member and DMs list",
|
description: "Show a user's Voice Channel indicator in the member and DMs list",
|
||||||
default: true,
|
default: true,
|
||||||
|
@ -82,12 +82,12 @@ export default definePlugin({
|
||||||
match: /\.subtext,children:.+?}\)\]}\)(?=])/,
|
match: /\.subtext,children:.+?}\)\]}\)(?=])/,
|
||||||
replace: "$&,$self.VoiceChannelIndicator({userId:arguments[0]?.user?.id})"
|
replace: "$&,$self.VoiceChannelIndicator({userId:arguments[0]?.user?.id})"
|
||||||
},
|
},
|
||||||
predicate: () => settings.store.showInVoiceMemberList
|
predicate: () => settings.store.showInMemberList
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
if (settings.store.showInVoiceMemberList) {
|
if (settings.store.showInMemberList) {
|
||||||
addDecorator("UserVoiceShow", ({ user }) => user == null ? null : <VoiceChannelIndicator userId={user.id} />);
|
addDecorator("UserVoiceShow", ({ user }) => user == null ? null : <VoiceChannelIndicator userId={user.id} />);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -15,7 +15,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-uvs-tooltip-container {
|
.vc-uvs-tooltip-container {
|
||||||
max-width: 200px;
|
max-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-uvs-tooltip-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vc-uvs-guild-name {
|
.vc-uvs-guild-name {
|
||||||
|
@ -31,7 +37,5 @@
|
||||||
|
|
||||||
.vc-uvs-vc-members {
|
.vc-uvs-vc-members {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 8px 0;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
}
|
}
|
||||||
|
|
21
src/plugins/webhookManager.desktop/README.MD
Normal file
21
src/plugins/webhookManager.desktop/README.MD
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# WebhookManager
|
||||||
|
Manage your webhooks easily; delete, send messages, get detailed info and more.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
- /webhook send - *Sends a message through a webhook.*
|
||||||
|
- /webhook delete - *Deletes any webhook that is specified.*
|
||||||
|
- /webhook info - *Gets advanced details on the webhook such as the name, profile pic, server and channel ID, and additionally, information on person who created it*
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Full /webhookinfo Output</summary>
|
||||||
|
|
||||||
|
- Webhook Username
|
||||||
|
- Webhook ID
|
||||||
|
- Webhook Token
|
||||||
|
- Channel ID
|
||||||
|
- Server ID
|
||||||
|
- Webhook Profile Picture
|
||||||
|
- Webhook Type
|
||||||
|
- Creator Profile
|
||||||
|
</details>
|
176
src/plugins/webhookManager.desktop/index.tsx
Normal file
176
src/plugins/webhookManager.desktop/index.tsx
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from "@api/Commands";
|
||||||
|
import { Devs } from "@utils/constants";
|
||||||
|
import { Margins } from "@utils/margins";
|
||||||
|
import { ModalContent, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
||||||
|
import definePlugin, { PluginNative } from "@utils/types";
|
||||||
|
import { Button, Forms, React, Switch, TextInput, useState } from "@webpack/common";
|
||||||
|
|
||||||
|
const Native = VencordNative.pluginHelpers.WebhookManager as PluginNative<typeof import("./native")>;
|
||||||
|
let url, content, username, avatarUrl = "";
|
||||||
|
let jsonMode = false;
|
||||||
|
|
||||||
|
// TODO: add sending as raw
|
||||||
|
function WebhookMessageModal(props: ModalProps) {
|
||||||
|
const [params, setParams] = useState({ content: "", username: "", avatarUrl: "", url: "", jsonMode: false });
|
||||||
|
|
||||||
|
const onURL = (url: string) => setParams(prev => ({ ...prev, url }));
|
||||||
|
const onContent = (content: string) => setParams(prev => ({ ...prev, content }));
|
||||||
|
const onUsername = (username: string) => setParams(prev => ({ ...prev, username }));
|
||||||
|
const onAvatar = (avatarUrl: string) => setParams(prev => ({ ...prev, avatarUrl }));
|
||||||
|
const onSwitch = (jsonMode: boolean) => setParams(prev => ({ ...prev, jsonMode }));
|
||||||
|
|
||||||
|
|
||||||
|
return <ModalRoot {...props} size={ModalSize.MEDIUM} className={"wm-send-webhook"} >
|
||||||
|
<ModalContent className="wm-send-webhook-content">
|
||||||
|
<Forms.FormTitle className={Margins.top20}>Webhook URL</Forms.FormTitle>
|
||||||
|
<TextInput
|
||||||
|
placeholder={"Webhook URL"}
|
||||||
|
value={params.url}
|
||||||
|
onChange={onURL}
|
||||||
|
/>
|
||||||
|
<Forms.FormTitle className={Margins.top20}>Webhook Message</Forms.FormTitle>
|
||||||
|
<TextInput
|
||||||
|
placeholder={"Content"}
|
||||||
|
value={params.content}
|
||||||
|
onChange={onContent}
|
||||||
|
/>
|
||||||
|
<Forms.FormTitle className={Margins.top20}>Webhook Username</Forms.FormTitle>
|
||||||
|
<TextInput
|
||||||
|
placeholder={"Username"}
|
||||||
|
value={params.username}
|
||||||
|
onChange={onUsername}
|
||||||
|
/>
|
||||||
|
<Forms.FormTitle className={Margins.top20}>Webhook Avatar URL</Forms.FormTitle>
|
||||||
|
<TextInput
|
||||||
|
placeholder={"Image URL"}
|
||||||
|
value={params.avatarUrl}
|
||||||
|
onChange={onAvatar}
|
||||||
|
/>
|
||||||
|
<Switch
|
||||||
|
key="wm-raw"
|
||||||
|
value={jsonMode}
|
||||||
|
onChange={onSwitch}
|
||||||
|
>Send as Raw JSON</Switch>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
if (jsonMode !== true) {
|
||||||
|
Native.executeWebhook(params.url, {
|
||||||
|
content: params.content,
|
||||||
|
username: params.username,
|
||||||
|
avatar_url: params.avatarUrl
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Native.executeWebhook(params.url, {
|
||||||
|
webhookMessage: params.content,
|
||||||
|
username: params.username,
|
||||||
|
avatar_url: params.avatarUrl
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
|
>Send Webhook</Button>
|
||||||
|
</ModalContent>
|
||||||
|
</ModalRoot >;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "WebhookManager",
|
||||||
|
description: "Manage your webhooks easily; delete, send messages, get detailed info and more.",
|
||||||
|
authors: [Devs.Byeoon, Devs.Ven],
|
||||||
|
dependencies: ["CommandsAPI"],
|
||||||
|
commands: [
|
||||||
|
{
|
||||||
|
name: "webhook delete",
|
||||||
|
description: "Delete a webhook.",
|
||||||
|
inputType: ApplicationCommandInputType.BUILT_IN,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: "url",
|
||||||
|
description: "The URL of the webhook",
|
||||||
|
type: ApplicationCommandOptionType.STRING,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
execute: async (option, ctx) => {
|
||||||
|
try {
|
||||||
|
await fetch(findOption(option, "url", ""), {
|
||||||
|
method: "DELETE"
|
||||||
|
});
|
||||||
|
sendBotMessage(ctx.channel.id, {
|
||||||
|
content: "The webhook has deleted successfully."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
sendBotMessage(ctx.channel.id, {
|
||||||
|
content: "There was an error deleting the webhook. Did you input a valid webhook URL? Error: " + error
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "webhook info",
|
||||||
|
description: "Retrieve information about a webhook.",
|
||||||
|
inputType: ApplicationCommandInputType.BUILT_IN,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: "url",
|
||||||
|
description: "The URL of the webhook",
|
||||||
|
type: ApplicationCommandOptionType.STRING,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
execute: async (option, ctx) => {
|
||||||
|
const webhookUrl = findOption(option, "url", "");
|
||||||
|
const { user, avatar, name, id, token, type, channel_id, guild_id }
|
||||||
|
= await fetch(webhookUrl).then(res => res.json());
|
||||||
|
|
||||||
|
sendBotMessage(ctx.channel.id, {
|
||||||
|
content: `This webhook was created by ${user?.name}.`,
|
||||||
|
embeds: [
|
||||||
|
{
|
||||||
|
title: "Webhook Information",
|
||||||
|
color: "1323",
|
||||||
|
// @ts-ignore
|
||||||
|
author: {
|
||||||
|
name,
|
||||||
|
url: ""
|
||||||
|
},
|
||||||
|
thumbnail: {
|
||||||
|
url: `https://cdn.discordapp.com/avatars/${id}/${avatar}.png`,
|
||||||
|
proxyURL: `https://cdn.discordapp.com/avatars/${id}/${avatar}.png`,
|
||||||
|
height: 128,
|
||||||
|
width: 128
|
||||||
|
},
|
||||||
|
description: `
|
||||||
|
Webhook ID: ${id}
|
||||||
|
Webhook Token: ${token}
|
||||||
|
Webhook Type: ${type}
|
||||||
|
Channel ID: ${channel_id}
|
||||||
|
Server ID: ${guild_id}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "webhook send",
|
||||||
|
description: "Send a message through a webhook.",
|
||||||
|
inputType: ApplicationCommandInputType.BUILT_IN,
|
||||||
|
async execute(_, ctx) {
|
||||||
|
openModal(props => <WebhookMessageModal {...props} />);
|
||||||
|
sendBotMessage(ctx.channel.id, {
|
||||||
|
content: "Your webhook message has been executed."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
22
src/plugins/webhookManager.desktop/native.ts
Normal file
22
src/plugins/webhookManager.desktop/native.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { IpcMainInvokeEvent } from "electron";
|
||||||
|
import https from "https";
|
||||||
|
|
||||||
|
const DiscordHosts = new Set(["discord.com", "ptb.discord.com", "canary.discord.com"]);
|
||||||
|
|
||||||
|
export function executeWebhook(_event: IpcMainInvokeEvent, url: string, body: object) {
|
||||||
|
const { hostname, pathname } = new URL(url);
|
||||||
|
|
||||||
|
if (!DiscordHosts.has(hostname) || !pathname.startsWith("/api/webhooks/")) {
|
||||||
|
throw new Error("This URL is not a valid webhook.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const req = https.request(url, { method: "POST", headers: { "Content-Type": "application/json", } });
|
||||||
|
req.write(JSON.stringify(body));
|
||||||
|
req.end();
|
||||||
|
}
|
|
@ -475,7 +475,7 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
||||||
name: "Sqaaakoi",
|
name: "Sqaaakoi",
|
||||||
id: 259558259491340288n
|
id: 259558259491340288n
|
||||||
},
|
},
|
||||||
Byron: {
|
Byeoon: {
|
||||||
name: "byeoon",
|
name: "byeoon",
|
||||||
id: 1167275288036655133n
|
id: 1167275288036655133n
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue