Implement greeting
This commit is contained in:
parent
0db40d7a0a
commit
b6065145ee
103
src/api/routes/channels/#channel_id/greet.ts
Normal file
103
src/api/routes/channels/#channel_id/greet.ts
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
|
Copyright (C) 2025 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { route } from "@spacebar/api";
|
||||||
|
import { Channel, emitEvent, GreetRequestSchema, Message, MessageCreateEvent, MessageType, Permissions, Sticker } from "@spacebar/util";
|
||||||
|
import { Request, Response, Router } from "express";
|
||||||
|
import { In } from "typeorm";
|
||||||
|
|
||||||
|
const router: Router = Router();
|
||||||
|
|
||||||
|
router.post(
|
||||||
|
"/",
|
||||||
|
route({
|
||||||
|
requestBody: "GreetRequestSchema",
|
||||||
|
permission: "MANAGE_CHANNELS",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
body: "Message",
|
||||||
|
},
|
||||||
|
404: {},
|
||||||
|
400: {
|
||||||
|
body: "APIErrorResponse",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
async (req: Request, res: Response) => {
|
||||||
|
const payload = req.body as GreetRequestSchema;
|
||||||
|
const { channel_id } = req.params;
|
||||||
|
|
||||||
|
const channel = await Channel.findOneOrFail({
|
||||||
|
where: { id: channel_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
const targetMessage = await Message.findOneOrFail({
|
||||||
|
where: {
|
||||||
|
id: payload.message_reference?.message_id,
|
||||||
|
channel_id: payload.message_reference?.channel_id,
|
||||||
|
guild_id: payload.message_reference?.guild_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!channel.isDm() && targetMessage.type != MessageType.GUILD_MEMBER_JOIN)
|
||||||
|
return res.status(400).json({
|
||||||
|
code: 400, // TODO: what's the actual error code?
|
||||||
|
message: "Cannot send greet message referencing this message.",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!(await channel.getUserPermissions({ user_id: req.user_id })).has(Permissions.FLAGS.SEND_MESSAGES)) {
|
||||||
|
return res.status(403).json({
|
||||||
|
code: 403,
|
||||||
|
message: "Missing Permissions: SEND_MESSAGES",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const specCompliant = true; // incase we want to allow clients to add more than one sticker to pick
|
||||||
|
if (specCompliant && payload.sticker_ids.length != 1)
|
||||||
|
return res.status(400).json({
|
||||||
|
code: 400,
|
||||||
|
message: "Must include exactly one sticker.",
|
||||||
|
});
|
||||||
|
|
||||||
|
const stickers = await Sticker.find({ where: { id: In(payload.sticker_ids) } });
|
||||||
|
|
||||||
|
const randomSticker = stickers[Math.floor(Math.random() * stickers.length)];
|
||||||
|
|
||||||
|
const message = Message.create({
|
||||||
|
channel_id: channel_id,
|
||||||
|
author_id: req.user_id,
|
||||||
|
type: MessageType.REPLY,
|
||||||
|
message_reference: { ...payload.message_reference, type: 0 },
|
||||||
|
referenced_message: targetMessage,
|
||||||
|
sticker_items: randomSticker ? [{ id: randomSticker.id, name: randomSticker.name, format_type: randomSticker.format_type }] : [],
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
message.save(),
|
||||||
|
emitEvent({
|
||||||
|
event: "MESSAGE_CREATE",
|
||||||
|
data: message,
|
||||||
|
channel_id,
|
||||||
|
} as MessageCreateEvent),
|
||||||
|
]);
|
||||||
|
|
||||||
|
res.send(channel);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export default router;
|
||||||
@ -324,7 +324,7 @@ router.post(
|
|||||||
|
|
||||||
if (!req.rights.has(Rights.FLAGS.BYPASS_RATE_LIMITS)) {
|
if (!req.rights.has(Rights.FLAGS.BYPASS_RATE_LIMITS)) {
|
||||||
const limits = Config.get().limits;
|
const limits = Config.get().limits;
|
||||||
if (limits.absoluteRate.register.enabled) {
|
if (limits.absoluteRate.sendMessage.enabled) {
|
||||||
const count = await Message.count({
|
const count = await Message.count({
|
||||||
where: {
|
where: {
|
||||||
channel_id,
|
channel_id,
|
||||||
|
|||||||
@ -51,4 +51,6 @@ router.get(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// TODO: POST to send a message to the user
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
@ -210,6 +210,7 @@ export class Message extends BaseClass {
|
|||||||
message_id: string;
|
message_id: string;
|
||||||
channel_id?: string;
|
channel_id?: string;
|
||||||
guild_id?: string;
|
guild_id?: string;
|
||||||
|
type?: number; // 0 = DEFAULT, 1 = FORWARD
|
||||||
};
|
};
|
||||||
|
|
||||||
@JoinColumn({ name: "message_reference_id" })
|
@JoinColumn({ name: "message_reference_id" })
|
||||||
|
|||||||
31
src/util/schemas/GreetRequestSchema.ts
Normal file
31
src/util/schemas/GreetRequestSchema.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ConnectedAccountTokenData } from "../interfaces";
|
||||||
|
import { AllowedMentions } from "@spacebar/util*";
|
||||||
|
|
||||||
|
export interface GreetRequestSchema {
|
||||||
|
sticker_ids: string[];
|
||||||
|
allowed_mentions?: AllowedMentions;
|
||||||
|
message_reference?: {
|
||||||
|
message_id: string;
|
||||||
|
channel_id?: string;
|
||||||
|
guild_id?: string;
|
||||||
|
fail_if_not_exists?: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -41,6 +41,7 @@ export * from "./EmojiCreateSchema";
|
|||||||
export * from "./EmojiModifySchema";
|
export * from "./EmojiModifySchema";
|
||||||
export * from "./ForgotPasswordSchema";
|
export * from "./ForgotPasswordSchema";
|
||||||
export * from "./GatewayPayloadSchema";
|
export * from "./GatewayPayloadSchema";
|
||||||
|
export * from "./GreetRequestSchema";
|
||||||
export * from "./GuildCreateSchema";
|
export * from "./GuildCreateSchema";
|
||||||
export * from "./GuildSubscriptionsBulkSchema";
|
export * from "./GuildSubscriptionsBulkSchema";
|
||||||
export * from "./GuildTemplateCreateSchema";
|
export * from "./GuildTemplateCreateSchema";
|
||||||
|
|||||||
Reference in New Issue
Block a user