mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-11 00:16:07 +00:00
* 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
61 lines
2.1 KiB
TypeScript
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();
|
|
}
|