a fun bot for the hc slack
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}