This repository has no description
1import { SlackApp } from "slack-edge";
2
3import { takes } from "./features/index";
4
5import { t } from "./libs/template";
6import { blog } from "./libs/Logger";
7import { version, name } from "../package.json";
8import { apiRouter, video } from "./features/api";
9const environment = process.env.NODE_ENV;
10
11import * as Sentry from "@sentry/bun";
12
13// Check required environment variables
14const requiredVars = [
15 "SLACK_BOT_TOKEN",
16 "SLACK_SIGNING_SECRET",
17 "SLACK_REVIEW_CHANNEL",
18 "SLACK_LOG_CHANNEL",
19 "SLACK_SPAM_CHANNEL",
20 "SLACK_USER_TOKEN",
21 "API_URL",
22 "SENTRY_DSN",
23] as const;
24const missingVars = requiredVars.filter((varName) => !process.env[varName]);
25
26if (missingVars.length > 0) {
27 throw new Error(
28 `Missing required environment variables: ${missingVars.join(", ")}`,
29 );
30}
31
32Sentry.init({
33 dsn: process.env.SENTRY_DSN,
34 environment,
35 release: version,
36});
37
38console.log(
39 `----------------------------------\n${name} Server\n----------------------------------\n`,
40);
41console.log(`🏗️ Starting ${name}...`);
42console.log("📦 Loading Slack App...");
43console.log("🔑 Loading environment variables...");
44
45const slackApp = new SlackApp({
46 env: {
47 SLACK_BOT_TOKEN: process.env.SLACK_BOT_TOKEN as string,
48 SLACK_SIGNING_SECRET: process.env.SLACK_SIGNING_SECRET as string,
49 SLACK_LOGGING_LEVEL: "INFO",
50 },
51 startLazyListenerAfterAck: true,
52});
53const slackClient = slackApp.client;
54
55takes();
56
57export default {
58 port: process.env.PORT || 3000,
59 development: environment === "dev",
60 async fetch(request: Request) {
61 const url = new URL(request.url);
62 const path = url.pathname.split("/").filter(Boolean)[0]
63 ? `/${url.pathname.split("/").filter(Boolean)[0]}`
64 : "/";
65
66 // CORS headers to allow all origins
67 const corsHeaders = {
68 "Access-Control-Allow-Origin": "*",
69 "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
70 "Access-Control-Allow-Headers": "Content-Type, Authorization",
71 };
72
73 // Handle preflight OPTIONS request
74 if (request.method === "OPTIONS") {
75 return new Response(null, {
76 status: 204,
77 headers: corsHeaders,
78 });
79 }
80
81 let response: Response;
82 switch (path) {
83 case "/":
84 response = new Response(`Hello World from ${name}@${version}`);
85 break;
86 case "/health":
87 response = new Response("OK");
88 break;
89 case "/slack":
90 response = await slackApp.run(request);
91 break;
92 case "/api":
93 response = await apiRouter(url);
94 break;
95 default:
96 response = new Response("404 Not Found", { status: 404 });
97 }
98
99 // Add CORS headers to all responses
100 const newHeaders = new Headers(response.headers);
101 for (const [key, value] of Object.entries(corsHeaders)) {
102 newHeaders.set(key, value);
103 }
104
105 return new Response(response.body, {
106 status: response.status,
107 statusText: response.statusText,
108 headers: newHeaders,
109 });
110 },
111};
112
113console.log(
114 `🚀 Server Started in ${
115 Bun.nanoseconds() / 1000000
116 } milliseconds on version: ${version}!\n\n----------------------------------\n`,
117);
118
119blog(
120 t("app.startup", {
121 environment,
122 }),
123 "start",
124 {
125 channel: process.env.SLACK_SPAM_CHANNEL || "",
126 },
127);
128
129console.log("\n----------------------------------\n");
130
131export { slackApp, slackClient, version, name, environment };