mirror of
https://github.com/discordeno/discordeno.git
synced 2026-06-03 09:20:08 +00:00
@@ -1,4 +1,4 @@
|
||||
import { eventHandlers, setBotID } from "../../bot.ts";
|
||||
import { eventHandlers, setApplicationID, setBotID } from "../../bot.ts";
|
||||
import {
|
||||
DiscordPayload,
|
||||
PresenceUpdatePayload,
|
||||
@@ -24,6 +24,7 @@ export async function handleInternalReady(
|
||||
|
||||
const payload = data.d as ReadyPayload;
|
||||
setBotID(payload.user.id);
|
||||
setApplicationID(payload.application.id);
|
||||
|
||||
// Triggered on each shard
|
||||
eventHandlers.shardReady?.(shardID);
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
GetMessagesAfter,
|
||||
GetMessagesAround,
|
||||
GetMessagesBefore,
|
||||
InvitePayload,
|
||||
MessageContent,
|
||||
MessageCreateOptions,
|
||||
Permission,
|
||||
@@ -19,6 +20,7 @@ import {
|
||||
import { endpoints } from "../../util/constants.ts";
|
||||
import {
|
||||
botHasChannelPermissions,
|
||||
botHasPermission,
|
||||
calculateBits,
|
||||
} from "../../util/permissions.ts";
|
||||
import { cacheHandlers } from "../controllers/cache.ts";
|
||||
@@ -301,6 +303,39 @@ export async function createInvite(
|
||||
return RequestManager.post(endpoints.CHANNEL_INVITES(channelID), options);
|
||||
}
|
||||
|
||||
/** Returns an invite for the given code. */
|
||||
export function getInvite(inviteCode: string) {
|
||||
return RequestManager.get(endpoints.INVITE(inviteCode)) as Promise<
|
||||
InvitePayload
|
||||
>;
|
||||
}
|
||||
|
||||
/** Deletes an invite for the given code. Requires `MANAGE_CHANNELS` or `MANAGE_GUILD` permission */
|
||||
export async function deleteInvite(
|
||||
channelID: string,
|
||||
inviteCode: string,
|
||||
) {
|
||||
const hasPerm = await botHasChannelPermissions(channelID, [
|
||||
"MANAGE_CHANNELS",
|
||||
]);
|
||||
|
||||
if (!hasPerm) {
|
||||
const channel = await cacheHandlers.get("channels", channelID);
|
||||
|
||||
const hasManageGuildPerm = await botHasPermission(channel!.guildID, [
|
||||
"MANAGE_GUILD",
|
||||
]);
|
||||
|
||||
if (!hasManageGuildPerm) {
|
||||
throw new Error(Errors.MISSING_MANAGE_CHANNELS);
|
||||
}
|
||||
}
|
||||
|
||||
return RequestManager.delete(endpoints.INVITE(inviteCode)) as Promise<
|
||||
InvitePayload
|
||||
>;
|
||||
}
|
||||
|
||||
/** Gets the webhooks for this channel. Requires MANAGE_WEBHOOKS */
|
||||
export async function getChannelWebhooks(channelID: string) {
|
||||
const hasManageWebhooksPerm = await botHasChannelPermissions(
|
||||
|
||||
@@ -729,6 +729,11 @@ export function leaveGuild(guildID: string) {
|
||||
return RequestManager.delete(endpoints.GUILD_LEAVE(guildID));
|
||||
}
|
||||
|
||||
/** Returns an array of voice regions that can be used when creating servers. */
|
||||
export function getAvailableVoiceRegions() {
|
||||
return RequestManager.get(endpoints.VOICE_REGIONS);
|
||||
}
|
||||
|
||||
/** 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 function getVoiceRegions(guildID: string) {
|
||||
return RequestManager.get(endpoints.GUILD_REGIONS(guildID));
|
||||
@@ -767,13 +772,23 @@ export function getGuild(guildID: string, counts = true) {
|
||||
}
|
||||
|
||||
/** Returns the guild template if it exists */
|
||||
export async function getTemplate(templateCode: string) {
|
||||
const result = await RequestManager.get(
|
||||
endpoints.GUILD_TEMPLATE(templateCode),
|
||||
) as GuildTemplate;
|
||||
const template = await structures.createTemplate(result);
|
||||
return template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the guild template if it exists
|
||||
* @deprecated will get removed in v11 use `getTemplate` instead
|
||||
*/
|
||||
export function getGuildTemplate(
|
||||
guildID: string,
|
||||
templateCode: string,
|
||||
) {
|
||||
return RequestManager.get(
|
||||
`${endpoints.GUILD_TEMPLATES(guildID)}/${templateCode}`,
|
||||
) as Promise<Template>;
|
||||
return getTemplate(templateCode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import {
|
||||
channelOverwriteHasPermission,
|
||||
createInvite,
|
||||
deleteInvite,
|
||||
deleteMessages,
|
||||
editChannel,
|
||||
followChannel,
|
||||
getChannelInvites,
|
||||
getChannelWebhooks,
|
||||
getInvite,
|
||||
getMessage,
|
||||
getMessages,
|
||||
getPins,
|
||||
@@ -40,6 +42,7 @@ import {
|
||||
emojiURL,
|
||||
fetchMembers,
|
||||
getAuditLogs,
|
||||
getAvailableVoiceRegions,
|
||||
getBan,
|
||||
getBans,
|
||||
getChannel,
|
||||
@@ -57,6 +60,7 @@ import {
|
||||
getMembersByQuery,
|
||||
getPruneCount,
|
||||
getRoles,
|
||||
getTemplate,
|
||||
getUser,
|
||||
getVanityURL,
|
||||
getVoiceRegions,
|
||||
@@ -131,6 +135,8 @@ export let handlers = {
|
||||
getPins,
|
||||
isChannelSynced,
|
||||
sendMessage,
|
||||
getInvite,
|
||||
deleteInvite,
|
||||
startTyping,
|
||||
|
||||
// Gateway handler
|
||||
@@ -171,9 +177,11 @@ export let handlers = {
|
||||
getGuildPreview,
|
||||
getGuildTemplate,
|
||||
getGuildTemplates,
|
||||
getAvailableVoiceRegions,
|
||||
getIntegrations,
|
||||
getInvites,
|
||||
getMember,
|
||||
getTemplate,
|
||||
getMembersByQuery,
|
||||
getPruneCount,
|
||||
getRoles,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { botID } from "../../bot.ts";
|
||||
import { applicationID } from "../../bot.ts";
|
||||
import { RequestManager } from "../../rest/request_manager.ts";
|
||||
import {
|
||||
CreateSlashCommandOptions,
|
||||
@@ -206,8 +206,8 @@ export function createSlashCommand(options: CreateSlashCommandOptions) {
|
||||
|
||||
return RequestManager.post(
|
||||
options.guildID
|
||||
? endpoints.COMMANDS_GUILD(botID, options.guildID)
|
||||
: endpoints.COMMANDS(botID),
|
||||
? endpoints.COMMANDS_GUILD(applicationID, options.guildID)
|
||||
: endpoints.COMMANDS(applicationID),
|
||||
{
|
||||
...options,
|
||||
},
|
||||
@@ -219,8 +219,8 @@ export function getSlashCommands(guildID?: string) {
|
||||
// TODO: Should this be a returned as a collection?
|
||||
return RequestManager.get(
|
||||
guildID
|
||||
? endpoints.COMMANDS_GUILD(botID, guildID)
|
||||
: endpoints.COMMANDS(botID),
|
||||
? endpoints.COMMANDS_GUILD(applicationID, guildID)
|
||||
: endpoints.COMMANDS(applicationID),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -230,8 +230,8 @@ export function getSlashCommands(guildID?: string) {
|
||||
export function upsertSlashCommand(options: UpsertSlashCommandOptions) {
|
||||
return RequestManager.post(
|
||||
options.guildID
|
||||
? endpoints.COMMANDS_GUILD_ID(botID, options.id, options.guildID)
|
||||
: endpoints.COMMANDS_ID(botID, options.id),
|
||||
? endpoints.COMMANDS_GUILD_ID(applicationID, options.id, options.guildID)
|
||||
: endpoints.COMMANDS_ID(applicationID, options.id),
|
||||
{
|
||||
...options,
|
||||
},
|
||||
@@ -242,8 +242,8 @@ export function upsertSlashCommand(options: UpsertSlashCommandOptions) {
|
||||
export function editSlashCommand(options: EditSlashCommandOptions) {
|
||||
return RequestManager.patch(
|
||||
options.guildID
|
||||
? endpoints.COMMANDS_GUILD_ID(botID, options.id, options.guildID)
|
||||
: endpoints.COMMANDS_ID(botID, options.id),
|
||||
? endpoints.COMMANDS_GUILD_ID(applicationID, options.id, options.guildID)
|
||||
: endpoints.COMMANDS_ID(applicationID, options.id),
|
||||
{
|
||||
...options,
|
||||
},
|
||||
@@ -252,8 +252,12 @@ export function editSlashCommand(options: EditSlashCommandOptions) {
|
||||
|
||||
/** Deletes a slash command. */
|
||||
export function deleteSlashCommand(id: string, guildID?: string) {
|
||||
if (!guildID) return RequestManager.delete(endpoints.COMMANDS_ID(botID, id));
|
||||
return RequestManager.delete(endpoints.COMMANDS_GUILD_ID(botID, id, guildID));
|
||||
if (!guildID) {
|
||||
return RequestManager.delete(endpoints.COMMANDS_ID(applicationID, id));
|
||||
}
|
||||
return RequestManager.delete(
|
||||
endpoints.COMMANDS_GUILD_ID(applicationID, id, guildID),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,7 +273,7 @@ export function executeSlashCommand(
|
||||
) {
|
||||
// If its already been executed, we need to send a followup response
|
||||
if (cache.executedSlashCommands.has(token)) {
|
||||
return RequestManager.post(endpoints.WEBHOOK(botID, token), {
|
||||
return RequestManager.post(endpoints.WEBHOOK(applicationID, token), {
|
||||
...options,
|
||||
});
|
||||
}
|
||||
@@ -298,11 +302,11 @@ export function deleteSlashResponse(
|
||||
) {
|
||||
if (!messageID) {
|
||||
return RequestManager.delete(
|
||||
endpoints.INTERACTION_ORIGINAL_ID_TOKEN(botID, token),
|
||||
endpoints.INTERACTION_ORIGINAL_ID_TOKEN(applicationID, token),
|
||||
);
|
||||
}
|
||||
return RequestManager.delete(
|
||||
endpoints.INTERACTION_ID_TOKEN_MESSAGEID(botID, token, messageID),
|
||||
endpoints.INTERACTION_ID_TOKEN_MESSAGEID(applicationID, token, messageID),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -312,7 +316,7 @@ export function editSlashResponse(
|
||||
options: EditSlashResponseOptions,
|
||||
) {
|
||||
return RequestManager.patch(
|
||||
endpoints.INTERACTION_ORIGINAL_ID_TOKEN(botID, token),
|
||||
endpoints.INTERACTION_ORIGINAL_ID_TOKEN(applicationID, token),
|
||||
options,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import { spawnShards } from "./ws/shard_manager.ts";
|
||||
|
||||
export let authorization = "";
|
||||
export let botID = "";
|
||||
export let applicationID = "";
|
||||
|
||||
export let eventHandlers: EventHandlers = {};
|
||||
|
||||
@@ -74,6 +75,11 @@ export function setBotID(id: string) {
|
||||
if (botID !== id) botID = id;
|
||||
}
|
||||
|
||||
/** INTERNAL LIB function used to set the application ID once the READY event is sent by Discord. */
|
||||
export function setApplicationID(id: string) {
|
||||
if (applicationID !== id) applicationID = id;
|
||||
}
|
||||
|
||||
// BIG BRAIN BOT STUFF ONLY BELOW THIS
|
||||
|
||||
/**
|
||||
|
||||
28
src/types/invite.ts
Normal file
28
src/types/invite.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Guild } from "../api/structures/mod.ts";
|
||||
import { ChannelCreatePayload } from "./channel.ts";
|
||||
import { UserPayload } from "./guild.ts";
|
||||
|
||||
/** https://discord.com/developers/docs/resources/invite#invite-object */
|
||||
export interface InvitePayload {
|
||||
/** the invite code (unique ID) */
|
||||
code: string;
|
||||
/** the guild this invite is for */
|
||||
guild?: Partial<Guild>;
|
||||
/** the channel this invite is for */
|
||||
channel: Partial<ChannelCreatePayload>;
|
||||
/** the user who created the invite */
|
||||
inviter?: UserPayload;
|
||||
/** the target user for this invite */
|
||||
target_user?: Partial<UserPayload>;
|
||||
/** the type of user target for this invite */
|
||||
target_user_type?: InviteTargetUserTypes;
|
||||
/** approximate count of online members (only present when target_user is set) */
|
||||
approximate_presence_count?: number;
|
||||
/** approximate count of total members */
|
||||
approximate_member_count: number;
|
||||
}
|
||||
|
||||
/** https://discord.com/developers/docs/resources/invite#invite-resource */
|
||||
export enum InviteTargetUserTypes {
|
||||
STREAM = 1,
|
||||
}
|
||||
@@ -6,6 +6,7 @@ export * from "./errors.ts";
|
||||
export * from "./fetch.ts";
|
||||
export * from "./guild.ts";
|
||||
export * from "./interactions.ts";
|
||||
export * from "./invite.ts";
|
||||
export * from "./member.ts";
|
||||
export * from "./message.ts";
|
||||
export * from "./options.ts";
|
||||
|
||||
@@ -10,9 +10,14 @@ export interface CacheData {
|
||||
members: Collection<string, Member>;
|
||||
unavailableGuilds: Collection<string, number>;
|
||||
presences: Collection<string, PresenceUpdatePayload>;
|
||||
// TODO: The type Collection's second provided generic [function] should have a definite shape.
|
||||
// deno-lint-ignore ban-types
|
||||
fetchAllMembersProcessingRequests: Collection<string, Function>;
|
||||
fetchAllMembersProcessingRequests: Collection<
|
||||
string,
|
||||
(
|
||||
value:
|
||||
| Collection<string, Member>
|
||||
| PromiseLike<Collection<string, Member>>,
|
||||
) => void
|
||||
>;
|
||||
executedSlashCommands: Collection<string, string>;
|
||||
}
|
||||
|
||||
|
||||
@@ -117,6 +117,9 @@ export const endpoints = {
|
||||
GUILD_TEMPLATES: (guildID: string) => `${GUILDS_BASE(guildID)}/templates`,
|
||||
GUILD_PREVIEW: (guildID: string) => `${GUILDS_BASE(guildID)}/preview`,
|
||||
|
||||
// Voice
|
||||
VOICE_REGIONS: `${baseEndpoints.BASE_URL}/voice/regions`,
|
||||
|
||||
INVITE: (inviteCode: string) =>
|
||||
`${baseEndpoints.BASE_URL}/invites/${inviteCode}`,
|
||||
|
||||
@@ -132,14 +135,18 @@ export const endpoints = {
|
||||
`${baseEndpoints.BASE_URL}/webhooks/${webhookID}/${token}/github`,
|
||||
|
||||
// Application Endpoints
|
||||
COMMANDS: (botID: string) =>
|
||||
`${baseEndpoints.BASE_URL}/applications/${botID}/commands`,
|
||||
COMMANDS_GUILD: (botID: string, guildID: string) =>
|
||||
`${baseEndpoints.BASE_URL}/applications/${botID}/guilds/${guildID}/commands`,
|
||||
COMMANDS_ID: (botID: string, commandID: string) =>
|
||||
`${baseEndpoints.BASE_URL}/applications/${botID}/commands/${commandID}`,
|
||||
COMMANDS_GUILD_ID: (botID: string, commandID: string, guildID: string) =>
|
||||
`${baseEndpoints.BASE_URL}/applications/${botID}/guilds/${guildID}/commands/${commandID}`,
|
||||
COMMANDS: (applicationID: string) =>
|
||||
`${baseEndpoints.BASE_URL}/applications/${applicationID}/commands`,
|
||||
COMMANDS_GUILD: (applicationID: string, guildID: string) =>
|
||||
`${baseEndpoints.BASE_URL}/applications/${applicationID}/guilds/${guildID}/commands`,
|
||||
COMMANDS_ID: (applicationID: string, commandID: string) =>
|
||||
`${baseEndpoints.BASE_URL}/applications/${applicationID}/commands/${commandID}`,
|
||||
COMMANDS_GUILD_ID: (
|
||||
applicationID: string,
|
||||
commandID: string,
|
||||
guildID: string,
|
||||
) =>
|
||||
`${baseEndpoints.BASE_URL}/applications/${applicationID}/guilds/${guildID}/commands/${commandID}`,
|
||||
|
||||
// Interaction Endpoints
|
||||
INTERACTION_ID_TOKEN: (interactionID: string, token: string) =>
|
||||
|
||||
@@ -67,8 +67,11 @@ export function createShard(
|
||||
}
|
||||
};
|
||||
|
||||
ws.onerror = ({ timeStamp }) => {
|
||||
eventHandlers.debug?.({ type: "wsError", data: { timeStamp } });
|
||||
ws.onerror = (errorEvent) => {
|
||||
eventHandlers.debug?.({
|
||||
type: "wsError",
|
||||
data: { shardID: basicShard.id, ...errorEvent },
|
||||
});
|
||||
};
|
||||
|
||||
ws.onmessage = ({ data: message }) => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { controllers } from "../api/controllers/mod.ts";
|
||||
import { Guild } from "../api/structures/guild.ts";
|
||||
import { Member } from "../api/structures/mod.ts";
|
||||
import { eventHandlers, IdentifyPayload } from "../bot.ts";
|
||||
import {
|
||||
DiscordBotGatewayData,
|
||||
@@ -8,6 +9,7 @@ import {
|
||||
GatewayOpcode,
|
||||
} from "../types/mod.ts";
|
||||
import { cache } from "../util/cache.ts";
|
||||
import { Collection } from "../util/collection.ts";
|
||||
import { BotStatusRequest, delay } from "../util/utils.ts";
|
||||
import {
|
||||
botGatewayStatusRequest,
|
||||
@@ -90,9 +92,9 @@ export async function handleDiscordPayload(
|
||||
|
||||
export function requestAllMembers(
|
||||
guild: Guild,
|
||||
// TODO: The parameter "resolve" should have a "stronger" type.
|
||||
// deno-lint-ignore ban-types
|
||||
resolve: Function,
|
||||
resolve: (
|
||||
value: Collection<string, Member> | PromiseLike<Collection<string, Member>>,
|
||||
) => void,
|
||||
options?: FetchMembersOptions,
|
||||
) {
|
||||
const nonce = `${guild.id}-${Date.now()}`;
|
||||
|
||||
Reference in New Issue
Block a user