mirror of https://github.com/openclaw/openclaw.git
fix: honor twitch default outbound account
This commit is contained in:
parent
2a5fbf0fd6
commit
84db697cd6
|
|
@ -0,0 +1,75 @@
|
|||
import { describe, expect, it, vi, beforeEach } from "vitest";
|
||||
import { twitchMessageActions } from "./actions.js";
|
||||
import { twitchOutbound } from "./outbound.js";
|
||||
import { resolveTwitchAccountContext } from "./config.js";
|
||||
|
||||
vi.mock("./config.js", () => ({
|
||||
DEFAULT_ACCOUNT_ID: "default",
|
||||
resolveTwitchAccountContext: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("./outbound.js", () => ({
|
||||
twitchOutbound: {
|
||||
sendText: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe("twitchMessageActions", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("uses configured defaultAccount when action accountId is omitted", async () => {
|
||||
vi.mocked(resolveTwitchAccountContext)
|
||||
.mockImplementationOnce(() => ({
|
||||
accountId: "secondary",
|
||||
account: {
|
||||
channel: "secondary-channel",
|
||||
username: "secondary",
|
||||
accessToken: "oauth:secondary-token",
|
||||
clientId: "secondary-client",
|
||||
enabled: true,
|
||||
},
|
||||
tokenResolution: { source: "config", token: "oauth:secondary-token" },
|
||||
configured: true,
|
||||
availableAccountIds: ["default", "secondary"],
|
||||
}))
|
||||
.mockImplementation((_cfg, accountId) => ({
|
||||
accountId: accountId?.trim() || "secondary",
|
||||
account: {
|
||||
channel: "secondary-channel",
|
||||
username: "secondary",
|
||||
accessToken: "oauth:secondary-token",
|
||||
clientId: "secondary-client",
|
||||
enabled: true,
|
||||
},
|
||||
tokenResolution: { source: "config", token: "oauth:secondary-token" },
|
||||
configured: true,
|
||||
availableAccountIds: ["default", "secondary"],
|
||||
}));
|
||||
vi.mocked(twitchOutbound.sendText!).mockResolvedValue({
|
||||
channel: "twitch",
|
||||
messageId: "msg-1",
|
||||
timestamp: 1,
|
||||
});
|
||||
|
||||
await twitchMessageActions.handleAction!({
|
||||
action: "send",
|
||||
params: { message: "Hello!" },
|
||||
cfg: {
|
||||
channels: {
|
||||
twitch: {
|
||||
defaultAccount: "secondary",
|
||||
},
|
||||
},
|
||||
},
|
||||
} as never);
|
||||
|
||||
expect(twitchOutbound.sendText).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
accountId: "secondary",
|
||||
to: "secondary-channel",
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* Handles tool-based actions for Twitch, such as sending messages.
|
||||
*/
|
||||
|
||||
import { DEFAULT_ACCOUNT_ID, resolveTwitchAccountContext } from "./config.js";
|
||||
import { resolveTwitchAccountContext } from "./config.js";
|
||||
import { twitchOutbound } from "./outbound.js";
|
||||
import type { ChannelMessageActionAdapter, ChannelMessageActionContext } from "./types.js";
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ export const twitchMessageActions: ChannelMessageActionAdapter = {
|
|||
|
||||
const message = readStringParam(ctx.params, "message", { required: true });
|
||||
const to = readStringParam(ctx.params, "to", { required: false });
|
||||
const accountId = ctx.accountId ?? DEFAULT_ACCOUNT_ID;
|
||||
const accountId = ctx.accountId ?? resolveTwitchAccountContext(ctx.cfg).accountId;
|
||||
|
||||
const { account, availableAccountIds } = resolveTwitchAccountContext(ctx.cfg, accountId);
|
||||
if (!account) {
|
||||
|
|
|
|||
|
|
@ -305,6 +305,57 @@ describe("outbound", () => {
|
|||
);
|
||||
});
|
||||
|
||||
it("uses configured defaultAccount when accountId is omitted", async () => {
|
||||
const { sendMessageTwitchInternal } = await import("./send.js");
|
||||
|
||||
vi.mocked(resolveTwitchAccountContext)
|
||||
.mockImplementationOnce(() => ({
|
||||
accountId: "secondary",
|
||||
account: {
|
||||
...mockAccount,
|
||||
channel: "secondary-channel",
|
||||
},
|
||||
tokenResolution: { source: "config", token: mockAccount.accessToken },
|
||||
configured: true,
|
||||
availableAccountIds: ["default", "secondary"],
|
||||
}))
|
||||
.mockImplementation((_cfg, accountId) => ({
|
||||
accountId: accountId?.trim() || "secondary",
|
||||
account: {
|
||||
...mockAccount,
|
||||
channel: "secondary-channel",
|
||||
},
|
||||
tokenResolution: { source: "config", token: mockAccount.accessToken },
|
||||
configured: true,
|
||||
availableAccountIds: ["default", "secondary"],
|
||||
}));
|
||||
vi.mocked(sendMessageTwitchInternal).mockResolvedValue({
|
||||
ok: true,
|
||||
messageId: "msg-secondary",
|
||||
});
|
||||
|
||||
await twitchOutbound.sendText!({
|
||||
cfg: {
|
||||
channels: {
|
||||
twitch: {
|
||||
defaultAccount: "secondary",
|
||||
},
|
||||
},
|
||||
} as typeof mockConfig,
|
||||
to: "#secondary-channel",
|
||||
text: "Hello!",
|
||||
});
|
||||
|
||||
expect(sendMessageTwitchInternal).toHaveBeenCalledWith(
|
||||
"secondary-channel",
|
||||
"Hello!",
|
||||
expect.any(Object),
|
||||
"secondary",
|
||||
true,
|
||||
console,
|
||||
);
|
||||
});
|
||||
|
||||
it("should handle abort signal", async () => {
|
||||
const abortController = new AbortController();
|
||||
abortController.abort();
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ export const twitchOutbound: ChannelOutboundAdapter = {
|
|||
throw new Error("Outbound delivery aborted");
|
||||
}
|
||||
|
||||
const resolvedAccountId = accountId ?? DEFAULT_ACCOUNT_ID;
|
||||
const resolvedAccountId = accountId ?? resolveTwitchAccountContext(cfg).accountId;
|
||||
const { account, availableAccountIds } = resolveTwitchAccountContext(cfg, resolvedAccountId);
|
||||
if (!account) {
|
||||
throw new Error(
|
||||
|
|
|
|||
Loading…
Reference in New Issue