openclaw/extensions/slack/src/account-inspect.ts
scoootscooob 8746362f5e
refactor(slack): move Slack channel code to extensions/slack/src/ (#45621)
Move all Slack channel implementation files from src/slack/ to
extensions/slack/src/ and replace originals with shim re-exports.
This follows the extension migration pattern for channel plugins.

- Copy all .ts files to extensions/slack/src/ (preserving directory
  structure: monitor/, http/, monitor/events/, monitor/message-handler/)
- Transform import paths: external src/ imports use relative paths
  back to src/, internal slack imports stay relative within extension
- Replace all src/slack/ files with shim re-exports pointing to
  the extension copies
- Update tsconfig.plugin-sdk.dts.json rootDir from "src" to "." so
  the DTS build can follow shim chains into extensions/
- Update write-plugin-sdk-entry-dts.ts re-export path accordingly
- Preserve extensions/slack/index.ts, package.json, openclaw.plugin.json,
  src/channel.ts, src/runtime.ts, src/channel.test.ts (untouched)
2026-03-14 02:47:04 -07:00

187 lines
5.7 KiB
TypeScript

import type { OpenClawConfig } from "../../../src/config/config.js";
import {
hasConfiguredSecretInput,
normalizeSecretInputString,
} from "../../../src/config/types.secrets.js";
import type { SlackAccountConfig } from "../../../src/config/types.slack.js";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js";
import type { SlackAccountSurfaceFields } from "./account-surface-fields.js";
import {
mergeSlackAccountConfig,
resolveDefaultSlackAccountId,
type SlackTokenSource,
} from "./accounts.js";
export type SlackCredentialStatus = "available" | "configured_unavailable" | "missing";
export type InspectedSlackAccount = {
accountId: string;
enabled: boolean;
name?: string;
mode?: SlackAccountConfig["mode"];
botToken?: string;
appToken?: string;
signingSecret?: string;
userToken?: string;
botTokenSource: SlackTokenSource;
appTokenSource: SlackTokenSource;
signingSecretSource?: SlackTokenSource;
userTokenSource: SlackTokenSource;
botTokenStatus: SlackCredentialStatus;
appTokenStatus: SlackCredentialStatus;
signingSecretStatus?: SlackCredentialStatus;
userTokenStatus: SlackCredentialStatus;
configured: boolean;
config: SlackAccountConfig;
} & SlackAccountSurfaceFields;
function inspectSlackToken(value: unknown): {
token?: string;
source: Exclude<SlackTokenSource, "env">;
status: SlackCredentialStatus;
} {
const token = normalizeSecretInputString(value);
if (token) {
return {
token,
source: "config",
status: "available",
};
}
if (hasConfiguredSecretInput(value)) {
return {
source: "config",
status: "configured_unavailable",
};
}
return {
source: "none",
status: "missing",
};
}
export function inspectSlackAccount(params: {
cfg: OpenClawConfig;
accountId?: string | null;
envBotToken?: string | null;
envAppToken?: string | null;
envUserToken?: string | null;
}): InspectedSlackAccount {
const accountId = normalizeAccountId(
params.accountId ?? resolveDefaultSlackAccountId(params.cfg),
);
const merged = mergeSlackAccountConfig(params.cfg, accountId);
const enabled = params.cfg.channels?.slack?.enabled !== false && merged.enabled !== false;
const allowEnv = accountId === DEFAULT_ACCOUNT_ID;
const mode = merged.mode ?? "socket";
const isHttpMode = mode === "http";
const configBot = inspectSlackToken(merged.botToken);
const configApp = inspectSlackToken(merged.appToken);
const configSigningSecret = inspectSlackToken(merged.signingSecret);
const configUser = inspectSlackToken(merged.userToken);
const envBot = allowEnv
? normalizeSecretInputString(params.envBotToken ?? process.env.SLACK_BOT_TOKEN)
: undefined;
const envApp = allowEnv
? normalizeSecretInputString(params.envAppToken ?? process.env.SLACK_APP_TOKEN)
: undefined;
const envUser = allowEnv
? normalizeSecretInputString(params.envUserToken ?? process.env.SLACK_USER_TOKEN)
: undefined;
const botToken = configBot.token ?? envBot;
const appToken = configApp.token ?? envApp;
const signingSecret = configSigningSecret.token;
const userToken = configUser.token ?? envUser;
const botTokenSource: SlackTokenSource = configBot.token
? "config"
: configBot.status === "configured_unavailable"
? "config"
: envBot
? "env"
: "none";
const appTokenSource: SlackTokenSource = configApp.token
? "config"
: configApp.status === "configured_unavailable"
? "config"
: envApp
? "env"
: "none";
const signingSecretSource: SlackTokenSource = configSigningSecret.token
? "config"
: configSigningSecret.status === "configured_unavailable"
? "config"
: "none";
const userTokenSource: SlackTokenSource = configUser.token
? "config"
: configUser.status === "configured_unavailable"
? "config"
: envUser
? "env"
: "none";
return {
accountId,
enabled,
name: merged.name?.trim() || undefined,
mode,
botToken,
appToken,
...(isHttpMode ? { signingSecret } : {}),
userToken,
botTokenSource,
appTokenSource,
...(isHttpMode ? { signingSecretSource } : {}),
userTokenSource,
botTokenStatus: configBot.token
? "available"
: configBot.status === "configured_unavailable"
? "configured_unavailable"
: envBot
? "available"
: "missing",
appTokenStatus: configApp.token
? "available"
: configApp.status === "configured_unavailable"
? "configured_unavailable"
: envApp
? "available"
: "missing",
...(isHttpMode
? {
signingSecretStatus: configSigningSecret.token
? "available"
: configSigningSecret.status === "configured_unavailable"
? "configured_unavailable"
: "missing",
}
: {}),
userTokenStatus: configUser.token
? "available"
: configUser.status === "configured_unavailable"
? "configured_unavailable"
: envUser
? "available"
: "missing",
configured: isHttpMode
? (configBot.status !== "missing" || Boolean(envBot)) &&
configSigningSecret.status !== "missing"
: (configBot.status !== "missing" || Boolean(envBot)) &&
(configApp.status !== "missing" || Boolean(envApp)),
config: merged,
groupPolicy: merged.groupPolicy,
textChunkLimit: merged.textChunkLimit,
mediaMaxMb: merged.mediaMaxMb,
reactionNotifications: merged.reactionNotifications,
reactionAllowlist: merged.reactionAllowlist,
replyToMode: merged.replyToMode,
replyToModeByChatType: merged.replyToModeByChatType,
actions: merged.actions,
slashCommand: merged.slashCommand,
dm: merged.dm,
channels: merged.channels,
};
}