slack-edge
Version:
Slack app development framework for edge functions with streamlined TypeScript support
112 lines • 5.11 kB
JavaScript
;
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.");
}
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}`);
}
};
}
}
// 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