Files
openclaw/extensions/slack/src/client.ts
Dallin Romney 39e1be080c feat(slack): support alternate Web API roots (#97154)
* Allow Slack to target alternate Web API roots

* Protect Slack API URL routing

* Simplify Slack API URL routing

* Use env-only Slack API root routing

* Remove Slack client option alias

* Keep Slack API URL dotenv test inline

* Remove leftover Slack PR churn

* Block workspace Slack API URL dotenv

* Preserve Slack proxy HTTPS protocol

* Keep Slack option resolution explicit

* Remove Slack probe formatting diff

* fix(slack): preserve explicit API root precedence

* fix(slack): narrow cached write client options
2026-06-28 18:52:37 -07:00

61 lines
2.1 KiB
TypeScript

// Slack plugin module implements client behavior.
import { createHash } from "node:crypto";
import { type WebClientOptions, WebClient } from "@slack/web-api";
import { resolveSlackWebClientOptions, resolveSlackWriteClientOptions } from "./client-options.js";
const SLACK_WRITE_CLIENT_CACHE_MAX = 32;
const slackWriteClientCache = new Map<string, WebClient>();
type SlackWriteClientCacheOptions = Pick<WebClientOptions, "slackApiUrl">;
export {
resolveSlackWebClientOptions,
resolveSlackWriteClientOptions,
SLACK_DEFAULT_RETRY_OPTIONS,
SLACK_WRITE_RETRY_OPTIONS,
} from "./client-options.js";
export function createSlackWebClient(token: string, options: WebClientOptions = {}) {
return new WebClient(token, resolveSlackWebClientOptions(options));
}
export function createSlackWriteClient(token: string, options: WebClientOptions = {}) {
return new WebClient(token, resolveSlackWriteClientOptions(options));
}
export function createSlackTokenCacheKey(token: string): string {
return `sha256:${createHash("sha256").update(token).digest("base64url")}`;
}
function slackWriteClientCacheKey(token: string, options: SlackWriteClientCacheOptions): string {
const tokenKey = createSlackTokenCacheKey(token);
return options.slackApiUrl ? `${tokenKey}:api:${options.slackApiUrl}` : tokenKey;
}
export function getSlackWriteClient(
token: string,
options: SlackWriteClientCacheOptions = {},
): WebClient {
const resolvedOptions = resolveSlackWriteClientOptions(options);
const tokenKey = slackWriteClientCacheKey(token, resolvedOptions);
const cached = slackWriteClientCache.get(tokenKey);
if (cached) {
slackWriteClientCache.delete(tokenKey);
slackWriteClientCache.set(tokenKey, cached);
return cached;
}
const client = new WebClient(token, resolvedOptions);
if (slackWriteClientCache.size >= SLACK_WRITE_CLIENT_CACHE_MAX) {
const oldestTokenKey = slackWriteClientCache.keys().next().value;
if (oldestTokenKey) {
slackWriteClientCache.delete(oldestTokenKey);
}
}
slackWriteClientCache.set(tokenKey, client);
return client;
}
export function clearSlackWriteClientCacheForTest(): void {
slackWriteClientCache.clear();
}