mirror of
https://github.com/discordeno/discordeno.git
synced 2026-06-01 00:10:07 +00:00
tris lovely typos
This commit is contained in:
1
mod.ts
1
mod.ts
@@ -1,5 +1,4 @@
|
||||
export * from "./src/bot.ts";
|
||||
export * from "./src/cache.ts";
|
||||
export * from "./src/handlers/mod.ts";
|
||||
export * from "./src/helpers/mod.ts";
|
||||
export * from "./src/rest/mod.ts";
|
||||
|
||||
63
src/bot.ts
63
src/bot.ts
@@ -13,6 +13,10 @@ import {
|
||||
higherRolePosition,
|
||||
requireBotChannelPermissions,
|
||||
requireBotGuildPermissions,
|
||||
botHasChannelPermissions,
|
||||
calculateBits,
|
||||
isHigherPosition,
|
||||
requireOverwritePermissions,
|
||||
} from "./util/permissions.ts";
|
||||
import {
|
||||
checkRateLimits,
|
||||
@@ -45,6 +49,7 @@ import {
|
||||
DiscordenoVoiceState,
|
||||
transformVoiceState,
|
||||
DiscordenoMessage,
|
||||
DiscordenoRole,
|
||||
} from "./transformers/mod.ts";
|
||||
import {
|
||||
baseEndpoints,
|
||||
@@ -74,7 +79,15 @@ import {
|
||||
processGatewayQueue,
|
||||
} from "./ws/mod.ts";
|
||||
import { validateLength } from "./util/validate_length.ts";
|
||||
import { delay, validateComponents, validateSlashOptionChoices, validateSlashOptions } from "./util/utils.ts";
|
||||
import {
|
||||
delay,
|
||||
formatImageURL,
|
||||
hasProperty,
|
||||
validateComponents,
|
||||
validateSlashCommands,
|
||||
validateSlashOptionChoices,
|
||||
validateSlashOptions,
|
||||
} from "./util/utils.ts";
|
||||
import { iconBigintToHash, iconHashToBigInt } from "./util/hash.ts";
|
||||
import { calculateShardId } from "./util/calculate_shard_id.ts";
|
||||
import {
|
||||
@@ -296,6 +309,8 @@ import { DiscordenoEmoji, transformEmoji } from "./transformers/emoji.ts";
|
||||
import { transformActivity } from "./transformers/activity.ts";
|
||||
import { DiscordenoPresence, transformPresence } from "./transformers/presence.ts";
|
||||
import { DiscordReady } from "./types/gateway/ready.ts";
|
||||
import { urlToBase64 } from "./util/url_to_base64.ts";
|
||||
import { transformAttachment } from "./transformers/attachment.ts";
|
||||
|
||||
export function createBot(options: CreateBotOptions) {
|
||||
return {
|
||||
@@ -312,6 +327,7 @@ export function createBot(options: CreateBotOptions) {
|
||||
cache: {
|
||||
execute: async function (
|
||||
type:
|
||||
| "FILTER_CATEGORY_CHILDREN_CHANNELS"
|
||||
| "DELETE_MESSAGES_FROM_CHANNEL"
|
||||
| "DELETE_ROLE_FROM_MEMBER"
|
||||
| "BULK_DELETE_MESSAGES"
|
||||
@@ -323,6 +339,7 @@ export function createBot(options: CreateBotOptions) {
|
||||
| "DELETE_GUILD_FROM_MEMBER",
|
||||
options: Record<string, any>
|
||||
) {},
|
||||
executedSlashCommands: new Set<string>(),
|
||||
fetchAllMembersProcessingRequests: new Collection<string, Function>(),
|
||||
messages: {
|
||||
get: async function (id: bigint): Promise<DiscordenoMessage | undefined> {
|
||||
@@ -351,6 +368,9 @@ export function createBot(options: CreateBotOptions) {
|
||||
delete: async function (id: bigint): Promise<void> {
|
||||
return;
|
||||
},
|
||||
size: async function (): Promise<number> {
|
||||
return 0;
|
||||
},
|
||||
},
|
||||
channels: {
|
||||
get: async function (id: bigint): Promise<DiscordenoChannel | undefined> {
|
||||
@@ -473,6 +493,12 @@ export function createEventHandlers(events: Partial<EventHandlers>): EventHandle
|
||||
stageInstanceCreate: events.stageInstanceCreate ?? ignore,
|
||||
stageInstanceDelete: events.stageInstanceDelete ?? ignore,
|
||||
stageInstanceUpdate: events.stageInstanceUpdate ?? ignore,
|
||||
roleCreate: events.roleCreate ?? ignore,
|
||||
roleDelete: events.roleDelete ?? ignore,
|
||||
roleUpdate: events.roleUpdate ?? ignore,
|
||||
webhooksUpdate: events.webhooksUpdate ?? ignore,
|
||||
botUpdate: events.botUpdate ?? ignore,
|
||||
typingStart: events.typingStart ?? ignore,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -599,6 +625,14 @@ export function createUtils(options: Partial<HelperUtils>) {
|
||||
requireBotChannelPermissions,
|
||||
requireBotGuildPermissions,
|
||||
validateComponents,
|
||||
hasProperty,
|
||||
urlToBase64,
|
||||
botHasChannelPermissions,
|
||||
calculateBits,
|
||||
isHigherPosition,
|
||||
formatImageURL,
|
||||
validateSlashCommands,
|
||||
requireOverwritePermissions,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -626,7 +660,15 @@ export interface HelperUtils {
|
||||
validateSlashOptionChoices: typeof validateSlashOptionChoices;
|
||||
requireBotChannelPermissions: typeof requireBotChannelPermissions;
|
||||
requireBotGuildPermissions: typeof requireBotGuildPermissions;
|
||||
botHasChannelPermissions: typeof botHasChannelPermissions;
|
||||
validateComponents: typeof validateComponents;
|
||||
hasProperty: typeof hasProperty;
|
||||
urlToBase64: typeof urlToBase64;
|
||||
calculateBits: typeof calculateBits;
|
||||
isHigherPosition: typeof isHigherPosition;
|
||||
formatImageURL: typeof formatImageURL;
|
||||
validateSlashCommands: typeof validateSlashCommands;
|
||||
requireOverwritePermissions: typeof requireOverwritePermissions;
|
||||
}
|
||||
|
||||
export function createGatewayManager(
|
||||
@@ -691,7 +733,7 @@ export async function stopBot(bot: Bot) {
|
||||
bot.gateway.closeWS(shard.ws, 3061, "Discordeno Testing Finished! Do Not RESUME!");
|
||||
});
|
||||
|
||||
await delay(3000);
|
||||
await delay(5000);
|
||||
}
|
||||
|
||||
export interface CreateBotOptions {
|
||||
@@ -1055,12 +1097,14 @@ export interface Transformers {
|
||||
emoji: typeof transformEmoji;
|
||||
activity: typeof transformActivity;
|
||||
presence: typeof transformPresence;
|
||||
attachment: typeof transformAttachment;
|
||||
}
|
||||
|
||||
export function createTransformers(options: Partial<Transformers>) {
|
||||
return {
|
||||
activity: options.activity || transformActivity,
|
||||
application: options.application || transformApplication,
|
||||
attachment: options.attachment || transformAttachment,
|
||||
channel: options.channel || transformChannel,
|
||||
emoji: options.emoji || transformEmoji,
|
||||
guild: options.guild || transformGuild,
|
||||
@@ -1322,6 +1366,21 @@ export interface EventHandlers {
|
||||
guildDelete: (bot: Bot, id: bigint, guild?: DiscordenoGuild) => any;
|
||||
guildUpdate: (bot: Bot, guild: DiscordenoGuild, cachedGuild?: DiscordenoGuild) => any;
|
||||
raw: (bot: Bot, data: GatewayPayload, shardId: number) => any;
|
||||
roleCreate: (bot: Bot, guild: DiscordenoGuild, role: DiscordenoRole) => any;
|
||||
roleDelete: (bot: Bot, guild: DiscordenoGuild, role: DiscordenoRole) => any;
|
||||
roleUpdate: (bot: Bot, guild: DiscordenoGuild, role: DiscordenoRole, oldRole?: DiscordenoRole) => any;
|
||||
webhooksUpdate: (bot: Bot, payload: { channelId: bigint; guildId: bigint }) => any;
|
||||
botUpdate: (bot: Bot, user: DiscordenoUser) => any;
|
||||
typingStart: (
|
||||
bot: Bot,
|
||||
payload: {
|
||||
guildId: bigint | undefined;
|
||||
channelId: bigint;
|
||||
userId: bigint;
|
||||
timestamp: number;
|
||||
member: DiscordenoMember | undefined;
|
||||
}
|
||||
) => any;
|
||||
}
|
||||
|
||||
export function createBotConstants() {
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { IntegrationCreateUpdate } from "../../types/integrations/integrati
|
||||
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
export function handleIntegrationUpdate(bot: Bot, data: DiscordGatewayPayload) {
|
||||
bot.events.integrationsUpdate(
|
||||
bot.events.integrationUpdate(
|
||||
bot,
|
||||
bot.transformers.integration(bot, data.d as SnakeCasedPropertiesDeep<IntegrationCreateUpdate>)
|
||||
);
|
||||
|
||||
@@ -3,7 +3,6 @@ import { Bot } from "../../bot.ts";
|
||||
/** Gets an array of all the channels ids that are the children of this category.
|
||||
* ⚠️ This does not work for custom cache users!
|
||||
*/
|
||||
export function categoryChildren(bot: Bot, parentChannelId: bigint) {
|
||||
// TODO: Cache Filter ?
|
||||
return bot.cache.channels.filter((channel) => channel.parentId === parentChannelId);
|
||||
export async function categoryChildren(bot: Bot, parentChannelId: bigint) {
|
||||
return await bot.cache.execute("FILTER_CATEGORY_CHILDREN_CHANNELS", { parentChannelId });
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@ export async function createChannel(bot: Bot, guildId: bigint, options?: CreateG
|
||||
: {}
|
||||
);
|
||||
|
||||
const discordenoChannel = bot.transformers.channel(result);
|
||||
await bot.cache.channels.set(discordenoChannel.id, discordenoChannel);
|
||||
const channel = bot.transformers.channel(bot, { channel: result, guildId });
|
||||
await bot.cache.channels.set(channel.id, channel);
|
||||
|
||||
return discordenoChannel;
|
||||
return channel;
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ import type { Bot } from "../../bot.ts";
|
||||
|
||||
/** Delete a channel in your server. Bot needs MANAGE_CHANNEL permissions in the server. */
|
||||
export async function deleteChannel(bot: Bot, channelId: bigint, reason?: string) {
|
||||
const channel = await cacheHandlers.get("channels", channelId);
|
||||
const channel = await bot.cache.channels.get(channelId);
|
||||
|
||||
if (channel?.guildId) {
|
||||
const guild = await cacheHandlers.get("guilds", channel.guildId);
|
||||
const guild = await bot.cache.guilds.get(channel.guildId);
|
||||
if (!guild) throw new Error(bot.constants.Errors.GUILD_NOT_FOUND);
|
||||
|
||||
if (guild.rulesChannelId === channelId) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { Channel } from "../../types/channels/channel.ts";
|
||||
import type { ModifyChannel } from "../../types/channels/modify_channel.ts";
|
||||
import type { Bot } from "../../bot.ts";
|
||||
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
import { DiscordenoChannel } from "../../transformers/channel.ts";
|
||||
|
||||
/** Update a channel's settings. Requires the `MANAGE_CHANNELS` permission for the guild. */
|
||||
@@ -40,34 +39,29 @@ export async function editChannel(bot: Bot, channelId: bigint, options: ModifyCh
|
||||
}
|
||||
}
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Channel>>(
|
||||
bot.rest,
|
||||
"patch",
|
||||
bot.constants.endpoints.CHANNEL_BASE(channelId),
|
||||
{
|
||||
name: options.name,
|
||||
topic: options.topic,
|
||||
bitrate: options.bitrate,
|
||||
userLimit: options.userLimit,
|
||||
rateLimitPerUser: options.rateLimitPerUser,
|
||||
position: options.position,
|
||||
parentId: options.parentId,
|
||||
nsfw: options.nsfw,
|
||||
type: options.type,
|
||||
permissionOverwrites: options.permissionOverwrites
|
||||
? options.permissionOverwrites?.map((overwrite) => {
|
||||
return {
|
||||
...overwrite,
|
||||
allow: calculateBits(overwrite.allow),
|
||||
deny: calculateBits(overwrite.deny),
|
||||
};
|
||||
})
|
||||
: undefined,
|
||||
reason,
|
||||
}
|
||||
);
|
||||
const result = await bot.rest.runMethod<Channel>(bot.rest, "patch", bot.constants.endpoints.CHANNEL_BASE(channelId), {
|
||||
name: options.name,
|
||||
topic: options.topic,
|
||||
bitrate: options.bitrate,
|
||||
userLimit: options.userLimit,
|
||||
rateLimitPerUser: options.rateLimitPerUser,
|
||||
position: options.position,
|
||||
parentId: options.parentId,
|
||||
nsfw: options.nsfw,
|
||||
type: options.type,
|
||||
permissionOverwrites: options.permissionOverwrites
|
||||
? options.permissionOverwrites?.map((overwrite) => {
|
||||
return {
|
||||
...overwrite,
|
||||
allow: bot.utils.calculateBits(overwrite.allow),
|
||||
deny: bot.utils.calculateBits(overwrite.deny),
|
||||
};
|
||||
})
|
||||
: undefined,
|
||||
reason,
|
||||
});
|
||||
|
||||
return bot.transformers.channel(result);
|
||||
return bot.transformers.channel(bot, { channel: result, guildId: bot.transformers.snowflake(result.guild_id!) });
|
||||
}
|
||||
|
||||
interface EditChannelRequest {
|
||||
@@ -91,7 +85,7 @@ function processEditChannelQueue(bot: Bot) {
|
||||
|
||||
const now = Date.now();
|
||||
editChannelNameTopicQueue.forEach(async (request) => {
|
||||
eventHandlers.debug?.("loop", `Running forEach loop in edit_channel file.`);
|
||||
bot.events.debug(`Running forEach loop in edit_channel file.`);
|
||||
if (now < request.timestamp) return;
|
||||
// 10 minutes have passed so we can reset this channel again
|
||||
if (!request.items.length) {
|
||||
@@ -119,7 +113,7 @@ function processEditChannelQueue(bot: Bot) {
|
||||
|
||||
if (editChannelNameTopicQueue.size) {
|
||||
setTimeout(() => {
|
||||
eventHandlers.debug?.("loop", `Running setTimeout in EDIT_CHANNEL file.`);
|
||||
bot.events.debug(`Running setTimeout in EDIT_CHANNEL file.`);
|
||||
processEditChannelQueue(bot);
|
||||
}, 60000);
|
||||
} else {
|
||||
|
||||
@@ -14,5 +14,5 @@ export async function followChannel(bot: Bot, sourceChannelId: bigint, targetCha
|
||||
}
|
||||
);
|
||||
|
||||
return data.webhookId;
|
||||
return bot.transformers.snowflake(data.webhook_id);
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ import type { Channel } from "../../types/channels/channel.ts";
|
||||
export async function getChannel(bot: Bot, channelId: bigint, addToCache = true) {
|
||||
const result = await bot.rest.runMethod<Channel>(bot.rest, "get", bot.constants.endpoints.CHANNEL_BASE(channelId));
|
||||
|
||||
const discordenoChannel = bot.transformers.channel({
|
||||
const discordenoChannel = bot.transformers.channel(bot, {
|
||||
channel: result,
|
||||
guildId: result.guildId ? bot.transformers.snowflake(result.guildId) : undefined,
|
||||
guildId: result.guild_id ? bot.transformers.snowflake(result.guild_id) : undefined,
|
||||
});
|
||||
if (addToCache) {
|
||||
await bot.cache.channels.set(discordenoChannel.id, discordenoChannel);
|
||||
|
||||
@@ -13,12 +13,12 @@ export async function getChannels(bot: Bot, guildId: bigint, addToCache = true)
|
||||
(
|
||||
await Promise.all(
|
||||
result.map(async (res) => {
|
||||
const discordenoChannel = await bot.transformers.channel({ channel: res, guildId });
|
||||
const channel = bot.transformers.channel(bot, { channel: res, guildId });
|
||||
if (addToCache) {
|
||||
await bot.cache.channels.set(discordenoChannel.id, discordenoChannel);
|
||||
await bot.cache.channels.set(channel.id, channel);
|
||||
}
|
||||
|
||||
return discordenoChannel;
|
||||
return channel;
|
||||
})
|
||||
)
|
||||
).map((c) => [c.id, c])
|
||||
|
||||
@@ -5,5 +5,5 @@ import type { Bot } from "../../bot.ts";
|
||||
export async function getPins(bot: Bot, channelId: bigint) {
|
||||
const result = await bot.rest.runMethod<Message[]>(bot.rest, "get", bot.constants.endpoints.CHANNEL_PINS(channelId));
|
||||
|
||||
return result.map(bot.transformers.message);
|
||||
return result.map((msg) => bot.transformers.message(bot, msg));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ChannelTypes } from "../../types/channels/channel_types.ts";
|
||||
import { ChannelTypes } from "../../types/channels/channel_types.ts";
|
||||
import type { StageInstance } from "../../types/channels/stage_instance.ts";
|
||||
import type { Bot } from "../../bot.ts";
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ export async function startTyping(bot: Bot, channelId: bigint) {
|
||||
throw new Error(bot.constants.Errors.CHANNEL_NOT_TEXT_BASED);
|
||||
}
|
||||
|
||||
const hasSendMessagesPerm = await bot.utils.botHasChannelPermissions(bots, channelId, ["SEND_MESSAGES"]);
|
||||
const hasSendMessagesPerm = await bot.utils.botHasChannelPermissions(bot, channelId, ["SEND_MESSAGES"]);
|
||||
if (!hasSendMessagesPerm) {
|
||||
throw new Error(bot.constants.Errors.MISSING_SEND_MESSAGES);
|
||||
}
|
||||
|
||||
@@ -2,17 +2,17 @@ import type { Bot } from "../../../bot.ts";
|
||||
|
||||
/** Adds a user to a thread. Requires the ability to send messages in the thread. Requires the thread is not archived. */
|
||||
export async function addToThread(bot: Bot, threadId: bigint, userId: bigint) {
|
||||
const thread = await bot.cache.threads.get(threadId);
|
||||
if (thread) {
|
||||
if (thread.archived) {
|
||||
throw new Error(bot.constants.Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS);
|
||||
}
|
||||
// const thread = await bot.cache.threads.get(threadId);
|
||||
// if (thread) {
|
||||
// if (thread.archived) {
|
||||
// throw new Error(bot.constants.Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS);
|
||||
// }
|
||||
|
||||
// If a user id is provided SEND_MESSAGES is required.
|
||||
const channel = await bot.cache.channels.get(thread.parentId);
|
||||
// TODO: does MANAGE_THREADS override this????
|
||||
if (channel) await bot.utils.requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES"]);
|
||||
}
|
||||
// // If a user id is provided SEND_MESSAGES is required.
|
||||
// const channel = await bot.cache.channels.get(thread.parentId);
|
||||
// // TODO: does MANAGE_THREADS override this????
|
||||
// if (channel) await bot.utils.requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES"]);
|
||||
// }
|
||||
|
||||
return await bot.rest.runMethod<undefined>(bot.rest, "put", bot.constants.endpoints.THREAD_USER(threadId, userId));
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ import type { Bot } from "../../../bot.ts";
|
||||
|
||||
/** Delete a thread in your server. Bot needs MANAGE_THREADS permissions in the server. */
|
||||
export async function deleteThread(bot: Bot, threadId: bigint, reason?: string) {
|
||||
const thread = await bot.cache.threads.get(threadId);
|
||||
if (thread) {
|
||||
const channel = await bot.cache.channels.get(thread?.parentId);
|
||||
if (channel?.guildId) await bot.utils.requireBotGuildPermissions(bot, channel.guildId, ["MANAGE_THREADS"]);
|
||||
}
|
||||
// const thread = await bot.cache.threads.get(threadId);
|
||||
// if (thread) {
|
||||
// const channel = await bot.cache.channels.get(thread?.parentId);
|
||||
// if (channel?.guildId) await bot.utils.requireBotGuildPermissions(bot, channel.guildId, ["MANAGE_THREADS"]);
|
||||
// }
|
||||
|
||||
return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.CHANNEL_BASE(threadId), {
|
||||
reason,
|
||||
});
|
||||
// return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.CHANNEL_BASE(threadId), {
|
||||
// reason,
|
||||
// });
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ import type { Bot } from "../../../bot.ts";
|
||||
|
||||
/** Adds the bot to the thread. Cannot join an archived thread. */
|
||||
export async function joinThread(bot: Bot, threadId: bigint) {
|
||||
const thread = await bot.cache.threads.get(threadId);
|
||||
if (thread?.archived) {
|
||||
throw new Error(bot.contants.Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS);
|
||||
}
|
||||
// const thread = await bot.cache.threads.get(threadId);
|
||||
// if (thread?.archived) {
|
||||
// throw new Error(bot.constants.Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS);
|
||||
// }
|
||||
|
||||
return await bot.rest.runMethod<undefined>(bot.rest, "put", bot.constants.endpoints.THREAD_ME(threadId));
|
||||
// return await bot.rest.runMethod<undefined>(bot.rest, "put", bot.constants.endpoints.THREAD_ME(threadId));
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ import type { Bot } from "../../../bot.ts";
|
||||
|
||||
/** Removes the bot from a thread. Requires the thread is not archived. */
|
||||
export async function leaveThread(bot: Bot, threadId: bigint) {
|
||||
const thread = await bot.cache.threads.get(threadId);
|
||||
if (thread?.archived) throw new Error(bot.constants.Errors.CANNOT_LEAVE_ARCHIVED_THREAD);
|
||||
// const thread = await bot.cache.threads.get(threadId);
|
||||
// if (thread?.archived) throw new Error(bot.constants.Errors.CANNOT_LEAVE_ARCHIVED_THREAD);
|
||||
|
||||
return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.THREAD_ME(threadId));
|
||||
// return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.THREAD_ME(threadId));
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@ import type { Bot } from "../../../bot.ts";
|
||||
|
||||
/** Sets a thread channel to be locked. */
|
||||
export async function lockThread(bot: Bot, threadId: bigint) {
|
||||
return await bot.utils.editThread(bot, threadId, { locked: true });
|
||||
// return await bot.utils.editThread(bot, threadId, { locked: true });
|
||||
}
|
||||
|
||||
@@ -2,15 +2,15 @@ import type { Bot } from "../../../bot.ts";
|
||||
|
||||
/** Removes a user from a thread. Requires the MANAGE_THREADS permission or that you are the creator of the thread. Also requires the thread is not archived. */
|
||||
export async function removeThreadMember(bot: Bot, threadId: bigint, userId: bigint) {
|
||||
const thread = await bot.cache.threads.get(threadId);
|
||||
if (thread) {
|
||||
if (thread.archived) throw new Error(bot.constants.Errors.CANNOT_REMOVE_FROM_ARCHIVED_THREAD);
|
||||
// const thread = await bot.cache.threads.get(threadId);
|
||||
// if (thread) {
|
||||
// if (thread.archived) throw new Error(bot.constants.Errors.CANNOT_REMOVE_FROM_ARCHIVED_THREAD);
|
||||
|
||||
if (thread.ownerId !== bot.id) {
|
||||
const channel = await bot.cache.channels.get(thread.parentId);
|
||||
if (channel) await bot.utils.requireBotChannelPermissions(bot, channel, ["MANAGE_THREADS"]);
|
||||
}
|
||||
}
|
||||
// if (thread.ownerId !== bot.id) {
|
||||
// const channel = await bot.cache.channels.get(thread.parentId);
|
||||
// if (channel) await bot.utils.requireBotChannelPermissions(bot, channel, ["MANAGE_THREADS"]);
|
||||
// }
|
||||
// }
|
||||
|
||||
return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.THREAD_USER(threadId, userId));
|
||||
// return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.THREAD_USER(threadId, userId));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { StageInstance } from "../../types/channels/stage_instance.ts";
|
||||
import type { Bot } from "../../bot.ts";
|
||||
import type { ChannelTypes } from "../../types/channels/channel_types.ts";
|
||||
import { ChannelTypes } from "../../types/channels/channel_types.ts";
|
||||
|
||||
/** Updates fields of an existing Stage instance. Requires the user to be a moderator of the Stage channel. */
|
||||
export async function updateStageInstance(
|
||||
@@ -15,7 +15,7 @@ export async function updateStageInstance(
|
||||
throw new Error(bot.constants.Errors.CHANNEL_NOT_STAGE_VOICE);
|
||||
}
|
||||
|
||||
await bot.utils.requireBotChannelPermissions(channel, ["MOVE_MEMBERS", "MUTE_MEMBERS", "MANAGE_CHANNELS"]);
|
||||
await bot.utils.requireBotChannelPermissions(bot, channel, ["MOVE_MEMBERS", "MUTE_MEMBERS", "MANAGE_CHANNELS"]);
|
||||
}
|
||||
|
||||
if (
|
||||
|
||||
@@ -14,6 +14,7 @@ import type { Bot } from "../../bot.ts";
|
||||
* - When suppressed, the user will have their `request_to_speak_timestamp` removed.
|
||||
*/
|
||||
export async function updateBotVoiceState(
|
||||
bot: Bot,
|
||||
guildId: bigint,
|
||||
options: UpdateSelfVoiceState | ({ userId: bigint } & UpdateOthersVoiceState)
|
||||
) {
|
||||
@@ -22,13 +23,13 @@ export async function updateBotVoiceState(
|
||||
"patch",
|
||||
bot.constants.endpoints.UPDATE_VOICE_STATE(
|
||||
guildId,
|
||||
bot.utils.hasOwnProperty(options, "userId") ? options.userId : undefined
|
||||
bot.utils.hasProperty(options, "userId") ? options.userId : undefined
|
||||
),
|
||||
{
|
||||
channel_id: options.channelId,
|
||||
suppress: options.suppress,
|
||||
request_to_speak_timestamp: options.requestToSpeakTimestamp,
|
||||
user_id: options.userId,
|
||||
request_to_speak_timestamp: bot.utils.hasProperty(options, "requestToSpeakTimestamp") ? options.requestToSpeakTimestamp : undefined,
|
||||
user_id: bot.utils.hasProperty(options, "userId") ? options.userId : undefined
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
export async function addDiscoverySubcategory(bot: Bot, guildId: bigint, categoryId: number) {
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
|
||||
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<AddGuildDiscoverySubcategory>>(
|
||||
return await bot.rest.runMethod<AddGuildDiscoverySubcategory>(
|
||||
bot.rest,
|
||||
"post",
|
||||
bot.constants.endpoints.DISCOVERY_SUBCATEGORY(guildId, categoryId)
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { Bot } from "../../bot.ts";
|
||||
export async function editDiscovery(bot: Bot, guildId: bigint, data: ModifyGuildDiscoveryMetadata) {
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
|
||||
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<DiscoveryMetadata>>(
|
||||
return await bot.rest.runMethod<DiscoveryMetadata>(
|
||||
bot.rest,
|
||||
"patch",
|
||||
bot.constants.endpoints.DISCOVERY_METADATA(guildId),
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { Bot } from "../../bot.ts";
|
||||
export async function getDiscovery(bot: Bot, guildId: bigint) {
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
|
||||
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<DiscoveryMetadata>>(
|
||||
return await bot.rest.runMethod<DiscoveryMetadata>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.DISCOVERY_METADATA(guildId)
|
||||
|
||||
@@ -5,7 +5,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Returns a Collection (mapped by Id of the discovery category object) of discovery category objects that can be used when editing guilds */
|
||||
export async function getDiscoveryCategories(bot: Bot) {
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<DiscoveryCategory>[]>(
|
||||
const result = await bot.rest.runMethod<DiscoveryCategory[]>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.DISCOVERY_CATEGORIES
|
||||
|
||||
@@ -3,7 +3,8 @@ import type { Bot } from "../../bot.ts";
|
||||
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
export async function validDiscoveryTerm(bot: Bot, term: string) {
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<ValidateDiscoverySearchTerm>>(
|
||||
const result = await bot.rest.runMethod<ValidateDiscoverySearchTerm>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.DISCOVERY_VALID_TERM,
|
||||
{ term }
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { CreateGuildEmoji } from "../../types/emojis/create_guild_emoji.ts";
|
||||
import type { Emoji } from "../../types/emojis/emoji.ts";
|
||||
import type { Bot } from "../../bot.ts";
|
||||
import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Create an emoji in the server. Emojis and animated emojis have a maximum file size of 256kb. Attempting to upload an emoji larger than this limit will fail and return 400 Bad Request and an error message, but not a JSON status code. If a URL is provided to the image parameter, Discordeno will automatically convert it to a base64 string internally. */
|
||||
export async function createEmoji(bot: Bot, guildId: bigint, name: string, image: string, options: CreateGuildEmoji) {
|
||||
@@ -11,7 +10,7 @@ export async function createEmoji(bot: Bot, guildId: bigint, name: string, image
|
||||
image = await bot.utils.urlToBase64(image);
|
||||
}
|
||||
|
||||
const emoji = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Emoji>>(
|
||||
const emoji = await bot.rest.runMethod<Emoji>(bot.rest,
|
||||
"post",
|
||||
bot.constants.endpoints.GUILD_EMOJIS(guildId),
|
||||
{
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
import type { Emoji } from "../../types/emojis/emoji.ts";
|
||||
import type { ModifyGuildEmoji } from "../../types/emojis/modify_guild_emoji.ts";
|
||||
import type { Bot } from "../../bot.ts";
|
||||
import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Modify the given emoji. Requires the MANAGE_EMOJIS permission. */
|
||||
export async function editEmoji(bot: Bot, guildId: bigint, id: bigint, options: ModifyGuildEmoji) {
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_EMOJIS"]);
|
||||
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<Emoji>>(
|
||||
"patch",
|
||||
bot.constants.endpoints.GUILD_EMOJI(guildId, id),
|
||||
options
|
||||
);
|
||||
return await bot.rest.runMethod<Emoji>(bot.rest, "patch", bot.constants.endpoints.GUILD_EMOJI(guildId, id), options);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { Bot } from "../../bot.ts";
|
||||
* ⚠️ **If you need this, you are probably doing something wrong. Always use cache.guilds.get()?.emojis
|
||||
*/
|
||||
export async function getEmoji(bot: Bot, guildId: bigint, emojiId: bigint, addToCache = true) {
|
||||
const result = await bot.rest.runMethod<Emoji>("get", bot.constants.endpoints.GUILD_EMOJI(guildId, emojiId));
|
||||
const result = await bot.rest.runMethod<Emoji>(bot.rest, "get", bot.constants.endpoints.GUILD_EMOJI(guildId, emojiId));
|
||||
|
||||
if (addToCache) {
|
||||
const guild = await bot.cache.guilds.get(guildId);
|
||||
|
||||
@@ -12,11 +12,11 @@ export async function getEmojis(bot: Bot, guildId: bigint, addToCache = true) {
|
||||
const result = await bot.rest.runMethod<Emoji[]>(bot.rest, "get", bot.constants.endpoints.GUILD_EMOJIS(guildId));
|
||||
|
||||
if (addToCache) {
|
||||
const guild = await bot.cache.guilds.get("guilds", guildId);
|
||||
const guild = await bot.cache.guilds.get(guildId);
|
||||
if (!guild) throw new Error(Errors.GUILD_NOT_FOUND);
|
||||
|
||||
result.forEach((emoji) => {
|
||||
bot.events.debug("loop", `Running forEach loop in get_emojis file.`);
|
||||
bot.events.debug(`Running forEach loop in get_emojis file.`);
|
||||
guild.emojis.set(bot.transformers.snowflake(emoji.id!), emoji);
|
||||
});
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ export async function editGuild(bot: Bot, guildId: bigint, options: ModifyGuild)
|
||||
const cached = await bot.cache.guilds.get(guildId);
|
||||
return bot.transformers.guild(bot, {
|
||||
guild: result,
|
||||
shardId:
|
||||
cached?.shardId || Number((BigInt(result.id) >> 22n % BigInt(bot.gateway.botGatewayData.shards)).toString()),
|
||||
shardId: cached?.shardId || bot.utils.calculateShardId(bot.gateway, guildId),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { WelcomeScreen } from "../../types/guilds/welcome_screen.ts";
|
||||
import type { Bot } from "../../bot.ts";
|
||||
|
||||
export async function editWelcomeScreen(bot: Bot, guildId: bigint, options: ModifyGuildWelcomeScreen) {
|
||||
return await bot.rest.runMethod<WelcomeScreen>("patch", bot.constants.endpoints.GUILD_WELCOME_SCREEN(guildId), {
|
||||
return await bot.rest.runMethod<WelcomeScreen>(bot.rest, "patch", bot.constants.endpoints.GUILD_WELCOME_SCREEN(guildId), {
|
||||
enabled: options.enabled,
|
||||
welcomeScreen: options.welcomeScreen?.map((welcomeScreen) => {
|
||||
return {
|
||||
|
||||
@@ -7,9 +7,9 @@ export async function getAuditLogs(bot: Bot, guildId: bigint, options?: GetGuild
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, ["VIEW_AUDIT_LOG"]);
|
||||
|
||||
return await bot.rest.runMethod<AuditLog>(bot.rest, "get", bot.constants.endpoints.GUILD_AUDIT_LOGS(guildId), {
|
||||
user_id: options.userId,
|
||||
action_type: options.actionType,
|
||||
before: options.before,
|
||||
user_id: options?.userId,
|
||||
action_type: options?.actionType,
|
||||
before: options?.before,
|
||||
limit: options?.limit && options.limit >= 1 && options.limit <= 100 ? options.limit : 50,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export async function getGuild(
|
||||
|
||||
const guild = await bot.transformers.guild(bot, {
|
||||
guild: result,
|
||||
shardId: Number((BigInt(guildId) >> 22n) % BigInt(ws.botGatewayData.shards)),
|
||||
shardId: bot.utils.calculateShardId(bot.gateway, guildId),
|
||||
});
|
||||
|
||||
if (options.addToCache) {
|
||||
|
||||
@@ -8,7 +8,7 @@ export async function getPruneCount(bot: Bot, guildId: bigint, options?: GetGuil
|
||||
throw new Error(bot.constants.Errors.PRUNE_MAX_DAYS);
|
||||
}
|
||||
|
||||
await bot.utils.requireBotGuildPermissions(guildId, ["KICK_MEMBERS"]);
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, ["KICK_MEMBERS"]);
|
||||
|
||||
const result = await bot.rest.runMethod(
|
||||
bot.rest,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Collection } from "../../util/collection.ts";
|
||||
import type { Bot } from "../../bot.ts";
|
||||
|
||||
/** Returns a list of voice region objects for the guild. Unlike the similar /voice route, this returns VIP servers when the guild is VIP-enabled. */
|
||||
export async function getVoiceRegions(boot: Bot, guildId: bigint) {
|
||||
export async function getVoiceRegions(bot: Bot, guildId: bigint) {
|
||||
const result = await bot.rest.runMethod<VoiceRegion[]>(
|
||||
bot.rest,
|
||||
"get",
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { Bot } from "../../bot.ts";
|
||||
|
||||
export async function getWelcomeScreen(bot: Bot, guildId: bigint) {
|
||||
return await bot.rest.runMethod<WelcomeScreen>(
|
||||
bot.rset,
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.GUILD_WELCOME_SCREEN(guildId)
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { Bot } from "../../bot.ts";
|
||||
/** Returns the widget for the guild. */
|
||||
export async function getWidget(bot: Bot, guildId: bigint, options?: { force: boolean }) {
|
||||
if (!options?.force) {
|
||||
const guild = await bot.cacahe.guilds.get(guildId);
|
||||
const guild = await bot.cache.guilds.get(guildId);
|
||||
if (!guild) throw new Error(bot.constants.Errors.GUILD_NOT_FOUND);
|
||||
if (!guild?.widgetEnabled) throw new Error(bot.constants.Errors.GUILD_WIDGET_NOT_ENABLED);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { Bot } from "../../bot.ts";
|
||||
|
||||
/** Returns the guild widget object. Requires the MANAGE_GUILD permission. */
|
||||
export async function getWidgetSettings(bot: Bot, guildId: bigint) {
|
||||
await bot.utils.requireBotGuildPermissions(guildId, ["MANAGE_GUILD"]);
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
|
||||
|
||||
return await bot.rest.runMethod<GuildWidget>(bot.rest, "get", bot.constants.endpoints.GUILD_WIDGET(guildId));
|
||||
}
|
||||
|
||||
@@ -17,9 +17,7 @@ export function guildBannerURL(
|
||||
? bot.utils.formatImageURL(
|
||||
bot.constants.endpoints.GUILD_BANNER(
|
||||
id,
|
||||
typeof options.banner === "string"
|
||||
? options.banner
|
||||
: bot.utils.iconBigintToHash(options.banner, options.animated ?? true)
|
||||
typeof options.banner === "string" ? options.banner : bot.utils.iconBigintToHash(options.banner)
|
||||
),
|
||||
options.size || 128,
|
||||
options.format
|
||||
|
||||
@@ -17,9 +17,7 @@ export function guildIconURL(
|
||||
? bot.utils.formatImageURL(
|
||||
bot.constants.endpoints.GUILD_ICON(
|
||||
id,
|
||||
typeof options.icon === "string"
|
||||
? options.icon
|
||||
: bot.utils.iconBigintToHash(options.icon, options.animated ?? true)
|
||||
typeof options.icon === "string" ? options.icon : bot.utils.iconBigintToHash(options.icon)
|
||||
),
|
||||
options.size || 128,
|
||||
options.format
|
||||
|
||||
@@ -19,7 +19,7 @@ export function guildSplashURL(
|
||||
id,
|
||||
typeof options.splash === "string"
|
||||
? options.splash
|
||||
: bot.utils.iconBigintToHash(options.splash, options.animated ?? true)
|
||||
: bot.utils.iconBigintToHash(options.splash)
|
||||
),
|
||||
options.size || 128,
|
||||
options.format
|
||||
|
||||
@@ -6,7 +6,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
export async function getIntegrations(bot: Bot, guildId: bigint) {
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
|
||||
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<Integration>>(
|
||||
return await bot.rest.runMethod<Integration>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.GUILD_INTEGRATIONS(guildId)
|
||||
|
||||
@@ -14,7 +14,7 @@ import type { Bot } from "../../../bot.ts";
|
||||
* Guild commands update **instantly**. We recommend you use guild commands for quick testing, and global commands when they're ready for public use.
|
||||
*/
|
||||
export async function createSlashCommand(bot: Bot, options: CreateGlobalApplicationCommand, guildId?: bigint) {
|
||||
[options] = bot.utils.validateSlashCommands([options], true) as CreateGlobalApplicationCommand[];
|
||||
[options] = bot.utils.validateSlashCommands(bot, [options], true) as CreateGlobalApplicationCommand[];
|
||||
|
||||
return await bot.rest.runMethod<ApplicationCommand>(
|
||||
bot.rest,
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { Bot } from "../../../bot.ts";
|
||||
|
||||
/** Fetches the global command for the given Id. If a guildId is provided, the guild command will be fetched. */
|
||||
export async function getSlashCommand(bot: Bot, commandId: bigint, guildId?: bigint) {
|
||||
const result = await bot.rest.runMethod<ApplicationCommand>(
|
||||
const result = await bot.rest.runMethod<ApplicationCommand>(bot.rest,
|
||||
"get",
|
||||
guildId
|
||||
? bot.constants.endpoints.COMMANDS_GUILD_ID(bot.applicationId, guildId, commandId)
|
||||
@@ -13,6 +13,6 @@ export async function getSlashCommand(bot: Bot, commandId: bigint, guildId?: big
|
||||
return {
|
||||
...result,
|
||||
id: bot.transformers.snowflake(result.id),
|
||||
applicationId: bot.transformers.snowflake(result.applicationId),
|
||||
applicationId: bot.transformers.snowflake(result.application_id),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ export async function getSlashCommands(bot: Bot, guildId?: bigint) {
|
||||
{
|
||||
...command,
|
||||
id: bot.transformers.snowflake(command.id),
|
||||
applicationId: bot.transformers.snowflake(command.applicationId),
|
||||
applicationId: bot.transformers.snowflake(command.application_id),
|
||||
},
|
||||
])
|
||||
);
|
||||
|
||||
@@ -11,7 +11,7 @@ export async function upsertSlashCommand(
|
||||
options: EditGlobalApplicationCommand,
|
||||
guildId?: bigint
|
||||
) {
|
||||
[options] = bot.utils.validateSlashCommands([options]);
|
||||
[options] = bot.utils.validateSlashCommands(bot, [options]);
|
||||
|
||||
return await bot.rest.runMethod<ApplicationCommand>(
|
||||
bot.rest,
|
||||
|
||||
@@ -13,7 +13,7 @@ export async function upsertSlashCommands(
|
||||
options: MakeRequired<EditGlobalApplicationCommand, "name">[],
|
||||
guildId?: bigint
|
||||
) {
|
||||
options = bot.utils.validateSlashCommands(options) as MakeRequired<EditGlobalApplicationCommand, "name">[];
|
||||
options = bot.utils.validateSlashCommands(bot, options) as MakeRequired<EditGlobalApplicationCommand, "name">[];
|
||||
|
||||
return await bot.rest.runMethod<ApplicationCommand[]>(
|
||||
bot.rest,
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Returns the initial Interaction response. Functions the same as Get Webhook Message */
|
||||
export async function getOriginalInteractionResponse(bot: Bot, token: string) {
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
|
||||
const result = await bot.rest.runMethod<Message>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.INTERACTION_ORIGINAL_ID_TOKEN(bot.applicationId, token)
|
||||
|
||||
@@ -32,28 +32,20 @@ export async function sendInteractionResponse(
|
||||
options.data = { ...options.data, allowedMentions: { parse: [] } };
|
||||
}
|
||||
|
||||
const allowedMentions: AllowedMentions = options.data?.allowedMentions || { parse: [] };
|
||||
|
||||
// If its already been executed, we need to send a followup response
|
||||
if (bot.cache.executedSlashCommands.has(token)) {
|
||||
return await bot.rest.runMethod(bot.rest, "post", bot.cosntants.endpoints.WEBHOOK(bot.applicationId, token), {
|
||||
return await bot.rest.runMethod(bot.rest, "post", bot.constants.endpoints.WEBHOOK(bot.applicationId, token), {
|
||||
content: options.data.content,
|
||||
tts: options.data.tts,
|
||||
embeds: options.data.embeds,
|
||||
allowed_mentions: {
|
||||
parse: options.data.allowedMentions.parse,
|
||||
roles: options.data.allowedMentions.roles,
|
||||
users: options.data.allowedMentions.users,
|
||||
replied_user: options.data.allowedMentions.repliedUser,
|
||||
parse: allowedMentions.parse,
|
||||
roles: allowedMentions.roles,
|
||||
users: allowedMentions.users,
|
||||
replied_user: allowedMentions.repliedUser,
|
||||
},
|
||||
...(options.data.messageReference?.messageId
|
||||
? {
|
||||
message_reference: {
|
||||
message_id: options.data.messageReference.messageId,
|
||||
channel_id: options.data.messageReference.channelId,
|
||||
guild_id: options.data.messageReference.guildId,
|
||||
fail_if_not_exists: options.data.messageReference.failIfNotExists === true,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
file: options.data.file,
|
||||
// TODO: Snakelize components??
|
||||
components: options.data.components,
|
||||
@@ -62,10 +54,10 @@ export async function sendInteractionResponse(
|
||||
}
|
||||
|
||||
// Expire in 15 minutes
|
||||
cache.executedSlashCommands.add(token);
|
||||
bot.cache.executedSlashCommands.add(token);
|
||||
setTimeout(() => {
|
||||
eventHandlers.debug?.("loop", `Running setTimeout in send_interaction_response file.`);
|
||||
cache.executedSlashCommands.delete(token);
|
||||
bot.events.debug(`Running setTimeout in send_interaction_response file.`);
|
||||
bot.cache.executedSlashCommands.delete(token);
|
||||
}, 900000);
|
||||
|
||||
return await bot.rest.runMethod(
|
||||
@@ -77,21 +69,11 @@ export async function sendInteractionResponse(
|
||||
tts: options.data.tts,
|
||||
embeds: options.data.embeds,
|
||||
allowed_mentions: {
|
||||
parse: options.data.allowedMentions.parse,
|
||||
roles: options.data.allowedMentions.roles,
|
||||
users: options.data.allowedMentions.users,
|
||||
replied_user: options.data.allowedMentions.repliedUser,
|
||||
parse: allowedMentions.parse,
|
||||
roles: allowedMentions.roles,
|
||||
users: allowedMentions.users,
|
||||
replied_user: allowedMentions.repliedUser,
|
||||
},
|
||||
...(options.data.messageReference?.messageId
|
||||
? {
|
||||
message_reference: {
|
||||
message_id: options.data.messageReference.messageId,
|
||||
channel_id: options.data.messageReference.channelId,
|
||||
guild_id: options.data.messageReference.guildId,
|
||||
fail_if_not_exists: options.data.messageReference.failIfNotExists === true,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
file: options.data.file,
|
||||
// TODO: Snakelize components??
|
||||
components: options.data.components,
|
||||
|
||||
@@ -6,7 +6,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Creates a new invite for this channel. Requires CREATE_INSTANT_INVITE */
|
||||
export async function createInvite(bot: Bot, channelId: bigint, options: CreateChannelInvite = {}) {
|
||||
await bot.utils.requireBotChannelPermissions(channelId, ["CREATE_INSTANT_INVITE"]);
|
||||
await bot.utils.requireBotChannelPermissions(bot, channelId, ["CREATE_INSTANT_INVITE"]);
|
||||
|
||||
if (options.maxAge && (options.maxAge < 0 || options.maxAge > 604800)) {
|
||||
throw new Error(Errors.INVITE_MAX_AGE_INVALID);
|
||||
@@ -15,7 +15,7 @@ export async function createInvite(bot: Bot, channelId: bigint, options: CreateC
|
||||
throw new Error(Errors.INVITE_MAX_USES_INVALID);
|
||||
}
|
||||
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<InviteMetadata>>(
|
||||
return await bot.rest.runMethod<InviteMetadata>(
|
||||
bot.rest,
|
||||
"post",
|
||||
bot.constants.endpoints.CHANNEL_INVITES(channelId),
|
||||
|
||||
@@ -6,14 +6,14 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
export async function deleteInvite(bot: Bot, channelId: bigint, inviteCode: string) {
|
||||
const channel = await bot.cache.channels.get(channelId);
|
||||
if (channel) {
|
||||
const hasPerm = await bot.utils.botHasChannelPermissions(channel, ["MANAGE_CHANNELS"]);
|
||||
const hasPerm = await bot.utils.botHasChannelPermissions(bot, channel, ["MANAGE_CHANNELS"]);
|
||||
|
||||
if (!hasPerm) {
|
||||
await bot.utils.requireBotGuildPermissions(channel.guildId, ["MANAGE_GUILD"]);
|
||||
await bot.utils.requireBotGuildPermissions(bot, channel.guildId, ["MANAGE_GUILD"]);
|
||||
}
|
||||
}
|
||||
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<InviteMetadata>>(
|
||||
return await bot.rest.runMethod<InviteMetadata>(
|
||||
bot.rest,
|
||||
"delete",
|
||||
bot.constants.endpoints.INVITE(inviteCode)
|
||||
|
||||
@@ -5,9 +5,9 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Gets the invites for this channel. Requires MANAGE_CHANNEL */
|
||||
export async function getChannelInvites(bot: Bot, channelId: bigint) {
|
||||
await bot.utils.requireBotChannelPermissions(channelId, ["MANAGE_CHANNELS"]);
|
||||
await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_CHANNELS"]);
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<InviteMetadata>[]>(
|
||||
const result = await bot.rest.runMethod<InviteMetadata[]>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.CHANNEL_INVITES(channelId)
|
||||
|
||||
@@ -5,12 +5,12 @@ import type { Bot } from "../../bot.ts";
|
||||
|
||||
/** Returns an invite for the given code or throws an error if the invite doesn't exists. */
|
||||
export async function getInvite(bot: Bot, inviteCode: string, options?: GetInvite) {
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<InviteMetadata>>(
|
||||
return await bot.rest.runMethod<InviteMetadata>(bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.INVITE(inviteCode),
|
||||
{
|
||||
with_counts: options.withCounts,
|
||||
with_expiration: options.withExpiration,
|
||||
with_counts: options?.withCounts,
|
||||
with_expiration: options?.withExpiration,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ import type { Bot } from "../../bot.ts";
|
||||
export async function getInvites(bot: Bot, guildId: bigint) {
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<InviteMetadata>[]>(
|
||||
const result = await bot.rest.runMethod<InviteMetadata[]>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.GUILD_INVITES(guildId)
|
||||
);
|
||||
|
||||
@@ -20,7 +20,7 @@ export function avatarURL(
|
||||
userId,
|
||||
typeof options.avatar === "string"
|
||||
? options.avatar
|
||||
: bot.utils.iconBigintToHash(options.avatar, options.animated ?? true)
|
||||
: bot.utils.iconBigintToHash(options.avatar)
|
||||
),
|
||||
options.size || 128,
|
||||
options.format
|
||||
|
||||
@@ -43,7 +43,7 @@ export async function editMember(bot: Bot, guildId: bigint, memberId: bigint, op
|
||||
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, [...requiredPerms]);
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<GuildMemberWithUser>>(
|
||||
const result = await bot.rest.runMethod<GuildMemberWithUser>(
|
||||
bot.rest,
|
||||
"patch",
|
||||
bot.constants.endpoints.GUILD_MEMBER(guildId, memberId),
|
||||
|
||||
@@ -22,9 +22,9 @@ export function fetchMembers(
|
||||
// You can request 1 member without the intent
|
||||
// Check if intents is not 0 as proxy ws won't set intents in other instances
|
||||
if (
|
||||
bot.gateway.identifyPayload.intents &&
|
||||
bot.intents &&
|
||||
(!options?.limit || options.limit > 1) &&
|
||||
!(bot.gateway.identifyPayload.intents & DiscordGatewayIntents.GuildMembers)
|
||||
!(bot.intents & DiscordGatewayIntents.GuildMembers)
|
||||
) {
|
||||
throw new Error(bot.constants.Errors.MISSING_INTENT_GUILD_MEMBERS);
|
||||
}
|
||||
@@ -35,10 +35,9 @@ export function fetchMembers(
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const nonce = `${guildId}-${Date.now()}`;
|
||||
// TODO: FIND A BETTER WAY TO DO THAT?
|
||||
cache.fetchAllMembersProcessingRequests.set(nonce, resolve);
|
||||
bot.cache.fetchAllMembersProcessingRequests.set(nonce, resolve);
|
||||
|
||||
bot.gateway.sendShardMessage(shardId, {
|
||||
bot.gateway.sendShardMessage(bot.gateway, shardId, {
|
||||
op: DiscordGatewayOpcodes.RequestGuildMembers,
|
||||
d: {
|
||||
guild_id: guildId,
|
||||
|
||||
@@ -10,7 +10,7 @@ export async function getMember(bot: Bot, guildId: bigint, id: bigint, options?:
|
||||
const guild = await bot.cache.guilds.get(guildId);
|
||||
if (!guild && !options?.force) return;
|
||||
|
||||
const data = await bot.rest.runMethod<SnakeCasedPropertiesDeep<GuildMemberWithUser>>(
|
||||
const data = await bot.rest.runMethod<GuildMemberWithUser>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.GUILD_MEMBER(guildId, id)
|
||||
|
||||
@@ -4,7 +4,6 @@ import type { ListGuildMembers } from "../../types/members/list_guild_members.ts
|
||||
import type { Bot } from "../../bot.ts";
|
||||
import { Collection } from "../../util/collection.ts";
|
||||
import type { DiscordenoMember } from "../../transformers/member.ts";
|
||||
import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/**
|
||||
* ⚠️ BEGINNER DEVS!! YOU SHOULD ALMOST NEVER NEED THIS AND YOU CAN GET FROM cache.members.get()
|
||||
@@ -17,13 +16,13 @@ import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
export async function getMembers(bot: Bot, guildId: bigint, options?: ListGuildMembers & { addToCache?: boolean }) {
|
||||
// Check if intents is not 0 as proxy ws won't set intents in other instances
|
||||
if (
|
||||
bot.gateway.identifyPayload.intents &&
|
||||
!(bot.gateway.identifyPayload.intents & DiscordGatewayIntents.GuildMembers)
|
||||
bot.intents &&
|
||||
!(bot.intents & DiscordGatewayIntents.GuildMembers)
|
||||
) {
|
||||
throw new Error(bot.cache.Errors.MISSING_INTENT_GUILD_MEMBERS);
|
||||
throw new Error(bot.constants.Errors.MISSING_INTENT_GUILD_MEMBERS);
|
||||
}
|
||||
|
||||
const guild = await cacheHandlers.get("guilds", guildId);
|
||||
const guild = await bot.cache.guilds.get(guildId);
|
||||
if (!guild) throw new Error(bot.constants.Errors.GUILD_NOT_FOUND);
|
||||
|
||||
const members = new Collection<bigint, DiscordenoMember>();
|
||||
@@ -31,13 +30,13 @@ export async function getMembers(bot: Bot, guildId: bigint, options?: ListGuildM
|
||||
let membersLeft = options?.limit ?? guild.memberCount;
|
||||
let loops = 1;
|
||||
while ((options?.limit ?? guild.memberCount) > members.size && membersLeft > 0) {
|
||||
eventHandlers.debug?.("loop", "Running while loop in getMembers function.");
|
||||
bot.events.debug("Running while loop in getMembers function.");
|
||||
|
||||
if (options?.limit && options.limit > 1000) {
|
||||
console.log(`Paginating get members from REST. #${loops} / ${Math.ceil((options?.limit ?? 1) / 1000)}`);
|
||||
}
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<GuildMemberWithUser>[]>(
|
||||
const result = await bot.rest.runMethod<GuildMemberWithUser[]>(
|
||||
bot.rest,
|
||||
"get",
|
||||
`${bot.constants.endpoints.GUILD_MEMBERS(guildId)}?limit=${membersLeft > 1000 ? 1000 : membersLeft}${
|
||||
@@ -47,7 +46,7 @@ export async function getMembers(bot: Bot, guildId: bigint, options?: ListGuildM
|
||||
|
||||
const discordenoMembers = await Promise.all(
|
||||
result.map(async (member) => {
|
||||
const discordenoMember = bot.transformers.member(member, guildId);
|
||||
const discordenoMember = bot.transformers.member(bot, member, guildId);
|
||||
|
||||
if (options?.addToCache !== false) {
|
||||
await bot.cache.members.set(discordenoMember.id, discordenoMember);
|
||||
@@ -60,13 +59,13 @@ export async function getMembers(bot: Bot, guildId: bigint, options?: ListGuildM
|
||||
if (!discordenoMembers.length) break;
|
||||
|
||||
discordenoMembers.forEach((member) => {
|
||||
bot.events.debug("loop", `Running forEach loop in get_members file.`);
|
||||
bot.events.debug(`Running forEach loop in get_members file.`);
|
||||
members.set(member.id, member);
|
||||
});
|
||||
|
||||
options = {
|
||||
limit: options?.limit,
|
||||
after: bot.transformers.snowflake(discordenoMembers[discordenoMembers.length - 1].id),
|
||||
after: discordenoMembers[discordenoMembers.length - 1].id.toString(),
|
||||
};
|
||||
|
||||
membersLeft -= 1000;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Bot } from "../../bot.ts";
|
||||
/** Kick a member from the server */
|
||||
export async function kick(bot: Bot, guildId: bigint, memberId: bigint, reason?: string) {
|
||||
const botsHighestRole = await bot.utils.highestRole(bot, guildId, botId);
|
||||
const botsHighestRole = await bot.utils.highestRole(bot, guildId, bot.id);
|
||||
const membersHighestRole = await bot.utils.highestRole(bot, guildId, memberId);
|
||||
if (botsHighestRole && membersHighestRole && botsHighestRole.position <= membersHighestRole.position) {
|
||||
throw new Error(bot.constants.Errors.BOTS_HIGHEST_ROLE_TOO_LOW);
|
||||
|
||||
@@ -25,7 +25,7 @@ export async function searchMembers(
|
||||
}
|
||||
}
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<GuildMemberWithUser>[]>(
|
||||
const result = await bot.rest.runMethod<GuildMemberWithUser[]>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.GUILD_MEMBERS_SEARCH(guildId),
|
||||
|
||||
@@ -10,7 +10,7 @@ export async function sendDirectMessage(bot: Bot, memberId: bigint, content: str
|
||||
let dmChannel = await bot.cache.channels.get(memberId);
|
||||
if (!dmChannel) {
|
||||
// If not available in cache create a new one.
|
||||
const dmChannelData = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Channel>>(
|
||||
const dmChannelData = await bot.rest.runMethod<Channel>(
|
||||
bot.rest,
|
||||
"post",
|
||||
bot.constants.endpoints.USER_DM,
|
||||
@@ -25,5 +25,5 @@ export async function sendDirectMessage(bot: Bot, memberId: bigint, content: str
|
||||
}
|
||||
|
||||
// If it does exist try sending a message to this user
|
||||
return await bot.helpers.sendMessage(dmChannel.id, content);
|
||||
return await bot.helpers.sendMessage(bot, dmChannel.id, content);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { Bot } from "../../bot.ts";
|
||||
|
||||
/** Remove the ban for a user. Requires BAN_MEMBERS permission */
|
||||
export async function unban(bot: Bot, guildId: bigint, id: bigint) {
|
||||
await bot.utils.requireBotGuildPermissions(guildId, ["BAN_MEMBERS"]);
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, ["BAN_MEMBERS"]);
|
||||
|
||||
return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.GUILD_BAN(guildId, id));
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ export async function addReactions(
|
||||
await Promise.all(reactions.map((reaction) => bot.helpers.addReaction(bot, channelId, messageId, reaction)));
|
||||
} else {
|
||||
for (const reaction of reactions) {
|
||||
bot.events.debug("loop", "Running for of loop in addReactions function.");
|
||||
bot.events.debug("Running for of loop in addReactions function.");
|
||||
await bot.helpers.addReaction(bot, channelId, messageId, reaction);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ export async function editMessage(bot: Bot, channelId: bigint, messageId: bigint
|
||||
throw new Error(bot.constants.Errors.MESSAGE_MAX_LENGTH);
|
||||
}
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
|
||||
const result = await bot.rest.runMethod<Message>(
|
||||
bot.rest,
|
||||
"patch",
|
||||
bot.constants.endpoints.CHANNEL_MESSAGE(channelId, messageId),
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// import { cacheHandlers } from "../../cache.ts";
|
||||
import type { Message } from "../../types/messages/message.ts";
|
||||
import type { Bot } from "../../bot.ts";
|
||||
import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Fetch a single message from the server. Requires VIEW_CHANNEL and READ_MESSAGE_HISTORY */
|
||||
export async function getMessage(bot: Bot, channelId: bigint, id: bigint) {
|
||||
@@ -9,7 +7,7 @@ export async function getMessage(bot: Bot, channelId: bigint, id: bigint) {
|
||||
await bot.utils.requireBotChannelPermissions(bot, channelId, ["VIEW_CHANNEL", "READ_MESSAGE_HISTORY"]);
|
||||
}
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
|
||||
const result = await bot.rest.runMethod<Message>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.CHANNEL_MESSAGE(channelId, id)
|
||||
|
||||
@@ -6,7 +6,6 @@ import type {
|
||||
} from "../../types/messages/get_messages.ts";
|
||||
import type { Message } from "../../types/messages/message.ts";
|
||||
import type { Bot } from "../../bot.ts";
|
||||
import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Fetches between 2-100 messages. Requires VIEW_CHANNEL and READ_MESSAGE_HISTORY */
|
||||
export async function getMessages(
|
||||
@@ -20,7 +19,7 @@ export async function getMessages(
|
||||
throw new Error(bot.constants.Errors.INVALID_GET_MESSAGES_LIMIT);
|
||||
}
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>[]>(
|
||||
const result = await bot.rest.runMethod<Message[]>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.CHANNEL_MESSAGES(channelId),
|
||||
|
||||
@@ -4,7 +4,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Crosspost a message in a News Channel to following channels. */
|
||||
export async function publishMessage(bot: Bot, channelId: bigint, messageId: bigint) {
|
||||
const data = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
|
||||
const data = await bot.rest.runMethod<Message>(
|
||||
bot.rest,
|
||||
"post",
|
||||
bot.constants.endpoints.CHANNEL_MESSAGE_CROSSPOST(channelId, messageId)
|
||||
|
||||
@@ -73,7 +73,7 @@ export async function sendMessage(bot: Bot, channelId: bigint, content: string |
|
||||
}
|
||||
}
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
|
||||
const result = await bot.rest.runMethod<Message>(
|
||||
bot.rest,
|
||||
"post",
|
||||
bot.constants.endpoints.CHANNEL_MESSAGES(channelId),
|
||||
|
||||
@@ -9,7 +9,7 @@ export async function suppressEmbeds(bot: Bot, channelId: bigint, messageId: big
|
||||
|
||||
await bot.utils.requireBotChannelPermissions(bot, channelId, message ? ["MANAGE_MESSAGES"] : ["SEND_MESSAGES"]);
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
|
||||
const result = await bot.rest.runMethod<Message>(
|
||||
bot.rest,
|
||||
"patch",
|
||||
bot.constants.endpoints.CHANNEL_MESSAGE(channelId, messageId),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Errors } from "../../types/discordeno/errors.ts";
|
||||
import type { User } from "../../types/users/user.ts";
|
||||
import type { Bot } from "../../bot.ts";
|
||||
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Modifies the bot's username or avatar.
|
||||
* NOTE: username: if changed may cause the bot's discriminator to be randomized.
|
||||
@@ -27,7 +26,7 @@ export async function editBotProfile(bot: Bot, options: { username?: string; bot
|
||||
|
||||
const avatar = options?.botAvatarURL ? await bot.utils.urlToBase64(options?.botAvatarURL) : options?.botAvatarURL;
|
||||
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<User>>(bot, "patch", bot.constants.endpoints.USER_BOT, {
|
||||
return await bot.rest.runMethod<User>(bot.rest, "patch", bot.constants.endpoints.USER_BOT, {
|
||||
username: options.username?.trim(),
|
||||
avatar,
|
||||
});
|
||||
|
||||
@@ -3,10 +3,10 @@ import { DiscordGatewayOpcodes } from "../../types/codes/gateway_opcodes.ts";
|
||||
import type { StatusUpdate } from "../../types/gateway/status_update.ts";
|
||||
|
||||
export function editBotStatus(bot: Bot, data: Omit<StatusUpdate, "afk" | "since">) {
|
||||
bot.ws.shards.forEach((shard) => {
|
||||
bot.events.debug("loop", `Running forEach loop in editBotStatus function.`);
|
||||
bot.gateway.shards.forEach((shard) => {
|
||||
bot.events.debug(`Running forEach loop in editBotStatus function.`);
|
||||
|
||||
bot.ws.sendShardMessage(shard, {
|
||||
bot.gateway.sendShardMessage(bot.gateway, shard, {
|
||||
op: DiscordGatewayOpcodes.StatusUpdate,
|
||||
d: {
|
||||
since: null,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Get the bots Gateway metadata that can help during the operation of large or sharded bots. */
|
||||
export async function getGatewayBot(bot: Bot): Promise<GetGatewayBot> {
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<GetGatewayBot>>(
|
||||
const result = await bot.rest.runMethod<GetGatewayBot>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.GATEWAY_BOT
|
||||
|
||||
@@ -4,7 +4,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** This function will return the raw user payload in the rare cases you need to fetch a user directly from the API. */
|
||||
export async function getUser(bot: Bot, userId: bigint) {
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<User>>(
|
||||
return await bot.rest.runMethod<User>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.USER(userId)
|
||||
|
||||
@@ -4,7 +4,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Get the applications info */
|
||||
export async function getApplicationInfo(bot: Bot) {
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<Omit<Application, "flags">>>(
|
||||
return await bot.rest.runMethod<Omit<Application, "flags">>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.OAUTH2_APPLICATION
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { Bot } from "../../bot.ts";
|
||||
|
||||
/** Add a role to the member */
|
||||
export async function addRole(bot: Bot, guildId: bigint, memberId: bigint, roleId: bigint, reason?: string) {
|
||||
const isHigherRolePosition = await bot.utils.isHigherPosition(guildId, bot.id, roleId);
|
||||
const isHigherRolePosition = await bot.utils.isHigherPosition(bot, guildId, bot.id, roleId);
|
||||
if (!isHigherRolePosition) {
|
||||
throw new Error(bot.constants.Errors.BOTS_HIGHEST_ROLE_TOO_LOW);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
export async function createRole(bot: Bot, guildId: bigint, options: CreateGuildRole, reason?: string) {
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_ROLES"]);
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Role>>(
|
||||
const result = await bot.rest.runMethod<Role>(bot.rest,
|
||||
"post",
|
||||
bot.constants.endpoints.GUILD_ROLES(guildId),
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
export async function editRole(bot: Bot, guildId: bigint, id: bigint, options: CreateGuildRole) {
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_ROLES"]);
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Role>>(
|
||||
const result = await bot.rest.runMethod<Role>(
|
||||
bot.rest,
|
||||
"patch",
|
||||
bot.constants.endpoints.GUILD_ROLE(guildId, id),
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { Role } from "../../types/permissions/role.ts";
|
||||
import type { Bot } from "../../bot.ts";
|
||||
import { Collection } from "../../util/collection.ts";
|
||||
import { DiscordenoRole } from "../../transformers/role.ts";
|
||||
|
||||
/** Returns a list of role objects for the guild.
|
||||
*
|
||||
* ⚠️ **If you need this, you are probably doing something wrong. This is not intended for use. Your roles will be cached in your guild.**
|
||||
@@ -11,7 +12,7 @@ export async function getRoles(bot: Bot, guildId: bigint, addToCache = true) {
|
||||
|
||||
const result = await bot.rest.runMethod<Role[]>(bot.rest, "get", bot.constants.endpoints.GUILD_ROLES(guildId));
|
||||
|
||||
const roleStructures = result.map((role: Role) => bot.transformers.role({ role, guildId }));
|
||||
const roleStructures = result.map((role) => bot.transformers.role(bot, { role, guildId }));
|
||||
|
||||
const roles = new Collection(roleStructures.map((role: DiscordenoRole) => [role.id, role]));
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ export async function createGuildFromTemplate(bot: Bot, templateCode: string, da
|
||||
data
|
||||
);
|
||||
|
||||
return bot.transformers.guild(
|
||||
createdGuild,
|
||||
Number((BigInt(createdGuild.id) >> 22n % BigInt(bot.ws.botGatewayData.shards)).toString())
|
||||
);
|
||||
return bot.transformers.guild(bot, {
|
||||
guild: createdGuild,
|
||||
shardId: bot.utils.calculateShardId(bot.gateway, bot.transformers.snowflake(createdGuild.id)),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import type { Bot } from "../../bot.ts";
|
||||
export async function getGuildTemplates(bot: Bot, guildId: bigint) {
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
|
||||
|
||||
const templates = await bot.rest.runMethod<Template[]>("get", bot.constants.endpoints.GUILD_TEMPLATES(guildId));
|
||||
const templates = await bot.rest.runMethod<Template[]>(bot.rest, "get", bot.constants.endpoints.GUILD_TEMPLATES(guildId));
|
||||
|
||||
return new Collection(templates.map((template) => [template.code, template]));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { UpdateVoiceState } from "../../types/voice/update_voice_state.ts";
|
||||
import type { AtLeastOne } from "../../types/util.ts";
|
||||
import type { Bot } from "../../bot.ts";
|
||||
import { DiscordGatewayOpcodes } from "../../types/codes/gateway_opcodes.ts";
|
||||
|
||||
/** Connect or join a voice channel inside a guild. By default, the "selfDeaf" option is true. Requires `CONNECT` and `VIEW_CHANNEL` permissions. */
|
||||
export async function connectToVoiceChannel(
|
||||
@@ -11,8 +12,8 @@ export async function connectToVoiceChannel(
|
||||
) {
|
||||
await bot.utils.requireBotChannelPermissions(bot, channelId, ["CONNECT", "VIEW_CHANNEL"]);
|
||||
|
||||
bot.ws.sendShardMessage(bot.utils.calculateShardId(guildId), {
|
||||
op: bot.constants.DiscordGatewayOpcodes.VoiceStateUpdate,
|
||||
bot.gateway.sendShardMessage(bot.gateway, bot.utils.calculateShardId(bot.gateway, guildId), {
|
||||
op: DiscordGatewayOpcodes.VoiceStateUpdate,
|
||||
d: {
|
||||
guild_id: guildId,
|
||||
channel_id: channelId,
|
||||
|
||||
@@ -9,7 +9,7 @@ import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
* Webhook names cannot be: 'clyde'
|
||||
*/
|
||||
export async function createWebhook(bot: Bot, channelId: bigint, options: CreateWebhook) {
|
||||
await bot.utils.requireBotChannelPermissions(channelId, ["MANAGE_WEBHOOKS"]);
|
||||
await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS"]);
|
||||
|
||||
if (
|
||||
// Specific usernames that discord does not allow
|
||||
@@ -19,7 +19,7 @@ export async function createWebhook(bot: Bot, channelId: bigint, options: Create
|
||||
throw new Error(bot.constants.Errors.INVALID_WEBHOOK_NAME);
|
||||
}
|
||||
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<Webhook>>(
|
||||
return await bot.rest.runMethod<Webhook>(
|
||||
bot.rest,
|
||||
"post",
|
||||
bot.constants.endpoints.CHANNEL_WEBHOOKS(channelId),
|
||||
|
||||
@@ -4,5 +4,5 @@ import type { Bot } from "../../bot.ts";
|
||||
export async function deleteWebhook(bot: Bot, channelId: bigint, webhookId: bigint) {
|
||||
await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS"]);
|
||||
|
||||
return await bot.rest.runMethod<undefined>(bot.rset, "delete", bot.constants.endpoints.WEBHOOK_ID(webhookId));
|
||||
return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.WEBHOOK_ID(webhookId));
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Edit a webhook. Requires the `MANAGE_WEBHOOKS` permission. Returns the updated webhook object on success. */
|
||||
export async function editWebhook(bot: Bot, channelId: bigint, webhookId: bigint, options: ModifyWebhook) {
|
||||
await bot.utils.requireBotChannelPermissions(channelId, ["MANAGE_WEBHOOKS"]);
|
||||
await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS"]);
|
||||
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<Webhook>>(
|
||||
return await bot.rest.runMethod<Webhook>(
|
||||
bot.rest,
|
||||
"patch",
|
||||
bot.constants.endpoints.WEBHOOK_ID(webhookId),
|
||||
|
||||
@@ -41,10 +41,10 @@ export async function editWebhookMessage(
|
||||
}
|
||||
|
||||
if (options.components?.length) {
|
||||
bot.utils.validateComponents(options.components);
|
||||
bot.utils.validateComponents(bot, options.components);
|
||||
}
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
|
||||
const result = await bot.rest.runMethod<Message>(
|
||||
bot.rest,
|
||||
"patch",
|
||||
options.messageId
|
||||
@@ -54,12 +54,12 @@ export async function editWebhookMessage(
|
||||
content: options.content,
|
||||
embeds: options.embeds,
|
||||
file: options.file,
|
||||
allowed_mentions: {
|
||||
parse: content.allowedMentions.parse,
|
||||
roles: content.allowedMentions.roles,
|
||||
users: content.allowedMentions.users,
|
||||
replied_user: content.allowedMentions.repliedUser,
|
||||
},
|
||||
allowed_mentions: options.allowedMentions ? {
|
||||
parse: options.allowedMentions.parse,
|
||||
roles: options.allowedMentions.roles,
|
||||
users: options.allowedMentions.users,
|
||||
replied_user: options.allowedMentions.repliedUser,
|
||||
} : undefined,
|
||||
attachments: options.attachments,
|
||||
// TODO: Snakelize components??
|
||||
components: options.components,
|
||||
|
||||
@@ -10,7 +10,7 @@ export async function editWebhookWithToken(
|
||||
webhookToken: string,
|
||||
options: Omit<ModifyWebhook, "channelId">
|
||||
) {
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<Webhook>>(
|
||||
return await bot.rest.runMethod<Webhook>(
|
||||
bot.rest,
|
||||
"patch",
|
||||
bot.constants.endpoints.WEBHOOK(webhookId, webhookToken),
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Returns the new webhook object for the given id. */
|
||||
export async function getWebhook(bot: Bot, webhookId: bigint) {
|
||||
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<Webhook>>(
|
||||
return await bot.rest.runMethod<Webhook>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.WEBHOOK_ID(webhookId)
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { Bot } from "../../bot.ts";
|
||||
|
||||
/** Returns a previously-sent webhook message from the same token. Returns a message object on success. */
|
||||
export async function getWebhookMessage(bot: Bot, webhookId: bigint, webhookToken: string, messageId: bigint) {
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
|
||||
const result = await bot.rest.runMethod<Message>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.WEBHOOK_MESSAGE(webhookId, webhookToken, messageId)
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
export async function getWebhooks(bot: Bot, guildId: bigint) {
|
||||
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_WEBHOOKS"]);
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Webhook>[]>(
|
||||
const result = await bot.rest.runMethod<Webhook[]>(
|
||||
bot.rest,
|
||||
"get",
|
||||
bot.constants.endpoints.GUILD_WEBHOOKS(guildId)
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { Bot } from "../../bot.ts";
|
||||
import { DiscordAllowedMentionsTypes } from "../../types/messages/allowed_mentions_types.ts";
|
||||
import type { Message } from "../../types/messages/message.ts";
|
||||
import type { ExecuteWebhook } from "../../types/webhooks/execute_webhook.ts";
|
||||
import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||
|
||||
/** Send a webhook with webhook Id and webhook token */
|
||||
export async function sendWebhook(bot: Bot, webhookId: bigint, webhookToken: string, options: ExecuteWebhook) {
|
||||
@@ -38,7 +37,7 @@ export async function sendWebhook(bot: Bot, webhookId: bigint, webhookToken: str
|
||||
}
|
||||
}
|
||||
|
||||
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
|
||||
const result = await bot.rest.runMethod<Message>(
|
||||
bot.rest,
|
||||
"post",
|
||||
`${bot.constants.endpoints.WEBHOOK(webhookId, webhookToken)}?wait=${options.wait ?? false}${
|
||||
|
||||
@@ -4,7 +4,7 @@ import { RestManager } from "../bot.ts";
|
||||
export function cleanupQueues(rest: RestManager) {
|
||||
for (const [key, queue] of rest.pathQueues) {
|
||||
rest.debug(`[REST - cleanupQueues] Running for of loop. ${key}`);
|
||||
if (queue.length) continue;
|
||||
if (queue.requests.length) continue;
|
||||
// REMOVE IT FROM CACHE
|
||||
rest.pathQueues.delete(key);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ export function processRequestHeaders(rest: RestManager, url: string, headers: H
|
||||
}
|
||||
|
||||
if (ratelimited && !rest.processingRateLimitedPaths) {
|
||||
rest.processRateLimitedPaths();
|
||||
rest.processRateLimitedPaths(rest);
|
||||
}
|
||||
return ratelimited ? bucketId : undefined;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { RestManager } from "../bot.ts";
|
||||
import { SnakeCasedPropertiesDeep } from "../types/util.ts";
|
||||
import { API_VERSION, BASE_URL, IMAGE_BASE_URL } from "../util/constants.ts";
|
||||
|
||||
export async function runMethod<T = any>(
|
||||
@@ -8,7 +9,7 @@ export async function runMethod<T = any>(
|
||||
body?: unknown,
|
||||
retryCount = 0,
|
||||
bucketId?: string
|
||||
): Promise<T> {
|
||||
): Promise<SnakeCasedPropertiesDeep<T>> {
|
||||
rest.debug(
|
||||
`[REST - RequestCreate] Method: ${method} | URL: ${url} | Retry Count: ${retryCount} | Bucket ID: ${bucketId} | Body: ${JSON.stringify(
|
||||
body
|
||||
|
||||
35
src/transformers/attachment.ts
Normal file
35
src/transformers/attachment.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { Bot } from "../bot.ts";
|
||||
import { Attachment } from "../types/messages/attachment.ts";
|
||||
import { SnakeCasedPropertiesDeep } from "../types/util.ts";
|
||||
|
||||
export function transformAttachment(bot: Bot, payload: SnakeCasedPropertiesDeep<Attachment>): DiscordenoAttachment {
|
||||
return {
|
||||
id: bot.transformers.snowflake(payload.id),
|
||||
filename: payload.filename,
|
||||
contentType: payload.content_type,
|
||||
size: payload.size,
|
||||
url: payload.url,
|
||||
proxyUrl: payload.proxy_url,
|
||||
height: payload.height ?? undefined,
|
||||
width: payload.width ?? undefined,
|
||||
};
|
||||
}
|
||||
|
||||
export interface DiscordenoAttachment {
|
||||
/** Attachment id */
|
||||
id: bigint;
|
||||
/** Name of file attached */
|
||||
filename: string;
|
||||
/** The attachment's [media type](https://en.wikipedia.org/wiki/Media_type) */
|
||||
contentType?: string;
|
||||
/** Size of file in bytes */
|
||||
size: number;
|
||||
/** Source url of file */
|
||||
url: string;
|
||||
/** A proxied url of file */
|
||||
proxyUrl: string;
|
||||
/** Height of file (if image) */
|
||||
height?: number;
|
||||
/** Width of file (if image) */
|
||||
width?: number;
|
||||
}
|
||||
@@ -30,13 +30,11 @@ export function transformRole(
|
||||
};
|
||||
}
|
||||
|
||||
export interface DiscordenoRole extends Omit<Role, "tags" | "id" | "permissions"> {
|
||||
export interface DiscordenoRole extends Omit<Role, "tags" | "id" | "permissions" | "hoist" | "mentionable" | "managed"> {
|
||||
/** The role id */
|
||||
id: bigint;
|
||||
/** The bot id that is associated with this role. */
|
||||
botId?: bigint;
|
||||
/** If this role is the nitro boost role. */
|
||||
isNitroBoostRole: boolean;
|
||||
/** The integration id that is associated with this role */
|
||||
integrationId?: bigint;
|
||||
/** The roles guildId */
|
||||
|
||||
@@ -49,7 +49,7 @@ export async function dispatchRequirements(bot: Bot, data: DiscordGatewayPayload
|
||||
bot.events.debug(`[DISPATCH] New Guild ID has appeared: ${id} in ${data.t} event`);
|
||||
|
||||
const rawGuild = (await bot.helpers
|
||||
.getGuild(id, {
|
||||
.getGuild(bot, id, {
|
||||
counts: true,
|
||||
addToCache: false,
|
||||
})
|
||||
@@ -63,8 +63,8 @@ export async function dispatchRequirements(bot: Bot, data: DiscordGatewayPayload
|
||||
bot.events.debug(`[DISPATCH] Guild ID ${id} has been found. ${rawGuild.name}`);
|
||||
|
||||
const [channels, botMember] = await Promise.all([
|
||||
bot.helpers.getChannels(id, false),
|
||||
bot.helpers.getMember(id, bot.id, { force: true }),
|
||||
bot.helpers.getChannels(bot, id, false),
|
||||
bot.helpers.getMember(bot, id, bot.id, { force: true }),
|
||||
]).catch((error) => {
|
||||
bot.events.debug(error);
|
||||
return [];
|
||||
@@ -78,8 +78,10 @@ export async function dispatchRequirements(bot: Bot, data: DiscordGatewayPayload
|
||||
}
|
||||
|
||||
const guild = bot.transformers.guild(bot, {
|
||||
...rawGuild,
|
||||
member_count: rawGuild.approximateMemberCount,
|
||||
guild: {
|
||||
...rawGuild,
|
||||
member_count: rawGuild.approximate_member_count,
|
||||
},
|
||||
shardId,
|
||||
});
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ export function validateSlashCommands(
|
||||
// Taken from https://fettblog.eu/typescript-hasownproperty/
|
||||
/** TS save way to check if a property exists in an object */
|
||||
// deno-lint-ignore ban-types
|
||||
export function hasOwnProperty<T extends {}, Y extends PropertyKey = string>(
|
||||
export function hasProperty<T extends {}, Y extends PropertyKey = string>(
|
||||
obj: T,
|
||||
prop: Y
|
||||
): obj is T & Record<Y, unknown> {
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
import { getGatewayBot } from "../helpers/misc/get_gateway_bot.ts";
|
||||
import { GatewayManager } from "../bot.ts";
|
||||
import { GetGatewayBot } from "../types/gateway/get_gateway_bot.ts";
|
||||
|
||||
/** The handler to automatically reshard when necessary. */
|
||||
export async function resharder(gateway: GatewayManager) {
|
||||
gateway.botGatewayData = await getGatewayBot();
|
||||
// TODO: is it possible to route this to REST?
|
||||
const results = (await fetch(`https://discord.com/api/gateway/bot`, {
|
||||
headers: { Authorization: gateway.token },
|
||||
}).then((res) => res.json())) as GetGatewayBot;
|
||||
|
||||
const percentage = ((gateway.botGatewayData.shards - gateway.maxShards) / gateway.maxShards) * 100;
|
||||
const percentage = ((results.shards - gateway.maxShards) / gateway.maxShards) * 100;
|
||||
// Less than necessary% being used so do nothing
|
||||
if (percentage < gateway.reshardPercentage) return;
|
||||
|
||||
// Don't have enough identify rate limits to reshard
|
||||
if (gateway.botGatewayData.sessionStartLimit.remaining < gateway.botGatewayData.shards) {
|
||||
if (results.sessionStartLimit.remaining < results.shards) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Begin resharding
|
||||
gateway.maxShards = gateway.botGatewayData.shards;
|
||||
gateway.maxShards = results.shards;
|
||||
// If more than 100K servers, begin switching to 16x sharding
|
||||
if (gateway.maxShards && gateway.useOptimalLargeBotSharding) {
|
||||
gateway.maxShards = Math.ceil(
|
||||
gateway.maxShards /
|
||||
(gateway.botGatewayData.sessionStartLimit.maxConcurrency === 1
|
||||
? 16
|
||||
: gateway.botGatewayData.sessionStartLimit.maxConcurrency)
|
||||
(results.sessionStartLimit.maxConcurrency === 1 ? 16 : results.sessionStartLimit.maxConcurrency)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user