mirror of
https://github.com/spacebarchat/server.git
synced 2024-11-22 02:12:40 +01:00
Add basic message interceptor framework
Signed-off-by: TheArcaneBrony <myrainbowdash949@gmail.com>
This commit is contained in:
parent
01a05a1787
commit
506954f3df
4995
pnpm-lock.yaml
Normal file
4995
pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load Diff
@ -289,7 +289,7 @@ router.post(
|
|||||||
edited_timestamp: undefined,
|
edited_timestamp: undefined,
|
||||||
timestamp: new Date(),
|
timestamp: new Date(),
|
||||||
});
|
});
|
||||||
|
if (message.id == "0") return res.json(message); // Don't handle cancelled messages.
|
||||||
channel.last_message_id = message.id;
|
channel.last_message_id = message.id;
|
||||||
|
|
||||||
if (channel.isDm()) {
|
if (channel.isDm()) {
|
||||||
|
@ -40,12 +40,14 @@ import {
|
|||||||
Config,
|
Config,
|
||||||
Sticker,
|
Sticker,
|
||||||
MessageCreateSchema,
|
MessageCreateSchema,
|
||||||
EmbedCache,
|
EmbedCache, MessageOptions,
|
||||||
} from "@fosscord/util";
|
} from "@fosscord/util";
|
||||||
import { HTTPError } from "lambert-server";
|
import { HTTPError } from "lambert-server";
|
||||||
import { In } from "typeorm";
|
import { In } from "typeorm";
|
||||||
import { EmbedHandlers } from "@fosscord/api";
|
import { EmbedHandlers } from "@fosscord/api";
|
||||||
import * as Sentry from "@sentry/node";
|
import * as Sentry from "@sentry/node";
|
||||||
|
import { MessageInterceptResult } from "@fosscord/util/message_interceptors/IMessageInterceptor";
|
||||||
|
import { PluralCommandInterceptor } from "../../../util/message_interceptors/plural_tooling/PluralCommandInterceptor";
|
||||||
const allow_empty = false;
|
const allow_empty = false;
|
||||||
// TODO: check webhook, application, system author, stickers
|
// TODO: check webhook, application, system author, stickers
|
||||||
// TODO: embed gifs/videos/images
|
// TODO: embed gifs/videos/images
|
||||||
@ -53,6 +55,26 @@ const allow_empty = false;
|
|||||||
const LINK_REGEX =
|
const LINK_REGEX =
|
||||||
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/g;
|
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/g;
|
||||||
|
|
||||||
|
const interceptors = [new PluralCommandInterceptor()];
|
||||||
|
|
||||||
|
async function runMessageInterceptors(ctx: { message: Message, opts: MessageOptions }): Promise<MessageInterceptResult> {
|
||||||
|
const result = new MessageInterceptResult();
|
||||||
|
result.cancel = false;
|
||||||
|
result.message = ctx.message;
|
||||||
|
for (const interceptorsKey in interceptors) {
|
||||||
|
const interceptor = interceptors[interceptorsKey];
|
||||||
|
const interceptorResult = await interceptor.execute(ctx);
|
||||||
|
|
||||||
|
result.message = interceptorResult.message;
|
||||||
|
if (interceptorResult.cancel) {
|
||||||
|
result.cancel = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
export async function handleMessage(opts: MessageOptions): Promise<Message> {
|
export async function handleMessage(opts: MessageOptions): Promise<Message> {
|
||||||
const channel = await Channel.findOneOrFail({
|
const channel = await Channel.findOneOrFail({
|
||||||
where: { id: opts.channel_id },
|
where: { id: opts.channel_id },
|
||||||
@ -192,11 +214,22 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
|
|||||||
|
|
||||||
// TODO: check and put it all in the body
|
// TODO: check and put it all in the body
|
||||||
|
|
||||||
|
// root@Rory - 2023-02-18 - Add message interceptors, for use in dev/plurality, might be useful for plugins too.
|
||||||
|
let interceptMessageResult: MessageInterceptResult = await runMessageInterceptors({
|
||||||
|
opts,
|
||||||
|
message,
|
||||||
|
});
|
||||||
|
if(interceptMessageResult.cancel) {
|
||||||
|
message.id = "0"; //identify as cancelled message, as to prevent it from being distributed
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: cache link result in db
|
// TODO: cache link result in db
|
||||||
export async function postHandleMessage(message: Message) {
|
export async function postHandleMessage(message: Message) {
|
||||||
|
if (message.id == "0") return; // don't handle cancelled messages
|
||||||
const content = message.content?.replace(/ *`[^)]*` */g, ""); // remove markdown
|
const content = message.content?.replace(/ *`[^)]*` */g, ""); // remove markdown
|
||||||
let links = content?.match(LINK_REGEX);
|
let links = content?.match(LINK_REGEX);
|
||||||
if (!links) return;
|
if (!links) return;
|
||||||
@ -268,7 +301,7 @@ export async function postHandleMessage(message: Message) {
|
|||||||
|
|
||||||
export async function sendMessage(opts: MessageOptions) {
|
export async function sendMessage(opts: MessageOptions) {
|
||||||
const message = await handleMessage({ ...opts, timestamp: new Date() });
|
const message = await handleMessage({ ...opts, timestamp: new Date() });
|
||||||
|
if (message.id == "0") return; // don't handle cancelled messages
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
Message.insert(message),
|
Message.insert(message),
|
||||||
emitEvent({
|
emitEvent({
|
||||||
@ -285,17 +318,3 @@ export async function sendMessage(opts: MessageOptions) {
|
|||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MessageOptions extends MessageCreateSchema {
|
|
||||||
id?: string;
|
|
||||||
type?: MessageType;
|
|
||||||
pinned?: boolean;
|
|
||||||
author_id?: string;
|
|
||||||
webhook_id?: string;
|
|
||||||
application_id?: string;
|
|
||||||
embeds?: Embed[];
|
|
||||||
channel_id?: string;
|
|
||||||
attachments?: Attachment[];
|
|
||||||
edited_timestamp?: Date;
|
|
||||||
timestamp?: Date;
|
|
||||||
}
|
|
||||||
|
@ -217,6 +217,8 @@ export class Message extends BaseClass {
|
|||||||
|
|
||||||
@Column({ type: "simple-json", nullable: true })
|
@Column({ type: "simple-json", nullable: true })
|
||||||
components?: MessageComponent[];
|
components?: MessageComponent[];
|
||||||
|
|
||||||
|
ephemeral?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MessageComponent {
|
export interface MessageComponent {
|
||||||
|
@ -25,3 +25,4 @@ export * from "./dtos/index";
|
|||||||
export * from "./schemas";
|
export * from "./schemas";
|
||||||
export * from "./imports";
|
export * from "./imports";
|
||||||
export * from "./config";
|
export * from "./config";
|
||||||
|
export * from "./message_interceptors";
|
||||||
|
15
src/util/interfaces/MessageOptions.ts
Normal file
15
src/util/interfaces/MessageOptions.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Attachment, Embed, MessageCreateSchema, MessageType } from "@fosscord/util*";
|
||||||
|
|
||||||
|
export interface MessageOptions extends MessageCreateSchema {
|
||||||
|
id?: string;
|
||||||
|
type?: MessageType;
|
||||||
|
pinned?: boolean;
|
||||||
|
author_id?: string;
|
||||||
|
webhook_id?: string;
|
||||||
|
application_id?: string;
|
||||||
|
embeds?: Embed[];
|
||||||
|
channel_id?: string;
|
||||||
|
attachments?: Attachment[];
|
||||||
|
edited_timestamp?: Date;
|
||||||
|
timestamp?: Date;
|
||||||
|
}
|
@ -21,3 +21,4 @@ export * from "./Presence";
|
|||||||
export * from "./Interaction";
|
export * from "./Interaction";
|
||||||
export * from "./Event";
|
export * from "./Event";
|
||||||
export * from "./Status";
|
export * from "./Status";
|
||||||
|
export * from "./MessageOptions";
|
15
src/util/message_interceptors/IMessageInterceptor.ts
Normal file
15
src/util/message_interceptors/IMessageInterceptor.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Message, MessageOptions } from "@fosscord/util";
|
||||||
|
|
||||||
|
export interface IMessageInterceptor {
|
||||||
|
execute(ctx: MessageInterceptorContext): Promise<MessageInterceptResult>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MessageInterceptResult {
|
||||||
|
cancel: boolean;
|
||||||
|
message: Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MessageInterceptorContext {
|
||||||
|
message: Message;
|
||||||
|
opts: MessageOptions;
|
||||||
|
}
|
1
src/util/message_interceptors/index.ts
Normal file
1
src/util/message_interceptors/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from "./IMessageInterceptor";
|
@ -0,0 +1,46 @@
|
|||||||
|
import {
|
||||||
|
emitEvent,
|
||||||
|
IMessageInterceptor, Message,
|
||||||
|
MessageCreateEvent, MessageDeleteEvent, MessageFlags,
|
||||||
|
MessageInterceptorContext,
|
||||||
|
MessageInterceptResult, MessageTypes
|
||||||
|
} from "@fosscord/util";
|
||||||
|
|
||||||
|
export class PluralCommandInterceptor implements IMessageInterceptor {
|
||||||
|
async execute(ctx: MessageInterceptorContext): Promise<MessageInterceptResult> {
|
||||||
|
let result = new MessageInterceptResult();
|
||||||
|
result.cancel = false;
|
||||||
|
result.message = ctx.message;
|
||||||
|
|
||||||
|
if(ctx.message.content?.toLowerCase().startsWith("p;")) {
|
||||||
|
console.log("[PluralCommandInterceptor] Plural command prefix detected, cancelling message send. Content: ", ctx.message.content)
|
||||||
|
result.cancel = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(result.cancel) {
|
||||||
|
/*await emitEvent({
|
||||||
|
event: "MESSAGE_DELETE",
|
||||||
|
channel_id: ctx.message.channel_id,
|
||||||
|
data: {
|
||||||
|
id: ctx.message.id,
|
||||||
|
channel_id: ctx.message.channel_id,
|
||||||
|
guild_id: ctx.message.guild_id
|
||||||
|
},
|
||||||
|
} as MessageDeleteEvent);*/
|
||||||
|
//result.message.flags = String((BigInt(ctx.message.flags ?? "0")) | MessageTypes.);
|
||||||
|
// @ts-ignore
|
||||||
|
result.message.ephemeral = true;
|
||||||
|
result.message.content += ' (ephemeral?)';
|
||||||
|
/*await emitEvent({
|
||||||
|
event: "MESSAGE_CREATE",
|
||||||
|
//channel_id: ctx.opts.channel_id,
|
||||||
|
user_id: ctx.opts.author_id,
|
||||||
|
data: ctx.message.toJSON(),
|
||||||
|
} as MessageCreateEvent);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user