A work-in-progress chat bot for Streamplace with chat overlay functionality
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Better pronouns command, handling changes in actor profile or chat profile

+85 -22
+36 -18
utils/commands/defaultCommands.ts
··· 153 153 }; 154 154 155 155 const pronounsCommand: CommandWrapper = async (event, _params, bot) => { 156 - const streamer = await bot.getUserProfile(bot.getStreamerDid()); 156 + const streamerDid = bot.getStreamerDid(); 157 + let target: UserProfile; 158 + let mention, targetDid; 159 + // Check for mentioned user, fall back to streamer 160 + if ( 161 + is( 162 + AppBskyRichtextFacet.mentionSchema, 163 + event.commit.record?.facets?.[0]?.features?.[0], 164 + ) 165 + ) { 166 + mention = event.commit.record?.facets?.[0]?.features?.[0]; 167 + targetDid = mention.did as Did; 168 + target = await didResolver.resolve(targetDid); 169 + } else { 170 + targetDid = streamerDid; 171 + target = await bot.getUserProfile(streamerDid); 172 + } 173 + 157 174 const actorProfileURL: `${string}:${string}` = 158 - `https://pdsls.dev/at://${event.did}/app.bsky.actor.profile/self`; 175 + `https://pdsls.dev/at://${targetDid}/app.bsky.actor.profile/self`; 159 176 160 177 const richtextBuilder = new RichtextBuilder(); 161 - if (streamer.actorProfile?.pronouns) { 178 + if (target.actorProfile?.pronouns) { 162 179 richtextBuilder 163 - .addMention(streamer.handle, bot.getStreamerDid()) 180 + .addMention(target.handle, bot.getStreamerDid()) 164 181 .addText( 165 - `'s pronouns are ${streamer.actorProfile.pronouns}. `, 182 + `'s pronouns are ${target.actorProfile.pronouns}.`, 166 183 ); 167 - } 168 - richtextBuilder.addText("You can set your pronouns and website in your ") 169 - .addLink("app.bsky.actor.profile", actorProfileURL) 170 - .addText( 171 - ". You can't currently set them in the Bluesky app, however you can use ", 184 + } else {richtextBuilder.addText( 185 + "You can set your pronouns and website in your ", 172 186 ) 173 - .addLink("Blacksky", "https://blacksky.community/") 174 - .addText(", ") 175 - .addLink("Witchsky", "https://witchsky.app/") 176 - .addText(", ") 177 - .addLink("Anisota", "https://anisota.net/") 178 - .addText(" or ") 179 - .addLink("PDSls", "https://pdsls.dev/") 180 - .addText("."); 187 + .addLink("app.bsky.actor.profile", actorProfileURL) 188 + .addText( 189 + ". You can't currently set them in the Bluesky app, however you can use ", 190 + ) 191 + .addLink("Blacksky", "https://blacksky.community/") 192 + .addText(", ") 193 + .addLink("Witchsky", "https://witchsky.app/") 194 + .addText(", ") 195 + .addLink("Anisota", "https://anisota.net/") 196 + .addText(" or ") 197 + .addLink("PDSls", "https://pdsls.dev/") 198 + .addText(".");} 181 199 182 200 const { text, facets } = richtextBuilder; 183 201 await bot.sendMessage(text, facets);
+8
utils/didResolver.ts
··· 86 86 } 87 87 } 88 88 89 + getUser(did: Did): UserProfile | undefined { 90 + return this.cache.get(did); 91 + } 92 + 93 + setUser(did: Did, profile: UserProfile) { 94 + this.cache.set(did, profile); 95 + } 96 + 89 97 clearUserFromCache(did: Did) { 90 98 this.cache.delete(did); 91 99 }
+41 -4
utils/eventHandler.ts
··· 1 - import { AppBskyGraphFollow } from "@atcute/bluesky"; 1 + import { AppBskyActorProfile, AppBskyGraphFollow } from "@atcute/bluesky"; 2 2 import RichtextBuilder from "@atcute/bluesky-richtext-builder"; 3 3 import { CommitEvent, JetstreamEvent } from "@atcute/jetstream"; 4 4 import { is, ResourceUri } from "@atcute/lexicons"; ··· 9 9 OnlineTimtinkersBotCommand, 10 10 OnlineTimtinkersBotShoutout, 11 11 PlaceStreamChatMessage, 12 + PlaceStreamChatProfile, 12 13 PlaceStreamLivestream, 13 14 PlaceStreamLiveTeleport, 14 15 } from "./lexicons/index.ts"; ··· 86 87 } 87 88 } 88 89 89 - private async handleActorProfile(event: CommitEvent): Promise<void> { 90 + private handleActorProfile(event: CommitEvent): void { 91 + if (!didResolver.getUser(event.did)) return; 92 + if (event.commit.rkey !== "self") return; 93 + const profile = didResolver.getUser(event.did)!; 94 + // Case created or updated profile 95 + if ( 96 + event.commit.operation === "create" || 97 + event.commit.operation === "update" 98 + ) { 99 + const record = event.commit 100 + .record as AppBskyActorProfile.Main; 101 + profile.actorProfile = record; 102 + didResolver.setUser(event.did, profile); 103 + } 104 + // Case deleted profile 105 + if (event.commit.operation === "delete") { 106 + profile.actorProfile = undefined; 107 + didResolver.setUser(event.did, profile); 108 + } 90 109 } 91 110 92 111 private async handleChatMessage(event: CommitEvent): Promise<void> { ··· 121 140 } 122 141 } 123 142 124 - private async handleChatProfile(event: CommitEvent): Promise<void> { 143 + private handleChatProfile(event: CommitEvent): void { 144 + if (!didResolver.getUser(event.did)) return; 145 + if (event.commit.rkey !== "self") return; 146 + const profile = didResolver.getUser(event.did)!; 147 + // Case created or updated profile 148 + if ( 149 + event.commit.operation === "create" || 150 + event.commit.operation === "update" 151 + ) { 152 + const record = event.commit 153 + .record as PlaceStreamChatProfile.Main; 154 + profile.chatProfile = record; 155 + didResolver.setUser(event.did, profile); 156 + } 157 + // Case deleted profile 158 + if (event.commit.operation === "delete") { 159 + profile.chatProfile = undefined; 160 + didResolver.setUser(event.did, profile); 161 + } 125 162 } 126 163 127 164 private async handleTeleport(event: CommitEvent): Promise<void> { ··· 200 237 bot!.getShoutouts().set(record.user, record); 201 238 bot!.getShoutoutsByAtUri().set(uri, record.user); 202 239 if (event.commit.operation === "update") { 203 - bot!.getGreeted().set(record.user, false); 240 + bot!.getGreeted().delete(record.user); 204 241 } 205 242 } 206 243 // Case deleted shoutout