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.

!uptime command

+56 -1
+56 -1
utils/commands/defaultCommands.ts
··· 1 1 import RichtextBuilder from "@atcute/bluesky-richtext-builder"; 2 - import { getRecord } from "../atcuteUtils.ts"; 2 + import { getRecord, listRecords } from "../atcuteUtils.ts"; 3 3 import { didResolver } from "../didResolver.ts"; 4 4 import type { CommandWrapper } from "../commandHandler.ts"; 5 5 import { FOLLOWER_MODE } from "../../env.ts"; 6 6 import { AppBskyRichtextFacet } from "@atcute/bluesky"; 7 7 import { is } from "@atcute/lexicons"; 8 8 import { buildRichtext } from "../richtextUtils.ts"; 9 + import { PlaceStreamLivestream } from "../lexicons/index.ts"; 9 10 10 11 const commandsCommand: CommandWrapper = async (_message, _params, bot) => { 11 12 const commandsList = Array.from( ··· 277 278 await bot.sendMessage(text, facets); 278 279 }; 279 280 281 + const uptimeCommand: CommandWrapper = async (_event, _params, bot) => { 282 + const streamerDid = bot.getStreamerDid(); 283 + const streamer = await bot.getUserProfile(streamerDid); 284 + try { 285 + const { records } = await listRecords(streamer.pdsEndpoint, { 286 + repo: streamerDid, 287 + collection: "place.stream.livestream", 288 + }); 289 + if (!records || records.length < 1) return; 290 + const record = records[0].value as PlaceStreamLivestream.Main; 291 + if (!record.lastSeenAt) return; 292 + const lastSeen = new Date(record.lastSeenAt).getTime(); 293 + const now = Date.now(); 294 + const idleTimeoutMs = 295 + record.idleTimeoutSeconds && record.idleTimeoutSeconds > 0 296 + ? record.idleTimeoutSeconds * 1000 297 + : 300 * 1000; 298 + if ((now - lastSeen) > idleTimeoutMs) return; 299 + 300 + const created = new Date(record.createdAt).getTime(); 301 + const elapsedMs = now - created; 302 + const elapsedHours = Math.floor(elapsedMs / (1000 * 60 * 60)); 303 + const elapsedMinutes = Math.floor( 304 + (elapsedMs % (1000 * 60 * 60)) / (1000 * 60), 305 + ); 306 + 307 + let uptimeText: string; 308 + if (elapsedHours === 0) { 309 + uptimeText = `${elapsedMinutes} minute${ 310 + elapsedMinutes !== 1 ? "s" : "" 311 + }`; 312 + } else if (elapsedMinutes === 0) { 313 + uptimeText = `${elapsedHours} hour${elapsedHours !== 1 ? "s" : ""}`; 314 + } else { 315 + uptimeText = `${elapsedHours} hour${ 316 + elapsedHours !== 1 ? "s" : "" 317 + } and ${elapsedMinutes} minute${elapsedMinutes !== 1 ? "s" : ""}`; 318 + } 319 + 320 + const { text, facets } = new RichtextBuilder() 321 + .addMention(streamer.handle, streamerDid) 322 + .addText(" has been live for ") 323 + .addText(uptimeText); 324 + 325 + await bot.sendMessage(text, facets); 326 + } catch (error) { 327 + console.error( 328 + "Error checking if streamer is live:", 329 + error, 330 + ); 331 + } 332 + }; 333 + 280 334 export const defaultCommands: Map<string, CommandWrapper> = new Map([ 281 335 ["commands", commandsCommand], 282 336 ["bot", botCommand], 283 337 ["shoutout", shoutoutCommand], 284 338 ["so", shoutoutCommand], 339 + ["uptime", uptimeCommand], 285 340 ["hug", hugCommand], 286 341 ["song", songCommand], 287 342 ["linkat", linkatCommand],