backfilling — first steps

This commit is contained in:
Erkin Alp Güney 2022-04-23 10:56:47 +03:00
parent d3682e4c21
commit b81017bc60
2 changed files with 87 additions and 2 deletions

View File

@ -1,5 +1,18 @@
import { Channel, emitEvent, getPermission, getRights, MessageDeleteEvent, Message, MessageUpdateEvent } from "@fosscord/util"; import {
Attachment,
Channel,
Embed,
emitEvent,
getPermission,
getRights,
Message,
MessageCreateEvent,
MessageDeleteEvent,
MessageUpdateEvent,
uploadFile
} from "@fosscord/util";
import { Router, Response, Request } from "express"; import { Router, Response, Request } from "express";
import multer from "multer";
import { route } from "@fosscord/api"; import { route } from "@fosscord/api";
import { handleMessage, postHandleMessage } from "@fosscord/api"; import { handleMessage, postHandleMessage } from "@fosscord/api";
import { MessageCreateSchema } from "../index"; import { MessageCreateSchema } from "../index";
@ -7,6 +20,15 @@ import { MessageCreateSchema } from "../index";
const router = Router(); const router = Router();
// TODO: message content/embed string length limit // TODO: message content/embed string length limit
const messageUpload = multer({
limits: {
fileSize: 1024 * 1024 * 100,
fields: 10,
files: 1
},
storage: multer.memoryStorage()
}); // max upload 50 mb
router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGES", right: "SEND_MESSAGES" }), async (req: Request, res: Response) => { router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGES", right: "SEND_MESSAGES" }), async (req: Request, res: Response) => {
const { message_id, channel_id } = req.params; const { message_id, channel_id } = req.params;
var body = req.body as MessageCreateSchema; var body = req.body as MessageCreateSchema;
@ -51,6 +73,68 @@ router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGE
return res.json(message); return res.json(message);
}); });
// Backfill message with specific timestamp
router.put(
"/",
messageUpload.single("file"),
async (req, res, next) => {
if (req.body.payload_json) {
req.body = JSON.parse(req.body.payload_json);
}
next();
},
route({ body: "MessageCreateSchema", permission: "SEND_MESSAGES", right: "SEND_BACKDATED_EVENTS" }),
async (req: Request, res: Response) => {
const { channel_id, message_id } = req.params;
var body = req.body as MessageCreateSchema;
const attachments: Attachment[] = [];
if (req.file) {
try {
const file = await uploadFile(`/attachments/${req.params.channel_id}`, req.file);
attachments.push({ ...file, proxy_url: file.url });
} catch (error) {
return res.status(400).json(error);
}
}
const channel = await Channel.findOneOrFail({ where: { id: channel_id }, relations: ["recipients", "recipients.user"] });
// TODO: check the ID is not from the future, to prevent future-faking of channel histories
const embeds = body.embeds || [];
if (body.embed) embeds.push(body.embed);
let message = await handleMessage({
...body,
type: 0,
pinned: false,
author_id: req.user_id,
id: message_id,
embeds,
channel_id,
attachments,
edited_timestamp: undefined,
timestamp: undefined, // FIXME: calculate timestamp from snowflake
});
channel.last_message_id = message.id;
//Fix for the client bug
delete message.member
await Promise.all([
message.save(),
emitEvent({ event: "MESSAGE_CREATE", channel_id: channel_id, data: message } as MessageCreateEvent),
channel.save()
]);
postHandleMessage(message).catch((e) => { }); // no await as it shouldnt block the message send function and silently catch error
return res.json(message);
}
);
router.get("/", route({ permission: "VIEW_CHANNEL" }), async (req: Request, res: Response) => { router.get("/", route({ permission: "VIEW_CHANNEL" }), async (req: Request, res: Response) => {
const { message_id, channel_id } = req.params; const { message_id, channel_id } = req.params;

View File

@ -91,7 +91,8 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
if (opts.message_reference.channel_id !== opts.channel_id) throw new HTTPError("You can only reference messages from this channel"); if (opts.message_reference.channel_id !== opts.channel_id) throw new HTTPError("You can only reference messages from this channel");
} }
} }
// Q: should be checked if the referenced message exists? ANSWER: NO /** Q: should be checked if the referenced message exists? ANSWER: NO
otherwise backfilling won't work **/
// @ts-ignore // @ts-ignore
message.type = MessageType.REPLY; message.type = MessageType.REPLY;
} }