mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-03 05:26:07 +00:00
Merge branch 'main' of https://github.com/yuzudev/biscuit into add-n128
This commit is contained in:
commit
fd15e1a5f4
@ -1,39 +1,78 @@
|
|||||||
import type { DiscordMessage, DiscordReady } from "../vendor/external.ts";
|
import type {
|
||||||
|
DiscordGuildMemberAdd,
|
||||||
|
DiscordGuildMemberRemove,
|
||||||
|
DiscordGuildMemberUpdate,
|
||||||
|
DiscordInteraction,
|
||||||
|
DiscordMessage,
|
||||||
|
DiscordMessageDelete,
|
||||||
|
DiscordReady,
|
||||||
|
} from "../vendor/external.ts";
|
||||||
import type { Snowflake } from "../util/Snowflake.ts";
|
import type { Snowflake } from "../util/Snowflake.ts";
|
||||||
import type { Session } from "../session/Session.ts";
|
import type { Session } from "../session/Session.ts";
|
||||||
|
import Member from "../structures/Member.ts";
|
||||||
import Message from "../structures/Message.ts";
|
import Message from "../structures/Message.ts";
|
||||||
|
import User from "../structures/User.ts";
|
||||||
|
import Interaction from "../structures/Interaction.ts";
|
||||||
|
|
||||||
export type RawHandler<T extends unknown[]> = (...args: [Session, number, ...T]) => void;
|
export type RawHandler<T> = (...args: [Session, number, T]) => void;
|
||||||
export type Handler<T extends unknown[]> = (...args: T) => unknown;
|
export type Handler<T extends unknown[]> = (...args: T) => unknown;
|
||||||
|
|
||||||
export type Ready = [DiscordReady];
|
export const READY: RawHandler<DiscordReady> = (session, shardId, payload) => {
|
||||||
export const READY: RawHandler<Ready> = (session, shardId, payload) => {
|
session.applicationId = payload.application.id;
|
||||||
session.emit("ready", payload, shardId);
|
session.botId = payload.user.id;
|
||||||
|
session.emit("ready", { ...payload, user: new User(session, payload.user) }, shardId);
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MessageCreate = [DiscordMessage];
|
export const MESSAGE_CREATE: RawHandler<DiscordMessage> = (session, _shardId, message) => {
|
||||||
export const MESSAGE_CREATE: RawHandler<MessageCreate> = (session, _shardId, message) => {
|
|
||||||
session.emit("messageCreate", new Message(session, message));
|
session.emit("messageCreate", new Message(session, message));
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MessageUpdate = [DiscordMessage];
|
export const MESSAGE_UPDATE: RawHandler<DiscordMessage> = (session, _shardId, new_message) => {
|
||||||
export const MESSAGE_UPDATE: RawHandler<MessageUpdate> = (session, _shardId, new_message) => {
|
|
||||||
session.emit("messageUpdate", new Message(session, new_message));
|
session.emit("messageUpdate", new Message(session, new_message));
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MessageDelete = [Snowflake];
|
export const MESSAGE_DELETE: RawHandler<DiscordMessageDelete> = (session, _shardId, { id, channel_id, guild_id }) => {
|
||||||
export const MESSAGE_DELETE: RawHandler<MessageDelete> = (session, _shardId, deleted_message_id) => {
|
session.emit("messageDelete", { id, channelId: channel_id, guildId: guild_id });
|
||||||
session.emit("messageDelete", deleted_message_id);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const raw: RawHandler<[unknown]> = (session, shardId, data) => {
|
export const GUILD_MEMBER_ADD: RawHandler<DiscordGuildMemberAdd> = (session, _shardId, member) => {
|
||||||
|
session.emit("guildMemberAdd", new Member(session, member, member.guild_id));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GUILD_MEMBER_UPDATE: RawHandler<DiscordGuildMemberUpdate> = (session, _shardId, member) => {
|
||||||
|
session.emit("guildMemberUpdate", new Member(session, member, member.guild_id));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GUILD_MEMBER_REMOVE: RawHandler<DiscordGuildMemberRemove> = (session, _shardId, member) => {
|
||||||
|
session.emit("guildMemberRemove", new User(session, member.user), member.guild_id);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const INTERACTION_CREATE: RawHandler<DiscordInteraction> = (session, _shardId, interaction) => {
|
||||||
|
session.unrepliedInteractions.add(BigInt(interaction.id));
|
||||||
|
|
||||||
|
// could be improved
|
||||||
|
setTimeout(() => session.unrepliedInteractions.delete(BigInt(interaction.id)), 15 * 60 * 1000);
|
||||||
|
|
||||||
|
session.emit("interactionCreate", new Interaction(session, interaction));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const raw: RawHandler<unknown> = (session, shardId, data) => {
|
||||||
session.emit("raw", data, shardId);
|
session.emit("raw", data, shardId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export interface Ready extends Omit<DiscordReady, "user"> {
|
||||||
|
user: User;
|
||||||
|
}
|
||||||
|
|
||||||
|
// deno-fmt-ignore-file
|
||||||
export interface Events {
|
export interface Events {
|
||||||
"ready": Handler<[DiscordReady, number]>;
|
"ready": Handler<[Ready, number]>;
|
||||||
"messageCreate": Handler<[Message]>;
|
"messageCreate": Handler<[Message]>;
|
||||||
"messageUpdate": Handler<[Message]>;
|
"messageUpdate": Handler<[Message]>;
|
||||||
"messageDelete": Handler<[Snowflake]>;
|
"messageDelete": Handler<[{ id: Snowflake, channelId: Snowflake, guildId?: Snowflake }]>;
|
||||||
"raw": Handler<[unknown]>;
|
"guildMemberAdd": Handler<[Member]>;
|
||||||
|
"guildMemberUpdate": Handler<[Member]>;
|
||||||
|
"guildMemberRemove": Handler<[User, Snowflake]>;
|
||||||
|
"interactionCreate": Handler<[Interaction]>;
|
||||||
|
"raw": Handler<[unknown, number]>;
|
||||||
}
|
}
|
||||||
|
5
mod.ts
5
mod.ts
@ -2,12 +2,15 @@ export * from "./structures/AnonymousGuild.ts";
|
|||||||
export * from "./structures/Attachment.ts";
|
export * from "./structures/Attachment.ts";
|
||||||
export * from "./structures/Base.ts";
|
export * from "./structures/Base.ts";
|
||||||
export * from "./structures/BaseGuild.ts";
|
export * from "./structures/BaseGuild.ts";
|
||||||
export * from "./structures/Channel.ts";
|
export * from "./structures/BaseChannel.ts";
|
||||||
|
export * from "./structures/Component.ts";
|
||||||
export * from "./structures/DMChannel.ts";
|
export * from "./structures/DMChannel.ts";
|
||||||
|
export * from "./structures/Embed.ts";
|
||||||
export * from "./structures/Emoji.ts";
|
export * from "./structures/Emoji.ts";
|
||||||
export * from "./structures/Guild.ts";
|
export * from "./structures/Guild.ts";
|
||||||
export * from "./structures/GuildChannel.ts";
|
export * from "./structures/GuildChannel.ts";
|
||||||
export * from "./structures/GuildEmoji.ts";
|
export * from "./structures/GuildEmoji.ts";
|
||||||
|
export * from "./structures/Interaction.ts";
|
||||||
export * from "./structures/Invite.ts";
|
export * from "./structures/Invite.ts";
|
||||||
export * from "./structures/InviteGuild.ts";
|
export * from "./structures/InviteGuild.ts";
|
||||||
export * from "./structures/Member.ts";
|
export * from "./structures/Member.ts";
|
||||||
|
@ -4,7 +4,7 @@ import type { Events } from "../handlers/Actions.ts";
|
|||||||
|
|
||||||
import { Snowflake } from "../util/Snowflake.ts";
|
import { Snowflake } from "../util/Snowflake.ts";
|
||||||
import { EventEmitter } from "../util/EventEmmiter.ts";
|
import { EventEmitter } from "../util/EventEmmiter.ts";
|
||||||
import { createGatewayManager, createRestManager } from "../vendor/external.ts";
|
import { createGatewayManager, createRestManager, getBotIdFromToken } from "../vendor/external.ts";
|
||||||
|
|
||||||
import * as Routes from "../util/Routes.ts";
|
import * as Routes from "../util/Routes.ts";
|
||||||
import * as Actions from "../handlers/Actions.ts";
|
import * as Actions from "../handlers/Actions.ts";
|
||||||
@ -39,6 +39,27 @@ export class Session extends EventEmitter {
|
|||||||
rest: ReturnType<typeof createRestManager>;
|
rest: ReturnType<typeof createRestManager>;
|
||||||
gateway: ReturnType<typeof createGatewayManager>;
|
gateway: ReturnType<typeof createGatewayManager>;
|
||||||
|
|
||||||
|
unrepliedInteractions: Set<bigint> = new Set();
|
||||||
|
|
||||||
|
#botId: Snowflake;
|
||||||
|
#applicationId?: Snowflake;
|
||||||
|
|
||||||
|
set applicationId(id: Snowflake) {
|
||||||
|
this.#applicationId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
get applicationId() {
|
||||||
|
return this.#applicationId!;
|
||||||
|
}
|
||||||
|
|
||||||
|
set botId(id: Snowflake) {
|
||||||
|
this.#botId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
get botId() {
|
||||||
|
return this.#botId;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(options: SessionOptions) {
|
constructor(options: SessionOptions) {
|
||||||
super();
|
super();
|
||||||
this.options = options;
|
this.options = options;
|
||||||
@ -71,7 +92,8 @@ export class Session extends EventEmitter {
|
|||||||
},
|
},
|
||||||
handleDiscordPayload: this.options.rawHandler ?? defHandler,
|
handleDiscordPayload: this.options.rawHandler ?? defHandler,
|
||||||
});
|
});
|
||||||
// TODO: set botId in Session.botId or something
|
|
||||||
|
this.#botId = getBotIdFromToken(options.token).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
override on<K extends keyof Events>(event: K, func: Events[K]): this;
|
override on<K extends keyof Events>(event: K, func: Events[K]): this;
|
||||||
@ -89,6 +111,11 @@ export class Session extends EventEmitter {
|
|||||||
return super.once(event, func);
|
return super.once(event, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override emit<K extends keyof Events>(event: K, ...params: Parameters<Events[K]>): boolean;
|
||||||
|
override emit<K extends string>(event: K, ...params: unknown[]): boolean {
|
||||||
|
return super.emit(event, ...params);
|
||||||
|
}
|
||||||
|
|
||||||
async start() {
|
async start() {
|
||||||
const getGatewayBot = () => this.rest.runMethod<DiscordGetGatewayBot>(this.rest, "GET", Routes.GATEWAY_BOT());
|
const getGatewayBot = () => this.rest.runMethod<DiscordGetGatewayBot>(this.rest, "GET", Routes.GATEWAY_BOT());
|
||||||
|
|
||||||
|
49
structures/BaseChannel.ts
Normal file
49
structures/BaseChannel.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import type { Model } from "./Base.ts";
|
||||||
|
import type { Snowflake } from "../util/Snowflake.ts";
|
||||||
|
import type { Session } from "../session/Session.ts";
|
||||||
|
import type { ChannelTypes, DiscordChannel } from "../vendor/external.ts";
|
||||||
|
import TextChannel from "./TextChannel.ts";
|
||||||
|
import VoiceChannel from "./VoiceChannel.ts";
|
||||||
|
import DMChannel from "./DMChannel.ts";
|
||||||
|
import NewsChannel from "./NewsChannel.ts";
|
||||||
|
import ThreadChannel from "./ThreadChannel.ts";
|
||||||
|
|
||||||
|
export abstract class BaseChannel implements Model {
|
||||||
|
constructor(session: Session, data: DiscordChannel) {
|
||||||
|
this.id = data.id;
|
||||||
|
this.session = session;
|
||||||
|
this.name = data.name;
|
||||||
|
this.type = data.type;
|
||||||
|
}
|
||||||
|
readonly id: Snowflake;
|
||||||
|
readonly session: Session;
|
||||||
|
|
||||||
|
name?: string;
|
||||||
|
type: ChannelTypes;
|
||||||
|
|
||||||
|
isText(): this is TextChannel {
|
||||||
|
return this instanceof TextChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
isVoice(): this is VoiceChannel {
|
||||||
|
return this instanceof VoiceChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
isDM(): this is DMChannel {
|
||||||
|
return this instanceof DMChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
isNews(): this is NewsChannel {
|
||||||
|
return this instanceof NewsChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
isThread(): this is ThreadChannel {
|
||||||
|
return this instanceof ThreadChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
toString(): string {
|
||||||
|
return `<#${this.id}>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BaseChannel;
|
@ -1,24 +0,0 @@
|
|||||||
import type { Model } from "./Base.ts";
|
|
||||||
import type { Snowflake } from "../util/Snowflake.ts";
|
|
||||||
import type { Session } from "../session/Session.ts";
|
|
||||||
import type { ChannelTypes, DiscordChannel } from "../vendor/external.ts";
|
|
||||||
|
|
||||||
export abstract class Channel implements Model {
|
|
||||||
constructor(session: Session, data: DiscordChannel) {
|
|
||||||
this.id = data.id;
|
|
||||||
this.session = session;
|
|
||||||
this.name = data.name;
|
|
||||||
this.type = data.type;
|
|
||||||
}
|
|
||||||
readonly id: Snowflake;
|
|
||||||
readonly session: Session;
|
|
||||||
|
|
||||||
name?: string;
|
|
||||||
type: ChannelTypes;
|
|
||||||
|
|
||||||
toString(): string {
|
|
||||||
return `<#${this.id}>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Channel;
|
|
41
structures/Component.ts
Normal file
41
structures/Component.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import type { Session } from "../session/Session.ts";
|
||||||
|
import type { DiscordComponent, MessageComponentTypes } from "../vendor/external.ts";
|
||||||
|
import Emoji from "./Emoji.ts";
|
||||||
|
|
||||||
|
export class Component {
|
||||||
|
constructor(session: Session, data: DiscordComponent) {
|
||||||
|
this.session = session;
|
||||||
|
this.customId = data.custom_id;
|
||||||
|
this.type = data.type;
|
||||||
|
this.components = data.components?.map((component) => new Component(session, component));
|
||||||
|
this.disabled = !!data.disabled;
|
||||||
|
|
||||||
|
if (data.emoji) {
|
||||||
|
this.emoji = new Emoji(session, data.emoji);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.maxValues = data.max_values;
|
||||||
|
this.minValues = data.min_values;
|
||||||
|
this.label = data.label;
|
||||||
|
this.value = data.value;
|
||||||
|
this.options = data.options ?? [];
|
||||||
|
this.placeholder = data.placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly session: Session;
|
||||||
|
|
||||||
|
customId?: string;
|
||||||
|
type: MessageComponentTypes;
|
||||||
|
components?: Component[];
|
||||||
|
disabled: boolean;
|
||||||
|
emoji?: Emoji;
|
||||||
|
maxValues?: number;
|
||||||
|
minValues?: number;
|
||||||
|
label?: string;
|
||||||
|
value?: string;
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
options: any[];
|
||||||
|
placeholder?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Component;
|
@ -1,16 +1,23 @@
|
|||||||
|
import type { Model } from "./Base.ts";
|
||||||
import type { Snowflake } from "../util/Snowflake.ts";
|
import type { Snowflake } from "../util/Snowflake.ts";
|
||||||
import type { Session } from "../session/Session.ts";
|
import type { Session } from "../session/Session.ts";
|
||||||
import type { DiscordChannel } from "../vendor/external.ts";
|
import type { DiscordChannel } from "../vendor/external.ts";
|
||||||
import Channel from "./Channel.ts";
|
import BaseChannel from "./BaseChannel.ts";
|
||||||
|
import User from "./User.ts";
|
||||||
import * as Routes from "../util/Routes.ts";
|
import * as Routes from "../util/Routes.ts";
|
||||||
|
|
||||||
export class DMChannel extends Channel {
|
export class DMChannel extends BaseChannel implements Model {
|
||||||
constructor(session: Session, data: DiscordChannel) {
|
constructor(session: Session, data: DiscordChannel) {
|
||||||
super(session, data);
|
super(session, data);
|
||||||
data.last_message_id ? this.lastMessageId = data.last_message_id : undefined;
|
|
||||||
// Waiting for implementation of botId in session
|
this.user = new User(this.session, data.recipents!.find((r) => r.id !== this.session.botId)!);
|
||||||
//this.user = new User(this.session, data.recipents!.find((r) => r.id !== this.session.botId));
|
|
||||||
|
if (data.last_message_id) {
|
||||||
|
this.lastMessageId = data.last_message_id;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user: User;
|
||||||
lastMessageId?: Snowflake;
|
lastMessageId?: Snowflake;
|
||||||
|
|
||||||
async close() {
|
async close() {
|
||||||
|
101
structures/Embed.ts
Normal file
101
structures/Embed.ts
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import type { DiscordEmbed, EmbedTypes } from "../vendor/external.ts";
|
||||||
|
|
||||||
|
export interface Embed {
|
||||||
|
title?: string;
|
||||||
|
timestamp?: string;
|
||||||
|
type?: EmbedTypes;
|
||||||
|
url?: string;
|
||||||
|
color?: number;
|
||||||
|
description?: string;
|
||||||
|
author?: {
|
||||||
|
name: string;
|
||||||
|
iconURL?: string;
|
||||||
|
proxyIconURL?: string;
|
||||||
|
url?: string;
|
||||||
|
};
|
||||||
|
footer?: {
|
||||||
|
text: string;
|
||||||
|
iconURL?: string;
|
||||||
|
proxyIconURL?: string;
|
||||||
|
};
|
||||||
|
fields?: Array<{
|
||||||
|
name: string;
|
||||||
|
value: string;
|
||||||
|
inline?: boolean;
|
||||||
|
}>;
|
||||||
|
thumbnail?: {
|
||||||
|
url: string;
|
||||||
|
proxyURL?: string;
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
|
};
|
||||||
|
video?: {
|
||||||
|
url?: string;
|
||||||
|
proxyURL?: string;
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
|
};
|
||||||
|
image?: {
|
||||||
|
url: string;
|
||||||
|
proxyURL?: string;
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
|
};
|
||||||
|
provider?: {
|
||||||
|
url?: string;
|
||||||
|
name?: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function embed(data: Embed): DiscordEmbed {
|
||||||
|
return {
|
||||||
|
title: data.title,
|
||||||
|
timestamp: data.timestamp,
|
||||||
|
type: data.type,
|
||||||
|
url: data.url,
|
||||||
|
color: data.color,
|
||||||
|
description: data.description,
|
||||||
|
author: {
|
||||||
|
name: data.author?.name!,
|
||||||
|
url: data.author?.url,
|
||||||
|
icon_url: data.author?.iconURL,
|
||||||
|
proxy_icon_url: data.author?.proxyIconURL,
|
||||||
|
},
|
||||||
|
footer: data.footer || {
|
||||||
|
text: data.footer!.text,
|
||||||
|
icon_url: data.footer!.iconURL,
|
||||||
|
proxy_icon_url: data.footer!.proxyIconURL,
|
||||||
|
},
|
||||||
|
fields: data.fields?.map((f) => {
|
||||||
|
return {
|
||||||
|
name: f.name,
|
||||||
|
value: f.value,
|
||||||
|
inline: f.inline,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
thumbnail: data.thumbnail || {
|
||||||
|
url: data.thumbnail!.url,
|
||||||
|
proxy_url: data.thumbnail!.proxyURL,
|
||||||
|
width: data.thumbnail!.width,
|
||||||
|
height: data.thumbnail!.height,
|
||||||
|
},
|
||||||
|
video: {
|
||||||
|
url: data.video?.url,
|
||||||
|
proxy_url: data.video?.proxyURL,
|
||||||
|
width: data.video?.width,
|
||||||
|
height: data.video?.height,
|
||||||
|
},
|
||||||
|
image: data.image || {
|
||||||
|
url: data.image!.url,
|
||||||
|
proxy_url: data.image!.proxyURL,
|
||||||
|
width: data.image!.width,
|
||||||
|
height: data.image!.height,
|
||||||
|
},
|
||||||
|
provider: {
|
||||||
|
url: data.provider?.url,
|
||||||
|
name: data.provider?.name,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Embed;
|
@ -1,7 +1,13 @@
|
|||||||
import type { Model } from "./Base.ts";
|
import type { Model } from "./Base.ts";
|
||||||
import type { Snowflake } from "../util/Snowflake.ts";
|
import type { Snowflake } from "../util/Snowflake.ts";
|
||||||
import type { Session } from "../session/Session.ts";
|
import type { Session } from "../session/Session.ts";
|
||||||
import type { DiscordEmoji, DiscordGuild, DiscordInviteMetadata, DiscordRole } from "../vendor/external.ts";
|
import type {
|
||||||
|
DiscordEmoji,
|
||||||
|
DiscordGuild,
|
||||||
|
DiscordInviteMetadata,
|
||||||
|
DiscordMemberWithUser,
|
||||||
|
DiscordRole,
|
||||||
|
} from "../vendor/external.ts";
|
||||||
import type { GetInvite } from "../util/Routes.ts";
|
import type { GetInvite } from "../util/Routes.ts";
|
||||||
import {
|
import {
|
||||||
DefaultMessageNotificationLevels,
|
DefaultMessageNotificationLevels,
|
||||||
@ -46,6 +52,40 @@ export interface ModifyGuildEmoji {
|
|||||||
roles?: Snowflake[];
|
roles?: Snowflake[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://discord.com/developers/docs/resources/guild#create-guild-ban
|
||||||
|
*/
|
||||||
|
export interface CreateGuildBan {
|
||||||
|
deleteMessageDays?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
||||||
|
reason?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://discord.com/developers/docs/resources/guild#modify-guild-member
|
||||||
|
*/
|
||||||
|
export interface ModifyGuildMember {
|
||||||
|
nick?: string;
|
||||||
|
roles?: Snowflake[];
|
||||||
|
mute?: boolean;
|
||||||
|
deaf?: boolean;
|
||||||
|
channelId?: Snowflake;
|
||||||
|
communicationDisabledUntil?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://discord.com/developers/docs/resources/guild#begin-guild-prune
|
||||||
|
*/
|
||||||
|
export interface BeginGuildPrune {
|
||||||
|
days?: number;
|
||||||
|
computePruneCount?: boolean;
|
||||||
|
includeRoles?: Snowflake[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ModifyRolePositions {
|
||||||
|
id: Snowflake;
|
||||||
|
position?: number | null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a guild
|
* Represents a guild
|
||||||
* @link https://discord.com/developers/docs/resources/guild#guild-object
|
* @link https://discord.com/developers/docs/resources/guild#guild-object
|
||||||
@ -62,7 +102,8 @@ export class Guild extends BaseGuild implements Model {
|
|||||||
this.vefificationLevel = data.verification_level;
|
this.vefificationLevel = data.verification_level;
|
||||||
this.defaultMessageNotificationLevel = data.default_message_notifications;
|
this.defaultMessageNotificationLevel = data.default_message_notifications;
|
||||||
this.explicitContentFilterLevel = data.explicit_content_filter;
|
this.explicitContentFilterLevel = data.explicit_content_filter;
|
||||||
this.members = data.members?.map((member) => new Member(session, { ...member, user: member.user! })) ?? [];
|
this.members = data.members?.map((member) => new Member(session, { ...member, user: member.user! }, data.id)) ??
|
||||||
|
[];
|
||||||
this.roles = data.roles.map((role) => new Role(session, role, data.id));
|
this.roles = data.roles.map((role) => new Role(session, role, data.id));
|
||||||
this.emojis = data.emojis.map((guildEmoji) => new GuildEmoji(session, guildEmoji, data.id));
|
this.emojis = data.emojis.map((guildEmoji) => new GuildEmoji(session, guildEmoji, data.id));
|
||||||
}
|
}
|
||||||
@ -79,6 +120,20 @@ export class Guild extends BaseGuild implements Model {
|
|||||||
roles: Role[];
|
roles: Role[];
|
||||||
emojis: GuildEmoji[];
|
emojis: GuildEmoji[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 'null' would reset the nickname
|
||||||
|
*/
|
||||||
|
async editBotNickname(options: { nick: string | null; reason?: string }) {
|
||||||
|
const result = await this.session.rest.runMethod<{ nick?: string } | undefined>(
|
||||||
|
this.session.rest,
|
||||||
|
"PATCH",
|
||||||
|
Routes.USER_NICK(this.id),
|
||||||
|
options,
|
||||||
|
);
|
||||||
|
|
||||||
|
return result?.nick;
|
||||||
|
}
|
||||||
|
|
||||||
async createEmoji(options: CreateGuildEmoji): Promise<GuildEmoji> {
|
async createEmoji(options: CreateGuildEmoji): Promise<GuildEmoji> {
|
||||||
if (options.image && !options.image.startsWith("data:image/")) {
|
if (options.image && !options.image.startsWith("data:image/")) {
|
||||||
options.image = await urlToBase64(options.image);
|
options.image = await urlToBase64(options.image);
|
||||||
@ -162,6 +217,40 @@ export class Guild extends BaseGuild implements Model {
|
|||||||
return new Role(this.session, role, this.id);
|
return new Role(this.session, role, this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async addRole(memberId: Snowflake, roleId: Snowflake, { reason }: { reason?: string } = {}) {
|
||||||
|
await this.session.rest.runMethod<undefined>(
|
||||||
|
this.session.rest,
|
||||||
|
"PUT",
|
||||||
|
Routes.GUILD_MEMBER_ROLE(this.id, memberId, roleId),
|
||||||
|
{ reason },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeRole(memberId: Snowflake, roleId: Snowflake, { reason }: { reason?: string } = {}) {
|
||||||
|
await this.session.rest.runMethod<undefined>(
|
||||||
|
this.session.rest,
|
||||||
|
"DELETE",
|
||||||
|
Routes.GUILD_MEMBER_ROLE(this.id, memberId, roleId),
|
||||||
|
{ reason },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the roles moved
|
||||||
|
* */
|
||||||
|
async moveRoles(options: ModifyRolePositions[]) {
|
||||||
|
const roles = await this.session.rest.runMethod<DiscordRole[]>(
|
||||||
|
this.session.rest,
|
||||||
|
"PATCH",
|
||||||
|
Routes.GUILD_ROLES(this.id),
|
||||||
|
options,
|
||||||
|
);
|
||||||
|
|
||||||
|
return roles.map((role) => new Role(this.session, role, this.id));
|
||||||
|
}
|
||||||
|
|
||||||
async deleteInvite(inviteCode: string): Promise<void> {
|
async deleteInvite(inviteCode: string): Promise<void> {
|
||||||
await this.session.rest.runMethod<undefined>(
|
await this.session.rest.runMethod<undefined>(
|
||||||
this.session.rest,
|
this.session.rest,
|
||||||
@ -190,6 +279,91 @@ export class Guild extends BaseGuild implements Model {
|
|||||||
|
|
||||||
return invites.map((invite) => new Invite(this.session, invite));
|
return invites.map((invite) => new Invite(this.session, invite));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bans the member
|
||||||
|
*/
|
||||||
|
async banMember(memberId: Snowflake, options: CreateGuildBan) {
|
||||||
|
await this.session.rest.runMethod<undefined>(
|
||||||
|
this.session.rest,
|
||||||
|
"PUT",
|
||||||
|
Routes.GUILD_BAN(this.id, memberId),
|
||||||
|
options
|
||||||
|
? {
|
||||||
|
delete_message_days: options.deleteMessageDays,
|
||||||
|
reason: options.reason,
|
||||||
|
}
|
||||||
|
: {},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kicks the member
|
||||||
|
*/
|
||||||
|
async kickMember(memberId: Snowflake, { reason }: { reason?: string }) {
|
||||||
|
await this.session.rest.runMethod<undefined>(
|
||||||
|
this.session.rest,
|
||||||
|
"DELETE",
|
||||||
|
Routes.GUILD_MEMBER(this.id, memberId),
|
||||||
|
{ reason },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unbans the member
|
||||||
|
* */
|
||||||
|
async unbanMember(memberId: Snowflake) {
|
||||||
|
await this.session.rest.runMethod<undefined>(
|
||||||
|
this.session.rest,
|
||||||
|
"DELETE",
|
||||||
|
Routes.GUILD_BAN(this.id, memberId),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async editMember(memberId: Snowflake, options: ModifyGuildMember) {
|
||||||
|
const member = await this.session.rest.runMethod<DiscordMemberWithUser>(
|
||||||
|
this.session.rest,
|
||||||
|
"PATCH",
|
||||||
|
Routes.GUILD_MEMBER(this.id, memberId),
|
||||||
|
{
|
||||||
|
nick: options.nick,
|
||||||
|
roles: options.roles,
|
||||||
|
mute: options.mute,
|
||||||
|
deaf: options.deaf,
|
||||||
|
channel_id: options.channelId,
|
||||||
|
communication_disabled_until: options.communicationDisabledUntil
|
||||||
|
? new Date(options.communicationDisabledUntil).toISOString()
|
||||||
|
: undefined,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return new Member(this.session, member, this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
async pruneMembers(options: BeginGuildPrune): Promise<number> {
|
||||||
|
const result = await this.session.rest.runMethod<{ pruned: number }>(
|
||||||
|
this.session.rest,
|
||||||
|
"POST",
|
||||||
|
Routes.GUILD_PRUNE(this.id),
|
||||||
|
{
|
||||||
|
days: options.days,
|
||||||
|
compute_prune_count: options.computePruneCount,
|
||||||
|
include_roles: options.includeRoles,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return result.pruned;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getPruneCount(): Promise<number> {
|
||||||
|
const result = await this.session.rest.runMethod<{ pruned: number }>(
|
||||||
|
this.session.rest,
|
||||||
|
"GET",
|
||||||
|
Routes.GUILD_PRUNE(this.id),
|
||||||
|
);
|
||||||
|
|
||||||
|
return result.pruned;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Guild;
|
export default Guild;
|
||||||
|
@ -2,11 +2,11 @@ import type { Model } from "./Base.ts";
|
|||||||
import type { Snowflake } from "../util/Snowflake.ts";
|
import type { Snowflake } from "../util/Snowflake.ts";
|
||||||
import type { Session } from "../session/Session.ts";
|
import type { Session } from "../session/Session.ts";
|
||||||
import type { DiscordChannel, DiscordInviteMetadata } from "../vendor/external.ts";
|
import type { DiscordChannel, DiscordInviteMetadata } from "../vendor/external.ts";
|
||||||
import Channel from "./Channel.ts";
|
import BaseChannel from "./BaseChannel.ts";
|
||||||
import Invite from "./Invite.ts";
|
import Invite from "./Invite.ts";
|
||||||
import * as Routes from "../util/Routes.ts";
|
import * as Routes from "../util/Routes.ts";
|
||||||
|
|
||||||
export abstract class GuildChannel extends Channel implements Model {
|
export abstract class GuildChannel extends BaseChannel implements Model {
|
||||||
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
|
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
|
||||||
super(session, data);
|
super(session, data);
|
||||||
this.guildId = guildId;
|
this.guildId = guildId;
|
||||||
|
143
structures/Interaction.ts
Normal file
143
structures/Interaction.ts
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
import type { Model } from "./Base.ts";
|
||||||
|
import type { Snowflake } from "../util/Snowflake.ts";
|
||||||
|
import type { Session } from "../session/Session.ts";
|
||||||
|
import type {
|
||||||
|
DiscordInteraction,
|
||||||
|
DiscordMessage,
|
||||||
|
FileContent,
|
||||||
|
InteractionResponseTypes,
|
||||||
|
InteractionTypes,
|
||||||
|
} from "../vendor/external.ts";
|
||||||
|
import type { MessageFlags } from "../util/shared/flags.ts";
|
||||||
|
import type { AllowedMentions } from "./Message.ts";
|
||||||
|
import User from "./User.ts";
|
||||||
|
import Message from "./Message.ts";
|
||||||
|
import Member from "./Member.ts";
|
||||||
|
import * as Routes from "../util/Routes.ts";
|
||||||
|
|
||||||
|
export interface InteractionResponse {
|
||||||
|
type: InteractionResponseTypes;
|
||||||
|
data?: InteractionApplicationCommandCallbackData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InteractionApplicationCommandCallbackData {
|
||||||
|
content?: string;
|
||||||
|
tts?: boolean;
|
||||||
|
allowedMentions?: AllowedMentions;
|
||||||
|
files?: FileContent[];
|
||||||
|
customId?: string;
|
||||||
|
title?: string;
|
||||||
|
// components?: Component[];
|
||||||
|
flags?: MessageFlags;
|
||||||
|
choices?: ApplicationCommandOptionChoice[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptionchoice */
|
||||||
|
export interface ApplicationCommandOptionChoice {
|
||||||
|
name: string;
|
||||||
|
value: string | number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Interaction implements Model {
|
||||||
|
constructor(session: Session, data: DiscordInteraction) {
|
||||||
|
this.session = session;
|
||||||
|
this.id = data.id;
|
||||||
|
this.token = data.token;
|
||||||
|
this.type = data.type;
|
||||||
|
this.guildId = data.guild_id;
|
||||||
|
this.channelId = data.channel_id;
|
||||||
|
this.applicationId = data.application_id;
|
||||||
|
this.locale = data.locale;
|
||||||
|
this.data = data.data;
|
||||||
|
|
||||||
|
if (!data.guild_id) {
|
||||||
|
this.user = new User(session, data.user!);
|
||||||
|
} else {
|
||||||
|
this.member = new Member(session, data.member!, data.guild_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly session: Session;
|
||||||
|
readonly id: Snowflake;
|
||||||
|
readonly token: string;
|
||||||
|
|
||||||
|
type: InteractionTypes;
|
||||||
|
guildId?: Snowflake;
|
||||||
|
channelId?: Snowflake;
|
||||||
|
applicationId?: Snowflake;
|
||||||
|
locale?: string;
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
data: any;
|
||||||
|
user?: User;
|
||||||
|
member?: Member;
|
||||||
|
|
||||||
|
async respond({ type, data }: InteractionResponse) {
|
||||||
|
const toSend = {
|
||||||
|
tts: data?.tts,
|
||||||
|
title: data?.title,
|
||||||
|
flags: data?.flags,
|
||||||
|
content: data?.content,
|
||||||
|
choices: data?.choices,
|
||||||
|
custom_id: data?.customId,
|
||||||
|
allowed_mentions: data?.allowedMentions
|
||||||
|
? {
|
||||||
|
users: data.allowedMentions.users,
|
||||||
|
roles: data.allowedMentions.roles,
|
||||||
|
parse: data.allowedMentions.parse,
|
||||||
|
replied_user: data.allowedMentions.repliedUser,
|
||||||
|
}
|
||||||
|
: { parse: [] },
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.session.unrepliedInteractions.delete(BigInt(this.id))) {
|
||||||
|
await this.session.rest.sendRequest<undefined>(
|
||||||
|
this.session.rest,
|
||||||
|
{
|
||||||
|
url: Routes.INTERACTION_ID_TOKEN(this.id, this.token),
|
||||||
|
method: "POST",
|
||||||
|
payload: this.session.rest.createRequestBody(this.session.rest, {
|
||||||
|
method: "POST",
|
||||||
|
body: {
|
||||||
|
type: type,
|
||||||
|
data: toSend,
|
||||||
|
file: data?.files,
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
// remove authorization header
|
||||||
|
Authorization: "",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await this.session.rest.sendRequest<DiscordMessage>(
|
||||||
|
this.session.rest,
|
||||||
|
{
|
||||||
|
url: Routes.WEBHOOK(this.session.applicationId ?? this.session.botId, this.token),
|
||||||
|
method: "POST",
|
||||||
|
payload: this.session.rest.createRequestBody(this.session.rest, {
|
||||||
|
method: "POST",
|
||||||
|
body: {
|
||||||
|
...toSend,
|
||||||
|
file: data?.files,
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
// remove authorization header
|
||||||
|
Authorization: "",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return new Message(this.session, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inGuild(): this is Interaction & { user: undefined; guildId: Snowflake; member: Member } {
|
||||||
|
return !!this.guildId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Interaction;
|
@ -1,31 +1,24 @@
|
|||||||
import type { Model } from "./Base.ts";
|
import type { Model } from "./Base.ts";
|
||||||
import type { Snowflake } from "../util/Snowflake.ts";
|
import type { Snowflake } from "../util/Snowflake.ts";
|
||||||
import type { Session } from "../session/Session.ts";
|
import type { Session } from "../session/Session.ts";
|
||||||
import type { DiscordMember, MakeRequired } from "../vendor/external.ts";
|
import type { DiscordMemberWithUser } from "../vendor/external.ts";
|
||||||
import type { ImageFormat, ImageSize } from "../util/shared/images.ts";
|
import type { ImageFormat, ImageSize } from "../util/shared/images.ts";
|
||||||
|
import type { CreateGuildBan, ModifyGuildMember } from "./Guild.ts";
|
||||||
import { iconBigintToHash, iconHashToBigInt } from "../util/hash.ts";
|
import { iconBigintToHash, iconHashToBigInt } from "../util/hash.ts";
|
||||||
import User from "./User.ts";
|
import User from "./User.ts";
|
||||||
|
import Guild from "./Guild.ts";
|
||||||
import * as Routes from "../util/Routes.ts";
|
import * as Routes from "../util/Routes.ts";
|
||||||
|
|
||||||
/**
|
|
||||||
* @link https://discord.com/developers/docs/resources/guild#create-guild-ban
|
|
||||||
*/
|
|
||||||
export interface CreateGuildBan {
|
|
||||||
/** Number of days to delete messages for (0-7) */
|
|
||||||
deleteMessageDays?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
|
||||||
/** Reason for the ban */
|
|
||||||
reason?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a guild member
|
* Represents a guild member
|
||||||
* TODO: add a `guild` property somehow
|
* TODO: add a `guild` property somehow
|
||||||
* @link https://discord.com/developers/docs/resources/guild#guild-member-object
|
* @link https://discord.com/developers/docs/resources/guild#guild-member-object
|
||||||
*/
|
*/
|
||||||
export class Member implements Model {
|
export class Member implements Model {
|
||||||
constructor(session: Session, data: MakeRequired<DiscordMember, "user">) {
|
constructor(session: Session, data: DiscordMemberWithUser, guildId: Snowflake) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.user = new User(session, data.user);
|
this.user = new User(session, data.user);
|
||||||
|
this.guildId = guildId;
|
||||||
this.avatarHash = data.avatar ? iconHashToBigInt(data.avatar) : undefined;
|
this.avatarHash = data.avatar ? iconHashToBigInt(data.avatar) : undefined;
|
||||||
this.nickname = data.nick ? data.nick : undefined;
|
this.nickname = data.nick ? data.nick : undefined;
|
||||||
this.joinedTimestamp = Number.parseInt(data.joined_at);
|
this.joinedTimestamp = Number.parseInt(data.joined_at);
|
||||||
@ -39,8 +32,8 @@ export class Member implements Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly session: Session;
|
readonly session: Session;
|
||||||
|
|
||||||
user: User;
|
user: User;
|
||||||
|
guildId: Snowflake;
|
||||||
avatarHash?: bigint;
|
avatarHash?: bigint;
|
||||||
nickname?: string;
|
nickname?: string;
|
||||||
joinedTimestamp: number;
|
joinedTimestamp: number;
|
||||||
@ -63,39 +56,40 @@ export class Member implements Model {
|
|||||||
return new Date(this.joinedTimestamp);
|
return new Date(this.joinedTimestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
async ban(options: CreateGuildBan): Promise<Member> {
|
||||||
* Bans the member
|
await Guild.prototype.banMember.call({ id: this.guildId, session: this.session }, this.user.id, options);
|
||||||
*/
|
|
||||||
async ban(guildId: Snowflake, options: CreateGuildBan): Promise<Member> {
|
|
||||||
await this.session.rest.runMethod<undefined>(
|
|
||||||
this.session.rest,
|
|
||||||
"PUT",
|
|
||||||
Routes.GUILD_BAN(guildId, this.id),
|
|
||||||
options
|
|
||||||
? {
|
|
||||||
delete_message_days: options.deleteMessageDays,
|
|
||||||
reason: options.reason,
|
|
||||||
}
|
|
||||||
: {},
|
|
||||||
);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
async kick(options: { reason?: string }): Promise<Member> {
|
||||||
* Kicks the member
|
await Guild.prototype.kickMember.call({ id: this.guildId, session: this.session }, this.user.id, options);
|
||||||
*/
|
|
||||||
async kick(guildId: Snowflake, { reason }: { reason?: string }): Promise<Member> {
|
|
||||||
await this.session.rest.runMethod<undefined>(
|
|
||||||
this.session.rest,
|
|
||||||
"DELETE",
|
|
||||||
Routes.GUILD_MEMBER(guildId, this.id),
|
|
||||||
{ reason },
|
|
||||||
);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async unban() {
|
||||||
|
await Guild.prototype.unbanMember.call({ id: this.guildId, session: this.session }, this.user.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(options: ModifyGuildMember): Promise<Member> {
|
||||||
|
const member = await Guild.prototype.editMember.call(
|
||||||
|
{ id: this.guildId, session: this.session },
|
||||||
|
this.user.id,
|
||||||
|
options,
|
||||||
|
);
|
||||||
|
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
|
||||||
|
async addRole(roleId: Snowflake, options: { reason?: string } = {}) {
|
||||||
|
await Guild.prototype.addRole.call({ id: this.guildId, session: this.session }, this.user.id, roleId, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeRole(roleId: Snowflake, options: { reason?: string } = {}) {
|
||||||
|
await Guild.prototype.removeRole.call({ id: this.guildId, session: this.session }, this.user.id, roleId, options);
|
||||||
|
}
|
||||||
|
|
||||||
/** gets the user's avatar */
|
/** gets the user's avatar */
|
||||||
avatarUrl(options: { format?: ImageFormat; size?: ImageSize } = { size: 128 }) {
|
avatarUrl(options: { format?: ImageFormat; size?: ImageSize } = { size: 128 }) {
|
||||||
let url: string;
|
let url: string;
|
||||||
@ -103,7 +97,7 @@ export class Member implements Model {
|
|||||||
if (!this.avatarHash) {
|
if (!this.avatarHash) {
|
||||||
url = Routes.USER_DEFAULT_AVATAR(Number(this.user.discriminator) % 5);
|
url = Routes.USER_DEFAULT_AVATAR(Number(this.user.discriminator) % 5);
|
||||||
} else {
|
} else {
|
||||||
url = Routes.USER_AVATAR(this.id, iconBigintToHash(this.avatarHash));
|
url = Routes.USER_AVATAR(this.user.id, iconBigintToHash(this.avatarHash));
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${url}.${options.format ?? (url.includes("/a_") ? "gif" : "jpg")}?size=${options.size}`;
|
return `${url}.${options.format ?? (url.includes("/a_") ? "gif" : "jpg")}?size=${options.size}`;
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
import type { Model } from "./Base.ts";
|
import type { Model } from "./Base.ts";
|
||||||
import type { Snowflake } from "../util/Snowflake.ts";
|
import type { Snowflake } from "../util/Snowflake.ts";
|
||||||
import type { Session } from "../session/Session.ts";
|
import type { Session } from "../session/Session.ts";
|
||||||
import type { AllowedMentionsTypes, DiscordMessage, FileContent } from "../vendor/external.ts";
|
import type {
|
||||||
|
AllowedMentionsTypes,
|
||||||
|
DiscordEmbed,
|
||||||
|
DiscordMessage,
|
||||||
|
DiscordUser,
|
||||||
|
FileContent,
|
||||||
|
} from "../vendor/external.ts";
|
||||||
|
import type { GetReactions } from "../util/Routes.ts";
|
||||||
import { MessageFlags } from "../util/shared/flags.ts";
|
import { MessageFlags } from "../util/shared/flags.ts";
|
||||||
import User from "./User.ts";
|
import User from "./User.ts";
|
||||||
import Member from "./Member.ts";
|
import Member from "./Member.ts";
|
||||||
@ -33,6 +40,7 @@ export interface CreateMessage {
|
|||||||
allowedMentions?: AllowedMentions;
|
allowedMentions?: AllowedMentions;
|
||||||
files?: FileContent[];
|
files?: FileContent[];
|
||||||
messageReference?: CreateMessageReference;
|
messageReference?: CreateMessageReference;
|
||||||
|
embeds?: DiscordEmbed[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,6 +50,11 @@ export interface EditMessage extends Partial<CreateMessage> {
|
|||||||
flags?: MessageFlags;
|
flags?: MessageFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ReactionResolvable = string | {
|
||||||
|
name: string;
|
||||||
|
id: Snowflake;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a message
|
* Represents a message
|
||||||
* @link https://discord.com/developers/docs/resources/channel#message-object
|
* @link https://discord.com/developers/docs/resources/channel#message-object
|
||||||
@ -63,12 +76,10 @@ export class Message implements Model {
|
|||||||
this.attachments = data.attachments.map((attachment) => new Attachment(session, attachment));
|
this.attachments = data.attachments.map((attachment) => new Attachment(session, attachment));
|
||||||
|
|
||||||
// user is always null on MessageCreate and its replaced with author
|
// user is always null on MessageCreate and its replaced with author
|
||||||
this.member = data.member
|
|
||||||
? new Member(session, {
|
if (data.guild_id && data.member) {
|
||||||
...data.member,
|
this.member = new Member(session, { ...data.member, user: data.author }, data.guild_id);
|
||||||
user: data.author,
|
}
|
||||||
})
|
|
||||||
: undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly session: Session;
|
readonly session: Session;
|
||||||
@ -89,21 +100,38 @@ export class Message implements Model {
|
|||||||
return `https://discord.com/channels/${this.guildId ?? "@me"}/${this.channelId}/${this.id}`;
|
return `https://discord.com/channels/${this.guildId ?? "@me"}/${this.channelId}/${this.id}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async pin() {
|
||||||
|
await this.session.rest.runMethod<undefined>(
|
||||||
|
this.session.rest,
|
||||||
|
"PUT",
|
||||||
|
Routes.CHANNEL_PIN(this.channelId, this.id),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async unpin() {
|
||||||
|
await this.session.rest.runMethod<undefined>(
|
||||||
|
this.session.rest,
|
||||||
|
"DELETE",
|
||||||
|
Routes.CHANNEL_PIN(this.channelId, this.id),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/** Edits the current message */
|
/** Edits the current message */
|
||||||
async edit({ content, allowedMentions, flags }: EditMessage): Promise<Message> {
|
async edit(options: EditMessage): Promise<Message> {
|
||||||
const message = await this.session.rest.runMethod(
|
const message = await this.session.rest.runMethod(
|
||||||
this.session.rest,
|
this.session.rest,
|
||||||
"POST",
|
"POST",
|
||||||
Routes.CHANNEL_MESSAGE(this.id, this.channelId),
|
Routes.CHANNEL_MESSAGE(this.id, this.channelId),
|
||||||
{
|
{
|
||||||
content,
|
content: options.content,
|
||||||
allowed_mentions: {
|
allowed_mentions: {
|
||||||
parse: allowedMentions?.parse,
|
parse: options.allowedMentions?.parse,
|
||||||
roles: allowedMentions?.roles,
|
roles: options.allowedMentions?.roles,
|
||||||
users: allowedMentions?.users,
|
users: options.allowedMentions?.users,
|
||||||
replied_user: allowedMentions?.repliedUser,
|
replied_user: options.allowedMentions?.repliedUser,
|
||||||
},
|
},
|
||||||
flags,
|
flags: options.flags,
|
||||||
|
embeds: options.embeds,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -156,12 +184,98 @@ export class Message implements Model {
|
|||||||
fail_if_not_exists: options.messageReference.failIfNotExists ?? true,
|
fail_if_not_exists: options.messageReference.failIfNotExists ?? true,
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
|
embeds: options.embeds,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return new Message(this.session, message);
|
return new Message(this.session, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* alias for Message.addReaction
|
||||||
|
*/
|
||||||
|
get react() {
|
||||||
|
return this.addReaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
async addReaction(reaction: ReactionResolvable) {
|
||||||
|
const r = typeof reaction === "string" ? reaction : `${reaction.name}:${reaction.id}`;
|
||||||
|
|
||||||
|
await this.session.rest.runMethod<undefined>(
|
||||||
|
this.session.rest,
|
||||||
|
"PUT",
|
||||||
|
Routes.CHANNEL_MESSAGE_REACTION_ME(this.channelId, this.id, r),
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeReaction(reaction: ReactionResolvable, options?: { userId: Snowflake }) {
|
||||||
|
const r = typeof reaction === "string" ? reaction : `${reaction.name}:${reaction.id}`;
|
||||||
|
|
||||||
|
await this.session.rest.runMethod<undefined>(
|
||||||
|
this.session.rest,
|
||||||
|
"DELETE",
|
||||||
|
options?.userId
|
||||||
|
? Routes.CHANNEL_MESSAGE_REACTION_USER(
|
||||||
|
this.channelId,
|
||||||
|
this.id,
|
||||||
|
r,
|
||||||
|
options.userId,
|
||||||
|
)
|
||||||
|
: Routes.CHANNEL_MESSAGE_REACTION_ME(this.channelId, this.id, r),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get users who reacted with this emoji
|
||||||
|
*/
|
||||||
|
async fetchReactions(reaction: ReactionResolvable, options?: GetReactions): Promise<User[]> {
|
||||||
|
const r = typeof reaction === "string" ? reaction : `${reaction.name}:${reaction.id}`;
|
||||||
|
|
||||||
|
const users = await this.session.rest.runMethod<DiscordUser[]>(
|
||||||
|
this.session.rest,
|
||||||
|
"GET",
|
||||||
|
Routes.CHANNEL_MESSAGE_REACTION(this.channelId, this.id, encodeURIComponent(r), options),
|
||||||
|
);
|
||||||
|
|
||||||
|
return users.map((user) => new User(this.session, user));
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeReactionEmoji(reaction: ReactionResolvable) {
|
||||||
|
const r = typeof reaction === "string" ? reaction : `${reaction.name}:${reaction.id}`;
|
||||||
|
|
||||||
|
await this.session.rest.runMethod<undefined>(
|
||||||
|
this.session.rest,
|
||||||
|
"DELETE",
|
||||||
|
Routes.CHANNEL_MESSAGE_REACTION(this.channelId, this.id, r),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async nukeReactions() {
|
||||||
|
await this.session.rest.runMethod<undefined>(
|
||||||
|
this.session.rest,
|
||||||
|
"DELETE",
|
||||||
|
Routes.CHANNEL_MESSAGE_REACTIONS(this.channelId, this.id),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async crosspost() {
|
||||||
|
const message = await this.session.rest.runMethod<DiscordMessage>(
|
||||||
|
this.session.rest,
|
||||||
|
"POST",
|
||||||
|
Routes.CHANNEL_MESSAGE_CROSSPOST(this.channelId, this.id),
|
||||||
|
);
|
||||||
|
|
||||||
|
return new Message(this.session, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* alias of Message.crosspost
|
||||||
|
* */
|
||||||
|
get publish() {
|
||||||
|
return this.crosspost;
|
||||||
|
}
|
||||||
|
|
||||||
inGuild(): this is { guildId: Snowflake } & Message {
|
inGuild(): this is { guildId: Snowflake } & Message {
|
||||||
return !!this.guildId;
|
return !!this.guildId;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import type { Snowflake } from "../util/Snowflake.ts";
|
|||||||
import type { Session } from "../session/Session.ts";
|
import type { Session } from "../session/Session.ts";
|
||||||
import type { DiscordChannel } from "../vendor/external.ts";
|
import type { DiscordChannel } from "../vendor/external.ts";
|
||||||
import TextChannel from "./TextChannel.ts";
|
import TextChannel from "./TextChannel.ts";
|
||||||
|
import Message from "./Message.ts";
|
||||||
|
|
||||||
export class NewsChannel extends TextChannel {
|
export class NewsChannel extends TextChannel {
|
||||||
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
|
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
|
||||||
@ -9,6 +10,14 @@ export class NewsChannel extends TextChannel {
|
|||||||
this.defaultAutoArchiveDuration = data.default_auto_archive_duration;
|
this.defaultAutoArchiveDuration = data.default_auto_archive_duration;
|
||||||
}
|
}
|
||||||
defaultAutoArchiveDuration?: number;
|
defaultAutoArchiveDuration?: number;
|
||||||
|
|
||||||
|
crosspostMessage(messageId: Snowflake): Promise<Message> {
|
||||||
|
return Message.prototype.crosspost.call({ id: messageId, channelId: this.id, session: this.session });
|
||||||
|
}
|
||||||
|
|
||||||
|
get publishMessage() {
|
||||||
|
return this.crosspostMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default NewsChannel;
|
export default NewsChannel;
|
||||||
|
@ -48,7 +48,6 @@ export class Role implements Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async delete(): Promise<void> {
|
async delete(): Promise<void> {
|
||||||
// cool jS trick
|
|
||||||
await Guild.prototype.deleteRole.call({ id: this.guildId, session: this.session }, this.id);
|
await Guild.prototype.deleteRole.call({ id: this.guildId, session: this.session }, this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +56,14 @@ export class Role implements Model {
|
|||||||
return role;
|
return role;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async add(memberId: Snowflake, options: { reason?: string } = {}) {
|
||||||
|
await Guild.prototype.addRole.call({ id: this.guildId, session: this.session }, memberId, this.id, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
async remove(memberId: Snowflake, options: { reason?: string } = {}) {
|
||||||
|
await Guild.prototype.removeRole.call({ id: this.guildId, session: this.session }, memberId, this.id, options);
|
||||||
|
}
|
||||||
|
|
||||||
toString() {
|
toString() {
|
||||||
switch (this.id) {
|
switch (this.id) {
|
||||||
case this.guildId:
|
case this.guildId:
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import type { Session } from "../session/Session.ts";
|
import type { Session } from "../session/Session.ts";
|
||||||
import type { Snowflake } from "../util/Snowflake.ts";
|
import type { Snowflake } from "../util/Snowflake.ts";
|
||||||
import type { GetMessagesOptions } from "../util/Routes.ts";
|
import type { GetMessagesOptions, GetReactions } from "../util/Routes.ts";
|
||||||
import type { DiscordChannel, DiscordInvite, DiscordMessage, TargetTypes } from "../vendor/external.ts";
|
import type { DiscordChannel, DiscordInvite, DiscordMessage, TargetTypes } from "../vendor/external.ts";
|
||||||
|
import type { CreateMessage, EditMessage, ReactionResolvable } from "./Message.ts";
|
||||||
import GuildChannel from "./GuildChannel.ts";
|
import GuildChannel from "./GuildChannel.ts";
|
||||||
import Guild from "./Guild.ts";
|
|
||||||
import ThreadChannel from "./ThreadChannel.ts";
|
import ThreadChannel from "./ThreadChannel.ts";
|
||||||
import Message from "./Message.ts";
|
import Message from "./Message.ts";
|
||||||
import Invite from "./Invite.ts";
|
import Invite from "./Invite.ts";
|
||||||
@ -37,7 +37,7 @@ export interface ThreadCreateOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class TextChannel extends GuildChannel {
|
export class TextChannel extends GuildChannel {
|
||||||
constructor(session: Session, data: DiscordChannel, guildId: Guild["id"]) {
|
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
|
||||||
super(session, data, guildId);
|
super(session, data, guildId);
|
||||||
data.last_message_id ? this.lastMessageId = data.last_message_id : undefined;
|
data.last_message_id ? this.lastMessageId = data.last_message_id : undefined;
|
||||||
data.last_pin_timestamp ? this.lastPinTimestamp = data.last_pin_timestamp : undefined;
|
data.last_pin_timestamp ? this.lastPinTimestamp = data.last_pin_timestamp : undefined;
|
||||||
@ -107,6 +107,58 @@ export class TextChannel extends GuildChannel {
|
|||||||
Routes.CHANNEL_TYPING(this.id),
|
Routes.CHANNEL_TYPING(this.id),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async pinMessage(messageId: Snowflake) {
|
||||||
|
await Message.prototype.pin.call({ id: messageId, channelId: this.id, session: this.session });
|
||||||
|
}
|
||||||
|
|
||||||
|
async unpinMessage(messageId: Snowflake) {
|
||||||
|
await Message.prototype.unpin.call({ id: messageId, channelId: this.id, session: this.session });
|
||||||
|
}
|
||||||
|
|
||||||
|
async addReaction(messageId: Snowflake, reaction: ReactionResolvable) {
|
||||||
|
await Message.prototype.addReaction.call(
|
||||||
|
{ channelId: this.id, id: messageId, session: this.session },
|
||||||
|
reaction,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeReaction(messageId: Snowflake, reaction: ReactionResolvable, options?: { userId: Snowflake }) {
|
||||||
|
await Message.prototype.removeReaction.call(
|
||||||
|
{ channelId: this.id, id: messageId, session: this.session },
|
||||||
|
reaction,
|
||||||
|
options,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeReactionEmoji(messageId: Snowflake, reaction: ReactionResolvable) {
|
||||||
|
await Message.prototype.removeReactionEmoji.call(
|
||||||
|
{ channelId: this.id, id: messageId, session: this.session },
|
||||||
|
reaction,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async nukeReactions(messageId: Snowflake) {
|
||||||
|
await Message.prototype.nukeReactions.call({ channelId: this.id, id: messageId });
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchReactions(messageId: Snowflake, reaction: ReactionResolvable, options?: GetReactions) {
|
||||||
|
const users = await Message.prototype.fetchReactions.call(
|
||||||
|
{ channelId: this.id, id: messageId, session: this.session },
|
||||||
|
reaction,
|
||||||
|
options,
|
||||||
|
);
|
||||||
|
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMessage(options: CreateMessage) {
|
||||||
|
return Message.prototype.reply.call({ channelId: this.id, session: this.session }, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
editMessage(messageId: Snowflake, options: EditMessage) {
|
||||||
|
return Message.prototype.edit.call({ channelId: this.id, id: messageId, session: this.session }, options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TextChannel;
|
export default TextChannel;
|
||||||
|
@ -1,16 +1,31 @@
|
|||||||
import type { Snowflake } from "../util/Snowflake.ts";
|
import type { Snowflake } from "../util/Snowflake.ts";
|
||||||
import type { Session } from "../session/Session.ts";
|
import type { Session } from "../session/Session.ts";
|
||||||
import type { DiscordChannel, VideoQualityModes } from "../vendor/external.ts";
|
import type { DiscordChannel, VideoQualityModes } from "../vendor/external.ts";
|
||||||
|
import { GatewayOpcodes } from "../vendor/external.ts";
|
||||||
|
import { calculateShardId } from "../vendor/gateway/calculateShardId.ts";
|
||||||
import GuildChannel from "./GuildChannel.ts";
|
import GuildChannel from "./GuildChannel.ts";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://discord.com/developers/docs/topics/gateway#update-voice-state
|
||||||
|
*/
|
||||||
|
export interface UpdateVoiceState {
|
||||||
|
guildId: string;
|
||||||
|
channelId?: string;
|
||||||
|
selfMute: boolean;
|
||||||
|
selfDeaf: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export class VoiceChannel extends GuildChannel {
|
export class VoiceChannel extends GuildChannel {
|
||||||
constructor(session: Session, guildId: Snowflake, data: DiscordChannel) {
|
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
|
||||||
super(session, data, guildId);
|
super(session, data, guildId);
|
||||||
this.bitRate = data.bitrate;
|
this.bitRate = data.bitrate;
|
||||||
this.userLimit = data.user_limit ?? 0;
|
this.userLimit = data.user_limit ?? 0;
|
||||||
data.rtc_region ? this.rtcRegion = data.rtc_region : undefined;
|
|
||||||
this.videoQuality = data.video_quality_mode;
|
this.videoQuality = data.video_quality_mode;
|
||||||
this.nsfw = !!data.nsfw;
|
this.nsfw = !!data.nsfw;
|
||||||
|
|
||||||
|
if (data.rtc_region) {
|
||||||
|
this.rtcRegion = data.rtc_region;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bitRate?: number;
|
bitRate?: number;
|
||||||
userLimit: number;
|
userLimit: number;
|
||||||
@ -18,6 +33,28 @@ export class VoiceChannel extends GuildChannel {
|
|||||||
|
|
||||||
videoQuality?: VideoQualityModes;
|
videoQuality?: VideoQualityModes;
|
||||||
nsfw: boolean;
|
nsfw: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function was gathered from Discordeno it may not work
|
||||||
|
*/
|
||||||
|
async connect(options?: UpdateVoiceState) {
|
||||||
|
const shardId = calculateShardId(this.session.gateway, BigInt(super.guildId));
|
||||||
|
const shard = this.session.gateway.manager.shards.get(shardId);
|
||||||
|
|
||||||
|
if (!shard) {
|
||||||
|
throw new Error(`Shard (id: ${shardId} not found`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await shard.send({
|
||||||
|
op: GatewayOpcodes.VoiceStateUpdate,
|
||||||
|
d: {
|
||||||
|
guild_id: super.guildId,
|
||||||
|
channel_id: super.id,
|
||||||
|
self_mute: Boolean(options?.selfMute),
|
||||||
|
self_deaf: options?.selfDeaf ?? true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default VoiceChannel;
|
export default VoiceChannel;
|
||||||
|
@ -46,10 +46,6 @@ export function MESSAGE_CREATE_THREAD(channelId: Snowflake, messageId: Snowflake
|
|||||||
return `/channels/${channelId}/messages/${messageId}/threads`;
|
return `/channels/${channelId}/messages/${messageId}/threads`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CHANNEL_PINS(channelId: Snowflake) {
|
|
||||||
return `/channels/${channelId}/pins`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** used to send messages */
|
/** used to send messages */
|
||||||
export function CHANNEL_MESSAGES(channelId: Snowflake, options?: GetMessagesOptions) {
|
export function CHANNEL_MESSAGES(channelId: Snowflake, options?: GetMessagesOptions) {
|
||||||
let url = `/channels/${channelId}/messages?`;
|
let url = `/channels/${channelId}/messages?`;
|
||||||
@ -139,3 +135,92 @@ export function INVITE(inviteCode: string, options?: GetInvite) {
|
|||||||
export function GUILD_INVITES(guildId: Snowflake) {
|
export function GUILD_INVITES(guildId: Snowflake) {
|
||||||
return `/guilds/${guildId}/invites`;
|
return `/guilds/${guildId}/invites`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function INTERACTION_ID_TOKEN(interactionId: Snowflake, token: string) {
|
||||||
|
return `/interactions/${interactionId}/${token}/callback`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function WEBHOOK(webhookId: Snowflake, token: string, options?: { wait?: boolean; threadId?: Snowflake }) {
|
||||||
|
let url = `/webhooks/${webhookId}/${token}?`;
|
||||||
|
|
||||||
|
if (options?.wait !== undefined) url += `wait=${options.wait}`;
|
||||||
|
if (options?.threadId) url += `threadId=${options.threadId}`;
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function USER_NICK(guildId: Snowflake) {
|
||||||
|
return `/guilds/${guildId}/members/@me`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://discord.com/developers/docs/resources/guild#get-guild-prune-count
|
||||||
|
*/
|
||||||
|
export interface GetGuildPruneCountQuery {
|
||||||
|
days?: number;
|
||||||
|
includeRoles?: Snowflake | Snowflake[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GUILD_PRUNE(guildId: Snowflake, options?: GetGuildPruneCountQuery) {
|
||||||
|
let url = `/guilds/${guildId}/prune?`;
|
||||||
|
|
||||||
|
if (options?.days) url += `days=${options.days}`;
|
||||||
|
if (options?.includeRoles) url += `&include_roles=${options.includeRoles}`;
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CHANNEL_PIN(channelId: Snowflake, messageId: Snowflake) {
|
||||||
|
return `/channels/${channelId}/pins/${messageId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CHANNEL_PINS(channelId: Snowflake) {
|
||||||
|
return `/channels/${channelId}/pins`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CHANNEL_MESSAGE_REACTION_ME(channelId: Snowflake, messageId: Snowflake, emoji: string) {
|
||||||
|
return `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}/@me`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CHANNEL_MESSAGE_REACTION_USER(
|
||||||
|
channelId: Snowflake,
|
||||||
|
messageId: Snowflake,
|
||||||
|
emoji: string,
|
||||||
|
userId: Snowflake,
|
||||||
|
) {
|
||||||
|
return `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}/${userId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CHANNEL_MESSAGE_REACTIONS(channelId: Snowflake, messageId: Snowflake) {
|
||||||
|
return `/channels/${channelId}/messages/${messageId}/reactions`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://discord.com/developers/docs/resources/channel#get-reactions-query-string-params
|
||||||
|
*/
|
||||||
|
export interface GetReactions {
|
||||||
|
after?: string;
|
||||||
|
limit?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CHANNEL_MESSAGE_REACTION(
|
||||||
|
channelId: Snowflake,
|
||||||
|
messageId: Snowflake,
|
||||||
|
emoji: string,
|
||||||
|
options?: GetReactions,
|
||||||
|
) {
|
||||||
|
let url = `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}?`;
|
||||||
|
|
||||||
|
if (options?.after) url += `after=${options.after}`;
|
||||||
|
if (options?.limit) url += `&limit=${options.limit}`;
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CHANNEL_MESSAGE_CROSSPOST(channelId: Snowflake, messageId: Snowflake) {
|
||||||
|
return `/channels/${channelId}/messages/${messageId}/crosspost`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GUILD_MEMBER_ROLE(guildId: Snowflake, memberId: Snowflake, roleId: Snowflake) {
|
||||||
|
return `/guilds/${guildId}/members/${memberId}/roles/${roleId}`;
|
||||||
|
}
|
||||||
|
1
vendor/external.ts
vendored
1
vendor/external.ts
vendored
@ -2,3 +2,4 @@ export * from "./gateway/mod.ts";
|
|||||||
export * from "./rest/mod.ts";
|
export * from "./rest/mod.ts";
|
||||||
export * from "./types/mod.ts";
|
export * from "./types/mod.ts";
|
||||||
export * from "./util/constants.ts";
|
export * from "./util/constants.ts";
|
||||||
|
export * from "./util/token.ts";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user