mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-01 20:46:08 +00:00
feat: members
This commit is contained in:
parent
f247669902
commit
bba3ded08c
111
structures/Member.ts
Normal file
111
structures/Member.ts
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import type { Model } from "./Base.ts";
|
||||||
|
import type { Snowflake } from "../util/Snowflake.ts";
|
||||||
|
import type { Session } from "../session/Session.ts";
|
||||||
|
import type { DiscordMember, MakeRequired } from "../vendor/external.ts";
|
||||||
|
import type { ImageFormat, ImageSize } from "../util/shared/images.ts";
|
||||||
|
import { iconBigintToHash, iconHashToBigInt } from "../util/hash.ts";
|
||||||
|
import { Routes } from "../util/mod.ts";
|
||||||
|
import { User } from "./User.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
|
||||||
|
* TODO: add a `guild` property somehow
|
||||||
|
* @link https://discord.com/developers/docs/resources/guild#guild-member-object
|
||||||
|
* */
|
||||||
|
export class Member implements Model {
|
||||||
|
constructor(session: Session, data: MakeRequired<DiscordMember, "user">) {
|
||||||
|
this.session = session;
|
||||||
|
this.user = new User(session, data.user);
|
||||||
|
this.avatarHash = data.avatar ? iconHashToBigInt(data.avatar) : undefined;
|
||||||
|
this.nickname = data.nick ? data.nick : undefined;
|
||||||
|
this.joinedTimestamp = Number.parseInt(data.joined_at);
|
||||||
|
this.roles = data.roles;
|
||||||
|
this.deaf = !!data.deaf;
|
||||||
|
this.mute = !!data.mute;
|
||||||
|
this.pending = !!data.pending;
|
||||||
|
this.communicationDisabledUntilTimestamp = data.communication_disabled_until ? Number.parseInt(data.communication_disabled_until) : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly session: Session;
|
||||||
|
|
||||||
|
user: User;
|
||||||
|
avatarHash?: bigint;
|
||||||
|
nickname?: string;
|
||||||
|
joinedTimestamp: number;
|
||||||
|
roles: Snowflake[];
|
||||||
|
deaf: boolean;
|
||||||
|
mute: boolean;
|
||||||
|
pending: boolean;
|
||||||
|
communicationDisabledUntilTimestamp?: number;
|
||||||
|
|
||||||
|
/** shorthand to User.id */
|
||||||
|
get id(): Snowflake {
|
||||||
|
return this.user.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
get nicknameOrUsername() {
|
||||||
|
return this.nickname ?? this.user.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
get joinedAt() {
|
||||||
|
return new Date(this.joinedTimestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bans the member
|
||||||
|
* */
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kicks the member
|
||||||
|
* */
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** gets the user's avatar */
|
||||||
|
avatarUrl(options: { format?: ImageFormat; size?: ImageSize } = { size: 128 }) {
|
||||||
|
let url: string;
|
||||||
|
|
||||||
|
if (!this.avatarHash) {
|
||||||
|
url = Routes.USER_DEFAULT_AVATAR(Number(this.user.discriminator) % 5);
|
||||||
|
} else {
|
||||||
|
url = Routes.USER_AVATAR(this.id, iconBigintToHash(this.avatarHash));
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${url}.${options.format ?? (url.includes("/a_") ? "gif" : "jpg")}?size=${options.size}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
return `<@!${this.user.id}>`;
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ import type { Snowflake } from "../util/Snowflake.ts";
|
|||||||
import type { Session } from "../session/mod.ts";
|
import type { Session } from "../session/mod.ts";
|
||||||
import type { AllowedMentionsTypes, DiscordMessage } from "../vendor/external.ts";
|
import type { AllowedMentionsTypes, DiscordMessage } from "../vendor/external.ts";
|
||||||
import { User } from "./User.ts";
|
import { User } from "./User.ts";
|
||||||
|
import { Member } from "./Member.ts";
|
||||||
import { Attachment } from "./Attachment.ts";
|
import { Attachment } from "./Attachment.ts";
|
||||||
import { MessageFlags, Routes } from "../util/mod.ts";
|
import { MessageFlags, Routes } from "../util/mod.ts";
|
||||||
|
|
||||||
@ -52,6 +53,12 @@ export class Message implements Model {
|
|||||||
this.content = data.content!;
|
this.content = data.content!;
|
||||||
|
|
||||||
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
|
||||||
|
this.member = data.member ? new Member(session, {
|
||||||
|
...data.member,
|
||||||
|
user: data.author,
|
||||||
|
}) : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly session: Session;
|
readonly session: Session;
|
||||||
@ -66,6 +73,7 @@ export class Message implements Model {
|
|||||||
content: string;
|
content: string;
|
||||||
|
|
||||||
attachments: Attachment[];
|
attachments: Attachment[];
|
||||||
|
member?: Member;
|
||||||
|
|
||||||
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}`;
|
||||||
|
@ -2,19 +2,10 @@ 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/mod.ts";
|
import type { Session } from "../session/mod.ts";
|
||||||
import type { DiscordUser } from "../vendor/external.ts";
|
import type { DiscordUser } from "../vendor/external.ts";
|
||||||
|
import type { ImageFormat, ImageSize } from "../util/shared/images.ts";
|
||||||
import { iconBigintToHash, iconHashToBigInt } from "../util/hash.ts";
|
import { iconBigintToHash, iconHashToBigInt } from "../util/hash.ts";
|
||||||
import { Routes } from "../util/mod.ts";
|
import { Routes } from "../util/mod.ts";
|
||||||
|
|
||||||
/**
|
|
||||||
* @link https://discord.com/developers/docs/reference#image-formatting
|
|
||||||
*/
|
|
||||||
export type ImageFormat = "jpg" | "jpeg" | "png" | "webp" | "gif" | "json";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @link https://discord.com/developers/docs/reference#image-formatting
|
|
||||||
*/
|
|
||||||
export type ImageSize = 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a user
|
* Represents a user
|
||||||
* @link https://discord.com/developers/docs/resources/user#user-object
|
* @link https://discord.com/developers/docs/resources/user#user-object
|
||||||
|
@ -12,7 +12,7 @@ session.on("ready", (_shardId, payload) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
session.on("messageCreate", (message) => {
|
session.on("messageCreate", (message) => {
|
||||||
if (message.content === "!ping") {
|
if (message.content.startsWith("!ping")) {
|
||||||
message.reply({ content: "pong!" });
|
message.reply({ content: "pong!" });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -31,10 +31,10 @@ export function CHANNEL_MESSAGES(channelId: Snowflake, options?: GetMessagesOpti
|
|||||||
let url = `/channels/${channelId}/messages?`;
|
let url = `/channels/${channelId}/messages?`;
|
||||||
|
|
||||||
if (options) {
|
if (options) {
|
||||||
if ("after" in options && options.after) url += `after=${options.after}`;
|
if (options.after) url += `after=${options.after}`;
|
||||||
if ("before" in options && options.before) url += `&before=${options.before}`;
|
if (options.before) url += `&before=${options.before}`;
|
||||||
if ("around" in options && options.around) url += `&around=${options.around}`;
|
if (options.around) url += `&around=${options.around}`;
|
||||||
if ("limit" in options && options.limit) url += `&limit=${options.limit}`;
|
if (options.limit) url += `&limit=${options.limit}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
@ -44,3 +44,32 @@ export function CHANNEL_MESSAGES(channelId: Snowflake, options?: GetMessagesOpti
|
|||||||
export function CHANNEL_MESSAGE(channelId: Snowflake, messageId: Snowflake) {
|
export function CHANNEL_MESSAGE(channelId: Snowflake, messageId: Snowflake) {
|
||||||
return `/channels/${channelId}/messages/${messageId}`;
|
return `/channels/${channelId}/messages/${messageId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** used to kick members */
|
||||||
|
export function GUILD_MEMBER(guildId: Snowflake, userId: Snowflake) {
|
||||||
|
return `/guilds/${guildId}/members/${userId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** used to ban members */
|
||||||
|
export function GUILD_BAN(guildId: Snowflake, userId: Snowflake) {
|
||||||
|
return `/guilds/${guildId}/bans/${userId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GetBans {
|
||||||
|
limit?: number;
|
||||||
|
before?: Snowflake;
|
||||||
|
after?: Snowflake;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** used to unban members */
|
||||||
|
export function GUILD_BANS(guildId: Snowflake, options?: GetBans) {
|
||||||
|
let url = `/guilds/${guildId}/bans?`;
|
||||||
|
|
||||||
|
if (options) {
|
||||||
|
if (options.limit) url += `limit=${options.limit}`;
|
||||||
|
if (options.after) url += `&after=${options.after}`;
|
||||||
|
if (options.before) url += `&before=${options.before}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
@ -2,4 +2,5 @@ export * from "./EventEmmiter.ts";
|
|||||||
export * from "./Snowflake.ts";
|
export * from "./Snowflake.ts";
|
||||||
export * from "./hash.ts";
|
export * from "./hash.ts";
|
||||||
export * from "./shared/flags.ts";
|
export * from "./shared/flags.ts";
|
||||||
|
export * from "./shared/images.ts";
|
||||||
export * as Routes from "./Routes.ts";
|
export * as Routes from "./Routes.ts";
|
||||||
|
9
util/shared/images.ts
Normal file
9
util/shared/images.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* @link https://discord.com/developers/docs/reference#image-formatting
|
||||||
|
*/
|
||||||
|
export type ImageFormat = "jpg" | "jpeg" | "png" | "webp" | "gif" | "json";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://discord.com/developers/docs/reference#image-formatting
|
||||||
|
*/
|
||||||
|
export type ImageSize = 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096;
|
Loading…
x
Reference in New Issue
Block a user