This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

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 };