mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-01 20:46:08 +00:00
minor changes
This commit is contained in:
parent
5083ce45a5
commit
8a5798e6a2
@ -1 +1 @@
|
||||
export * from "./MessageRelated.ts";
|
||||
export * from "./MessageRelated.ts";
|
||||
|
@ -2,17 +2,17 @@ import type { DiscordMessage, DiscordReady } from "../vendor/external.ts";
|
||||
import type { Session } from "../session/Session.ts";
|
||||
import { Message } from "../structures/Message.ts";
|
||||
|
||||
type Handler<T> = (...args: [ Session, number, T ]) => void;
|
||||
type Handler<T> = (...args: [Session, number, T]) => void;
|
||||
|
||||
// TODO: move this lol
|
||||
export const READY: Handler<DiscordReady> = (session, shardId, payload) => {
|
||||
session.emit("ready", shardId, payload);
|
||||
session.emit("ready", shardId, payload);
|
||||
};
|
||||
|
||||
export const MESSAGE_CREATE: Handler<DiscordMessage> = (session, _shardId, message) => {
|
||||
session.emit("messageCreate", new Message(session, message));
|
||||
session.emit("messageCreate", new Message(session, message));
|
||||
};
|
||||
|
||||
export const raw: Handler<unknown> = (session, shardId, data) => {
|
||||
session.emit("raw", data, shardId);
|
||||
}
|
||||
session.emit("raw", data, shardId);
|
||||
};
|
||||
|
@ -1,8 +1,4 @@
|
||||
import type {
|
||||
DiscordGetGatewayBot,
|
||||
GatewayBot,
|
||||
GatewayIntents,
|
||||
} from "../vendor/external.ts";
|
||||
import type { DiscordGetGatewayBot, GatewayBot, GatewayIntents } from "../vendor/external.ts";
|
||||
|
||||
import { EventEmitter, Routes, Snowflake } from "../util/mod.ts";
|
||||
|
||||
|
@ -3,10 +3,10 @@ import type { Session } from "../session/mod.ts";
|
||||
|
||||
/**
|
||||
* Represents a Discord data model
|
||||
* */
|
||||
export interface Base {
|
||||
*/
|
||||
export interface Model {
|
||||
/** id of the model */
|
||||
id: Snowflake;
|
||||
id: Snowflake;
|
||||
/** reference to the client that instantiated the model */
|
||||
session: Session;
|
||||
}
|
||||
}
|
||||
|
@ -1,94 +1,136 @@
|
||||
import type { Base } from "./Base.ts";
|
||||
import type { Model } from "./Base.ts";
|
||||
import type { Snowflake } from "../util/Snowflake.ts";
|
||||
import type { Session } from "../session/mod.ts";
|
||||
import type { DiscordMessage, AllowedMentionsTypes } from "../vendor/external.ts";
|
||||
import { Routes } from "../util/mod.ts";
|
||||
import type { AllowedMentionsTypes, DiscordMessage } from "../vendor/external.ts";
|
||||
import { User } from "./User.ts";
|
||||
import { MessageFlags, Routes } from "../util/mod.ts";
|
||||
|
||||
/**
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/resources/channel#allowed-mentions-object
|
||||
* */
|
||||
*/
|
||||
export interface AllowedMentions {
|
||||
parse?: AllowedMentionsTypes[];
|
||||
repliedUser?: boolean;
|
||||
roles?: Snowflake[];
|
||||
users?: Snowflake[];
|
||||
parse?: AllowedMentionsTypes[];
|
||||
repliedUser?: boolean;
|
||||
roles?: Snowflake[];
|
||||
users?: Snowflake[];
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/resources/channel#edit-message-json-params
|
||||
* */
|
||||
*/
|
||||
export interface EditMessage {
|
||||
content?: string;
|
||||
allowedMentions?: AllowedMentions;
|
||||
content?: string;
|
||||
allowedMentions?: AllowedMentions;
|
||||
flags?: MessageFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/resources/channel#create-message-json-params
|
||||
* */
|
||||
*/
|
||||
export interface CreateMessage {
|
||||
content?: string;
|
||||
allowedMentions?: AllowedMentions;
|
||||
content?: string;
|
||||
allowedMentions?: AllowedMentions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a message
|
||||
* @link https://discord.com/developers/docs/resources/channel#message-object
|
||||
* */
|
||||
export class Message implements Base {
|
||||
constructor(session: Session, data: DiscordMessage) {
|
||||
this.session = session;
|
||||
*/
|
||||
export class Message implements Model {
|
||||
constructor(session: Session, data: DiscordMessage) {
|
||||
this.session = session;
|
||||
this.id = data.id;
|
||||
|
||||
this.id = data.id;
|
||||
this.channelId = data.channel_id;
|
||||
this.guildId = data.guild_id;
|
||||
|
||||
this.channelId = data.channel_id;
|
||||
}
|
||||
this.author = new User(session, data.author);
|
||||
this.flags = data.flags;
|
||||
this.pinned = !!data.pinned;
|
||||
this.tts = !!data.tts;
|
||||
this.content = data.content!;
|
||||
}
|
||||
|
||||
/** the session that instantiated the message */
|
||||
session: Session;
|
||||
readonly session: Session;
|
||||
readonly id: Snowflake;
|
||||
|
||||
/** the id of the message */
|
||||
id: Snowflake;
|
||||
channelId: Snowflake;
|
||||
guildId?: Snowflake;
|
||||
author: User;
|
||||
flags?: MessageFlags;
|
||||
pinned: boolean;
|
||||
tts: boolean;
|
||||
content: string;
|
||||
|
||||
/** the id of the channel where the message was sent */
|
||||
channelId: Snowflake;
|
||||
get url() {
|
||||
return `https://discord.com/channels/${this.guildId ?? "@me"}/${this.channelId}/${this.id}`;
|
||||
}
|
||||
|
||||
/** Edits the current message */
|
||||
async edit({ content, allowedMentions }: EditMessage): Promise<Message> {
|
||||
const message = await this.session.rest.runMethod(
|
||||
this.session.rest,
|
||||
"POST",
|
||||
Routes.CHANNEL_MESSAGE(this.id, this.channelId),
|
||||
{
|
||||
content,
|
||||
allowed_mentions: {
|
||||
parse: allowedMentions?.parse,
|
||||
roles: allowedMentions?.roles,
|
||||
users: allowedMentions?.users,
|
||||
replied_user: allowedMentions?.repliedUser,
|
||||
},
|
||||
}
|
||||
);
|
||||
/** Edits the current message */
|
||||
async edit({ content, allowedMentions, flags }: EditMessage): Promise<Message> {
|
||||
const message = await this.session.rest.runMethod(
|
||||
this.session.rest,
|
||||
"POST",
|
||||
Routes.CHANNEL_MESSAGE(this.id, this.channelId),
|
||||
{
|
||||
content,
|
||||
allowed_mentions: {
|
||||
parse: allowedMentions?.parse,
|
||||
roles: allowedMentions?.roles,
|
||||
users: allowedMentions?.users,
|
||||
replied_user: allowedMentions?.repliedUser,
|
||||
},
|
||||
flags,
|
||||
},
|
||||
);
|
||||
|
||||
return message;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
/** Responds directly in the channel the message was sent */
|
||||
async respond({ content, allowedMentions }: CreateMessage): Promise<Message> {
|
||||
const message = await this.session.rest.runMethod(
|
||||
this.session.rest,
|
||||
"POST",
|
||||
Routes.CHANNEL_MESSAGES(this.channelId),
|
||||
{
|
||||
content,
|
||||
allowed_mentions: {
|
||||
parse: allowedMentions?.parse,
|
||||
roles: allowedMentions?.roles,
|
||||
users: allowedMentions?.users,
|
||||
replied_user: allowedMentions?.repliedUser,
|
||||
},
|
||||
}
|
||||
);
|
||||
async suppressEmbeds(suppress: true): Promise<Message>;
|
||||
async suppressEmbeds(suppress: false): Promise<Message | undefined>;
|
||||
async suppressEmbeds(suppress = true) {
|
||||
if (this.flags === MessageFlags.SUPPRESS_EMBEDS && suppress === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
}
|
||||
const message = await this.edit({ flags: MessageFlags.SUPPRESS_EMBEDS });
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
async delete({ reason }: { reason: string }): Promise<Message> {
|
||||
await this.session.rest.runMethod<undefined>(
|
||||
this.session.rest,
|
||||
"DELETE",
|
||||
Routes.CHANNEL_MESSAGE(this.channelId, this.id),
|
||||
{ reason },
|
||||
);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Responds directly in the channel the message was sent */
|
||||
async respond({ content, allowedMentions }: CreateMessage): Promise<Message> {
|
||||
const message = await this.session.rest.runMethod(
|
||||
this.session.rest,
|
||||
"POST",
|
||||
Routes.CHANNEL_MESSAGES(this.channelId),
|
||||
{
|
||||
content,
|
||||
allowed_mentions: {
|
||||
parse: allowedMentions?.parse,
|
||||
roles: allowedMentions?.roles,
|
||||
users: allowedMentions?.users,
|
||||
replied_user: allowedMentions?.repliedUser,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
inGuild(): this is { guildId: string } & Message {
|
||||
return Boolean(this.guildId);
|
||||
}
|
||||
}
|
||||
|
64
structures/User.ts
Normal file
64
structures/User.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import type { Model } from "./Base.ts";
|
||||
import type { Snowflake } from "../util/Snowflake.ts";
|
||||
import type { Session } from "../session/mod.ts";
|
||||
import type { DiscordUser } from "../vendor/external.ts";
|
||||
import { iconBigintToHash, iconHashToBigInt } from "../util/hash.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
|
||||
* @link https://discord.com/developers/docs/resources/user#user-object
|
||||
*/
|
||||
export class User implements Model {
|
||||
constructor(session: Session, data: DiscordUser) {
|
||||
this.session = session;
|
||||
this.id = data.id;
|
||||
|
||||
this.username = data.username;
|
||||
this.discriminator = data.discriminator;
|
||||
this.avatarHash = data.avatar ? iconHashToBigInt(data.avatar) : undefined;
|
||||
this.accentColor = data.accent_color;
|
||||
this.bot = !!data.bot;
|
||||
this.system = !!data.system;
|
||||
this.banner = data.banner;
|
||||
}
|
||||
|
||||
readonly session: Session;
|
||||
readonly id: Snowflake;
|
||||
|
||||
username: string;
|
||||
discriminator: string;
|
||||
avatarHash?: bigint;
|
||||
accentColor?: number;
|
||||
bot: boolean;
|
||||
system: boolean;
|
||||
banner?: string;
|
||||
|
||||
/** gets the user's username#discriminator */
|
||||
get tag() {
|
||||
return `${this.username}#${this.discriminator}}`;
|
||||
}
|
||||
|
||||
/** 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.discriminator) % 5);
|
||||
} else {
|
||||
url = Routes.USER_AVATAR(this.id, iconBigintToHash(this.avatarHash));
|
||||
}
|
||||
|
||||
return `${url}.${options.format ?? (url.includes("/a_") ? "gif" : "jpg")}?size=${options.size}`;
|
||||
}
|
||||
}
|
23
tests/mod.ts
23
tests/mod.ts
@ -1,19 +1,20 @@
|
||||
import * as Discord from "./deps.ts";
|
||||
import { GatewayIntents, Session } from "./deps.ts";
|
||||
|
||||
if (!Deno.args[0]) {
|
||||
throw new Error("Please provide a token");
|
||||
}
|
||||
|
||||
const session = new Discord.Session({
|
||||
token: Deno.args[0],
|
||||
intents: Discord.GatewayIntents.MessageContent | Discord.GatewayIntents.Guilds |
|
||||
Discord.GatewayIntents.GuildMessages,
|
||||
const intents = GatewayIntents.MessageContent | GatewayIntents.Guilds | GatewayIntents.GuildMessages;
|
||||
const session = new Session({ token: Deno.args[0], intents });
|
||||
|
||||
session.on("ready", (_shardId, payload) => {
|
||||
console.log("Logged in as:", payload.user.username);
|
||||
});
|
||||
|
||||
session.on("ready", (payload) => console.log(payload));
|
||||
session.on("messageCreate", (payload) => console.log(payload));
|
||||
// session.on("raw", (data, shardId) => console.log(shardId, data));
|
||||
session.on("messageCreate", (message) => {
|
||||
if (message.content === "!ping") {
|
||||
message.respond({ content: "pong!" });
|
||||
}
|
||||
});
|
||||
|
||||
console.log("hello");
|
||||
|
||||
session.start();
|
||||
await session.start();
|
||||
|
13
util/Cdn.ts
Normal file
13
util/Cdn.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import type { Snowflake } from "./Snowflake.ts";
|
||||
import { baseEndpoints as Endpoints } from "../vendor/external.ts";
|
||||
|
||||
export function USER_AVATAR(userId: Snowflake, icon: string) {
|
||||
return `${Endpoints.CDN_URL}/avatars/${userId}/${icon}`;
|
||||
}
|
||||
|
||||
export function USER_DEFAULT_AVATAR(
|
||||
/** user discriminator */
|
||||
altIcon: number,
|
||||
) {
|
||||
return `${Endpoints.CDN_URL}/embed/avatars/${altIcon}.png`;
|
||||
}
|
@ -1,26 +1,29 @@
|
||||
import type { Snowflake } from "./Snowflake.ts";
|
||||
|
||||
// cdn endpoints
|
||||
export * from "./Cdn.ts";
|
||||
|
||||
export function GATEWAY_BOT() {
|
||||
return "/gateway/bot";
|
||||
}
|
||||
|
||||
export interface GetMessagesOptions {
|
||||
limit?: number;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface GetMessagesOptions {
|
||||
around?: Snowflake;
|
||||
limit?: number;
|
||||
around?: Snowflake;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface GetMessagesOptions {
|
||||
before?: Snowflake;
|
||||
limit?: number;
|
||||
before?: Snowflake;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface GetMessagesOptions {
|
||||
after?: Snowflake;
|
||||
limit?: number;
|
||||
after?: Snowflake;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
/** used to send messages */
|
||||
@ -40,4 +43,4 @@ export function CHANNEL_MESSAGES(channelId: Snowflake, options?: GetMessagesOpti
|
||||
/** used to edit messages */
|
||||
export function CHANNEL_MESSAGE(channelId: Snowflake, messageId: Snowflake) {
|
||||
return `/channels/${channelId}/messages/${messageId}`;
|
||||
}
|
||||
}
|
||||
|
14
util/hash.ts
Normal file
14
util/hash.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Memory optimizations
|
||||
* All credits to the Discordeno authors
|
||||
*/
|
||||
|
||||
export function iconHashToBigInt(hash: string) {
|
||||
return BigInt("0x" + hash.startsWith("a_") ? `a${hash.substring(2)}` : `b${hash}`);
|
||||
}
|
||||
|
||||
export function iconBigintToHash(icon: bigint) {
|
||||
const hash = icon.toString(16);
|
||||
|
||||
return hash.startsWith("a") ? `a_${hash.substring(1)}` : hash.substring(1);
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
export * from "./EventEmmiter.ts";
|
||||
export * from "./Snowflake.ts";
|
||||
export * from "./hash.ts";
|
||||
export * from "./shared/flags.ts";
|
||||
export * as Routes from "./Routes.ts";
|
||||
|
23
util/shared/flags.ts
Normal file
23
util/shared/flags.ts
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/resources/channel#message-object-message-flags
|
||||
*/
|
||||
export enum MessageFlags {
|
||||
/** this message has been published to subscribed channels (via Channel Following) */
|
||||
CROSSPOSTED = 1 << 0,
|
||||
/** this message originated from a message in another channel (via Channel Following) */
|
||||
IS_CROSSPOST = 1 << 1,
|
||||
/** do not include any embeds when serializing this message */
|
||||
SUPPRESS_EMBEDS = 1 << 2,
|
||||
/** the source message for this crosspost has been deleted (via Channel Following) */
|
||||
SOURCE_MESSAGE_DELETED = 1 << 3,
|
||||
/** this message came from the urgent message system */
|
||||
URGENT = 1 << 4,
|
||||
/** this message has an associated thread, with the same id as the message */
|
||||
HAS_THREAD = 1 << 5,
|
||||
/** this message is only visible to the user who invoked the Interaction */
|
||||
EPHEMERAL = 1 << 6,
|
||||
/** this message is an Interaction Response and the bot is "thinking" */
|
||||
LOADING = 1 << 7,
|
||||
/** this message failed to mention some roles and add their members to the thread */
|
||||
FAILED_TO_MENTION_SOME_ROLES_IN_THREAD = 1 << 8,
|
||||
}
|
1
vendor/external.ts
vendored
1
vendor/external.ts
vendored
@ -1,3 +1,4 @@
|
||||
export * from "./gateway/mod.ts";
|
||||
export * from "./rest/mod.ts";
|
||||
export * from "./types/mod.ts";
|
||||
export * from "./util/constants.ts";
|
||||
|
Loading…
x
Reference in New Issue
Block a user