a fun bot for the hc slack
at v0.0.3 2.8 kB view raw
1import type { MessageResponse } from "../types"; 2import { getActiveTake } from "../services/database"; 3import { db } from "../../../libs/db"; 4import { takes as takesTable } from "../../../libs/schema"; 5import TakesConfig from "../../../libs/config"; 6import { generateSlackDate, prettyPrintTime } from "../../../libs/time"; 7import { getRemainingTime } from "../../../libs/time-periods"; 8 9export default async function handleStart( 10 userId: string, 11 channelId: string, 12 description?: string, 13): Promise<MessageResponse> { 14 const activeTake = await getActiveTake(userId); 15 if (activeTake.length > 0) { 16 return { 17 text: "You already have an active takes session! Use `/takes status` to check it.", 18 response_type: "ephemeral", 19 }; 20 } 21 22 // Create new takes session 23 const newTake = { 24 id: Bun.randomUUIDv7(), 25 userId, 26 status: "active", 27 targetDurationMs: TakesConfig.DEFAULT_SESSION_LENGTH * 60000, 28 periods: JSON.stringify([ 29 { 30 type: "active", 31 startTime: Date.now(), 32 endTime: null, 33 }, 34 ]), 35 elapsedTimeMs: 0, 36 description: description || null, 37 notifiedLowTime: false, 38 notifiedPauseExpiration: false, 39 }; 40 41 await db.insert(takesTable).values(newTake); 42 43 // Calculate end time for message 44 const endTime = getRemainingTime( 45 TakesConfig.DEFAULT_SESSION_LENGTH * 60000, 46 newTake.periods, 47 ); 48 49 const descriptionText = description 50 ? `\n\n*Working on:* ${description}` 51 : ""; 52 return { 53 text: `🎬 Takes session started! You have ${prettyPrintTime(endTime.remaining)} until ${generateSlackDate(endTime.endTime)}.${descriptionText}`, 54 response_type: "ephemeral", 55 blocks: [ 56 { 57 type: "section", 58 text: { 59 type: "mrkdwn", 60 text: `🎬 Takes session started!${descriptionText}`, 61 }, 62 }, 63 { 64 type: "divider", 65 }, 66 { 67 type: "context", 68 elements: [ 69 { 70 type: "mrkdwn", 71 text: `You have ${prettyPrintTime(endTime.remaining)} left until ${generateSlackDate(endTime.endTime)}.`, 72 }, 73 ], 74 }, 75 { 76 type: "actions", 77 elements: [ 78 { 79 type: "button", 80 text: { 81 type: "plain_text", 82 text: "✍️ edit", 83 emoji: true, 84 }, 85 value: "edit", 86 action_id: "takes_edit", 87 }, 88 { 89 type: "button", 90 text: { 91 type: "plain_text", 92 text: "⏸️ Pause", 93 emoji: true, 94 }, 95 value: "pause", 96 action_id: "takes_pause", 97 }, 98 { 99 type: "button", 100 text: { 101 type: "plain_text", 102 text: "⏹️ Stop", 103 emoji: true, 104 }, 105 value: "stop", 106 action_id: "takes_stop", 107 style: "danger", 108 }, 109 { 110 type: "button", 111 text: { 112 type: "plain_text", 113 text: "🔄 Refresh", 114 emoji: true, 115 }, 116 value: "status", 117 action_id: "takes_status", 118 }, 119 ], 120 }, 121 ], 122 }; 123}