···1515## Advanced usage
1616- Set up custom commands in your PDS based on [this lexicon](https://pds.ls/at://did:plc:xnpibbj2hcqlsodutcnirmxp/com.atproto.lexicon.schema/online.timtinkers.bot.command). You can find examples [here](https://pds.ls/at://did:plc:xnpibbj2hcqlsodutcnirmxp/online.timtinkers.bot.command) (work-in-progress)
1717- Set up custom shoutouts in your PDS based on [this lexicon](https://pds.ls/at://did:plc:xnpibbj2hcqlsodutcnirmxp/com.atproto.lexicon.schema/online.timtinkers.bot.shoutout). You can find my current shoutouts [here](https://pds.ls/at://did:plc:o6xucog6fghiyrvp7pyqxcs3/online.timtinkers.bot.shoutout)
1818-- Navigate to your chat overlay at https://bot.timtinkers.online/chat/alice.bsky.social or http://localhost:8000/chat/alice.bsky.social if you are self-hosting
1919-- If you want to build your own overlay and still want to use enriched messages (that include avatars, pronouns, banners, PDS hosts), you can also subscribe to the websocket at wss://bot.timtinkers.online/api/websocket/alice.bsky.social or ws://localhost:8000/api/websocket/alice.bsky.social respectively
1818+- Navigate to your chat overlay at https://bot.timtinkers.online/chat?streamer=alice.bsky.social or http://localhost:8000/chat?streamer=alice.bsky.social if you are self-hosting
1919+- If you want to build your own overlay and still want to use enriched messages (that include avatars, pronouns, banners, PDS hosts), you can also subscribe to the websocket at wss://bot.timtinkers.online/api/websocket?streamer=alice.bsky.social or ws://localhost:8000/api/websocket?streamer=alice.bsky.social respectively
20202121## Setup for self-hosters
2222
···302302303303 const { handle, pdsEndpoint, actorProfile, chatProfile } =
304304 await didResolver.resolve(commitEvent.did);
305305+ // Get streamer avatar
306306+ const streamerAvatar = (await didResolver.resolve(streamerDid))
307307+ .actorProfile?.avatar;
305308 // Get moderators for badge creation
306309 const moderators = botInstances.get(streamerDid)?.getModerators();
307310 const badges: BadgeView[] = [];
···367370 },
368371 cid: commitEvent.commit.cid,
369372 deleted: false,
373373+ streamerAvatarUrl: streamerAvatar
374374+ ? this.imageUrl(
375375+ streamerDid,
376376+ (streamerAvatar as BlobWithRef).ref.$link,
377377+ )
378378+ : undefined,
370379 indexedAt: new Date().toISOString(), // could convert the `time_us` but this is good enough
371380 record: commitEvent.commit.record as PlaceStreamChatMessage.Main,
372381 uri: `at://${commitEvent.did}/place.stream.chat.message/${commitEvent.commit.rkey}`,
+1
utils/globals.d.ts
···3434 };
3535 // it is not obvious to me why but the official lexicon has type Record<string, unknown> here
3636 record: import("./lexicons/index.ts").PlaceStreamChatMessage.Main;
3737+ streamerAvatarUrl?: string;
3738}
+5-3
utils/websocket.ts
···3535 this.connectToJetstream();
3636 }
37373838- // Handle new connection with pre-defined streamer DID
3939- handleNewConnection(client: WebSocket, streamerDid: Did) {
4040- // Initialize client with empty subscriptions
3838+ initClient(client: WebSocket) {
4139 this.clients.set(client, new Set());
4040+ }
42414242+ // Handle new connection with pre-defined streamer DID
4343+ handleNewConnection(client: WebSocket, streamerDid: Did) {
4444+ this.initClient(client);
4345 // Auto-subscribe to the streamer from the route parameter
4446 this.handleClientMessage(client, {
4547 type: "subscribe",