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.

atcute getRecord and listRecords wrappers

+50 -53
+29 -46
utils/atcuteUtils.ts
··· 120 120 getDid(): string | undefined { 121 121 return this.credentialManager.session?.did; 122 122 } 123 - 124 - // Get shoutouts from a specific DID's repository 125 - async getShoutouts(did: Did, pdsFallback?: string) { 126 - const rpc = new Client({ 127 - // TODO: get dynamic PDS - for now using fallback or configured PDS 128 - handler: simpleFetchHandler({ 129 - service: pdsFallback || this.config.pdsHostUrl, 130 - }), 131 - }); 132 - 133 - const shoutouts = await ok( 134 - rpc.get("com.atproto.repo.listRecords", { 135 - params: { 136 - repo: did, 137 - collection: "online.timtinkers.bot.shoutout", 138 - limit: 100, 139 - // TODO: cursor for pagination 140 - reverse: false, 141 - }, 142 - }), 143 - ); 144 - 145 - return shoutouts; 146 - } 147 123 } 148 124 149 125 // Shared handle resolver instance ··· 205 181 return handle; 206 182 } 207 183 208 - // Get app.bsky.actor.profile 209 - export async function getActorProfile(did: Did, pdsHostUrl: string) { 184 + // If you want even more generic wrappers: 185 + // interface XRPCQueries { 186 + // "com.atproto.repo.getRecord": ComAtprotoRepoGetRecord.mainSchema; 187 + // "com.atproto.repo.listRecords": ComAtprotoRepoListRecords.mainSchema; 188 + // } 189 + 190 + // com.atproto.repo.getRecord generic wrapper 191 + export async function getRecord( 192 + pdsHostUrl: string, 193 + params: { 194 + repo: Did; 195 + collection: `${string}.${string}.${string}`; 196 + rkey: string; 197 + }, 198 + ) { 210 199 const rpc = new Client({ 211 200 handler: simpleFetchHandler({ 212 201 service: pdsHostUrl, 213 202 }), 214 203 }); 215 204 216 - const actorProfile = await ok( 217 - rpc.get("com.atproto.repo.getRecord", { 218 - params: { 219 - repo: did, 220 - collection: "app.bsky.actor.profile", 221 - rkey: "self", 222 - }, 223 - }), 205 + const record = await ok( 206 + rpc.get("com.atproto.repo.getRecord", { params: params }), 224 207 ); 225 208 226 - return actorProfile; 209 + return record; 227 210 } 228 211 229 - // Get place.stream.chat.profile 230 - export async function getChatProfile(did: Did, pdsHostUrl: string) { 212 + // com.atproto.repo.listRecords generic wrapper 213 + export async function listRecords( 214 + pdsHostUrl: string, 215 + params: { 216 + repo: Did; 217 + collection: `${string}.${string}.${string}`; 218 + }, 219 + ) { 231 220 const rpc = new Client({ 232 221 handler: simpleFetchHandler({ 233 222 service: pdsHostUrl, 234 223 }), 235 224 }); 236 225 237 - const actorProfile = await ok( 238 - rpc.get("com.atproto.repo.getRecord", { 239 - params: { 240 - repo: did, 241 - collection: "place.stream.chat.profile", 242 - rkey: "self", 243 - }, 244 - }), 226 + const record = await ok( 227 + rpc.get("com.atproto.repo.listRecords", { params: params }), 245 228 ); 246 229 247 - return actorProfile; 230 + return record; 248 231 }
+11 -4
utils/didResolver.ts
··· 1 1 import { 2 - getActorProfile, 3 - getChatProfile, 4 2 getDidDocument, 5 3 getHandle, 6 4 getPDS, 5 + getRecord, 7 6 } from "./atcuteUtils.ts"; 8 7 import { fetchPronouns } from "./labelUtils.ts"; 9 8 declare type ActorProfile = import("@atcute/bluesky").AppBskyActorProfile.Main; ··· 50 49 51 50 const [actorProfileResult, chatProfileResult, pronounLabelsResult] = 52 51 await Promise.allSettled([ 53 - getActorProfile(did, pdsHostUrl), 54 - getChatProfile(did, pdsHostUrl), 52 + getRecord(pdsHostUrl, { 53 + repo: did, 54 + collection: "app.bsky.actor.profile", 55 + rkey: "self", 56 + }), 57 + getRecord(pdsHostUrl, { 58 + repo: did, 59 + collection: "place.stream.chat.profile", 60 + rkey: "self", 61 + }), 55 62 fetchPronouns([did]), 56 63 ]); 57 64
+10 -3
utils/streamplaceBot.ts
··· 1 1 import RichtextBuilder from "@atcute/bluesky-richtext-builder"; 2 - import { AtprotoClient, AtprotoClientConfig } from "./atcuteUtils.ts"; 2 + import { 3 + AtprotoClient, 4 + AtprotoClientConfig, 5 + listRecords, 6 + } from "./atcuteUtils.ts"; 3 7 import { didResolver } from "./didResolver.ts"; 4 8 5 9 export interface CommandHandler { ··· 66 70 67 71 const streamer = await this.getUserProfile(this.streamerDid); 68 72 try { 69 - const shoutoutsData = await this.client.getShoutouts( 70 - this.streamerDid, 73 + const shoutoutsData = await listRecords( 71 74 streamer.pdsEndpoint, 75 + { 76 + repo: this.streamerDid, 77 + collection: "online.timtinkers.bot.shoutout", 78 + }, 72 79 ); 73 80 74 81 // Cache all shoutouts