a fun bot for the hc slack
at v0.0.3 5.9 kB view raw
1import TakesConfig from "../../../libs/config"; 2import { generateSlackDate, prettyPrintTime } from "../../../libs/time"; 3import { 4 getPausedTimeRemaining, 5 getRemainingTime, 6} from "../../../libs/time-periods"; 7import { 8 getActiveTake, 9 getCompletedTakes, 10 getPausedTake, 11} from "../services/database"; 12import { expirePausedSessions } from "../services/notifications"; 13import type { MessageResponse } from "../types"; 14 15export default async function handleStatus( 16 userId: string, 17): Promise<MessageResponse | undefined> { 18 const activeTake = await getActiveTake(userId); 19 20 // First, check for expired paused sessions 21 await expirePausedSessions(); 22 23 if (activeTake.length > 0) { 24 const take = activeTake[0]; 25 if (!take) { 26 return; 27 } 28 29 const endTime = getRemainingTime(take.targetDurationMs, take.periods); 30 31 // Add description to display if present 32 const descriptionText = take.description 33 ? `\n\n*Working on:* ${take.description}` 34 : ""; 35 36 return { 37 text: `🎬 You have an active takes session with ${prettyPrintTime(endTime.remaining)} remaining.${descriptionText}`, 38 response_type: "ephemeral", 39 blocks: [ 40 { 41 type: "section", 42 text: { 43 type: "mrkdwn", 44 text: `🎬 You have an active takes session${descriptionText}`, 45 }, 46 }, 47 { 48 type: "divider", 49 }, 50 { 51 type: "context", 52 elements: [ 53 { 54 type: "mrkdwn", 55 text: `You have ${prettyPrintTime(endTime.remaining)} remaining until ${generateSlackDate(endTime.endTime)}.`, 56 }, 57 ], 58 }, 59 { 60 type: "actions", 61 elements: [ 62 { 63 type: "button", 64 text: { 65 type: "plain_text", 66 text: "✍️ edit", 67 emoji: true, 68 }, 69 value: "edit", 70 action_id: "takes_edit", 71 }, 72 { 73 type: "button", 74 text: { 75 type: "plain_text", 76 text: "⏸️ Pause", 77 emoji: true, 78 }, 79 value: "pause", 80 action_id: "takes_pause", 81 }, 82 { 83 type: "button", 84 text: { 85 type: "plain_text", 86 text: "⏹️ Stop", 87 emoji: true, 88 }, 89 value: "stop", 90 action_id: "takes_stop", 91 style: "danger", 92 }, 93 94 { 95 type: "button", 96 text: { 97 type: "plain_text", 98 text: "🔄 Refresh", 99 emoji: true, 100 }, 101 value: "status", 102 action_id: "takes_status", 103 }, 104 ], 105 }, 106 ], 107 }; 108 } 109 110 // Check for paused session 111 const pausedTakeStatus = await getPausedTake(userId); 112 113 if (pausedTakeStatus.length > 0) { 114 const pausedTake = pausedTakeStatus[0]; 115 if (!pausedTake) { 116 return; 117 } 118 119 // Calculate how much time remains before auto-completion 120 const endTime = getRemainingTime( 121 pausedTake.targetDurationMs, 122 pausedTake.periods, 123 ); 124 const pauseExpires = getPausedTimeRemaining(pausedTake.periods); 125 126 // Add notes to display if present 127 const descriptionText = pausedTake.description 128 ? `\n\n*Working on:* ${pausedTake.description}` 129 : ""; 130 131 return { 132 text: `⏸️ You have a paused takes session. It will auto-complete in ${prettyPrintTime(pauseExpires)} if not resumed.`, 133 response_type: "ephemeral", 134 blocks: [ 135 { 136 type: "section", 137 text: { 138 type: "mrkdwn", 139 text: `⏸️ Session paused! You have ${prettyPrintTime(endTime.remaining)} remaining.${descriptionText}`, 140 }, 141 }, 142 { 143 type: "divider", 144 }, 145 { 146 type: "context", 147 elements: [ 148 { 149 type: "mrkdwn", 150 text: `It will automatically finish in ${prettyPrintTime(pauseExpires)} (by ${generateSlackDate(new Date(new Date().getTime() - pauseExpires))}) if not resumed.`, 151 }, 152 ], 153 }, 154 { 155 type: "actions", 156 elements: [ 157 { 158 type: "button", 159 text: { 160 type: "plain_text", 161 text: "▶️ Resume", 162 emoji: true, 163 }, 164 value: "resume", 165 action_id: "takes_resume", 166 }, 167 { 168 type: "button", 169 text: { 170 type: "plain_text", 171 text: "⏹️ Stop", 172 emoji: true, 173 }, 174 value: "stop", 175 action_id: "takes_stop", 176 style: "danger", 177 }, 178 { 179 type: "button", 180 text: { 181 type: "plain_text", 182 text: "🔄 Refresh", 183 emoji: true, 184 }, 185 value: "status", 186 action_id: "takes_status", 187 }, 188 ], 189 }, 190 ], 191 }; 192 } 193 194 // Check history of completed sessions 195 const completedSessions = await getCompletedTakes(userId); 196 const takeTime = completedSessions.length 197 ? (() => { 198 const diffMs = 199 new Date().getTime() - 200 // @ts-expect-error - TS doesn't know that we are checking the length 201 completedSessions[completedSessions.length - 1] 202 ?.completedAt; 203 204 const hours = Math.ceil(diffMs / (1000 * 60 * 60)); 205 if (hours < 24) return `${hours} hours`; 206 207 const weeks = Math.floor(diffMs / (1000 * 60 * 60 * 24 * 7)); 208 if (weeks > 0 && weeks < 4) return `${weeks} weeks`; 209 210 const months = Math.floor(diffMs / (1000 * 60 * 60 * 24 * 30)); 211 return `${months} months`; 212 })() 213 : 0; 214 215 return { 216 text: `You have no active takes sessions. You've completed ${completedSessions.length} sessions in the last ${takeTime}.`, 217 response_type: "ephemeral", 218 blocks: [ 219 { 220 type: "section", 221 text: { 222 type: "mrkdwn", 223 text: `You have no active takes sessions. You've completed ${completedSessions.length} sessions in the last ${takeTime}.`, 224 }, 225 }, 226 { 227 type: "actions", 228 elements: [ 229 { 230 type: "button", 231 text: { 232 type: "plain_text", 233 text: "🎬 Start New Session", 234 emoji: true, 235 }, 236 value: "start", 237 action_id: "takes_start", 238 }, 239 { 240 type: "button", 241 text: { 242 type: "plain_text", 243 text: "📋 History", 244 emoji: true, 245 }, 246 value: "history", 247 action_id: "takes_history", 248 }, 249 ], 250 }, 251 ], 252 }; 253}