mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-03 05:26:07 +00:00
commit
4ae53b821c
@ -8,6 +8,10 @@ import type {
|
|||||||
DiscordMemberWithUser,
|
DiscordMemberWithUser,
|
||||||
DiscordMessage,
|
DiscordMessage,
|
||||||
DiscordMessageDelete,
|
DiscordMessageDelete,
|
||||||
|
DiscordMessageReactionAdd,
|
||||||
|
DiscordMessageReactionRemove,
|
||||||
|
DiscordMessageReactionRemoveAll,
|
||||||
|
DiscordMessageReactionRemoveEmoji,
|
||||||
DiscordReady,
|
DiscordReady,
|
||||||
// DiscordThreadMemberUpdate,
|
// DiscordThreadMemberUpdate,
|
||||||
// DiscordThreadMembersUpdate,
|
// DiscordThreadMembersUpdate,
|
||||||
@ -19,6 +23,7 @@ import type { Channel } from "../structures/channels/ChannelFactory.ts";
|
|||||||
import ChannelFactory from "../structures/channels/ChannelFactory.ts";
|
import ChannelFactory from "../structures/channels/ChannelFactory.ts";
|
||||||
import GuildChannel from "../structures/channels/GuildChannel.ts";
|
import GuildChannel from "../structures/channels/GuildChannel.ts";
|
||||||
import ThreadChannel from "../structures/channels/ThreadChannel.ts";
|
import ThreadChannel from "../structures/channels/ThreadChannel.ts";
|
||||||
|
import ThreadMember from "../structures/ThreadMember.ts";
|
||||||
import Member from "../structures/Member.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 User from "../structures/User.ts";
|
||||||
@ -103,10 +108,7 @@ export const THREAD_LIST_SYNC: RawHandler<DiscordThreadListSync> = (session, _sh
|
|||||||
guildId: payload.guild_id,
|
guildId: payload.guild_id,
|
||||||
channelIds: payload.channel_ids ?? [],
|
channelIds: payload.channel_ids ?? [],
|
||||||
threads: payload.threads.map((channel) => new ThreadChannel(session, channel, payload.guild_id)),
|
threads: payload.threads.map((channel) => new ThreadChannel(session, channel, payload.guild_id)),
|
||||||
members: payload.members.map((member) =>
|
members: payload.members.map((member) => new ThreadMember(session, member)),
|
||||||
// @ts-ignore: TODO: thread member structure
|
|
||||||
new Member(session, member as DiscordMemberWithUser, payload.guild_id)
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -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) => {
|
export const raw: RawHandler<unknown> = (session, shardId, data) => {
|
||||||
session.emit("raw", data, shardId);
|
session.emit("raw", data, shardId);
|
||||||
};
|
};
|
||||||
@ -126,12 +146,19 @@ export interface Ready extends Omit<DiscordReady, "user"> {
|
|||||||
user: User;
|
user: User;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: add partial reactions or something
|
||||||
|
type MessageReaction = any;
|
||||||
|
|
||||||
// deno-fmt-ignore-file
|
// deno-fmt-ignore-file
|
||||||
export interface Events {
|
export interface Events {
|
||||||
"ready": Handler<[Ready, number]>;
|
"ready": Handler<[Ready, number]>;
|
||||||
"messageCreate": Handler<[Message]>;
|
"messageCreate": Handler<[Message]>;
|
||||||
"messageUpdate": Handler<[Message]>;
|
"messageUpdate": Handler<[Message]>;
|
||||||
"messageDelete": Handler<[{ id: Snowflake, channelId: Snowflake, guildId?: Snowflake }]>;
|
"messageDelete": Handler<[{ id: Snowflake, channelId: Snowflake, guildId?: Snowflake }]>;
|
||||||
|
"messageReactionAdd": Handler<[MessageReaction]>;
|
||||||
|
"messageReactionRemove": Handler<[MessageReaction]>;
|
||||||
|
"messageReactionRemoveAll": Handler<[MessageReaction]>;
|
||||||
|
"messageReactionRemoveEmoji": Handler<[MessageReaction]>;
|
||||||
"guildMemberAdd": Handler<[Member]>;
|
"guildMemberAdd": Handler<[Member]>;
|
||||||
"guildMemberUpdate": Handler<[Member]>;
|
"guildMemberUpdate": Handler<[Member]>;
|
||||||
"guildMemberRemove": Handler<[User, Snowflake]>;
|
"guildMemberRemove": Handler<[User, Snowflake]>;
|
||||||
@ -142,7 +169,7 @@ export interface Events {
|
|||||||
"threadCreate": Handler<[ThreadChannel]>;
|
"threadCreate": Handler<[ThreadChannel]>;
|
||||||
"threadUpdate": Handler<[ThreadChannel]>;
|
"threadUpdate": Handler<[ThreadChannel]>;
|
||||||
"threadDelete": Handler<[ThreadChannel]>;
|
"threadDelete": Handler<[ThreadChannel]>;
|
||||||
"threadListSync": Handler<[{ guildId: Snowflake, channelIds: Snowflake[], threads: ThreadChannel[], members: Member[] }]>
|
"threadListSync": Handler<[{ guildId: Snowflake, channelIds: Snowflake[], threads: ThreadChannel[], members: ThreadMember[] }]>
|
||||||
"interactionCreate": Handler<[Interaction]>;
|
"interactionCreate": Handler<[Interaction]>;
|
||||||
"raw": Handler<[unknown, number]>;
|
"raw": Handler<[unknown, number]>;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import type { Model } from "./Base.ts";
|
import type { Model } from "./Base.ts";
|
||||||
import type { Snowflake } from "../util/Snowflake.ts";
|
|
||||||
import type { Session } from "../session/Session.ts";
|
import type { Session } from "../session/Session.ts";
|
||||||
import type {
|
import type {
|
||||||
AllowedMentionsTypes,
|
AllowedMentionsTypes,
|
||||||
@ -7,15 +6,20 @@ import type {
|
|||||||
DiscordMessage,
|
DiscordMessage,
|
||||||
DiscordUser,
|
DiscordUser,
|
||||||
FileContent,
|
FileContent,
|
||||||
|
MessageTypes,
|
||||||
|
MessageActivityTypes,
|
||||||
} from "../vendor/external.ts";
|
} from "../vendor/external.ts";
|
||||||
import type { Component } from "./components/Component.ts";
|
import type { Component } from "./components/Component.ts";
|
||||||
import type { GetReactions } from "../util/Routes.ts";
|
import type { GetReactions } from "../util/Routes.ts";
|
||||||
import { MessageFlags } from "../util/shared/flags.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 User from "./User.ts";
|
||||||
import Member from "./Member.ts";
|
import Member from "./Member.ts";
|
||||||
import Attachment from "./Attachment.ts";
|
import Attachment from "./Attachment.ts";
|
||||||
import ComponentFactory from "./components/ComponentFactory.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";
|
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
|
* @link https://discord.com/developers/docs/resources/channel#create-message-json-params
|
||||||
*/
|
*/
|
||||||
export interface CreateMessage {
|
export interface CreateMessage {
|
||||||
|
embeds?: DiscordEmbed[];
|
||||||
content?: string;
|
content?: string;
|
||||||
allowedMentions?: AllowedMentions;
|
allowedMentions?: AllowedMentions;
|
||||||
files?: FileContent[];
|
files?: FileContent[];
|
||||||
messageReference?: CreateMessageReference;
|
messageReference?: CreateMessageReference;
|
||||||
embeds?: DiscordEmbed[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,19 +78,32 @@ export class Message implements Model {
|
|||||||
this.session = session;
|
this.session = session;
|
||||||
this.id = data.id;
|
this.id = data.id;
|
||||||
|
|
||||||
|
this.type = data.type;
|
||||||
this.channelId = data.channel_id;
|
this.channelId = data.channel_id;
|
||||||
this.guildId = data.guild_id;
|
this.guildId = data.guild_id;
|
||||||
|
this.applicationId = data.application_id;
|
||||||
|
|
||||||
this.author = new User(session, data.author);
|
this.author = new User(session, data.author);
|
||||||
this.flags = data.flags;
|
this.flags = data.flags;
|
||||||
this.pinned = !!data.pinned;
|
this.pinned = !!data.pinned;
|
||||||
this.tts = !!data.tts;
|
this.tts = !!data.tts;
|
||||||
this.content = data.content!;
|
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.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
|
// webhook handling
|
||||||
if (data.author && data.author.discriminator === "0000") {
|
if (data.author.discriminator === "0000") {
|
||||||
this.webhook = {
|
this.webhook = {
|
||||||
id: data.author.id,
|
id: data.author.id,
|
||||||
username: data.author.username,
|
username: data.author.username,
|
||||||
@ -96,30 +113,70 @@ export class Message implements Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// user is always null on MessageCreate and its replaced with author
|
// user is always null on MessageCreate and its replaced with author
|
||||||
|
if (data.guild_id && data.member && !this.isWebhookMessage()) {
|
||||||
if (data.guild_id && data.member && data.author && !this.isWebhookMessage()) {
|
|
||||||
this.member = new Member(session, { ...data.member, user: data.author }, data.guild_id);
|
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 session: Session;
|
||||||
readonly id: Snowflake;
|
readonly id: Snowflake;
|
||||||
|
|
||||||
|
type: MessageTypes;
|
||||||
channelId: Snowflake;
|
channelId: Snowflake;
|
||||||
guildId?: Snowflake;
|
guildId?: Snowflake;
|
||||||
|
applicationId?: Snowflake;
|
||||||
author: User;
|
author: User;
|
||||||
flags?: MessageFlags;
|
flags?: MessageFlags;
|
||||||
pinned: boolean;
|
pinned: boolean;
|
||||||
tts: boolean;
|
tts: boolean;
|
||||||
content: string;
|
content: string;
|
||||||
|
nonce?: string | number;
|
||||||
|
mentionEveryone: boolean;
|
||||||
|
|
||||||
|
timestamp: number;
|
||||||
|
editedTimestamp?: number;
|
||||||
|
|
||||||
|
reactions: MessageReaction[];
|
||||||
attachments: Attachment[];
|
attachments: Attachment[];
|
||||||
|
embeds: DiscordEmbed[];
|
||||||
member?: Member;
|
member?: Member;
|
||||||
components?: Component[];
|
thread?: ThreadChannel;
|
||||||
|
components: Component[];
|
||||||
|
|
||||||
webhook?: WebhookAuthor;
|
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() {
|
get url() {
|
||||||
return `https://discord.com/channels/${this.guildId ?? "@me"}/${this.channelId}/${this.id}`;
|
return `https://discord.com/channels/${this.guildId ?? "@me"}/${this.channelId}/${this.id}`;
|
||||||
@ -301,12 +358,13 @@ export class Message implements Model {
|
|||||||
return this.crosspost;
|
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;
|
return !!this.guildId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** isWebhookMessage if the messages comes from a Webhook */
|
/** wheter the messages comes from a Webhook */
|
||||||
isWebhookMessage(): this is User & { author: Partial<User>; webhook: WebhookAuthor; member: undefined } {
|
isWebhookMessage(): this is Message & { author: Partial<User>; webhook: WebhookAuthor; member: undefined } {
|
||||||
return !!this.webhook;
|
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 { 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 { 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 BaseChannel from "./BaseChannel.ts";
|
||||||
|
import ThreadChannel from "./ThreadChannel.ts";
|
||||||
|
import ThreadMember from "../ThreadMember.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";
|
||||||
|
|
||||||
@ -44,7 +47,41 @@ export class GuildChannel extends BaseChannel implements Model {
|
|||||||
return invites.map((invite) => new Invite(this.session, invite));
|
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> {
|
async createThread(options: ThreadCreateOptions): Promise<ThreadChannel> {
|
||||||
const thread = await this.session.rest.runMethod<DiscordChannel>(
|
const thread = await this.session.rest.runMethod<DiscordChannel>(
|
||||||
this.session.rest,
|
this.session.rest,
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
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 { ChannelTypes, DiscordChannel } from "../../vendor/external.ts";
|
import type { ChannelTypes, DiscordChannel, DiscordThreadMember } from "../../vendor/external.ts";
|
||||||
import GuildChannel from "./GuildChannel.ts";
|
import GuildChannel from "./GuildChannel.ts";
|
||||||
import TextChannel from "./TextChannel.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 {
|
export class ThreadChannel extends GuildChannel implements Model {
|
||||||
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
|
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
|
||||||
@ -16,6 +18,10 @@ export class ThreadChannel extends GuildChannel implements Model {
|
|||||||
this.messageCount = data.message_count;
|
this.messageCount = data.message_count;
|
||||||
this.memberCount = data.member_count;
|
this.memberCount = data.member_count;
|
||||||
this.ownerId = data.owner_id;
|
this.ownerId = data.owner_id;
|
||||||
|
|
||||||
|
if (data.member) {
|
||||||
|
this.member = new ThreadMember(session, data.member);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override type: ChannelTypes.GuildNewsThread | ChannelTypes.GuildPrivateThread | ChannelTypes.GuildPublicThread;
|
override type: ChannelTypes.GuildNewsThread | ChannelTypes.GuildPrivateThread | ChannelTypes.GuildPublicThread;
|
||||||
@ -25,7 +31,50 @@ export class ThreadChannel extends GuildChannel implements Model {
|
|||||||
locked?: boolean;
|
locked?: boolean;
|
||||||
messageCount?: number;
|
messageCount?: number;
|
||||||
memberCount?: number;
|
memberCount?: number;
|
||||||
|
member?: ThreadMember;
|
||||||
ownerId?: Snowflake;
|
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);
|
TextChannel.applyTo(ThreadChannel);
|
||||||
|
@ -7,6 +7,8 @@ import type {
|
|||||||
DiscordInviteMetadata,
|
DiscordInviteMetadata,
|
||||||
DiscordMemberWithUser,
|
DiscordMemberWithUser,
|
||||||
DiscordRole,
|
DiscordRole,
|
||||||
|
DiscordListActiveThreads,
|
||||||
|
DiscordListArchivedThreads,
|
||||||
} from "../../vendor/external.ts";
|
} from "../../vendor/external.ts";
|
||||||
import type { GetInvite } from "../../util/Routes.ts";
|
import type { GetInvite } from "../../util/Routes.ts";
|
||||||
import {
|
import {
|
||||||
@ -21,6 +23,8 @@ import BaseGuild from "./BaseGuild.ts";
|
|||||||
import Role from "../Role.ts";
|
import Role from "../Role.ts";
|
||||||
import GuildEmoji from "../GuildEmoji.ts";
|
import GuildEmoji from "../GuildEmoji.ts";
|
||||||
import Invite from "../Invite.ts";
|
import Invite from "../Invite.ts";
|
||||||
|
import ThreadMember from "../ThreadMember.ts";
|
||||||
|
import ThreadChannel from "../channels/ThreadChannel.ts";
|
||||||
import * as Routes from "../../util/Routes.ts";
|
import * as Routes from "../../util/Routes.ts";
|
||||||
|
|
||||||
export interface CreateRole {
|
export interface CreateRole {
|
||||||
@ -362,6 +366,23 @@ export class Guild extends BaseGuild implements Model {
|
|||||||
|
|
||||||
return result.pruned;
|
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;
|
export default Guild;
|
||||||
|
@ -228,3 +228,74 @@ export function GUILD_MEMBER_ROLE(guildId: Snowflake, memberId: Snowflake, roleI
|
|||||||
export function CHANNEL_WEBHOOKS(channelId: Snowflake) {
|
export function CHANNEL_WEBHOOKS(channelId: Snowflake) {
|
||||||
return `/channels/${channelId}/webhooks`;
|
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