Skip to content

Commit fa2c264

Browse files
committed
feat: add mastodon style relays
1 parent 96628d7 commit fa2c264

8 files changed

Lines changed: 648 additions & 44 deletions

File tree

drizzle/meta/0062_snapshot.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2833,4 +2833,4 @@
28332833
"schemas": {},
28342834
"tables": {}
28352835
}
2836-
}
2836+
}

drizzle/meta/_journal.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,4 +451,4 @@
451451
"breakpoints": true
452452
}
453453
]
454-
}
454+
}

src/api/v1/statuses.ts

Lines changed: 212 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import {
6767
polls,
6868
posts,
6969
reactions,
70+
relays,
7071
} from "../../schema";
7172
import { formatPostContent } from "../../text";
7273
import { type Uuid, isUuid, uuid, uuidv7 } from "../../uuid";
@@ -280,6 +281,26 @@ app.post(
280281
preferSharedInbox: true,
281282
excludeBaseUris: [new URL(c.req.url)],
282283
});
284+
if (!owner.account.protected) {
285+
const acceptedRelays = await db.query.relays.findMany({
286+
where: eq(relays.state, "accepted"),
287+
with: {
288+
relayServerActor: true,
289+
},
290+
});
291+
await fedCtx.sendActivity(
292+
{ handle },
293+
acceptedRelays.map((relay) => ({
294+
id: new URL(relay.relayServerActor.iri),
295+
inboxId: new URL(relay.relayServerActor.inboxUrl),
296+
})),
297+
activity,
298+
{
299+
preferSharedInbox: true,
300+
excludeBaseUris: [new URL(c.req.url)],
301+
},
302+
);
303+
}
283304
}
284305
return c.json(serializePost(post, owner, c.req.url));
285306
},
@@ -371,6 +392,26 @@ app.put(
371392
preferSharedInbox: true,
372393
excludeBaseUris: [new URL(c.req.url)],
373394
});
395+
if (post?.visibility !== "direct" && !owner.account.protected) {
396+
const acceptedRelays = await db.query.relays.findMany({
397+
where: eq(relays.state, "accepted"),
398+
with: {
399+
relayServerActor: true,
400+
},
401+
});
402+
await fedCtx.sendActivity(
403+
owner,
404+
acceptedRelays.map((relay) => ({
405+
id: new URL(relay.relayServerActor.iri),
406+
inboxId: new URL(relay.relayServerActor.inboxUrl),
407+
})),
408+
activity,
409+
{
410+
preferSharedInbox: true,
411+
excludeBaseUris: [new URL(c.req.url)],
412+
},
413+
);
414+
}
374415
return c.json(serializePost(post!, owner, c.req.url));
375416
},
376417
);
@@ -433,6 +474,24 @@ app.delete(
433474
excludeBaseUris: [new URL(c.req.url)],
434475
},
435476
);
477+
const acceptedRelays = await db.query.relays.findMany({
478+
where: eq(relays.state, "accepted"),
479+
with: {
480+
relayServerActor: true,
481+
},
482+
});
483+
await fedCtx.sendActivity(
484+
owner,
485+
acceptedRelays.map((relay) => ({
486+
id: new URL(relay.relayServerActor.iri),
487+
inboxId: new URL(relay.relayServerActor.inboxUrl),
488+
})),
489+
activity,
490+
{
491+
preferSharedInbox: true,
492+
excludeBaseUris: [new URL(c.req.url)],
493+
},
494+
);
436495
}
437496
return c.json({
438497
...serializePost(post, owner, c.req.url),
@@ -797,15 +856,36 @@ app.post(
797856
where: eq(posts.id, id),
798857
with: getPostRelations(owner.id),
799858
});
859+
const activity = toAnnounce(post!, fedCtx);
800860
await fedCtx.sendActivity(
801861
{ username: owner.handle },
802862
"followers",
803-
toAnnounce(post!, fedCtx),
863+
activity,
804864
{
805865
preferSharedInbox: true,
806866
excludeBaseUris: [new URL(c.req.url)],
807867
},
808868
);
869+
if (!owner.account.protected) {
870+
const acceptedRelays = await db.query.relays.findMany({
871+
where: eq(relays.state, "accepted"),
872+
with: {
873+
relayServerActor: true,
874+
},
875+
});
876+
await fedCtx.sendActivity(
877+
owner,
878+
acceptedRelays.map((relay) => ({
879+
id: new URL(relay.relayServerActor.iri),
880+
inboxId: new URL(relay.relayServerActor.inboxUrl),
881+
})),
882+
activity,
883+
{
884+
preferSharedInbox: true,
885+
excludeBaseUris: [new URL(c.req.url)],
886+
},
887+
);
888+
}
809889
return c.json(serializePost(post!, owner, c.req.url));
810890
},
811891
);
@@ -852,18 +932,39 @@ app.post(
852932
.where(eq(posts.id, originalPostId));
853933
const fedCtx = federation.createContext(c.req.raw, undefined);
854934
for (const post of postList) {
935+
const activity = new Undo({
936+
actor: new URL(owner.account.iri),
937+
object: toAnnounce(post, fedCtx),
938+
});
855939
await fedCtx.sendActivity(
856940
{ username: owner.handle },
857941
"followers",
858-
new Undo({
859-
actor: new URL(owner.account.iri),
860-
object: toAnnounce(post, fedCtx),
861-
}),
942+
activity,
862943
{
863944
preferSharedInbox: true,
864945
excludeBaseUris: [new URL(c.req.url)],
865946
},
866947
);
948+
if (!owner.account.protected) {
949+
const acceptedRelays = await db.query.relays.findMany({
950+
where: eq(relays.state, "accepted"),
951+
with: {
952+
relayServerActor: true,
953+
},
954+
});
955+
await fedCtx.sendActivity(
956+
owner,
957+
acceptedRelays.map((relay) => ({
958+
id: new URL(relay.relayServerActor.iri),
959+
inboxId: new URL(relay.relayServerActor.inboxUrl),
960+
})),
961+
activity,
962+
{
963+
preferSharedInbox: true,
964+
excludeBaseUris: [new URL(c.req.url)],
965+
},
966+
);
967+
}
867968
}
868969
const originalPost = await db.query.posts.findFirst({
869970
where: eq(posts.id, originalPostId),
@@ -1014,23 +1115,39 @@ app.post(
10141115
} satisfies NewPinnedPost)
10151116
.returning();
10161117
const fedCtx = federation.createContext(c.req.raw, undefined);
1017-
await fedCtx.sendActivity(
1018-
owner,
1019-
"followers",
1020-
new Add({
1021-
id: new URL(
1022-
`#add/${result[0].index}`,
1023-
fedCtx.getFeaturedUri(owner.handle),
1024-
),
1025-
actor: new URL(owner.account.iri),
1026-
object: new URL(post.iri),
1027-
target: fedCtx.getFeaturedUri(owner.handle),
1028-
}),
1029-
{
1030-
preferSharedInbox: true,
1031-
excludeBaseUris: [new URL(c.req.url)],
1032-
},
1033-
);
1118+
const activity = new Add({
1119+
id: new URL(
1120+
`#add/${result[0].index}`,
1121+
fedCtx.getFeaturedUri(owner.handle),
1122+
),
1123+
actor: new URL(owner.account.iri),
1124+
object: new URL(post.iri),
1125+
target: fedCtx.getFeaturedUri(owner.handle),
1126+
});
1127+
await fedCtx.sendActivity(owner, "followers", activity, {
1128+
preferSharedInbox: true,
1129+
excludeBaseUris: [new URL(c.req.url)],
1130+
});
1131+
if (!owner.account.protected) {
1132+
const acceptedRelays = await db.query.relays.findMany({
1133+
where: eq(relays.state, "accepted"),
1134+
with: {
1135+
relayServerActor: true,
1136+
},
1137+
});
1138+
await fedCtx.sendActivity(
1139+
owner,
1140+
acceptedRelays.map((relay) => ({
1141+
id: new URL(relay.relayServerActor.iri),
1142+
inboxId: new URL(relay.relayServerActor.inboxUrl),
1143+
})),
1144+
activity,
1145+
{
1146+
preferSharedInbox: true,
1147+
excludeBaseUris: [new URL(c.req.url)],
1148+
},
1149+
);
1150+
}
10341151
const resultPost = await db.query.posts.findFirst({
10351152
where: eq(posts.id, postId),
10361153
with: getPostRelations(owner.id),
@@ -1070,23 +1187,39 @@ app.post(
10701187
with: getPostRelations(owner.id),
10711188
});
10721189
const fedCtx = federation.createContext(c.req.raw, undefined);
1073-
await fedCtx.sendActivity(
1074-
owner,
1075-
"followers",
1076-
new Remove({
1077-
id: new URL(
1078-
`#remove/${result[0].index}`,
1079-
fedCtx.getFeaturedUri(owner.handle),
1080-
),
1081-
actor: new URL(owner.account.iri),
1082-
object: new URL(post!.iri),
1083-
target: fedCtx.getFeaturedUri(owner.handle),
1084-
}),
1085-
{
1086-
preferSharedInbox: true,
1087-
excludeBaseUris: [new URL(c.req.url)],
1088-
},
1089-
);
1190+
const activity = new Remove({
1191+
id: new URL(
1192+
`#remove/${result[0].index}`,
1193+
fedCtx.getFeaturedUri(owner.handle),
1194+
),
1195+
actor: new URL(owner.account.iri),
1196+
object: new URL(post!.iri),
1197+
target: fedCtx.getFeaturedUri(owner.handle),
1198+
});
1199+
await fedCtx.sendActivity(owner, "followers", activity, {
1200+
preferSharedInbox: true,
1201+
excludeBaseUris: [new URL(c.req.url)],
1202+
});
1203+
if (!owner.account.protected) {
1204+
const acceptedRelays = await db.query.relays.findMany({
1205+
where: eq(relays.state, "accepted"),
1206+
with: {
1207+
relayServerActor: true,
1208+
},
1209+
});
1210+
await fedCtx.sendActivity(
1211+
owner,
1212+
acceptedRelays.map((relay) => ({
1213+
id: new URL(relay.relayServerActor.iri),
1214+
inboxId: new URL(relay.relayServerActor.inboxUrl),
1215+
})),
1216+
activity,
1217+
{
1218+
preferSharedInbox: true,
1219+
excludeBaseUris: [new URL(c.req.url)],
1220+
},
1221+
);
1222+
}
10901223
return c.json(serializePost(post!, owner, c.req.url));
10911224
},
10921225
);
@@ -1208,6 +1341,26 @@ async function addEmojiReaction(
12081341
activity,
12091342
{ preferSharedInbox: true, excludeBaseUris: [new URL(c.req.url)] },
12101343
);
1344+
if (!owner.account.protected) {
1345+
const acceptedRelays = await db.query.relays.findMany({
1346+
where: eq(relays.state, "accepted"),
1347+
with: {
1348+
relayServerActor: true,
1349+
},
1350+
});
1351+
await fedCtx.sendActivity(
1352+
owner,
1353+
acceptedRelays.map((relay) => ({
1354+
id: new URL(relay.relayServerActor.iri),
1355+
inboxId: new URL(relay.relayServerActor.inboxUrl),
1356+
})),
1357+
activity,
1358+
{
1359+
preferSharedInbox: true,
1360+
excludeBaseUris: [new URL(c.req.url)],
1361+
},
1362+
);
1363+
}
12111364
return c.json(serializePost(post, owner, c.req.url));
12121365
}
12131366

@@ -1301,6 +1454,26 @@ async function removeEmojiReaction(
13011454
activity,
13021455
{ preferSharedInbox: true, excludeBaseUris: [new URL(c.req.url)] },
13031456
);
1457+
if (!owner.account.protected) {
1458+
const acceptedRelays = await db.query.relays.findMany({
1459+
where: eq(relays.state, "accepted"),
1460+
with: {
1461+
relayServerActor: true,
1462+
},
1463+
});
1464+
await fedCtx.sendActivity(
1465+
owner,
1466+
acceptedRelays.map((relay) => ({
1467+
id: new URL(relay.relayServerActor.iri),
1468+
inboxId: new URL(relay.relayServerActor.inboxUrl),
1469+
})),
1470+
activity,
1471+
{
1472+
preferSharedInbox: true,
1473+
excludeBaseUris: [new URL(c.req.url)],
1474+
},
1475+
);
1476+
}
13041477
return c.json(serializePost(post, owner, c.req.url));
13051478
}
13061479

0 commit comments

Comments
 (0)