






















@@ -1,98 +1,11 @@
1-import { type RetryOptions, type WebClientOptions, WebClient } from "@slack/web-api";
2-import { HttpsProxyAgent } from "https-proxy-agent";
3-import { resolveEnvHttpProxyUrl } from "openclaw/plugin-sdk/infra-runtime";
4-5-export const SLACK_DEFAULT_RETRY_OPTIONS: RetryOptions = {
6-retries: 2,
7-factor: 2,
8-minTimeout: 500,
9-maxTimeout: 3000,
10-randomize: true,
11-};
12-13-export const SLACK_WRITE_RETRY_OPTIONS: RetryOptions = {
14-retries: 0,
15-};
16-17-/**
18- * Check whether a hostname is excluded from proxying by `NO_PROXY` / `no_proxy`.
19- * Supports comma-separated entries with optional leading dots (e.g. `.slack.com`).
20- */
21-function isHostExcludedByNoProxy(hostname: string, env: NodeJS.ProcessEnv = process.env): boolean {
22-const raw = env.no_proxy ?? env.NO_PROXY;
23-if (!raw) {
24-return false;
25-}
26-const entries = raw
27-.split(/[,\s]+/)
28-.map((e) => e.trim().toLowerCase())
29-.filter(Boolean);
30-const lower = hostname.toLowerCase();
31-for (const entry of entries) {
32-if (entry === "*") {
33-return true;
34-}
35-// Strip optional wildcard/leading dot so `*.slack.com` and `.slack.com`
36-// match both `slack.com` (apex) and Slack subdomains.
37-const bare = entry.startsWith("*.")
38- ? entry.slice(2)
39- : entry.startsWith(".")
40- ? entry.slice(1)
41- : entry;
42-if (lower === bare || lower.endsWith(`.${bare}`)) {
43-return true;
44-}
45-}
46-return false;
47-}
48-49-/**
50- * Build an HTTPS proxy agent from env vars (HTTPS_PROXY, HTTP_PROXY, etc.)
51- * for use as the `agent` option in Slack WebClient and Socket Mode connections.
52- *
53- * When set, this agent is forwarded through @slack/bolt → @slack/socket-mode →
54- * SlackWebSocket as the `httpAgent`, which the `ws` library uses to tunnel the
55- * WebSocket upgrade request through the proxy. This fixes Socket Mode in
56- * environments where outbound traffic must go through an HTTP CONNECT proxy.
57- *
58- * Respects `NO_PROXY` / `no_proxy` — if `*.slack.com` (or a matching pattern)
59- * appears in the exclusion list, returns `undefined` so the connection is direct.
60- *
61- * Returns `undefined` when no proxy env var is configured or when Slack hosts
62- * are excluded by `NO_PROXY`.
63- */
64-function resolveSlackProxyAgent(): HttpsProxyAgent<string> | undefined {
65-const proxyUrl = resolveEnvHttpProxyUrl("https");
66-if (!proxyUrl) {
67-return undefined;
68-}
69-// Slack Socket Mode connects to these hosts; skip proxy if excluded.
70-if (isHostExcludedByNoProxy("slack.com")) {
71-return undefined;
72-}
73-try {
74-return new HttpsProxyAgent(proxyUrl);
75-} catch {
76-// Malformed proxy URL — degrade gracefully to direct connection.
77-return undefined;
78-}
79-}
80-81-export function resolveSlackWebClientOptions(options: WebClientOptions = {}): WebClientOptions {
82-return {
83- ...options,
84-agent: options.agent ?? resolveSlackProxyAgent(),
85-retryConfig: options.retryConfig ?? SLACK_DEFAULT_RETRY_OPTIONS,
86-};
87-}
88-89-export function resolveSlackWriteClientOptions(options: WebClientOptions = {}): WebClientOptions {
90-return {
91- ...options,
92-agent: options.agent ?? resolveSlackProxyAgent(),
93-retryConfig: options.retryConfig ?? SLACK_WRITE_RETRY_OPTIONS,
94-};
95-}
1+import { type WebClientOptions, WebClient } from "@slack/web-api";
2+import { resolveSlackWebClientOptions, resolveSlackWriteClientOptions } from "./client-options.js";
3+export {
4+resolveSlackWebClientOptions,
5+resolveSlackWriteClientOptions,
6+SLACK_DEFAULT_RETRY_OPTIONS,
7+SLACK_WRITE_RETRY_OPTIONS,
8+} from "./client-options.js";
9699710export function createSlackWebClient(token: string, options: WebClientOptions = {}) {
9811return new WebClient(token, resolveSlackWebClientOptions(options));
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。