diff --git a/src/activitypub/routes/channel/#channel_id/index.ts b/src/activitypub/routes/channel/#channel_id/index.ts
index 95495ffe..bb76258e 100644
--- a/src/activitypub/routes/channel/#channel_id/index.ts
+++ b/src/activitypub/routes/channel/#channel_id/index.ts
@@ -1,5 +1,5 @@
import { route } from "@spacebar/api";
-import { Channel, Config } from "@spacebar/util";
+import { Channel } from "@spacebar/util";
import { Request, Response, Router } from "express";
const router = Router();
@@ -10,21 +10,5 @@ router.get("/", route({}), async (req: Request, res: Response) => {
const channel = await Channel.findOneOrFail({ where: { id } });
- const { webDomain } = Config.get().federation;
-
- return res.json({
- "@context": "https://www.w3.org/ns/activitystreams",
- type: "Group",
- id: `https://${webDomain}/fed/channel/${channel.id}`,
- name: channel.name,
- preferredUsername: channel.name,
- summary: channel.topic,
- icon: undefined,
-
- inbox: `https://${webDomain}/fed/channel/${channel.id}/inbox`,
- outbox: `https://${webDomain}/fed/channel/${channel.id}/outbox`,
- followers: `https://${webDomain}/fed/channel/${channel.id}/followers`,
- following: `https://${webDomain}/fed/channel/${channel.id}/following`,
- linked: `https://${webDomain}/fed/channel/${channel.id}/likeds`,
- });
+ return res.json(channel.toAP());
});
diff --git a/src/activitypub/routes/channel/#channel_id/messages/#message_id/index.ts b/src/activitypub/routes/channel/#channel_id/messages/#message_id/index.ts
index 6b806087..7ac5ae0a 100644
--- a/src/activitypub/routes/channel/#channel_id/messages/#message_id/index.ts
+++ b/src/activitypub/routes/channel/#channel_id/messages/#message_id/index.ts
@@ -1,5 +1,6 @@
import { route } from "@spacebar/api";
import { Config, Message } from "@spacebar/util";
+import { APAnnounce } from "activitypub-types";
import { Request, Response, Router } from "express";
const router = Router();
@@ -14,37 +15,15 @@ router.get("/", route({}), async (req: Request, res: Response) => {
});
const { webDomain } = Config.get().federation;
- return res.json({
+ const ret: APAnnounce = {
"@context": "https://www.w3.org/ns/activitystreams",
- id: "Announce",
- actor: `https://${webDomain}/fed/user/${message.author!.id}`,
+ id: `https://${webDomain}/fed/channel/${message.channel_id}/messages/${message.id}`,
+ type: "Announce",
+ actor: `https://${webDomain}/fed/user/${message.author_id}`,
published: message.timestamp,
- to: ["https://www.w3.org/ns/activitystreams#Public"],
- cc: [
- message.author?.id
- ? `https://${webDomain}/fed/users/${message.author.id}`
- : undefined,
- `https://${webDomain}/fed/channel/${channel_id}/followers`,
- ],
- object: {
- id: `https://${webDomain}/fed/channel/${channel_id}/mesages/${message.id}`,
- type: "Note",
- summary: null,
- inReplyTo: undefined, // TODO
- published: message.timestamp,
- url: `https://app.spacebar.chat/channels${
- message.guild?.id ? `/${message.guild.id}` : ""
- }/${channel_id}/${message.id}`,
- attributedTo: `https://${webDomain}/fed/user/${message.author!.id}`,
- to: ["https://www.w3.org/ns/activitystreams#Public"],
- cc: [
- message.author?.id
- ? `https://${webDomain}/fed/users/${message.author.id}`
- : undefined,
- `https://${webDomain}/fed/channel/${channel_id}/followers`,
- ],
- sensitive: false,
- content: message.content,
- },
- });
+ to: `https://${webDomain}/fed/channel/${message.channel_id}`,
+ object: message.toAP(),
+ };
+
+ return res.json(ret);
});
diff --git a/src/activitypub/routes/channel/#channel_id/outbox.ts b/src/activitypub/routes/channel/#channel_id/outbox.ts
index 03a31253..8c2dcc6e 100644
--- a/src/activitypub/routes/channel/#channel_id/outbox.ts
+++ b/src/activitypub/routes/channel/#channel_id/outbox.ts
@@ -1,5 +1,6 @@
import { route } from "@spacebar/api";
import { Config, Message, Snowflake } from "@spacebar/util";
+import { APOrderedCollection } from "activitypub-types";
import { Router } from "express";
import { FindManyOptions, FindOperator, LessThan, MoreThan } from "typeorm";
@@ -14,14 +15,16 @@ router.get("/", route({}), async (req, res) => {
const { webDomain } = Config.get().federation;
- if (!page)
- return res.json({
+ if (!page) {
+ const ret: APOrderedCollection = {
"@context": "https://www.w3.org/ns/activitystreams",
id: `https://${webDomain}/fed/users/${channel_id}/outbox`,
type: "OrderedCollection",
first: `https://${webDomain}/fed/users/${channel_id}/outbox?page=true`,
last: `https://${webDomain}/fed/users/${channel_id}/outbox?page=true&min_id=0`,
- });
+ };
+ return res.json(ret);
+ }
const after = min_id ? `${min_id}` : undefined;
const before = max_id ? `${max_id}` : undefined;
@@ -47,30 +50,26 @@ router.get("/", route({}), async (req, res) => {
const messages = await Message.find(query);
- return res.json({
+ // move this to like, Channel.createAPMessages or smth
+ const apMessages = messages.map((message) => ({
+ "@context": "https://www.w3.org/ns/activitystreams",
+ id: `https://${webDomain}/fed/channel/${message.channel_id}/messages/${message.id}`,
+ type: "Announce",
+ actor: `https://${webDomain}/fed/user/${message.author_id}`,
+ published: message.timestamp,
+ to: `https://${webDomain}/fed/channel/${message.channel_id}`,
+ object: message.toAP(),
+ }));
+
+ const ret: APOrderedCollection = {
"@context": "https://www.w3.org/ns/activitystreams",
id: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true`,
type: "OrderedCollection",
- next: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true&max_id=${
- messages[0]?.id || "0"
- }`,
- prev: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true&max_id=${
- messages[messages.length - 1]?.id || "0"
- }`,
- partOf: `https://${webDomain}/fed/channel/${channel_id}/outbox`,
- orderedItems: messages.map((message) => ({
- id: `https://${webDomain}/fed/channel/${channel_id}/message/${message.id}`,
- type: "Announce", // hmm
- actor: `https://${webDomain}/fed/channel/${channel_id}`,
- published: message.timestamp,
- to: ["https://www.w3.org/ns/activitystreams#Public"],
- cc: [
- message.author?.id
- ? `https://${webDomain}/fed/users/${message.author.id}`
- : undefined,
- `https://${webDomain}/fed/channel/${channel_id}/followers`,
- ],
- object: `https://${webDomain}/fed/channel/${channel_id}/messages/${message.id}`,
- })),
- });
+ first: `https://${webDomain}/fed/users/${channel_id}/outbox?page=true`,
+ last: `https://${webDomain}/fed/users/${channel_id}/outbox?page=true&min_id=0`,
+ totalItems: await Message.count({ where: { channel_id } }),
+ items: apMessages,
+ };
+
+ return res.json(ret);
});
diff --git a/src/activitypub/routes/user.ts b/src/activitypub/routes/user.ts
index 838d14b7..3366d711 100644
--- a/src/activitypub/routes/user.ts
+++ b/src/activitypub/routes/user.ts
@@ -1,5 +1,6 @@
import { route } from "@spacebar/api";
import { Config, User } from "@spacebar/util";
+import { APPerson } from "activitypub-types";
import { Request, Response, Router } from "express";
const router = Router();
@@ -12,7 +13,7 @@ router.get("/:id", route({}), async (req: Request, res: Response) => {
const { webDomain } = Config.get().federation;
- return res.json({
+ const ret: APPerson = {
"@context": "https://www.w3.org/ns/activitystreams",
type: "Person",
id: `https://${webDomain}/fed/user/${user.id}`,
@@ -31,6 +32,8 @@ router.get("/:id", route({}), async (req: Request, res: Response) => {
outbox: `https://${webDomain}/fed/user/${user.id}/outbox`,
followers: `https://${webDomain}/fed/user/${user.id}/followers`,
following: `https://${webDomain}/fed/user/${user.id}/following`,
- linked: `https://${webDomain}/fed/user/${user.id}/likeds`,
- });
+ liked: `https://${webDomain}/fed/user/${user.id}/likeds`,
+ };
+
+ return res.json(ret);
});
diff --git a/src/activitypub/util/actor.ts b/src/activitypub/util/actor.ts
deleted file mode 100644
index e69de29b..00000000
--- a/src/activitypub/util/actor.ts
+++ /dev/null
diff --git a/src/util/entities/Channel.ts b/src/util/entities/Channel.ts
index 19952bc2..93265d07 100644
--- a/src/util/entities/Channel.ts
+++ b/src/util/entities/Channel.ts
@@ -16,6 +16,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import { APActor } from "activitypub-types";
import { HTTPError } from "lambert-server";
import {
Column,
@@ -28,6 +29,7 @@ import {
import { DmChannelDTO } from "../dtos";
import { ChannelCreateEvent, ChannelRecipientRemoveEvent } from "../interfaces";
import {
+ Config,
InvisibleCharacters,
Snowflake,
containsAll,
@@ -482,6 +484,26 @@ export class Channel extends BaseClass {
owner_id: this.owner_id || undefined,
};
}
+
+ toAP(): APActor {
+ const { webDomain } = Config.get().federation;
+
+ return {
+ "@context": "https://www.w3.org/ns/activitystreams",
+ type: "Group",
+ id: `https://${webDomain}/fed/channel/${this.id}`,
+ name: this.name,
+ preferredUsername: this.name,
+ summary: this.topic,
+ icon: undefined,
+
+ inbox: `https://${webDomain}/fed/channel/${this.id}/inbox`,
+ outbox: `https://${webDomain}/fed/channel/${this.id}/outbox`,
+ followers: `https://${webDomain}/fed/channel/${this.id}/followers`,
+ following: `https://${webDomain}/fed/channel/${this.id}/following`,
+ liked: `https://${webDomain}/fed/channel/${this.id}/likeds`,
+ };
+ }
}
export interface ChannelPermissionOverwrite {
diff --git a/src/util/entities/Message.ts b/src/util/entities/Message.ts
index 3598d29f..dbaa9dd1 100644
--- a/src/util/entities/Message.ts
+++ b/src/util/entities/Message.ts
@@ -16,12 +16,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { User } from "./User";
-import { Member } from "./Member";
-import { Role } from "./Role";
-import { Channel } from "./Channel";
-import { InteractionType } from "../interfaces/Interaction";
-import { Application } from "./Application";
+import type { APNote } from "activitypub-types";
import {
Column,
CreateDateColumn,
@@ -34,11 +29,18 @@ import {
OneToMany,
RelationId,
} from "typeorm";
+import { Config } from "..";
+import { InteractionType } from "../interfaces/Interaction";
+import { Application } from "./Application";
+import { Attachment } from "./Attachment";
import { BaseClass } from "./BaseClass";
+import { Channel } from "./Channel";
import { Guild } from "./Guild";
-import { Webhook } from "./Webhook";
+import { Member } from "./Member";
+import { Role } from "./Role";
import { Sticker } from "./Sticker";
-import { Attachment } from "./Attachment";
+import { User } from "./User";
+import { Webhook } from "./Webhook";
export enum MessageType {
DEFAULT = 0,
@@ -240,6 +242,20 @@ export class Message extends BaseClass {
components: this.components ?? undefined,
};
}
+
+ toAP(): APNote {
+ const { webDomain } = Config.get().federation;
+
+ return {
+ id: `https://${webDomain}/fed/channel/${this.channel_id}/messages/${this.id}`,
+ type: "Note",
+ published: this.timestamp,
+ url: `https://${webDomain}/fed/channel/${this.channel_id}/messages/${this.id}`,
+ attributedTo: `https://${webDomain}/fed/user/${this.author_id}`,
+ to: `https://${webDomain}/fed/channel/${this.channel_id}`,
+ content: this.content,
+ };
+ }
}
export interface MessageComponent {
|