providing password reset services for a long while: circa 2025
at main 3.0 kB view raw
1import { SlackApp } from "slack-edge"; 2import SlackMessageQueue, { type SlackMessage } from "./features/message-queue"; 3 4import * as features from "./features/index"; 5 6import { version, name } from "./package.json"; 7const environment = process.env.NODE_ENV; 8import quip from "./quip"; 9 10console.log( 11 `----------------------------------\n${name} server\n----------------------------------\n`, 12); 13console.log(`🏗️ Starting ${name}...`); 14console.log("📦 Loading Slack App..."); 15console.log("🔑 Loading environment variables..."); 16 17if ( 18 !process.env.SLACK_BOT_TOKEN || 19 !process.env.SLACK_SIGNING_SECRET || 20 !process.env.ADMINS 21) { 22 throw new Error( 23 "Missing required environment variables: SLACK_BOT_TOKEN SLACK_SIGNING_SECRET or ADMINS", 24 ); 25} 26 27const slackApp = new SlackApp({ 28 env: { 29 SLACK_BOT_TOKEN: process.env.SLACK_BOT_TOKEN, 30 SLACK_SIGNING_SECRET: process.env.SLACK_SIGNING_SECRET, 31 SLACK_LOGGING_LEVEL: "INFO", 32 }, 33 startLazyListenerAfterAck: true, 34}); 35const slackClient = slackApp.client; 36 37const messageQueue = new SlackMessageQueue(slackClient, "data/slack-queue.db"); 38console.log(`👔 Message Queue Size: ${await messageQueue.queueLength()}`); 39 40console.log(`⚒️ Loading ${Object.entries(features).length} features...`); 41for (const [feature, handler] of Object.entries(features)) { 42 console.log(`📦 ${feature} loaded`); 43 if (typeof handler === "function") { 44 handler(); 45 } 46} 47 48export default { 49 port: process.env.PORT || 3000, 50 async fetch(request: Request) { 51 const url = new URL(request.url); 52 const path = url.pathname; 53 54 switch (path) { 55 case "/": 56 return new Response(`Hello World from ${name}@${version}`); 57 case "/health": 58 return new Response("OK"); 59 case "/slack": 60 return slackApp.run(request); 61 case "/slack/message": { 62 if ( 63 request.headers.get("Authorization") !== 64 `Bearer ${process.env.API_KEY}` 65 ) { 66 return new Response("Unauthorized", { status: 401 }); 67 } 68 69 const message: SlackMessage = await request.json(); 70 const { channel, text } = message; 71 72 if (!channel || !text) { 73 return new Response( 74 `Invalid fields: ${[ 75 !channel && "channel is required", 76 !text && "text is required", 77 ] 78 .filter(Boolean) 79 .join(", ")}`, 80 { status: 400 }, 81 ); 82 } 83 84 await messageQueue.enqueue(message); 85 86 return new Response(JSON.stringify({ ok: true }), { status: 200 }); 87 } 88 default: 89 return new Response("404 Not Found", { status: 404 }); 90 } 91 }, 92}; 93 94console.log( 95 `🚀 Server Started in ${Bun.nanoseconds() / 1000000} milliseconds on version: ${version}!\n\n----------------------------------\n`, 96); 97 98console.log(quip()); 99 100console.log("\n----------------------------------\n"); 101 102export { slackApp, slackClient, version, name, environment };