mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-12 09:41:11 +00:00
fix(cycles): split small runtime seams
This commit is contained in:
@@ -6,6 +6,8 @@ import { buildFileInfoCard, parseFileConsentInvoke, uploadToConsentUrl } from ".
|
||||
import { extractMSTeamsConversationMessageId, normalizeMSTeamsConversationId } from "./inbound.js";
|
||||
import { resolveMSTeamsSenderAccess } from "./monitor-handler/access.js";
|
||||
import { createMSTeamsMessageHandler } from "./monitor-handler/message-handler.js";
|
||||
export type { MSTeamsAccessTokenProvider } from "./attachments/types.js";
|
||||
import type { MSTeamsAccessTokenProvider } from "./attachments/types.js";
|
||||
import type { MSTeamsMonitorLogger } from "./monitor-types.js";
|
||||
import { getPendingUpload, removePendingUpload } from "./pending-uploads.js";
|
||||
import { withRevokedProxyFallback } from "./revoked-context.js";
|
||||
@@ -14,7 +16,6 @@ import type { MSTeamsTurnContext } from "./sdk-types.js";
|
||||
import {
|
||||
handleSigninTokenExchangeInvoke,
|
||||
handleSigninVerifyStateInvoke,
|
||||
type MSTeamsSsoDeps,
|
||||
parseSigninTokenExchangeValue,
|
||||
parseSigninVerifyStateValue,
|
||||
} from "./sso.js";
|
||||
@@ -22,10 +23,6 @@ import { buildGroupWelcomeText, buildWelcomeCard } from "./welcome-card.js";
|
||||
export type { MSTeamsMessageHandlerDeps } from "./monitor-handler.types.js";
|
||||
import type { MSTeamsMessageHandlerDeps } from "./monitor-handler.types.js";
|
||||
|
||||
export type MSTeamsAccessTokenProvider = {
|
||||
getAccessToken: (scope: string) => Promise<string>;
|
||||
};
|
||||
|
||||
export type MSTeamsActivityHandler = {
|
||||
onMessage: (
|
||||
handler: (context: unknown, next: () => Promise<void>) => Promise<void>,
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
* that ack; these helpers encapsulate token exchange and persistence.
|
||||
*/
|
||||
|
||||
import type { MSTeamsAccessTokenProvider } from "./monitor-handler.js";
|
||||
import type { MSTeamsAccessTokenProvider } from "./attachments/types.js";
|
||||
import type { MSTeamsSsoTokenStore } from "./sso-token-store.js";
|
||||
import { buildUserAgent } from "./user-agent.js";
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
startBackgroundTokenRefresh,
|
||||
stopBackgroundTokenRefresh,
|
||||
} from "./api.js";
|
||||
import { qqbotPlugin } from "./channel.js";
|
||||
import { formatQQBotAllowFrom } from "./channel-config-shared.js";
|
||||
import { formatVoiceText, processAttachments } from "./inbound-attachments.js";
|
||||
import { flushKnownUsers, recordKnownUser } from "./known-users.js";
|
||||
import { createMessageQueue, type QueuedMessage } from "./message-queue.js";
|
||||
@@ -748,13 +748,9 @@ export async function startGateway(ctx: GatewayContext): Promise<void> {
|
||||
const toAddress = fromAddress;
|
||||
|
||||
const rawAllowFrom = account.config?.allowFrom ?? [];
|
||||
const normalizedAllowFrom = qqbotPlugin.config?.formatAllowFrom
|
||||
? qqbotPlugin.config.formatAllowFrom({
|
||||
cfg: cfg,
|
||||
accountId: account.accountId,
|
||||
allowFrom: rawAllowFrom,
|
||||
})
|
||||
: rawAllowFrom.map((e: string) => e.replace(/^qqbot:/i, "").toUpperCase());
|
||||
const normalizedAllowFrom = formatQQBotAllowFrom({
|
||||
allowFrom: rawAllowFrom,
|
||||
});
|
||||
const normalizedSenderId = event.senderId.replace(/^qqbot:/i, "").toUpperCase();
|
||||
const allowAll =
|
||||
normalizedAllowFrom.length === 0 || normalizedAllowFrom.some((e) => e === "*");
|
||||
|
||||
@@ -36,11 +36,8 @@ import {
|
||||
warnMissingProviderGroupPolicyFallbackOnce,
|
||||
} from "./runtime-api.js";
|
||||
import { getZaloRuntime } from "./runtime.js";
|
||||
|
||||
export type ZaloRuntimeEnv = {
|
||||
log?: (message: string) => void;
|
||||
error?: (message: string) => void;
|
||||
};
|
||||
export type { ZaloRuntimeEnv } from "./monitor.types.js";
|
||||
import type { ZaloRuntimeEnv } from "./monitor.types.js";
|
||||
|
||||
export type ZaloMonitorOptions = {
|
||||
token: string;
|
||||
|
||||
4
extensions/zalo/src/monitor.types.ts
Normal file
4
extensions/zalo/src/monitor.types.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export type ZaloRuntimeEnv = {
|
||||
log?: (message: string) => void;
|
||||
error?: (message: string) => void;
|
||||
};
|
||||
@@ -2,7 +2,7 @@ import type { IncomingMessage, ServerResponse } from "node:http";
|
||||
import { safeEqualSecret } from "openclaw/plugin-sdk/browser-security-runtime";
|
||||
import type { ResolvedZaloAccount } from "./accounts.js";
|
||||
import type { ZaloFetch, ZaloUpdate } from "./api.js";
|
||||
import type { ZaloRuntimeEnv } from "./monitor.js";
|
||||
import type { ZaloRuntimeEnv } from "./monitor.types.js";
|
||||
import {
|
||||
createDedupeCache,
|
||||
createFixedWindowRateLimiter,
|
||||
|
||||
93
extensions/zalo/src/setup-allow-from.ts
Normal file
93
extensions/zalo/src/setup-allow-from.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
formatDocsLink,
|
||||
mergeAllowFromEntries,
|
||||
type ChannelSetupDmPolicy,
|
||||
type ChannelSetupWizard,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { resolveZaloAccount } from "./accounts.js";
|
||||
|
||||
type ZaloAccountSetupConfig = {
|
||||
enabled?: boolean;
|
||||
};
|
||||
|
||||
export async function noteZaloTokenHelp(
|
||||
prompter: Parameters<NonNullable<ChannelSetupWizard["finalize"]>>[0]["prompter"],
|
||||
): Promise<void> {
|
||||
await prompter.note(
|
||||
[
|
||||
"1) Open Zalo Bot Platform: https://bot.zaloplatforms.com",
|
||||
"2) Create a bot and get the token",
|
||||
"3) Token looks like 12345689:abc-xyz",
|
||||
"Tip: you can also set ZALO_BOT_TOKEN in your env.",
|
||||
`Docs: ${formatDocsLink("/channels/zalo", "zalo")}`,
|
||||
].join("\n"),
|
||||
"Zalo bot token",
|
||||
);
|
||||
}
|
||||
|
||||
export async function promptZaloAllowFrom(params: {
|
||||
cfg: OpenClawConfig;
|
||||
prompter: Parameters<NonNullable<ChannelSetupDmPolicy["promptAllowFrom"]>>[0]["prompter"];
|
||||
accountId: string;
|
||||
}): Promise<OpenClawConfig> {
|
||||
const { cfg, prompter, accountId } = params;
|
||||
const resolved = resolveZaloAccount({ cfg, accountId });
|
||||
const existingAllowFrom = resolved.config.allowFrom ?? [];
|
||||
const entry = await prompter.text({
|
||||
message: "Zalo allowFrom (user id)",
|
||||
placeholder: "123456789",
|
||||
initialValue: existingAllowFrom[0] ? String(existingAllowFrom[0]) : undefined,
|
||||
validate: (value) => {
|
||||
const raw = String(value ?? "").trim();
|
||||
if (!raw) {
|
||||
return "Required";
|
||||
}
|
||||
if (!/^\d+$/.test(raw)) {
|
||||
return "Use a numeric Zalo user id";
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
});
|
||||
const normalized = String(entry).trim();
|
||||
const unique = mergeAllowFromEntries(existingAllowFrom, [normalized]);
|
||||
|
||||
if (accountId === DEFAULT_ACCOUNT_ID) {
|
||||
return {
|
||||
...cfg,
|
||||
channels: {
|
||||
...cfg.channels,
|
||||
zalo: {
|
||||
...cfg.channels?.zalo,
|
||||
enabled: true,
|
||||
dmPolicy: "allowlist",
|
||||
allowFrom: unique,
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
}
|
||||
|
||||
const currentAccount = cfg.channels?.zalo?.accounts?.[accountId] as
|
||||
| ZaloAccountSetupConfig
|
||||
| undefined;
|
||||
return {
|
||||
...cfg,
|
||||
channels: {
|
||||
...cfg.channels,
|
||||
zalo: {
|
||||
...cfg.channels?.zalo,
|
||||
enabled: true,
|
||||
accounts: {
|
||||
...cfg.channels?.zalo?.accounts,
|
||||
[accountId]: {
|
||||
...currentAccount,
|
||||
enabled: currentAccount?.enabled ?? true,
|
||||
dmPolicy: "allowlist",
|
||||
allowFrom: unique,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
type ChannelSetupWizard,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { resolveDefaultZaloAccountId, resolveZaloAccount } from "./accounts.js";
|
||||
import { promptZaloAllowFrom } from "./setup-allow-from.js";
|
||||
|
||||
const channel = "zalo" as const;
|
||||
|
||||
@@ -109,14 +110,9 @@ export const zaloDmPolicy: ChannelSetupDmPolicy = {
|
||||
},
|
||||
};
|
||||
},
|
||||
promptAllowFrom: async (params) =>
|
||||
(await loadZaloSetupWizard()).dmPolicy?.promptAllowFrom?.(params) ?? params.cfg,
|
||||
promptAllowFrom: promptZaloAllowFrom,
|
||||
};
|
||||
|
||||
async function loadZaloSetupWizard(): Promise<ChannelSetupWizard> {
|
||||
return (await import("./setup-surface.js")).zaloSetupWizard;
|
||||
}
|
||||
|
||||
export function createZaloSetupWizardProxy(
|
||||
loadWizard: () => Promise<ChannelSetupWizard>,
|
||||
): ChannelSetupWizard {
|
||||
|
||||
@@ -2,27 +2,21 @@ import {
|
||||
buildSingleChannelSecretPromptState,
|
||||
createStandardChannelSetupStatus,
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
formatDocsLink,
|
||||
hasConfiguredSecretInput,
|
||||
mergeAllowFromEntries,
|
||||
promptSingleChannelSecretInput,
|
||||
runSingleChannelSecretStep,
|
||||
type ChannelSetupDmPolicy,
|
||||
type ChannelSetupWizard,
|
||||
type OpenClawConfig,
|
||||
type SecretInput,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { resolveZaloAccount } from "./accounts.js";
|
||||
import { noteZaloTokenHelp } from "./setup-allow-from.js";
|
||||
import { zaloDmPolicy } from "./setup-core.js";
|
||||
|
||||
const channel = "zalo" as const;
|
||||
|
||||
type UpdateMode = "polling" | "webhook";
|
||||
|
||||
type ZaloAccountSetupConfig = {
|
||||
enabled?: boolean;
|
||||
};
|
||||
|
||||
function setZaloUpdateMode(
|
||||
cfg: OpenClawConfig,
|
||||
accountId: string,
|
||||
@@ -98,86 +92,6 @@ function setZaloUpdateMode(
|
||||
} as OpenClawConfig;
|
||||
}
|
||||
|
||||
async function noteZaloTokenHelp(
|
||||
prompter: Parameters<NonNullable<ChannelSetupWizard["finalize"]>>[0]["prompter"],
|
||||
): Promise<void> {
|
||||
await prompter.note(
|
||||
[
|
||||
"1) Open Zalo Bot Platform: https://bot.zaloplatforms.com",
|
||||
"2) Create a bot and get the token",
|
||||
"3) Token looks like 12345689:abc-xyz",
|
||||
"Tip: you can also set ZALO_BOT_TOKEN in your env.",
|
||||
`Docs: ${formatDocsLink("/channels/zalo", "zalo")}`,
|
||||
].join("\n"),
|
||||
"Zalo bot token",
|
||||
);
|
||||
}
|
||||
|
||||
async function promptZaloAllowFrom(params: {
|
||||
cfg: OpenClawConfig;
|
||||
prompter: Parameters<NonNullable<ChannelSetupDmPolicy["promptAllowFrom"]>>[0]["prompter"];
|
||||
accountId: string;
|
||||
}): Promise<OpenClawConfig> {
|
||||
const { cfg, prompter, accountId } = params;
|
||||
const resolved = resolveZaloAccount({ cfg, accountId });
|
||||
const existingAllowFrom = resolved.config.allowFrom ?? [];
|
||||
const entry = await prompter.text({
|
||||
message: "Zalo allowFrom (user id)",
|
||||
placeholder: "123456789",
|
||||
initialValue: existingAllowFrom[0] ? String(existingAllowFrom[0]) : undefined,
|
||||
validate: (value) => {
|
||||
const raw = String(value ?? "").trim();
|
||||
if (!raw) {
|
||||
return "Required";
|
||||
}
|
||||
if (!/^\d+$/.test(raw)) {
|
||||
return "Use a numeric Zalo user id";
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
});
|
||||
const normalized = String(entry).trim();
|
||||
const unique = mergeAllowFromEntries(existingAllowFrom, [normalized]);
|
||||
|
||||
if (accountId === DEFAULT_ACCOUNT_ID) {
|
||||
return {
|
||||
...cfg,
|
||||
channels: {
|
||||
...cfg.channels,
|
||||
zalo: {
|
||||
...cfg.channels?.zalo,
|
||||
enabled: true,
|
||||
dmPolicy: "allowlist",
|
||||
allowFrom: unique,
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
}
|
||||
|
||||
const currentAccount = cfg.channels?.zalo?.accounts?.[accountId] as
|
||||
| ZaloAccountSetupConfig
|
||||
| undefined;
|
||||
return {
|
||||
...cfg,
|
||||
channels: {
|
||||
...cfg.channels,
|
||||
zalo: {
|
||||
...cfg.channels?.zalo,
|
||||
enabled: true,
|
||||
accounts: {
|
||||
...cfg.channels?.zalo?.accounts,
|
||||
[accountId]: {
|
||||
...currentAccount,
|
||||
enabled: currentAccount?.enabled ?? true,
|
||||
dmPolicy: "allowlist",
|
||||
allowFrom: unique,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
}
|
||||
|
||||
export { zaloSetupAdapter } from "./setup-core.js";
|
||||
|
||||
export const zaloSetupWizard: ChannelSetupWizard = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { callGateway } from "../gateway/call.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js";
|
||||
import type { GatewayRpcOpts } from "./gateway-rpc.js";
|
||||
import type { GatewayRpcOpts } from "./gateway-rpc.types.js";
|
||||
import { withProgress } from "./progress.js";
|
||||
|
||||
export async function callGatewayFromCliRuntime(
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import type { Command } from "commander";
|
||||
|
||||
export type GatewayRpcOpts = {
|
||||
url?: string;
|
||||
token?: string;
|
||||
timeout?: string;
|
||||
expectFinal?: boolean;
|
||||
json?: boolean;
|
||||
};
|
||||
export type { GatewayRpcOpts } from "./gateway-rpc.types.js";
|
||||
import type { GatewayRpcOpts } from "./gateway-rpc.types.js";
|
||||
|
||||
type GatewayRpcRuntimeModule = typeof import("./gateway-rpc.runtime.js");
|
||||
|
||||
|
||||
7
src/cli/gateway-rpc.types.ts
Normal file
7
src/cli/gateway-rpc.types.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export type GatewayRpcOpts = {
|
||||
url?: string;
|
||||
token?: string;
|
||||
timeout?: string;
|
||||
expectFinal?: boolean;
|
||||
json?: boolean;
|
||||
};
|
||||
Reference in New Issue
Block a user