✨ sticker upload
This commit is contained in:
parent
9e87caaae6
commit
f38ebe65ed
@ -514,6 +514,12 @@
|
|||||||
"attachments": {
|
"attachments": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {}
|
"items": {}
|
||||||
|
},
|
||||||
|
"sticker_ids": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
@ -5341,6 +5347,308 @@
|
|||||||
},
|
},
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
},
|
},
|
||||||
|
"ModifyGuildStickerSchema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"minLength": 2,
|
||||||
|
"maxLength": 30,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"maxLength": 100,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"maxLength": 200,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"tags"
|
||||||
|
],
|
||||||
|
"definitions": {
|
||||||
|
"ChannelPermissionOverwriteType": {
|
||||||
|
"enum": [
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"Embed": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"article",
|
||||||
|
"gifv",
|
||||||
|
"image",
|
||||||
|
"link",
|
||||||
|
"rich",
|
||||||
|
"video"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
"color": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"footer": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"text": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"icon_url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"proxy_icon_url": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"text"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"$ref": "#/definitions/EmbedImage"
|
||||||
|
},
|
||||||
|
"thumbnail": {
|
||||||
|
"$ref": "#/definitions/EmbedImage"
|
||||||
|
},
|
||||||
|
"video": {
|
||||||
|
"$ref": "#/definitions/EmbedImage"
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"author": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"icon_url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"proxy_icon_url": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fields": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"inline": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"value"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"EmbedImage": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"proxy_url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"height": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ChannelModifySchema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"maxLength": 100,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
10,
|
||||||
|
11,
|
||||||
|
12,
|
||||||
|
13,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6
|
||||||
|
],
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"topic": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"string"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"bitrate": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"user_limit": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"rate_limit_per_user": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"permission_overwrites": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"$ref": "#/definitions/ChannelPermissionOverwriteType"
|
||||||
|
},
|
||||||
|
"allow": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"deny": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"allow",
|
||||||
|
"deny",
|
||||||
|
"id",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parent_id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"nsfw": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"rtc_region": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"default_auto_archive_duration": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"UserPublic": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"username": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"discriminator": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"public_flags": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"avatar": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"accent_color": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"banner": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"bio": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"bot": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"bio",
|
||||||
|
"bot",
|
||||||
|
"discriminator",
|
||||||
|
"id",
|
||||||
|
"public_flags",
|
||||||
|
"username"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"PublicConnectedAccount": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"verifie": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"type",
|
||||||
|
"verifie"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
|
},
|
||||||
"TemplateCreateSchema": {
|
"TemplateCreateSchema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { Member, Sticker } from "@fosscord/util";
|
import { handleFile, Member, Snowflake, Sticker, StickerFormatType, StickerType, uploadFile } from "@fosscord/util";
|
||||||
import { Router, Request, Response } from "express";
|
import { Router, Request, Response } from "express";
|
||||||
import { route } from "@fosscord/api";
|
import { route } from "@fosscord/api";
|
||||||
import multer from "multer";
|
import multer from "multer";
|
||||||
|
import { HTTPError } from "lambert-server";
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
router.get("/", route({}), async (req: Request, res: Response) => {
|
router.get("/", route({}), async (req: Request, res: Response) => {
|
||||||
@ -20,12 +21,47 @@ const bodyParser = multer({
|
|||||||
storage: multer.memoryStorage()
|
storage: multer.memoryStorage()
|
||||||
}).single("file");
|
}).single("file");
|
||||||
|
|
||||||
router.post("/", bodyParser, route({ permission: "MANAGE_EMOJIS_AND_STICKERS" }), async (req: Request, res: Response) => {
|
router.post(
|
||||||
const { guild_id } = req.params;
|
"/",
|
||||||
await Member.IsInGuildOrFail(req.user_id, guild_id);
|
bodyParser,
|
||||||
|
route({ permission: "MANAGE_EMOJIS_AND_STICKERS", body: "ModifyGuildStickerSchema" }),
|
||||||
|
async (req: Request, res: Response) => {
|
||||||
|
if (!req.file) throw new HTTPError("missing file");
|
||||||
|
|
||||||
res.json(await Sticker.find({ guild_id }));
|
const { guild_id } = req.params;
|
||||||
});
|
const body = req.body as ModifyGuildStickerSchema;
|
||||||
|
const id = Snowflake.generate();
|
||||||
|
|
||||||
|
const [sticker] = await Promise.all([
|
||||||
|
new Sticker({
|
||||||
|
...body,
|
||||||
|
guild_id,
|
||||||
|
id,
|
||||||
|
type: StickerType.GUILD,
|
||||||
|
format_type: getStickerFormat(req.file.mimetype),
|
||||||
|
available: true
|
||||||
|
}).save(),
|
||||||
|
uploadFile(`/stickers/${id}`, req.file)
|
||||||
|
]);
|
||||||
|
|
||||||
|
res.json(sticker);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export function getStickerFormat(mime_type: string) {
|
||||||
|
switch (mime_type) {
|
||||||
|
case "image/apng":
|
||||||
|
return StickerFormatType.APNG;
|
||||||
|
case "application/json":
|
||||||
|
return StickerFormatType.LOTTIE;
|
||||||
|
case "image/png":
|
||||||
|
return StickerFormatType.PNG;
|
||||||
|
case "image/gif":
|
||||||
|
return StickerFormatType.GIF;
|
||||||
|
default:
|
||||||
|
throw new HTTPError("invalid sticker format: must be png, apng or lottie");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
router.get("/:sticker_id", route({}), async (req: Request, res: Response) => {
|
router.get("/:sticker_id", route({}), async (req: Request, res: Response) => {
|
||||||
const { guild_id, sticker_id } = req.params;
|
const { guild_id, sticker_id } = req.params;
|
||||||
@ -41,7 +77,6 @@ export interface ModifyGuildStickerSchema {
|
|||||||
*/
|
*/
|
||||||
name: string;
|
name: string;
|
||||||
/**
|
/**
|
||||||
* @minLength 2
|
|
||||||
* @maxLength 100
|
* @maxLength 100
|
||||||
*/
|
*/
|
||||||
description?: string;
|
description?: string;
|
||||||
|
@ -9,6 +9,7 @@ export enum StickerType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum StickerFormatType {
|
export enum StickerFormatType {
|
||||||
|
GIF = 0, // gif is a custom format type and not in discord spec
|
||||||
PNG = 1,
|
PNG = 1,
|
||||||
APNG = 2,
|
APNG = 2,
|
||||||
LOTTIE = 3,
|
LOTTIE = 3,
|
||||||
@ -22,16 +23,20 @@ export class Sticker extends BaseClass {
|
|||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
description?: string;
|
description?: string;
|
||||||
|
|
||||||
@Column()
|
@Column({ nullable: true })
|
||||||
tags: string;
|
available?: boolean;
|
||||||
|
|
||||||
@Column()
|
@Column({ nullable: true })
|
||||||
|
tags?: string;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
@RelationId((sticker: Sticker) => sticker.pack)
|
@RelationId((sticker: Sticker) => sticker.pack)
|
||||||
pack_id: string;
|
pack_id?: string;
|
||||||
|
|
||||||
@JoinColumn({ name: "pack_id" })
|
@JoinColumn({ name: "pack_id" })
|
||||||
@ManyToOne(() => require("./StickerPack").StickerPack, {
|
@ManyToOne(() => require("./StickerPack").StickerPack, {
|
||||||
onDelete: "CASCADE",
|
onDelete: "CASCADE",
|
||||||
|
nullable: true,
|
||||||
})
|
})
|
||||||
pack: import("./StickerPack").StickerPack;
|
pack: import("./StickerPack").StickerPack;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user