refactor: share extension channel status summaries

This commit is contained in:
Peter Steinberger 2026-03-14 02:07:04 +00:00
parent e885f1999f
commit 97dc493e2a
8 changed files with 72 additions and 74 deletions

View File

@ -30,6 +30,7 @@ import {
type OpenClawConfig,
} from "openclaw/plugin-sdk/googlechat";
import { GoogleChatConfigSchema } from "openclaw/plugin-sdk/googlechat";
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
import {
listGoogleChatAccountIds,
resolveDefaultGoogleChatAccountId,
@ -473,19 +474,13 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
}
return issues;
}),
buildChannelSummary: ({ snapshot }) => ({
configured: snapshot.configured ?? false,
buildChannelSummary: ({ snapshot }) =>
buildPassiveProbedChannelStatusSummary(snapshot, {
credentialSource: snapshot.credentialSource ?? "none",
audienceType: snapshot.audienceType ?? null,
audience: snapshot.audience ?? null,
webhookPath: snapshot.webhookPath ?? null,
webhookUrl: snapshot.webhookUrl ?? null,
running: snapshot.running ?? false,
lastStartAt: snapshot.lastStartAt ?? null,
lastStopAt: snapshot.lastStopAt ?? null,
lastError: snapshot.lastError ?? null,
probe: snapshot.probe,
lastProbeAt: snapshot.lastProbeAt ?? null,
}),
probeAccount: async ({ account }) => probeGoogleChat(account),
buildAccountSnapshot: ({ account, runtime, probe }) => {

View File

@ -29,6 +29,7 @@ import {
type ChannelPlugin,
type ResolvedIMessageAccount,
} from "openclaw/plugin-sdk/imessage";
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
import { getIMessageRuntime } from "./runtime.js";
const meta = getChatChannelMeta("imessage");
@ -264,16 +265,10 @@ export const imessagePlugin: ChannelPlugin<ResolvedIMessageAccount> = {
dbPath: null,
},
collectStatusIssues: (accounts) => collectStatusIssuesFromLastError("imessage", accounts),
buildChannelSummary: ({ snapshot }) => ({
configured: snapshot.configured ?? false,
running: snapshot.running ?? false,
lastStartAt: snapshot.lastStartAt ?? null,
lastStopAt: snapshot.lastStopAt ?? null,
lastError: snapshot.lastError ?? null,
buildChannelSummary: ({ snapshot }) =>
buildPassiveProbedChannelStatusSummary(snapshot, {
cliPath: snapshot.cliPath ?? null,
dbPath: snapshot.dbPath ?? null,
probe: snapshot.probe,
lastProbeAt: snapshot.lastProbeAt ?? null,
}),
probeAccount: async ({ timeoutMs }) =>
getIMessageRuntime().channel.imessage.probeIMessage(timeoutMs),

View File

@ -21,6 +21,7 @@ import {
type ChannelMessageActionName,
type ChannelPlugin,
} from "openclaw/plugin-sdk/mattermost";
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
import { MattermostConfigSchema } from "./config-schema.js";
import { resolveMattermostGroupRequireMention } from "./group-mentions.js";
import {
@ -419,17 +420,11 @@ export const mattermostPlugin: ChannelPlugin<ResolvedMattermostAccount> = {
lastStopAt: null,
lastError: null,
},
buildChannelSummary: ({ snapshot }) => ({
configured: snapshot.configured ?? false,
buildChannelSummary: ({ snapshot }) =>
buildPassiveProbedChannelStatusSummary(snapshot, {
botTokenSource: snapshot.botTokenSource ?? "none",
running: snapshot.running ?? false,
connected: snapshot.connected ?? false,
lastStartAt: snapshot.lastStartAt ?? null,
lastStopAt: snapshot.lastStopAt ?? null,
lastError: snapshot.lastError ?? null,
baseUrl: snapshot.baseUrl ?? null,
probe: snapshot.probe,
lastProbeAt: snapshot.lastProbeAt ?? null,
}),
probeAccount: async ({ account, timeoutMs }) => {
const token = account.botToken?.trim();

View File

@ -7,6 +7,7 @@ import {
mapAllowFromEntries,
type ChannelPlugin,
} from "openclaw/plugin-sdk/nostr";
import { buildPassiveChannelStatusSummary } from "../../shared/channel-status-summary.js";
import type { NostrProfile } from "./config-schema.js";
import { NostrConfigSchema } from "./config-schema.js";
import type { MetricEvent, MetricsSnapshot } from "./metrics.js";
@ -160,13 +161,9 @@ export const nostrPlugin: ChannelPlugin<ResolvedNostrAccount> = {
status: {
defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID),
collectStatusIssues: (accounts) => collectStatusIssuesFromLastError("nostr", accounts),
buildChannelSummary: ({ snapshot }) => ({
configured: snapshot.configured ?? false,
buildChannelSummary: ({ snapshot }) =>
buildPassiveChannelStatusSummary(snapshot, {
publicKey: snapshot.publicKey ?? null,
running: snapshot.running ?? false,
lastStartAt: snapshot.lastStartAt ?? null,
lastStopAt: snapshot.lastStopAt ?? null,
lastError: snapshot.lastError ?? null,
}),
buildAccountSnapshot: ({ account, runtime }) => ({
accountId: account.accountId,

View File

@ -0,0 +1,34 @@
type PassiveChannelStatusSnapshot = {
configured?: boolean;
running?: boolean;
lastStartAt?: number | null;
lastStopAt?: number | null;
lastError?: string | null;
probe?: unknown;
lastProbeAt?: number | null;
};
export function buildPassiveChannelStatusSummary<TExtra extends object>(
snapshot: PassiveChannelStatusSnapshot,
extra?: TExtra,
) {
return {
configured: snapshot.configured ?? false,
...(extra ?? ({} as TExtra)),
running: snapshot.running ?? false,
lastStartAt: snapshot.lastStartAt ?? null,
lastStopAt: snapshot.lastStopAt ?? null,
lastError: snapshot.lastError ?? null,
};
}
export function buildPassiveProbedChannelStatusSummary<TExtra extends object>(
snapshot: PassiveChannelStatusSnapshot,
extra?: TExtra,
) {
return {
...buildPassiveChannelStatusSummary(snapshot, extra),
probe: snapshot.probe,
lastProbeAt: snapshot.lastProbeAt ?? null,
};
}

View File

@ -38,6 +38,7 @@ import {
type ChannelPlugin,
type ResolvedSlackAccount,
} from "openclaw/plugin-sdk/slack";
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
import { getSlackRuntime } from "./runtime.js";
const meta = getChatChannelMeta("slack");
@ -421,16 +422,10 @@ export const slackPlugin: ChannelPlugin<ResolvedSlackAccount> = {
lastStopAt: null,
lastError: null,
},
buildChannelSummary: ({ snapshot }) => ({
configured: snapshot.configured ?? false,
buildChannelSummary: ({ snapshot }) =>
buildPassiveProbedChannelStatusSummary(snapshot, {
botTokenSource: snapshot.botTokenSource ?? "none",
appTokenSource: snapshot.appTokenSource ?? "none",
running: snapshot.running ?? false,
lastStartAt: snapshot.lastStartAt ?? null,
lastStopAt: snapshot.lastStopAt ?? null,
lastError: snapshot.lastError ?? null,
probe: snapshot.probe,
lastProbeAt: snapshot.lastProbeAt ?? null,
}),
probeAccount: async ({ account, timeoutMs }) => {
const token = account.botToken?.trim();

View File

@ -7,6 +7,7 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/twitch";
import { buildChannelConfigSchema } from "openclaw/plugin-sdk/twitch";
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
import { twitchMessageActions } from "./actions.js";
import { removeClientManager } from "./client-manager-registry.js";
import { TwitchConfigSchema } from "./config-schema.js";
@ -169,15 +170,8 @@ export const twitchPlugin: ChannelPlugin<TwitchAccountConfig> = {
},
/** Build channel summary from snapshot */
buildChannelSummary: ({ snapshot }: { snapshot: ChannelAccountSnapshot }) => ({
configured: snapshot.configured ?? false,
running: snapshot.running ?? false,
lastStartAt: snapshot.lastStartAt ?? null,
lastStopAt: snapshot.lastStopAt ?? null,
lastError: snapshot.lastError ?? null,
probe: snapshot.probe,
lastProbeAt: snapshot.lastProbeAt ?? null,
}),
buildChannelSummary: ({ snapshot }: { snapshot: ChannelAccountSnapshot }) =>
buildPassiveProbedChannelStatusSummary(snapshot),
/** Probe account connection */
probeAccount: async ({

View File

@ -29,6 +29,7 @@ import {
sendPayloadWithChunkedTextAndMedia,
setAccountEnabledInConfigSection,
} from "openclaw/plugin-sdk/zalouser";
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
import {
listZalouserAccountIds,
resolveDefaultZalouserAccountId,
@ -652,15 +653,7 @@ export const zalouserPlugin: ChannelPlugin<ResolvedZalouserAccount> = {
lastError: null,
},
collectStatusIssues: collectZalouserStatusIssues,
buildChannelSummary: ({ snapshot }) => ({
configured: snapshot.configured ?? false,
running: snapshot.running ?? false,
lastStartAt: snapshot.lastStartAt ?? null,
lastStopAt: snapshot.lastStopAt ?? null,
lastError: snapshot.lastError ?? null,
probe: snapshot.probe,
lastProbeAt: snapshot.lastProbeAt ?? null,
}),
buildChannelSummary: ({ snapshot }) => buildPassiveProbedChannelStatusSummary(snapshot),
probeAccount: async ({ account, timeoutMs }) => probeZalouser(account.profile, timeoutMs),
buildAccountSnapshot: async ({ account, runtime }) => {
const configured = await checkZcaAuthenticated(account.profile);