refactor: simplify channel setup conversions

This commit is contained in:
Peter Steinberger
2026-04-11 01:11:02 +01:00
parent 55f35708e1
commit 270630ba35
21 changed files with 37 additions and 29 deletions

View File

@@ -1058,7 +1058,7 @@ export const feishuPlugin: ChannelPlugin<ResolvedFeishuAccount, FeishuProbeResul
return jsonActionResult({ ok: true, reactions });
}
throw new Error(`Unsupported Feishu action: "${String(ctx.action)}"`);
throw new Error(`Unsupported Feishu action: "${ctx.action}"`);
},
},
bindings: {

View File

@@ -42,7 +42,7 @@ export function resolveFeishuAllowlistMatch(params: {
// Feishu allowlists are ID-based; mutable display names must never grant access.
const senderCandidates = [params.senderId, ...(params.senderIds ?? [])]
.map((entry) => normalizeFeishuAllowEntry(String(entry ?? "")))
.map((entry) => normalizeFeishuAllowEntry(entry ?? ""))
.filter(Boolean);
for (const senderId of senderCandidates) {

View File

@@ -276,7 +276,7 @@ function parseFeishuMessageItem(
senderType: item.sender?.sender_type,
content: parseFeishuMessageContent(rawContent, msgType),
contentType: msgType,
createTime: item.create_time ? parseInt(String(item.create_time), 10) : undefined,
createTime: item.create_time ? parseInt(item.create_time, 10) : undefined,
threadId: item.thread_id || undefined,
};
}

View File

@@ -141,7 +141,7 @@ async function postFirecrawlJson<T>(
detail = errorBody.text;
}
}
const safeDetail = wrapWebContent(String(detail).slice(0, 1_000), "web_fetch");
const safeDetail = wrapWebContent(detail.slice(0, 1_000), "web_fetch");
throw new Error(`${params.errorLabel} API error (${response.status}): ${safeDetail}`);
}
return await parse(response);

View File

@@ -43,7 +43,7 @@ export async function resolveMSTeamsSenderAccess(params: {
dmPolicy,
readStore: pairing.readStoreForDmPolicy,
});
const configuredDmAllowFrom = (msteamsCfg?.allowFrom ?? []).map((entry) => String(entry));
const configuredDmAllowFrom = msteamsCfg?.allowFrom ?? [];
const groupAllowFrom = msteamsCfg?.groupAllowFrom;
const resolvedAllowFromLists = resolveEffectiveAllowFromLists({
allowFrom: configuredDmAllowFrom,

View File

@@ -103,9 +103,8 @@ export async function monitorMSTeamsProvider(
try {
const allowEntries =
allowFrom
?.map((entry) => cleanAllowEntry(String(entry)))
.filter((entry) => entry && entry !== "*") ?? [];
allowFrom?.map((entry) => cleanAllowEntry(entry)).filter((entry) => entry && entry !== "*") ??
[];
if (allowEntries.length > 0) {
const { additions } = await resolveAllowlistUsers("msteams users", allowEntries);
allowFrom = mergeAllowlist({ existing: allowFrom, additions });
@@ -113,7 +112,7 @@ export async function monitorMSTeamsProvider(
if (Array.isArray(groupAllowFrom) && groupAllowFrom.length > 0) {
const groupEntries = groupAllowFrom
.map((entry) => cleanAllowEntry(String(entry)))
.map((entry) => cleanAllowEntry(entry))
.filter((entry) => entry && entry !== "*");
if (groupEntries.length > 0) {
const { additions } = await resolveAllowlistUsers("msteams group users", groupEntries);

View File

@@ -171,7 +171,7 @@ function payloadToInboundMessage(
const isGroupChat = true;
return {
messageId: String(payload.object.id),
messageId: payload.object.id,
roomToken: payload.target.id,
roomName: payload.target.name,
senderId: payload.actor.id,

View File

@@ -123,7 +123,7 @@ async function promptNextcloudTalkAllowFrom(params: {
message: "Nextcloud Talk allowFrom (user id)",
placeholder: "username",
parseEntries: (raw) => ({
entries: String(raw)
entries: raw
.split(/[\n,;]+/g)
.map(normalizeLowercaseStringOrEmpty)
.filter(Boolean),

View File

@@ -127,12 +127,24 @@ function parseSynologyUserId(value: string): string | null {
return /^\d+$/.test(cleaned) ? cleaned : null;
}
function normalizeSynologyAllowedUserId(value: unknown): string {
if (
typeof value === "string" ||
typeof value === "number" ||
typeof value === "boolean" ||
typeof value === "bigint"
) {
return `${value}`.trim();
}
return "";
}
function resolveExistingAllowedUserIds(cfg: OpenClawConfig, accountId: string): string[] {
const raw = getRawAccountConfig(cfg, accountId).allowedUserIds;
if (Array.isArray(raw)) {
return raw.map((value) => String(value).trim()).filter(Boolean);
return raw.map(normalizeSynologyAllowedUserId).filter(Boolean);
}
return String(raw ?? "")
return normalizeSynologyAllowedUserId(raw)
.split(",")
.map((value) => value.trim())
.filter(Boolean);

View File

@@ -99,7 +99,7 @@ export function createTlonSetupWizardBase(params: TlonSetupWizardBaseParams): Ch
placeholder: "https://your-ship-host",
currentValue: ({ cfg, accountId }) => resolveTlonAccount(cfg, accountId).url ?? undefined,
validate: ({ value }) => {
const next = validateUrbitBaseUrl(String(value ?? ""));
const next = validateUrbitBaseUrl(value ?? "");
if (!next.ok) {
return next.error;
}

View File

@@ -66,7 +66,7 @@ export const tlonSetupWizard = createTlonSetupWizardBase({
next = applyTlonSetupConfig({
cfg: next,
accountId,
input: { groupChannels: parseList(String(entry ?? "")) },
input: { groupChannels: parseList(entry ?? "") },
});
}
@@ -85,7 +85,7 @@ export const tlonSetupWizard = createTlonSetupWizardBase({
cfg: next,
accountId,
input: {
dmAllowlist: parseList(String(entry ?? "")).map((ship) => normalizeShip(ship)),
dmAllowlist: parseList(entry ?? "").map((ship) => normalizeShip(ship)),
},
});
}

View File

@@ -14,7 +14,7 @@ export function normalizeUrbitHostname(hostname: string | undefined): string {
}
export function validateUrbitBaseUrl(raw: string): UrbitBaseUrlValidation {
const trimmed = String(raw ?? "").trim();
const trimmed = raw.trim();
if (!trimmed) {
return { ok: false, error: "Required" };
}

View File

@@ -171,8 +171,7 @@ export function applyGroupGating(params: ApplyGroupGatingParams) {
commandAuthorized: false,
},
});
const effectiveWasMentioned =
mentionDecision.effectiveWasMentioned || Boolean(shouldBypassMention);
const effectiveWasMentioned = mentionDecision.effectiveWasMentioned || shouldBypassMention;
params.msg.wasMentioned = effectiveWasMentioned;
if (!shouldBypassMention && requireMention && mentionDecision.shouldSkip) {
return skipGroupMessageAndStoreHistory(

View File

@@ -33,7 +33,7 @@ export function isWhatsAppSupplementalSenderAllowed(params: {
return false;
}
for (const entry of params.allowFrom) {
const rawEntry = String(entry).trim();
const rawEntry = entry.trim();
if (!rawEntry) {
continue;
}

View File

@@ -89,7 +89,7 @@ async function resolveWhatsAppCommandAuthorized(params: {
return true;
}
const normalizedEntries = allowEntries
.map((entry) => normalizeE164(String(entry)))
.map((entry) => normalizeE164(entry))
.filter((entry): entry is string => Boolean(entry));
return normalizedEntries.includes(senderE164);
},

View File

@@ -102,7 +102,7 @@ export async function checkInboundAccessControl(params: {
}
const normalizedEntrySet = new Set(
allowEntries
.map((entry) => normalizeE164(String(entry)))
.map((entry) => normalizeE164(entry))
.filter((entry): entry is string => Boolean(entry)),
);
if (!params.group && isSamePhone) {

View File

@@ -181,7 +181,7 @@ export async function monitorWebInbox(options: {
const rememberOutboundMessage = (remoteJid: string, result: unknown) => {
const messageId =
typeof result === "object" && result && "key" in result
? String((result as { key?: { id?: string } }).key?.id ?? "")
? ((result as { key?: { id?: string } }).key?.id ?? "")
: "";
if (!messageId) {
return;

View File

@@ -13,7 +13,7 @@ function recordWhatsAppOutbound(accountId: string) {
function resolveOutboundMessageId(result: unknown): string {
return typeof result === "object" && result && "key" in result
? String((result as { key?: { id?: string } }).key?.id ?? "unknown")
? ((result as { key?: { id?: string } }).key?.id ?? "unknown")
: "unknown";
}

View File

@@ -56,9 +56,7 @@ export async function applyWhatsAppSecurityConfigFixes(params: {
params.env,
DEFAULT_ACCOUNT_ID,
).catch(() => []);
const normalized = Array.from(new Set(fromStore.map((entry) => String(entry).trim()))).filter(
Boolean,
);
const normalized = Array.from(new Set(fromStore.map((entry) => entry.trim()))).filter(Boolean);
if (normalized.length === 0) {
return { config: params.cfg, changes: [] };
}

View File

@@ -40,7 +40,7 @@ export const whatsappSetupWizard: ChannelSetupWizard = {
return [`${label}: ${configured ? "linked" : "not linked"}`];
},
},
resolveShouldPromptAccountIds: ({ shouldPromptAccountIds }) => Boolean(shouldPromptAccountIds),
resolveShouldPromptAccountIds: ({ shouldPromptAccountIds }) => shouldPromptAccountIds,
credentials: [],
finalize: async ({ cfg, accountId, forceAllowFrom, prompter, runtime }) =>
await finalizeWhatsAppSetup({ cfg, accountId, forceAllowFrom, prompter, runtime }),

View File

@@ -74,7 +74,7 @@ export function createWhatsAppSetupWizardProxy(
configuredScore: 5,
unconfiguredScore: 4,
},
resolveShouldPromptAccountIds: (params) => Boolean(params.shouldPromptAccountIds),
resolveShouldPromptAccountIds: (params) => params.shouldPromptAccountIds,
credentials: [],
delegateFinalize: true,
disable: (cfg) => ({