mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-03 05:26:07 +00:00
feat: threads
This commit is contained in:
parent
78b8cf9da0
commit
1cd41c67a7
@ -8,6 +8,10 @@ import type {
|
||||
DiscordMemberWithUser,
|
||||
DiscordMessage,
|
||||
DiscordMessageDelete,
|
||||
DiscordMessageReactionAdd,
|
||||
DiscordMessageReactionRemove,
|
||||
DiscordMessageReactionRemoveAll,
|
||||
DiscordMessageReactionRemoveEmoji,
|
||||
DiscordReady,
|
||||
// DiscordThreadMemberUpdate,
|
||||
// DiscordThreadMembersUpdate,
|
||||
@ -19,6 +23,7 @@ import type { Channel } from "../structures/channels/ChannelFactory.ts";
|
||||
import ChannelFactory from "../structures/channels/ChannelFactory.ts";
|
||||
import GuildChannel from "../structures/channels/GuildChannel.ts";
|
||||
import ThreadChannel from "../structures/channels/ThreadChannel.ts";
|
||||
import ThreadMember from "../structures/ThreadMember.ts";
|
||||
import Member from "../structures/Member.ts";
|
||||
import Message from "../structures/Message.ts";
|
||||
import User from "../structures/User.ts";
|
||||
@ -103,10 +108,7 @@ export const THREAD_LIST_SYNC: RawHandler<DiscordThreadListSync> = (session, _sh
|
||||
guildId: payload.guild_id,
|
||||
channelIds: payload.channel_ids ?? [],
|
||||
threads: payload.threads.map((channel) => new ThreadChannel(session, channel, payload.guild_id)),
|
||||
members: payload.members.map((member) =>
|
||||
// @ts-ignore: TODO: thread member structure
|
||||
new Member(session, member as DiscordMemberWithUser, payload.guild_id)
|
||||
),
|
||||
members: payload.members.map((member) => new ThreadMember(session, member)),
|
||||
});
|
||||
};
|
||||
|
||||
@ -118,6 +120,24 @@ export const CHANNEL_PINS_UPDATE: RawHandler<DiscordChannelPinsUpdate> = (sessio
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
export const MESSAGE_REACTION_ADD: RawHandler<DiscordMessageReactionAdd> = (session, _shardId, reaction) => {
|
||||
session.emit("messageReactionAdd", null);
|
||||
};
|
||||
|
||||
export const MESSAGE_REACTION_REMOVE: RawHandler<DiscordMessageReactionRemove> = (session, _shardId, reaction) => {
|
||||
session.emit("messageReactionRemove", null);
|
||||
};
|
||||
|
||||
export const MESSAGE_REACTION_REMOVE_ALL: RawHandler<DiscordMessageReactionRemoveAll> = (session, _shardId, reaction) => {
|
||||
session.emit("messageReactionRemoveAll", null);
|
||||
};
|
||||
|
||||
export const MESSAGE_REACTION_REMOVE_EMOJI: RawHandler<DiscordMessageReactionRemoveEmoji> = (session, _shardId, reaction) => {
|
||||
session.emit("messageReactionRemoveEmoji", null);
|
||||
};
|
||||
*/
|
||||
|
||||
export const raw: RawHandler<unknown> = (session, shardId, data) => {
|
||||
session.emit("raw", data, shardId);
|
||||
};
|
||||
@ -126,23 +146,30 @@ export interface Ready extends Omit<DiscordReady, "user"> {
|
||||
user: User;
|
||||
}
|
||||
|
||||
// TODO: add partial reactions or something
|
||||
type MessageReaction = any;
|
||||
|
||||
// deno-fmt-ignore-file
|
||||
export interface Events {
|
||||
"ready": Handler<[Ready, number]>;
|
||||
"messageCreate": Handler<[Message]>;
|
||||
"messageUpdate": Handler<[Message]>;
|
||||
"messageDelete": Handler<[{ id: Snowflake, channelId: Snowflake, guildId?: Snowflake }]>;
|
||||
"guildMemberAdd": Handler<[Member]>;
|
||||
"guildMemberUpdate": Handler<[Member]>;
|
||||
"guildMemberRemove": Handler<[User, Snowflake]>;
|
||||
"channelCreate": Handler<[Channel]>;
|
||||
"channelUpdate": Handler<[Channel]>;
|
||||
"channelDelete": Handler<[GuildChannel]>;
|
||||
"channelPinsUpdate": Handler<[{ guildId?: Snowflake, channelId: Snowflake, lastPinTimestamp?: number }]>
|
||||
"threadCreate": Handler<[ThreadChannel]>;
|
||||
"threadUpdate": Handler<[ThreadChannel]>;
|
||||
"threadDelete": Handler<[ThreadChannel]>;
|
||||
"threadListSync": Handler<[{ guildId: Snowflake, channelIds: Snowflake[], threads: ThreadChannel[], members: Member[] }]>
|
||||
"interactionCreate": Handler<[Interaction]>;
|
||||
"raw": Handler<[unknown, number]>;
|
||||
"ready": Handler<[Ready, number]>;
|
||||
"messageCreate": Handler<[Message]>;
|
||||
"messageUpdate": Handler<[Message]>;
|
||||
"messageDelete": Handler<[{ id: Snowflake, channelId: Snowflake, guildId?: Snowflake }]>;
|
||||
"messageReactionAdd": Handler<[MessageReaction]>;
|
||||
"messageReactionRemove": Handler<[MessageReaction]>;
|
||||
"messageReactionRemoveAll": Handler<[MessageReaction]>;
|
||||
"messageReactionRemoveEmoji": Handler<[MessageReaction]>;
|
||||
"guildMemberAdd": Handler<[Member]>;
|
||||
"guildMemberUpdate": Handler<[Member]>;
|
||||
"guildMemberRemove": Handler<[User, Snowflake]>;
|
||||
"channelCreate": Handler<[Channel]>;
|
||||
"channelUpdate": Handler<[Channel]>;
|
||||
"channelDelete": Handler<[GuildChannel]>;
|
||||
"channelPinsUpdate": Handler<[{ guildId?: Snowflake, channelId: Snowflake, lastPinTimestamp?: number }]>
|
||||
"threadCreate": Handler<[ThreadChannel]>;
|
||||
"threadUpdate": Handler<[ThreadChannel]>;
|
||||
"threadDelete": Handler<[ThreadChannel]>;
|
||||
"threadListSync": Handler<[{ guildId: Snowflake, channelIds: Snowflake[], threads: ThreadChannel[], members: ThreadMember[] }]>
|
||||
"interactionCreate": Handler<[Interaction]>;
|
||||
"raw": Handler<[unknown, number]>;
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import type { Model } from "./Base.ts";
|
||||
import type { Snowflake } from "../util/Snowflake.ts";
|
||||
import type { Session } from "../session/Session.ts";
|
||||
import type {
|
||||
AllowedMentionsTypes,
|
||||
@ -7,15 +6,20 @@ import type {
|
||||
DiscordMessage,
|
||||
DiscordUser,
|
||||
FileContent,
|
||||
MessageTypes,
|
||||
MessageActivityTypes,
|
||||
} from "../vendor/external.ts";
|
||||
import type { Component } from "./components/Component.ts";
|
||||
import type { GetReactions } from "../util/Routes.ts";
|
||||
import { MessageFlags } from "../util/shared/flags.ts";
|
||||
import { iconHashToBigInt } from "../util/hash.ts";
|
||||
import { Snowflake } from "../util/Snowflake.ts";
|
||||
import User from "./User.ts";
|
||||
import Member from "./Member.ts";
|
||||
import Attachment from "./Attachment.ts";
|
||||
import ComponentFactory from "./components/ComponentFactory.ts";
|
||||
import { iconHashToBigInt } from "../util/hash.ts";
|
||||
import MessageReaction from "./MessageReaction.ts";
|
||||
import ThreadChannel from "./channels/ThreadChannel.ts";
|
||||
import * as Routes from "../util/Routes.ts";
|
||||
|
||||
/**
|
||||
@ -39,11 +43,11 @@ export interface CreateMessageReference {
|
||||
* @link https://discord.com/developers/docs/resources/channel#create-message-json-params
|
||||
*/
|
||||
export interface CreateMessage {
|
||||
embeds?: DiscordEmbed[];
|
||||
content?: string;
|
||||
allowedMentions?: AllowedMentions;
|
||||
files?: FileContent[];
|
||||
messageReference?: CreateMessageReference;
|
||||
embeds?: DiscordEmbed[];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,19 +78,32 @@ export class Message implements Model {
|
||||
this.session = session;
|
||||
this.id = data.id;
|
||||
|
||||
this.type = data.type;
|
||||
this.channelId = data.channel_id;
|
||||
this.guildId = data.guild_id;
|
||||
this.applicationId = data.application_id;
|
||||
|
||||
this.author = new User(session, data.author);
|
||||
this.flags = data.flags;
|
||||
this.pinned = !!data.pinned;
|
||||
this.tts = !!data.tts;
|
||||
this.content = data.content!;
|
||||
this.nonce = data.nonce;
|
||||
this.mentionEveryone = data.mention_everyone;
|
||||
|
||||
this.timestamp = Date.parse(data.timestamp);
|
||||
this.editedTimestamp = data.edited_timestamp ? Date.parse(data.edited_timestamp) : undefined;
|
||||
|
||||
this.reactions = data.reactions?.map((react) => new MessageReaction(session, react)) ?? [];
|
||||
this.attachments = data.attachments.map((attachment) => new Attachment(session, attachment));
|
||||
this.embeds = data.embeds;
|
||||
|
||||
if (data.thread && data.guild_id) {
|
||||
this.thread = new ThreadChannel(session, data.thread, data.guild_id);
|
||||
}
|
||||
|
||||
// webhook handling
|
||||
if (data.author && data.author.discriminator === "0000") {
|
||||
if (data.author.discriminator === "0000") {
|
||||
this.webhook = {
|
||||
id: data.author.id,
|
||||
username: data.author.username,
|
||||
@ -96,30 +113,70 @@ export class Message implements Model {
|
||||
}
|
||||
|
||||
// user is always null on MessageCreate and its replaced with author
|
||||
|
||||
if (data.guild_id && data.member && data.author && !this.isWebhookMessage()) {
|
||||
if (data.guild_id && data.member && !this.isWebhookMessage()) {
|
||||
this.member = new Member(session, { ...data.member, user: data.author }, data.guild_id);
|
||||
}
|
||||
|
||||
this.components = data.components?.map((component) => ComponentFactory.from(session, component));
|
||||
this.components = data.components?.map((component) => ComponentFactory.from(session, component)) ?? [];
|
||||
|
||||
if (data.activity) {
|
||||
this.activity = {
|
||||
partyId: data.activity.party_id,
|
||||
type: data.activity.type,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
readonly session: Session;
|
||||
readonly id: Snowflake;
|
||||
|
||||
type: MessageTypes;
|
||||
channelId: Snowflake;
|
||||
guildId?: Snowflake;
|
||||
applicationId?: Snowflake;
|
||||
author: User;
|
||||
flags?: MessageFlags;
|
||||
pinned: boolean;
|
||||
tts: boolean;
|
||||
content: string;
|
||||
nonce?: string | number;
|
||||
mentionEveryone: boolean;
|
||||
|
||||
timestamp: number;
|
||||
editedTimestamp?: number;
|
||||
|
||||
reactions: MessageReaction[];
|
||||
attachments: Attachment[];
|
||||
embeds: DiscordEmbed[];
|
||||
member?: Member;
|
||||
components?: Component[];
|
||||
thread?: ThreadChannel;
|
||||
components: Component[];
|
||||
|
||||
webhook?: WebhookAuthor;
|
||||
activity?: {
|
||||
partyId?: Snowflake;
|
||||
type: MessageActivityTypes;
|
||||
};
|
||||
|
||||
get createdTimestamp() {
|
||||
return Snowflake.snowflakeToTimestamp(this.id);
|
||||
}
|
||||
|
||||
get createdAt() {
|
||||
return new Date(this.createdTimestamp);
|
||||
}
|
||||
|
||||
get sentAt() {
|
||||
return new Date(this.timestamp);
|
||||
}
|
||||
|
||||
get editedAt() {
|
||||
return this.editedTimestamp ? new Date(this.editedTimestamp) : undefined;
|
||||
}
|
||||
|
||||
get edited() {
|
||||
return this.editedTimestamp;
|
||||
}
|
||||
|
||||
get url() {
|
||||
return `https://discord.com/channels/${this.guildId ?? "@me"}/${this.channelId}/${this.id}`;
|
||||
@ -301,12 +358,13 @@ export class Message implements Model {
|
||||
return this.crosspost;
|
||||
}
|
||||
|
||||
inGuild(): this is { guildId: Snowflake } & Message {
|
||||
/** wheter the message comes from a guild **/
|
||||
inGuild(): this is Message & { guildId: Snowflake } {
|
||||
return !!this.guildId;
|
||||
}
|
||||
|
||||
/** isWebhookMessage if the messages comes from a Webhook */
|
||||
isWebhookMessage(): this is User & { author: Partial<User>; webhook: WebhookAuthor; member: undefined } {
|
||||
/** wheter the messages comes from a Webhook */
|
||||
isWebhookMessage(): this is Message & { author: Partial<User>; webhook: WebhookAuthor; member: undefined } {
|
||||
return !!this.webhook;
|
||||
}
|
||||
}
|
||||
|
23
structures/MessageReaction.ts
Normal file
23
structures/MessageReaction.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import type { Session } from "../session/Session.ts";
|
||||
import type { DiscordReaction } from "../vendor/external.ts";
|
||||
import Emoji from "./Emoji.ts";
|
||||
|
||||
/**
|
||||
* Represents a reaction
|
||||
* @link https://discord.com/developers/docs/resources/channel#reaction-object
|
||||
* */
|
||||
export class MessageReaction {
|
||||
constructor(session: Session, data: DiscordReaction) {
|
||||
this.session = session;
|
||||
this.me = data.me;
|
||||
this.count = data.count;
|
||||
this.emoji = new Emoji(session, data.emoji);
|
||||
}
|
||||
|
||||
readonly session: Session;
|
||||
me: boolean;
|
||||
count: number;
|
||||
emoji: Emoji;
|
||||
}
|
||||
|
||||
export default MessageReaction;
|
47
structures/ThreadMember.ts
Normal file
47
structures/ThreadMember.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import type { Model } from "./Base.ts";
|
||||
import type { Session } from "../session/Session.ts";
|
||||
import type { Snowflake } from "../util/Snowflake.ts";
|
||||
import type { DiscordThreadMember } from "../vendor/external.ts";
|
||||
import * as Routes from "../util/Routes.ts";
|
||||
|
||||
/**
|
||||
* A member that comes from a thread
|
||||
* @link https://discord.com/developers/docs/resources/channel#thread-member-object
|
||||
* **/
|
||||
export class ThreadMember implements Model {
|
||||
constructor(session: Session, data: DiscordThreadMember) {
|
||||
this.session = session;
|
||||
this.id = data.id;
|
||||
this.flags = data.flags;
|
||||
this.timestamp = Date.parse(data.join_timestamp);
|
||||
}
|
||||
|
||||
readonly session: Session;
|
||||
readonly id: Snowflake;
|
||||
flags: number;
|
||||
timestamp: number;
|
||||
|
||||
get threadId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
async quitThread(memberId: Snowflake = this.session.botId) {
|
||||
await this.session.rest.runMethod<undefined>(
|
||||
this.session.rest,
|
||||
"DELETE",
|
||||
Routes.THREAD_USER(this.id, memberId),
|
||||
);
|
||||
}
|
||||
|
||||
async fetchMember(memberId: Snowflake = this.session.botId) {
|
||||
const member = await this.session.rest.runMethod<DiscordThreadMember>(
|
||||
this.session.rest,
|
||||
"GET",
|
||||
Routes.THREAD_USER(this.id, memberId),
|
||||
);
|
||||
|
||||
return new ThreadMember(this.session, member);
|
||||
}
|
||||
}
|
||||
|
||||
export default ThreadMember;
|
@ -1,8 +1,11 @@
|
||||
import type { Model } from "../Base.ts";
|
||||
import type { Snowflake } from "../../util/Snowflake.ts";
|
||||
import type { Session } from "../../session/Session.ts";
|
||||
import type { ChannelTypes, DiscordChannel, DiscordInviteMetadata } from "../../vendor/external.ts";
|
||||
import type { ChannelTypes, DiscordChannel, DiscordInviteMetadata, DiscordListArchivedThreads } from "../../vendor/external.ts";
|
||||
import type { ListArchivedThreads } from "../../util/Routes.ts";
|
||||
import BaseChannel from "./BaseChannel.ts";
|
||||
import ThreadChannel from "./ThreadChannel.ts";
|
||||
import ThreadMember from "../ThreadMember.ts";
|
||||
import Invite from "../Invite.ts";
|
||||
import * as Routes from "../../util/Routes.ts";
|
||||
|
||||
@ -44,7 +47,41 @@ export class GuildChannel extends BaseChannel implements Model {
|
||||
return invites.map((invite) => new Invite(this.session, invite));
|
||||
}
|
||||
|
||||
|
||||
async getArchivedThreads(options: ListArchivedThreads & { type: "public" | "private" | "privateJoinedThreads" }) {
|
||||
let func: (channelId: Snowflake, options: ListArchivedThreads) => string;
|
||||
|
||||
switch (options.type) {
|
||||
case "public":
|
||||
func = Routes.THREAD_ARCHIVED_PUBLIC;
|
||||
break;
|
||||
case "private":
|
||||
func = Routes.THREAD_START_PRIVATE;
|
||||
break;
|
||||
case "privateJoinedThreads":
|
||||
func = Routes.THREAD_ARCHIVED_PRIVATE_JOINED;
|
||||
break;
|
||||
}
|
||||
|
||||
const { threads, members, has_more } = await this.session.rest.runMethod<DiscordListArchivedThreads>(
|
||||
this.session.rest,
|
||||
"GET",
|
||||
func(this.id, options)
|
||||
);
|
||||
|
||||
return {
|
||||
threads: Object.fromEntries(
|
||||
threads.map((thread) => [thread.id, new ThreadChannel(this.session, thread, this.id)]),
|
||||
) as Record<Snowflake, ThreadChannel>,
|
||||
members: Object.fromEntries(
|
||||
members.map((threadMember) => [threadMember.id, new ThreadMember(this.session, threadMember)]),
|
||||
) as Record<Snowflake, ThreadMember>,
|
||||
hasMore: has_more,
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: should be in TextChannel
|
||||
async createThread(options: ThreadCreateOptions): Promise<ThreadChannel> {
|
||||
const thread = await this.session.rest.runMethod<DiscordChannel>(
|
||||
this.session.rest,
|
||||
|
@ -1,9 +1,11 @@
|
||||
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 type { ChannelTypes, DiscordChannel, DiscordThreadMember } from "../../vendor/external.ts";
|
||||
import GuildChannel from "./GuildChannel.ts";
|
||||
import TextChannel from "./TextChannel.ts";
|
||||
import ThreadMember from "../ThreadMember.ts";
|
||||
import * as Routes from "../../util/Routes.ts";
|
||||
|
||||
export class ThreadChannel extends GuildChannel implements Model {
|
||||
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
|
||||
@ -16,6 +18,10 @@ export class ThreadChannel extends GuildChannel implements Model {
|
||||
this.messageCount = data.message_count;
|
||||
this.memberCount = data.member_count;
|
||||
this.ownerId = data.owner_id;
|
||||
|
||||
if (data.member) {
|
||||
this.member = new ThreadMember(session, data.member);
|
||||
}
|
||||
}
|
||||
|
||||
override type: ChannelTypes.GuildNewsThread | ChannelTypes.GuildPrivateThread | ChannelTypes.GuildPublicThread;
|
||||
@ -25,7 +31,50 @@ export class ThreadChannel extends GuildChannel implements Model {
|
||||
locked?: boolean;
|
||||
messageCount?: number;
|
||||
memberCount?: number;
|
||||
member?: ThreadMember;
|
||||
ownerId?: Snowflake;
|
||||
|
||||
async joinThread() {
|
||||
await this.session.rest.runMethod<undefined>(
|
||||
this.session.rest,
|
||||
"PUT",
|
||||
Routes.THREAD_ME(this.id),
|
||||
);
|
||||
}
|
||||
|
||||
async addToThread(guildMemberId: Snowflake) {
|
||||
await this.session.rest.runMethod<undefined>(
|
||||
this.session.rest,
|
||||
"PUT",
|
||||
Routes.THREAD_USER(this.id, guildMemberId),
|
||||
);
|
||||
}
|
||||
|
||||
async leaveToThread(guildMemberId: Snowflake) {
|
||||
await this.session.rest.runMethod<undefined>(
|
||||
this.session.rest,
|
||||
"DELETE",
|
||||
Routes.THREAD_USER(this.id, guildMemberId),
|
||||
);
|
||||
}
|
||||
|
||||
removeMember(memberId: Snowflake = this.session.botId) {
|
||||
return ThreadMember.prototype.quitThread.call({ id: this.id, session: this.session }, memberId);
|
||||
}
|
||||
|
||||
fetchMember(memberId: Snowflake = this.session.botId) {
|
||||
return ThreadMember.prototype.fetchMember.call({ id: this.id, session: this.session }, memberId);
|
||||
}
|
||||
|
||||
async fetchMembers(): Promise<ThreadMember[]> {
|
||||
const members = await this.session.rest.runMethod<DiscordThreadMember[]>(
|
||||
this.session.rest,
|
||||
"GET",
|
||||
Routes.THREAD_MEMBERS(this.id),
|
||||
);
|
||||
|
||||
return members.map((threadMember) => new ThreadMember(this.session, threadMember));
|
||||
}
|
||||
}
|
||||
|
||||
TextChannel.applyTo(ThreadChannel);
|
||||
|
@ -7,6 +7,8 @@ import type {
|
||||
DiscordInviteMetadata,
|
||||
DiscordMemberWithUser,
|
||||
DiscordRole,
|
||||
DiscordListActiveThreads,
|
||||
DiscordListArchivedThreads,
|
||||
} from "../../vendor/external.ts";
|
||||
import type { GetInvite } from "../../util/Routes.ts";
|
||||
import {
|
||||
@ -21,6 +23,8 @@ import BaseGuild from "./BaseGuild.ts";
|
||||
import Role from "../Role.ts";
|
||||
import GuildEmoji from "../GuildEmoji.ts";
|
||||
import Invite from "../Invite.ts";
|
||||
import ThreadMember from "../ThreadMember.ts";
|
||||
import ThreadChannel from "../channels/ThreadChannel.ts";
|
||||
import * as Routes from "../../util/Routes.ts";
|
||||
|
||||
export interface CreateRole {
|
||||
@ -362,6 +366,23 @@ export class Guild extends BaseGuild implements Model {
|
||||
|
||||
return result.pruned;
|
||||
}
|
||||
|
||||
async getActiveThreads() {
|
||||
const { threads, members } = await this.session.rest.runMethod<DiscordListActiveThreads>(
|
||||
this.session.rest,
|
||||
"GET",
|
||||
Routes.THREAD_ACTIVE(this.id)
|
||||
);
|
||||
|
||||
return {
|
||||
threads: Object.fromEntries(
|
||||
threads.map((thread) => [thread.id, new ThreadChannel(this.session, thread, this.id)]),
|
||||
) as Record<Snowflake, ThreadChannel>,
|
||||
members: Object.fromEntries(
|
||||
members.map((threadMember) => [threadMember.id, new ThreadMember(this.session, threadMember)]),
|
||||
) as Record<Snowflake, ThreadMember>,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default Guild;
|
||||
|
@ -228,3 +228,74 @@ export function GUILD_MEMBER_ROLE(guildId: Snowflake, memberId: Snowflake, roleI
|
||||
export function CHANNEL_WEBHOOKS(channelId: Snowflake) {
|
||||
return `/channels/${channelId}/webhooks`;
|
||||
}
|
||||
|
||||
|
||||
export function THREAD_START_PUBLIC(channelId: Snowflake, messageId: Snowflake) {
|
||||
return `/channels/${channelId}/messages/${messageId}/threads`;
|
||||
}
|
||||
|
||||
export function THREAD_START_PRIVATE(channelId: Snowflake) {
|
||||
return `/channels/${channelId}/threads`;
|
||||
}
|
||||
|
||||
export function THREAD_ACTIVE(guildId: Snowflake) {
|
||||
return `/guilds/${guildId}/threads/active`;
|
||||
}
|
||||
|
||||
export interface ListArchivedThreads {
|
||||
before?: number;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export function THREAD_ME(channelId: Snowflake) {
|
||||
return `/channels/${channelId}/thread-members/@me`;
|
||||
}
|
||||
|
||||
export function THREAD_MEMBERS(channelId: Snowflake) {
|
||||
return `/channels/${channelId}/thread-members`;
|
||||
}
|
||||
|
||||
export function THREAD_USER(channelId: Snowflake, userId: Snowflake) {
|
||||
return `/channels/${channelId}/thread-members/${userId}`;
|
||||
}
|
||||
|
||||
export function THREAD_ARCHIVED(channelId: Snowflake) {
|
||||
return `/channels/${channelId}/threads/archived`;
|
||||
}
|
||||
|
||||
export function THREAD_ARCHIVED_PUBLIC(channelId: Snowflake, options?: ListArchivedThreads) {
|
||||
let url = `/channels/${channelId}/threads/archived/public?`;
|
||||
|
||||
if (options) {
|
||||
if (options.before) url += `before=${new Date(options.before).toISOString()}`;
|
||||
if (options.limit) url += `&limit=${options.limit}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
export function THREAD_ARCHIVED_PRIVATE(channelId: Snowflake, options?: ListArchivedThreads) {
|
||||
let url = `/channels/${channelId}/threads/archived/private?`;
|
||||
|
||||
if (options) {
|
||||
if (options.before) url += `before=${new Date(options.before).toISOString()}`;
|
||||
if (options.limit) url += `&limit=${options.limit}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
export function THREAD_ARCHIVED_PRIVATE_JOINED(channelId: Snowflake, options?: ListArchivedThreads) {
|
||||
let url = `/channels/${channelId}/users/@me/threads/archived/private?`;
|
||||
|
||||
if (options) {
|
||||
if (options.before) url += `before=${new Date(options.before).toISOString()}`;
|
||||
if (options.limit) url += `&limit=${options.limit}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
export function FORUM_START(channelId: Snowflake) {
|
||||
return `/channels/${channelId}/threads?has_message=true`;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user