From 794df5d59759821dfd4d5f2eb11c3080ed736145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Hervier?= Date: Sun, 24 Nov 2024 22:14:27 +0100 Subject: [PATCH 1/3] Add reply_root event --- src/bot/BotEventEmitter.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/bot/BotEventEmitter.ts b/src/bot/BotEventEmitter.ts index 321d19d..8eb3ec4 100644 --- a/src/bot/BotEventEmitter.ts +++ b/src/bot/BotEventEmitter.ts @@ -253,16 +253,18 @@ export class BotEventEmitter extends EventEmitter { "app.bsky.feed.post", async ({ commit: { record, rkey }, did }) => { const uri = `at://${did}/app.bsky.feed.post/${rkey}`; - if (record.reply?.parent?.uri?.includes(`at://${this.bot.profile.did}`)) { + if (record.reply?.parent?.uri?.startsWith(`at://${this.bot.profile.did}/`)) { this.emit("reply", await this.bot.getPost(uri)); + } else if (record.reply?.root?.uri?.startsWith(`at://${this.bot.profile.did}/`)) { + this.emit("reply_root", await this.bot.getPost(uri)); } else if ( is("app.bsky.embed.record", record.embed) - && record.embed.record.uri.includes(`at://${this.bot.profile.did}`) + && record.embed.record.uri.startsWith(`at://${this.bot.profile.did}/`) ) { this.emit("quote", await this.bot.getPost(uri)); } else if ( is("app.bsky.embed.recordWithMedia", record.embed) - && record.embed.record.record.uri.includes(`at://${this.bot.profile.did}`) + && record.embed.record.record.uri.startsWith(`at://${this.bot.profile.did}/`) ) { this.emit("quote", await this.bot.getPost(uri)); } else if ( @@ -282,7 +284,7 @@ export class BotEventEmitter extends EventEmitter { "app.bsky.feed.repost", async ({ commit: { record, rkey }, did }) => { const uri = `at://${did}/app.bsky.feed.repost/${rkey}`; - if (record.subject?.uri?.includes(`at://${this.bot.profile.did}`)) { + if (record.subject?.uri?.startsWith(`at://${this.bot.profile.did}/`)) { this.emit("repost", { post: await this.bot.getPost(uri), user: await this.bot.getProfile(did), @@ -296,7 +298,7 @@ export class BotEventEmitter extends EventEmitter { "app.bsky.feed.like", async ({ commit: { record, rkey }, did }) => { const uri = `at://${did}/app.bsky.feed.like/${rkey}`; - if (record.subject?.uri?.includes(`at://${this.bot.profile.did}`)) { + if (record.subject?.uri?.startsWith(`at://${this.bot.profile.did}/`)) { const { collection, host } = parseAtUri(record.subject.uri); let subject: Post | FeedGenerator | Labeler | undefined; switch (collection) { From 35b9b611aa21a07e942b7cbf2659c290c68bac49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Hervier?= Date: Sun, 24 Nov 2024 22:34:06 +0100 Subject: [PATCH 2/3] Add ts docs for reply_root event --- src/bot/Bot.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bot/Bot.ts b/src/bot/Bot.ts index 9805212..12b8a05 100644 --- a/src/bot/Bot.ts +++ b/src/bot/Bot.ts @@ -160,6 +160,7 @@ export class Bot extends EventEmitter { this.eventEmitter.on("error", (error) => this.emit("error", error)); this.eventEmitter.on("close", () => this.emit("close")); this.eventEmitter.on("reply", (event) => this.emit("reply", event)); + this.eventEmitter.on("reply_root", (event) => this.emit("reply_root", event)); this.eventEmitter.on("quote", (event) => this.emit("quote", event)); this.eventEmitter.on("mention", (event) => this.emit("mention", event)); this.eventEmitter.on("repost", (event) => this.emit("repost", event)); @@ -1522,6 +1523,8 @@ export class Bot extends EventEmitter { override on(event: "close", listener: () => void): this; /** Emitted when the bot receives a reply. */ override on(event: "reply", listener: (post: Post) => void): this; + /** Emitted when the bot receives a reply inside a post thread initiated by the bot. */ + override on(event: "reply_root", listener: (post: Post) => void): this; /** Emitted when the bot receives a quote post. */ override on(event: "quote", listener: (post: Post) => void): this; /** Emitted when the bot is mentioned. */ @@ -1573,6 +1576,7 @@ export class Bot extends EventEmitter { override addListener(event: "error", listener: (error: unknown) => void): this; override addListener(event: "close", listener: () => void): this; override addListener(event: "reply", listener: (post: Post) => void): this; + override addListener(event: "reply_root", listener: (post: Post) => void): this; override addListener(event: "quote", listener: (post: Post) => void): this; override addListener(event: "mention", listener: (post: Post) => void): this; override addListener( From 19b8c2527bf15d001778eda780d497ab8e8ff510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Hervier?= Date: Sun, 24 Nov 2024 22:49:04 +0100 Subject: [PATCH 3/3] Add reply_root to polling interceptor --- src/bot/BotEventEmitter.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/bot/BotEventEmitter.ts b/src/bot/BotEventEmitter.ts index 8eb3ec4..53a48a9 100644 --- a/src/bot/BotEventEmitter.ts +++ b/src/bot/BotEventEmitter.ts @@ -388,12 +388,15 @@ export class BotEventEmitter extends EventEmitter { emitInvalidRecordError(notification); break; } + let isRootReply = false; if (notification.record.reply) { try { - const { host } = parseAtUri(notification.record.reply.parent.uri); - if (host !== this.bot.profile.did) { - // Ignore replies that aren't direct replies to the bot - break; + const { host: parentHost } = parseAtUri(notification.record.reply.parent.uri); + const { host: rootHost } = parseAtUri(notification.record.reply.parent.uri); + if (parentHost !== this.bot.profile.did && rootHost === this.bot.profile.did) { + isRootReply = true; // This reply is only a root-reply + } else if (parentHost !== this.bot.profile.did) { + break; // Ignore non-parent & non-root replies } } catch (e) { // Ignore invalid AT URI @@ -401,7 +404,7 @@ export class BotEventEmitter extends EventEmitter { } } const reply = await this.bot.getPost(notification.uri); - if (reply) this.emit("reply", reply); + if (reply) this.emit(isRootReply ? "reply_root" : "reply", reply); break; } case "quote": {