+50
-20
app/api/inngest/functions/index_post_mention.ts
+50
-20
app/api/inngest/functions/index_post_mention.ts
···
5
5
import { ids } from "lexicons/api/lexicons";
6
6
import { Notification, pingIdentityToUpdateNotification } from "src/notifications";
7
7
import { v7 } from "uuid";
8
+
import { idResolver } from "app/(home-pages)/reader/idResolver";
8
9
9
10
export const index_post_mention = inngest.createFunction(
10
11
{ id: "index_post_mention" },
···
13
14
let url = new URL(event.data.document_link);
14
15
let path = url.pathname.split("/").filter(Boolean);
15
16
16
-
let { data: pub, error } = await supabaseServerClient
17
-
.from("publications")
18
-
.select("*")
19
-
.eq("record->>base_path", url.host)
20
-
.single();
17
+
// Check if this is a standalone document URL (/p/didOrHandle/rkey/...)
18
+
const isStandaloneDoc = path[0] === "p" && path.length >= 3;
19
+
20
+
let documentUri: string;
21
+
let authorDid: string;
22
+
23
+
if (isStandaloneDoc) {
24
+
// Standalone doc: /p/didOrHandle/rkey/l-quote/...
25
+
const didOrHandle = decodeURIComponent(path[1]);
26
+
const rkey = path[2];
27
+
28
+
// Resolve handle to DID if necessary
29
+
let did = didOrHandle;
30
+
if (!didOrHandle.startsWith("did:")) {
31
+
const resolved = await step.run("resolve-handle", async () => {
32
+
return idResolver.handle.resolve(didOrHandle);
33
+
});
34
+
if (!resolved) {
35
+
return { message: `Could not resolve handle: ${didOrHandle}` };
36
+
}
37
+
did = resolved;
38
+
}
21
39
22
-
if (!pub) {
23
-
return {
24
-
message: `No publication found for ${url.host}/${path[0]}`,
25
-
error,
26
-
};
40
+
documentUri = AtUri.make(did, ids.PubLeafletDocument, rkey).toString();
41
+
authorDid = did;
42
+
} else {
43
+
// Publication post: look up by custom domain
44
+
let { data: pub, error } = await supabaseServerClient
45
+
.from("publications")
46
+
.select("*")
47
+
.eq("record->>base_path", url.host)
48
+
.single();
49
+
50
+
if (!pub) {
51
+
return {
52
+
message: `No publication found for ${url.host}/${path[0]}`,
53
+
error,
54
+
};
55
+
}
56
+
57
+
documentUri = AtUri.make(
58
+
pub.identity_did,
59
+
ids.PubLeafletDocument,
60
+
path[0],
61
+
).toString();
62
+
authorDid = pub.identity_did;
27
63
}
28
64
29
65
let bsky_post = await step.run("get-bsky-post-data", async () => {
···
38
74
if (!bsky_post) {
39
75
return { message: `No post found for ${event.data.post_uri}` };
40
76
}
41
-
42
-
const documentUri = AtUri.make(
43
-
pub.identity_did,
44
-
ids.PubLeafletDocument,
45
-
path[0],
46
-
).toString();
47
77
48
78
await step.run("index-bsky-post", async () => {
49
79
await supabaseServerClient.from("bsky_posts").upsert({
···
60
90
61
91
await step.run("create-notification", async () => {
62
92
// Only create notification if the quote is from someone other than the author
63
-
if (bsky_post.author.did !== pub.identity_did) {
93
+
if (bsky_post.author.did !== authorDid) {
64
94
// Check if a notification already exists for this post and recipient
65
95
const { data: existingNotification } = await supabaseServerClient
66
96
.from("notifications")
67
97
.select("id")
68
-
.eq("recipient", pub.identity_did)
98
+
.eq("recipient", authorDid)
69
99
.eq("data->>type", "quote")
70
100
.eq("data->>bsky_post_uri", bsky_post.uri)
71
101
.eq("data->>document_uri", documentUri)
···
74
104
if (!existingNotification) {
75
105
const notification: Notification = {
76
106
id: v7(),
77
-
recipient: pub.identity_did,
107
+
recipient: authorDid,
78
108
data: {
79
109
type: "quote",
80
110
bsky_post_uri: bsky_post.uri,
···
82
112
},
83
113
};
84
114
await supabaseServerClient.from("notifications").insert(notification);
85
-
await pingIdentityToUpdateNotification(pub.identity_did);
115
+
await pingIdentityToUpdateNotification(authorDid);
86
116
}
87
117
}
88
118
});