Discord: clarify Activities docs and add launch test

This commit is contained in:
Shadow
2026-02-17 20:51:01 -06:00
parent c62c422259
commit 2751493fc0
2 changed files with 32 additions and 2 deletions

View File

@@ -81,7 +81,6 @@ When the button is pressed, OpenClaw responds with the `LAUNCH_ACTIVITY` interac
## Notes
- The bundled A2UI page renders in Discord, but the node action bridge is not available in the Discord client. If you need Activity user actions to reach the Gateway, add a browser bridge to post actions back to the Gateway.
- The activity token is shared with anyone who can open the Activity URL. Omit the token only if you want fully public A2UI access.
Related:

View File

@@ -5,7 +5,7 @@ import type {
StringSelectMenuInteraction,
} from "@buape/carbon";
import type { Client } from "@buape/carbon";
import type { GatewayPresenceUpdate } from "discord-api-types/v10";
import { InteractionResponseType, Routes, type GatewayPresenceUpdate } from "discord-api-types/v10";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../../config/config.js";
import type { DiscordAccountConfig } from "../../config/types.discord.js";
@@ -313,6 +313,37 @@ describe("discord component interactions", () => {
expect(resolveDiscordComponentEntry({ id: "btn_1" })).toBeNull();
});
it("launches activities for launch-activity buttons", async () => {
registerDiscordComponentEntries({
entries: [createButtonEntry({ action: "launch-activity" })],
modals: [],
});
const restPost = vi.fn().mockResolvedValue(undefined);
const button = createDiscordComponentButton(createComponentContext());
const { interaction, defer, reply } = createComponentButtonInteraction({
rawData: {
channel_id: "dm-channel",
id: "interaction-1",
token: "token-123",
} as ButtonInteraction["rawData"],
client: { rest: { post: restPost } },
});
await button.run(interaction, { cid: "btn_1" } as ComponentData);
expect(restPost).toHaveBeenCalledTimes(1);
expect(restPost).toHaveBeenCalledWith(
Routes.interactionCallback("interaction-1", "token-123"),
{ body: { type: InteractionResponseType.LaunchActivity } },
);
expect(defer).not.toHaveBeenCalled();
expect(reply).not.toHaveBeenCalled();
expect(dispatchReplyMock).not.toHaveBeenCalled();
expect(deliverDiscordReplyMock).not.toHaveBeenCalled();
expect(resolveDiscordComponentEntry({ id: "btn_1" })).toBeNull();
});
it("keeps reusable buttons active after use", async () => {
registerDiscordComponentEntries({
entries: [createButtonEntry({ reusable: true })],