mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-04 22:16:08 +00:00
feat: message structure
This commit is contained in:
parent
781ef10e8c
commit
5083ce45a5
1
handlers/HandlerManager.ts
Normal file
1
handlers/HandlerManager.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from "./MessageRelated.ts";
|
18
handlers/MessageRelated.ts
Normal file
18
handlers/MessageRelated.ts
Normal file
@ -0,0 +1,18 @@
|
||||
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;
|
||||
|
||||
// TODO: move this lol
|
||||
export const READY: Handler<DiscordReady> = (session, shardId, payload) => {
|
||||
session.emit("ready", shardId, payload);
|
||||
};
|
||||
|
||||
export const MESSAGE_CREATE: Handler<DiscordMessage> = (session, _shardId, message) => {
|
||||
session.emit("messageCreate", new Message(session, message));
|
||||
};
|
||||
|
||||
export const raw: Handler<unknown> = (session, shardId, data) => {
|
||||
session.emit("raw", data, shardId);
|
||||
}
|
2
mod.ts
2
mod.ts
@ -1,5 +1,3 @@
|
||||
export * from "./session/mod.ts";
|
||||
export * from "./util/mod.ts";
|
||||
export * from "./structures/mod.ts";
|
||||
export * from "./vendor/external.ts";
|
||||
export * from "./handlers/mod.ts";
|
||||
|
@ -1,9 +1,10 @@
|
||||
import type { DiscordGatewayPayload, DiscordMessage, DiscordReady, Shard } from "../vendor/external.ts";
|
||||
import type { DiscordGatewayPayload, DiscordReady, Shard } from "../vendor/external.ts";
|
||||
import type { Message } from "../structures/Message.ts";
|
||||
|
||||
export type DiscordRawEventHandler = (shard: Shard, data: DiscordGatewayPayload) => unknown;
|
||||
|
||||
export interface Events {
|
||||
ready(payload: DiscordReady, shardId: number): unknown;
|
||||
messageCreate(message: DiscordMessage): unknown;
|
||||
ready(shardId: number, payload: DiscordReady): unknown;
|
||||
messageCreate(message: Message): unknown;
|
||||
raw(data: DiscordGatewayPayload, shardId: number): unknown;
|
||||
}
|
||||
|
@ -1,12 +1,7 @@
|
||||
import type {
|
||||
DiscordGatewayPayload,
|
||||
DiscordGetGatewayBot,
|
||||
DiscordMessage,
|
||||
DiscordReady,
|
||||
GatewayBot,
|
||||
GatewayDispatchEventNames,
|
||||
GatewayIntents,
|
||||
Shard,
|
||||
} from "../vendor/external.ts";
|
||||
|
||||
import { EventEmitter, Routes, Snowflake } from "../util/mod.ts";
|
||||
@ -15,6 +10,8 @@ import type { DiscordRawEventHandler, Events } from "./Events.ts";
|
||||
|
||||
import { createGatewayManager, createRestManager } from "../vendor/external.ts";
|
||||
|
||||
import * as Actions from "../handlers/HandlerManager.ts";
|
||||
|
||||
export interface RestOptions {
|
||||
secretKey?: string;
|
||||
applicationId?: Snowflake;
|
||||
@ -48,11 +45,14 @@ export class Session extends EventEmitter {
|
||||
this.options = options;
|
||||
|
||||
const defHandler: DiscordRawEventHandler = (shard, data) => {
|
||||
this.emit("raw", data, shard.id);
|
||||
Actions.raw(this, shard.id, data);
|
||||
|
||||
if (!data.t) return;
|
||||
if (!data.t) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.emit(data.t as GatewayDispatchEventNames, data, shard.id);
|
||||
// deno-lint-ignore no-explicit-any
|
||||
Actions[data.t as keyof typeof Actions]?.(this, shard.id, data.d as any);
|
||||
};
|
||||
|
||||
this.rest = createRestManager({
|
||||
@ -75,31 +75,25 @@ export class Session extends EventEmitter {
|
||||
// TODO: set botId in Session.botId or something
|
||||
}
|
||||
|
||||
/** TODO: move this */
|
||||
static #toSnakeCase(str: string) {
|
||||
// probably not a fast implementation
|
||||
return str.replace(/[A-Z]/g, (char) => "_" + char.toLowerCase());
|
||||
}
|
||||
|
||||
override on(event: "ready", func: Events["ready"]): this;
|
||||
override on(event: "messageCreate", func: Events["messageCreate"]): this;
|
||||
override on(event: "raw", func: Events["raw"]): this;
|
||||
override on(event: keyof Events, func: Events[keyof Events]): this {
|
||||
return super.on(Session.#toSnakeCase(event).toUpperCase(), func);
|
||||
return super.on(event, func);
|
||||
}
|
||||
|
||||
override off(event: "ready", func: Events["ready"]): this;
|
||||
override off(event: "messageCreate", func: Events["messageCreate"]): this;
|
||||
override off(event: "raw", func: Events["raw"]): this;
|
||||
override off(event: keyof Events, func: Events[keyof Events]): this {
|
||||
return super.off(Session.#toSnakeCase(event).toUpperCase(), func);
|
||||
return super.off(event, func);
|
||||
}
|
||||
|
||||
override once(event: "ready", func: Events["ready"]): this;
|
||||
override once(event: "messageCreate", func: Events["messageCreate"]): this;
|
||||
override once(event: "raw", func: Events["raw"]): this;
|
||||
override once(event: keyof Events, func: Events[keyof Events]): this {
|
||||
return super.once(Session.#toSnakeCase(event).toUpperCase(), func);
|
||||
return super.once(event, func);
|
||||
}
|
||||
|
||||
async start() {
|
||||
|
12
structures/Base.ts
Normal file
12
structures/Base.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import type { Snowflake } from "../util/mod.ts";
|
||||
import type { Session } from "../session/mod.ts";
|
||||
|
||||
/**
|
||||
* Represents a Discord data model
|
||||
* */
|
||||
export interface Base {
|
||||
/** id of the model */
|
||||
id: Snowflake;
|
||||
/** reference to the client that instantiated the model */
|
||||
session: Session;
|
||||
}
|
94
structures/Message.ts
Normal file
94
structures/Message.ts
Normal file
@ -0,0 +1,94 @@
|
||||
import type { Base } 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";
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/resources/channel#allowed-mentions-object
|
||||
* */
|
||||
export interface AllowedMentions {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/resources/channel#create-message-json-params
|
||||
* */
|
||||
export interface CreateMessage {
|
||||
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;
|
||||
|
||||
this.id = data.id;
|
||||
|
||||
this.channelId = data.channel_id;
|
||||
}
|
||||
|
||||
/** the session that instantiated the message */
|
||||
session: Session;
|
||||
|
||||
/** the id of the message */
|
||||
id: Snowflake;
|
||||
|
||||
/** the id of the channel where the message was sent */
|
||||
channelId: Snowflake;
|
||||
|
||||
/** 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,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
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,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return message;
|
||||
}
|
||||
}
|
@ -1,3 +1,43 @@
|
||||
import type { Snowflake } from "./Snowflake.ts";
|
||||
|
||||
export function GATEWAY_BOT() {
|
||||
return "/gateway/bot";
|
||||
}
|
||||
|
||||
export interface GetMessagesOptions {
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface GetMessagesOptions {
|
||||
around?: Snowflake;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface GetMessagesOptions {
|
||||
before?: Snowflake;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface GetMessagesOptions {
|
||||
after?: Snowflake;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
/** used to send messages */
|
||||
export function CHANNEL_MESSAGES(channelId: Snowflake, options?: GetMessagesOptions) {
|
||||
let url = `/channels/${channelId}/messages?`;
|
||||
|
||||
if (options) {
|
||||
if ("after" in options && options.after) url += `after=${options.after}`;
|
||||
if ("before" in options && options.before) url += `&before=${options.before}`;
|
||||
if ("around" in options && options.around) url += `&around=${options.around}`;
|
||||
if ("limit" in options && options.limit) url += `&limit=${options.limit}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
/** used to edit messages */
|
||||
export function CHANNEL_MESSAGE(channelId: Snowflake, messageId: Snowflake) {
|
||||
return `/channels/${channelId}/messages/${messageId}`;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user