summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMadeline <46743919+MaddyUnderStars@users.noreply.github.com>2023-08-15 00:04:57 +1000
committerMadeline <46743919+MaddyUnderStars@users.noreply.github.com>2023-08-15 00:04:57 +1000
commitff7f520ca39a114f30da631cc3d4db92dbf2f875 (patch)
treee23f34d804a6d713c63dd75ea13e9234bf2e22b1 /src
parentmmm bodyparser (diff)
downloadserver-ts-ff7f520ca39a114f30da631cc3d4db92dbf2f875.tar.xz
garbage
Diffstat (limited to 'src')
-rw-r--r--src/activitypub/routes/channel/#channel_id/inbox.ts15
-rw-r--r--src/util/entities/Message.ts58
-rw-r--r--src/util/entities/User.ts15
3 files changed, 85 insertions, 3 deletions
diff --git a/src/activitypub/routes/channel/#channel_id/inbox.ts b/src/activitypub/routes/channel/#channel_id/inbox.ts

index 01e267e7..a44944b6 100644 --- a/src/activitypub/routes/channel/#channel_id/inbox.ts +++ b/src/activitypub/routes/channel/#channel_id/inbox.ts
@@ -1,9 +1,22 @@ import { route } from "@spacebar/api"; +import { Message, emitEvent } from "@spacebar/util"; import { Router } from "express"; +import { HTTPError } from "lambert-server"; const router = Router(); export default router; router.post("/", route({}), async (req, res) => { - console.log(req.body); + const body = req.body; + + if (body.type != "Create") throw new HTTPError("not implemented"); + + const message = await Message.fromAP(body); + await message.save(); + + await emitEvent({ + event: "MESSAGE_CREATE", + channel_id: message.channel_id, + data: message.toJSON(), + }); }); diff --git a/src/util/entities/Message.ts b/src/util/entities/Message.ts
index 07ec8195..d157ba35 100644 --- a/src/util/entities/Message.ts +++ b/src/util/entities/Message.ts
@@ -16,7 +16,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ -import type { APAnnounce, APNote } from "activitypub-types"; +import type { + APAnnounce, + APNote, + APPerson, + AnyAPObject, +} from "activitypub-types"; +import fetch from "node-fetch"; import { Column, CreateDateColumn, @@ -29,7 +35,7 @@ import { OneToMany, RelationId, } from "typeorm"; -import { Config } from ".."; +import { Config, Snowflake } from ".."; import { InteractionType } from "../interfaces/Interaction"; import { Application } from "./Application"; import { Attachment } from "./Attachment"; @@ -269,6 +275,54 @@ export class Message extends BaseClass { content: this.content, }; } + + static async fromAP(data: APNote): Promise<Message> { + if (!data.attributedTo) + throw new Error("sb Message must have author (attributedTo)"); + + let attrib = Array.isArray(data.attributedTo) + ? data.attributedTo[0] + : data.attributedTo; + if (typeof attrib == "string") { + // fetch it + attrib = (await fetch(attrib).then((x) => x.json())) as AnyAPObject; + } + + if (attrib.type != "Person") + throw new Error("only Person can be author of sb Message"); //hm + + let to = data.to; + + if (Array.isArray(to)) + to = to.filter((x) => { + if (typeof x == "string") return x.includes("channel"); + return false; + }); + + if (!to) throw new Error("not deliverable"); + + const channel_id = (to as string).split("/").reverse()[0]; + + const channel = await Channel.findOneOrFail({ + where: { id: channel_id }, + relations: { guild: true }, + }); + + return Message.create({ + id: Snowflake.generate(), + author: await User.fromAP(attrib as APPerson), + content: data.content, // convert html to markdown + timestamp: data.published, + channel_id, + + sticker_items: [], + guild_id: channel.guild_id, + attachments: [], + embeds: [], + reactions: [], + type: 0, + }); + } } export interface MessageComponent { diff --git a/src/util/entities/User.ts b/src/util/entities/User.ts
index 1adeae3a..59713bce 100644 --- a/src/util/entities/User.ts +++ b/src/util/entities/User.ts
@@ -37,6 +37,7 @@ import { Session } from "./Session"; import { UserSettings } from "./UserSettings"; import crypto from "crypto"; +import fetch from "node-fetch"; import { promisify } from "util"; const generateKeyPair = promisify(crypto.generateKeyPair); @@ -322,6 +323,20 @@ export class User extends BaseClass { }; } + static async fromAP(data: APPerson | string): Promise<User> { + if (typeof data == "string") { + data = (await fetch(data, { + headers: { Accept: "application/activity+json" }, + }).then((x) => x.json())) as APPerson; + } + + return User.create({ + id: Snowflake.generate(), // hm + username: data.preferredUsername, + bio: data.summary, // TODO: convert to markdown + }); + } + static async getPublicUser(user_id: string, opts?: FindOneOptions<User>) { return await User.findOneOrFail({ where: { id: user_id },