Skip to content

Commit 93d0968

Browse files
committed
add handling of deleted users
1 parent 22ee5f3 commit 93d0968

File tree

3 files changed

+110
-11
lines changed

3 files changed

+110
-11
lines changed

deno.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
},
66
"imports": {
77
"@atproto/api": "npm:@atproto/api@^0.13.18",
8+
"@atproto/xrpc": "npm:@atproto/xrpc@^0.7.7",
89
"@db/sqlite": "jsr:@db/sqlite@^0.12.0",
910
"@std/assert": "jsr:@std/assert@1",
1011
"@std/path": "jsr:@std/path@^1.0.8",

deno.lock

Lines changed: 60 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

discord/client.ts

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Client, Collection, EmbedBuilder, Events, GatewayIntentBits } from "discord.js";
22
import { AppBskyFeedDefs, AtpAgent } from "@atproto/api";
3+
import { XRPCError } from "@atproto/xrpc";
34
import { Database } from "@db/sqlite";
45
import { getBlueskyPostLink, processPostText } from "../bluesky/helpers.ts";
56
import { CommandHandler } from "./commandHandler.ts";
@@ -91,6 +92,43 @@ export class BlueskyDiscordBot {
9192
return trackedAccounts;
9293
}
9394

95+
/**
96+
* Completely removes a Bluesky account from the database.
97+
* Removes all subscriptions across all channels, clears post history,
98+
* and stops tracking the account.
99+
*/
100+
forceRemoveAccount(did: string): boolean {
101+
try {
102+
const transaction = this.db.transaction(() => {
103+
const subsStmt = this.db.prepare(`
104+
DELETE FROM channel_subscriptions
105+
WHERE did = ?
106+
`);
107+
const deletedSubsCount = subsStmt.run(did);
108+
109+
const postsStmt = this.db.prepare(`
110+
DELETE FROM processed_posts
111+
WHERE did = ?
112+
`);
113+
postsStmt.run(did);
114+
115+
const trackStmt = this.db.prepare(`
116+
DELETE FROM tracked_accounts
117+
WHERE did = ?
118+
`);
119+
trackStmt.run(did);
120+
121+
console.log(`Force removed account ${did}. Removed ${deletedSubsCount} subscriptions.`);
122+
});
123+
124+
transaction();
125+
return true;
126+
} catch (error) {
127+
console.error(`Error forcing removal of account ${did}:`, error);
128+
return false;
129+
}
130+
}
131+
94132
private async pollBlueskyAccounts() {
95133
const accounts = this.getTrackedAccounts();
96134

@@ -115,6 +153,15 @@ export class BlueskyDiscordBot {
115153
console.log(`Data feed for ${account.did} less than 0.`);
116154
}
117155
} catch (error) {
156+
if (error instanceof XRPCError) {
157+
if (error.status === 400 && error.message?.includes("Profile not found")) {
158+
console.warn(`Profile ${account.did} not found. Purging from database...`);
159+
160+
this.forceRemoveAccount(account.did);
161+
162+
return;
163+
}
164+
}
118165
console.log(`Error polling account ${account.did}:`, error);
119166
}
120167
}
@@ -136,7 +183,7 @@ export class BlueskyDiscordBot {
136183
`;
137184
if (dbResp.length === 0) {
138185
this.db.sql`
139-
INSERT INTO processed_posts (post_uri, did, post_type) VALUES
186+
INSERT INTO processed_posts (post_uri, did, post_type) VALUES
140187
(${feedItem.post.uri}, ${authorOrReposter}, ${postType})
141188
`;
142189
// TODO: add culling of oldest posts over 100
@@ -150,7 +197,7 @@ export class BlueskyDiscordBot {
150197
private updateLastChecked(account: { did: string }, time: Date) {
151198
const sqliteDate = time.toISOString();
152199
this.db.sql`
153-
UPDATE tracked_accounts SET last_checked_at = ${sqliteDate} WHERE did = ${account.did}
200+
UPDATE tracked_accounts SET last_checked_at = ${sqliteDate} WHERE did = ${account.did}
154201
`;
155202
}
156203

0 commit comments

Comments
 (0)