mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-11 17:12:54 +00:00
* feat(plugin-sdk): add typed presentation command actions * test: use shared env helper in telegram bot tests * test: expect typed approval actions * test: expect typed sdk approval actions
96 lines
2.6 KiB
TypeScript
96 lines
2.6 KiB
TypeScript
import {
|
|
adaptMessagePresentationForChannel,
|
|
resolveMessagePresentationControlValue,
|
|
type MessagePresentation,
|
|
} from "openclaw/plugin-sdk/interactive-runtime";
|
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
import type { ChannelOutboundAdapter } from "../runtime-api.js";
|
|
|
|
export const MSTEAMS_PRESENTATION_CAPABILITIES = {
|
|
supported: true,
|
|
buttons: true,
|
|
selects: false,
|
|
context: true,
|
|
divider: true,
|
|
limits: {
|
|
actions: {
|
|
supportsStyles: false,
|
|
supportsDisabled: false,
|
|
},
|
|
text: {
|
|
markdownDialect: "markdown",
|
|
},
|
|
},
|
|
} satisfies ChannelOutboundAdapter["presentationCapabilities"];
|
|
|
|
export function buildMSTeamsPresentationCard(params: {
|
|
presentation: MessagePresentation;
|
|
text?: string | null;
|
|
}) {
|
|
const body: Record<string, unknown>[] = [];
|
|
const text = normalizeOptionalString(params.text);
|
|
if (text) {
|
|
body.push({
|
|
type: "TextBlock",
|
|
text,
|
|
wrap: true,
|
|
});
|
|
}
|
|
const presentation = adaptMessagePresentationForChannel({
|
|
presentation: params.presentation,
|
|
capabilities: MSTEAMS_PRESENTATION_CAPABILITIES,
|
|
});
|
|
if (presentation.title) {
|
|
body.push({
|
|
type: "TextBlock",
|
|
text: presentation.title,
|
|
weight: "Bolder",
|
|
size: "Medium",
|
|
wrap: true,
|
|
});
|
|
}
|
|
const actions: Record<string, unknown>[] = [];
|
|
for (const block of presentation.blocks) {
|
|
if (block.type === "text" || block.type === "context") {
|
|
body.push({
|
|
type: "TextBlock",
|
|
text: block.text,
|
|
wrap: true,
|
|
...(block.type === "context" ? { isSubtle: true, size: "Small" } : {}),
|
|
});
|
|
continue;
|
|
}
|
|
if (block.type === "divider") {
|
|
body.push({ type: "TextBlock", text: "---", wrap: true, isSubtle: true });
|
|
continue;
|
|
}
|
|
if (block.type === "buttons") {
|
|
for (const button of block.buttons) {
|
|
const targetUrl = button.url ?? button.webApp?.url ?? button.web_app?.url;
|
|
if (targetUrl) {
|
|
actions.push({
|
|
type: "Action.OpenUrl",
|
|
title: button.label,
|
|
url: targetUrl,
|
|
});
|
|
continue;
|
|
}
|
|
const value = resolveMessagePresentationControlValue(button);
|
|
if (value) {
|
|
actions.push({
|
|
type: "Action.Submit",
|
|
title: button.label,
|
|
data: button.action?.type === "command" ? value : { value, label: button.label },
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
type: "AdaptiveCard",
|
|
version: "1.4",
|
|
body,
|
|
...(actions.length ? { actions } : {}),
|
|
};
|
|
}
|