UNPKG

slack-edge

Version:

Slack app development framework for edge functions with streamlined TypeScript support

126 lines 5.65 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SocketModeClient = void 0; const slack_web_api_client_1 = require("slack-web-api-client"); const errors_1 = require("../errors"); const payload_handler_1 = require("./payload-handler"); /** * An experimental Socket Mode client * * Please note that this is still experimental and it's not recommended to use it for production apps. * If you need a reliable Socket Mode client, please use @slack/socket-mode library on Node.js along with slack-edge. * * @todo Implement proper reconnection logic * @todo Add connection monitor like 1st party SDKs do * @todo Add Bun support (the runtime does not work well with Socket Mode) */ class SocketModeClient { constructor( // deno-lint-ignore no-explicit-any app) { if (!app.socketMode) { throw new errors_1.ConfigError("socketMode: true must be set for running with Socket Mode"); } if (!app.appLevelToken) { throw new errors_1.ConfigError("appLevelToken must be set for running with Socket Mode"); } this.app = app; this.appLevelToken = app.appLevelToken; console.warn("WARNING: The Socket Mode support provided by slack-edge is still experimental and is not designed to handle reconnections for production-grade applications. It is recommended to use this mode only for local development and testing purposes."); } /** * Establishes a WebSocket connection to Slack using Socket Mode. * * This method opens a new WSS connection using the app-level token and sets up * event handlers for incoming messages, connection events, and errors. * * @throws {SocketModeError} If the WebSocket connection cannot be established */ async connect() { const client = new slack_web_api_client_1.SlackAPIClient(this.appLevelToken); try { const newConnection = await client.apps.connections.open(); this.ws = new WebSocket(newConnection.url); } catch (e) { throw new errors_1.SocketModeError(`Failed to establish a new WSS connection: ${e}`); } if (this.ws) { const ws = this.ws; // deno-lint-ignore require-await ws.onopen = async (ev) => { // TODO: make this customizable if ((0, slack_web_api_client_1.isDebugLogEnabled)(app.env.SLACK_LOGGING_LEVEL)) { console.log(`Now the Socket Mode client is connected to Slack: ${JSON.stringify(ev)}`); } }; // deno-lint-ignore require-await ws.onclose = async (ev) => { // TODO: make this customizable if ((0, slack_web_api_client_1.isDebugLogEnabled)(app.env.SLACK_LOGGING_LEVEL)) { console.log(`The Socket Mode client is disconnected from Slack: ${JSON.stringify(ev)}`); } }; // deno-lint-ignore require-await ws.onerror = async (e) => { // TODO: make this customizable console.error(`An error was thrown by the Socket Mode connection: ${e}`); }; const app = this.app; ws.onmessage = async (ev) => { try { if (ev.data && typeof ev.data === "string" && ev.data.startsWith("{")) { const data = JSON.parse(ev.data); if (data.type === "hello") { if ((0, slack_web_api_client_1.isDebugLogEnabled)(app.env.SLACK_LOGGING_LEVEL)) { console.log(`*** Received hello data ***\n ${ev.data}`); } return; } const request = (0, payload_handler_1.fromSocketModeToRequest)({ url: ws.url, body: data.payload, retryNum: data.retry_attempt, retryReason: data.retry_reason, }); if (!request) { return; } const response = await app.run(request); const message = { envelope_id: data.envelope_id, }; const payload = await (0, payload_handler_1.fromResponseToSocketModePayload)({ response }); if (payload) { message.payload = payload; } ws.send(JSON.stringify(message)); } else { if ((0, slack_web_api_client_1.isDebugLogEnabled)(app.env.SLACK_LOGGING_LEVEL)) { console.log(`*** Received non-JSON data ***\n ${ev.data}`); } } } catch (e) { console.error(`Failed to handle a WebSocke message: ${e}`); } }; } } /** * Disconnects from the Slack Socket Mode connection. * * This method closes the active WebSocket connection if one exists * and cleans up the connection reference. */ // deno-lint-ignore require-await async disconnect() { if (this.ws) { this.ws.close(); this.ws = undefined; } } } exports.SocketModeClient = SocketModeClient; //# sourceMappingURL=socket-mode-client.js.map