import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime" ;
import type { SlackChannelConfig } from "openclaw/plugin-sdk/config-runtime" ;
import { normalizeAccountId } from "openclaw/plugin-sdk/routing" ;
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime" ;
type SlackChannels = Record<string, SlackChannelConfig>;
type MigrationScope = "account" | "global" ;
export type SlackChannelMigrationResult = {
migrated: boolean ;
skippedExisting: boolean ;
scopes: MigrationScope[];
};
function resolveAccountChannels(
cfg: OpenClawConfig,
accountId?: string | null ,
): { channels?: SlackChannels } {
if (!accountId) {
return {};
}
const normalized = normalizeAccountId(accountId);
const accounts = cfg.channels?.slack?.accounts;
if (!accounts || typeof accounts !== "object" ) {
return {};
}
const exact = accounts[normalized];
if (exact?.channels) {
return { channels: exact.channels };
}
const matchKey = Object.keys(accounts).find(
(key) => normalizeLowercaseStringOrEmpty(key) === normalizeLowercaseStringOrEmpty(normalized),
);
return { channels: matchKey ? accounts[matchKey]?.channels : undefined };
}
export function migrateSlackChannelsInPlace(
channels: SlackChannels | undefined,
oldChannelId: string,
newChannelId: string,
): { migrated: boolean ; skippedExisting: boolean } {
if (!channels) {
return { migrated: false , skippedExisting: false };
}
if (oldChannelId === newChannelId) {
return { migrated: false , skippedExisting: false };
}
if (!Object.hasOwn(channels, oldChannelId)) {
return { migrated: false , skippedExisting: false };
}
if (Object.hasOwn(channels, newChannelId)) {
return { migrated: false , skippedExisting: true };
}
channels[newChannelId] = channels[oldChannelId];
delete channels[oldChannelId];
return { migrated: true , skippedExisting: false };
}
export function migrateSlackChannelConfig(params: {
cfg: OpenClawConfig;
accountId?: string | null ;
oldChannelId: string;
newChannelId: string;
}): SlackChannelMigrationResult {
const scopes: MigrationScope[] = [];
let migrated = false ;
let skippedExisting = false ;
const accountChannels = resolveAccountChannels(params.cfg, params.accountId).channels;
if (accountChannels) {
const result = migrateSlackChannelsInPlace(
accountChannels,
params.oldChannelId,
params.newChannelId,
);
if (result.migrated) {
migrated = true ;
scopes.push("account" );
}
if (result.skippedExisting) {
skippedExisting = true ;
}
}
const globalChannels = params.cfg.channels?.slack?.channels;
if (globalChannels) {
const result = migrateSlackChannelsInPlace(
globalChannels,
params.oldChannelId,
params.newChannelId,
);
if (result.migrated) {
migrated = true ;
scopes.push("global" );
}
if (result.skippedExisting) {
skippedExisting = true ;
}
}
return { migrated, skippedExisting, scopes };
}
Messung V0.5 in Prozent C=100 H=100 G=100
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland