a fun bot for the hc slack
1import { slackClient } from "../../../index";
2import { db } from "../../../libs/db";
3import { takes as takesTable } from "../../../libs/schema";
4import { eq } from "drizzle-orm";
5import { getActiveTake, getPausedTake } from "../services/database";
6import type { MessageResponse } from "../types";
7import { prettyPrintTime } from "../../../libs/time";
8import { calculateElapsedTime } from "../../../libs/time-periods";
9
10export default async function handleStop(
11 userId: string,
12 args?: string[],
13): Promise<MessageResponse | undefined> {
14 const activeTake = await getActiveTake(userId);
15
16 if (activeTake.length === 0) {
17 const pausedTake = await getPausedTake(userId);
18
19 if (pausedTake.length === 0) {
20 return {
21 text: `You don't have an active or paused takes session!`,
22 response_type: "ephemeral",
23 };
24 }
25
26 // Mark the paused session as completed
27 const pausedTakeToStop = pausedTake[0];
28 if (!pausedTakeToStop) {
29 return;
30 }
31
32 // Extract notes if provided
33 let notes = undefined;
34 if (args && args.length > 1) {
35 notes = args.slice(1).join(" ");
36 }
37
38 const elapsed = calculateElapsedTime(
39 JSON.parse(pausedTakeToStop.periods),
40 );
41
42 const res = await slackClient.chat.postMessage({
43 channel: userId,
44 text: "🎬 Your paused takes session has been completed. Please upload your takes video in this thread within the next 24 hours!",
45 blocks: [
46 {
47 type: "section",
48 text: {
49 type: "mrkdwn",
50 text: "🎬 Your paused takes session has been completed. Please upload your takes video in this thread within the next 24 hours!",
51 },
52 },
53 {
54 type: "divider",
55 },
56 {
57 type: "context",
58 elements: [
59 {
60 type: "mrkdwn",
61 text: `*Elapsed Time:* \`${prettyPrintTime(elapsed)}\`${pausedTakeToStop.description ? ` working on: *${pausedTakeToStop.description}*` : ""}`,
62 },
63 ],
64 },
65 ],
66 });
67
68 await db
69 .update(takesTable)
70 .set({
71 status: "waitingUpload",
72 ts: res.ts,
73 completedAt: new Date(),
74 elapsedTimeMs: elapsed,
75 ...(notes && { notes }),
76 })
77 .where(eq(takesTable.id, pausedTakeToStop.id));
78 } else {
79 // Mark the active session as completed
80 const activeTakeToStop = activeTake[0];
81 if (!activeTakeToStop) {
82 return;
83 }
84
85 // Extract notes if provided
86 let notes = undefined;
87 if (args && args.length > 1) {
88 notes = args.slice(1).join(" ");
89 }
90
91 const elapsed = calculateElapsedTime(
92 JSON.parse(activeTakeToStop.periods),
93 );
94
95 const res = await slackClient.chat.postMessage({
96 channel: userId,
97 text: "🎬 Your takes session has been completed. Please upload your takes video in this thread within the next 24 hours!",
98 blocks: [
99 {
100 type: "section",
101 text: {
102 type: "mrkdwn",
103 text: "🎬 Your takes session has been completed. Please upload your takes video in this thread within the next 24 hours!",
104 },
105 },
106 {
107 type: "divider",
108 },
109 {
110 type: "context",
111 elements: [
112 {
113 type: "mrkdwn",
114 text: `\`${prettyPrintTime(elapsed)}\`${activeTakeToStop.description ? ` working on: *${activeTakeToStop.description}*` : ""}`,
115 },
116 ],
117 },
118 ],
119 });
120
121 await db
122 .update(takesTable)
123 .set({
124 status: "waitingUpload",
125 ts: res.ts,
126 completedAt: new Date(),
127 elapsedTimeMs: elapsed,
128 ...(notes && { notes }),
129 })
130 .where(eq(takesTable.id, activeTakeToStop.id));
131 }
132
133 return {
134 text: "✅ Takes session completed! I hope you had fun!",
135 response_type: "ephemeral",
136 blocks: [
137 {
138 type: "section",
139 text: {
140 type: "mrkdwn",
141 text: "✅ Takes session completed! I hope you had fun!",
142 },
143 },
144 {
145 type: "actions",
146 elements: [
147 {
148 type: "button",
149 text: {
150 type: "plain_text",
151 text: "🎬 Start New Session",
152 emoji: true,
153 },
154 value: "start",
155 action_id: "takes_start",
156 },
157 {
158 type: "button",
159 text: {
160 type: "plain_text",
161 text: "📋 History",
162 emoji: true,
163 },
164 value: "history",
165 action_id: "takes_history",
166 },
167 ],
168 },
169 ],
170 };
171}