mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 07:57:28 +00:00
Mattermost: refresh interaction callback URL cache
This commit is contained in:
@@ -5,6 +5,7 @@ import { resolveMattermostAccount } from "./accounts.js";
|
|||||||
import type { MattermostClient } from "./client.js";
|
import type { MattermostClient } from "./client.js";
|
||||||
import {
|
import {
|
||||||
buildButtonAttachments,
|
buildButtonAttachments,
|
||||||
|
computeInteractionCallbackUrl,
|
||||||
createMattermostInteractionHandler,
|
createMattermostInteractionHandler,
|
||||||
generateInteractionToken,
|
generateInteractionToken,
|
||||||
getInteractionCallbackUrl,
|
getInteractionCallbackUrl,
|
||||||
@@ -136,7 +137,9 @@ describe("callback URL registry", () => {
|
|||||||
|
|
||||||
describe("resolveInteractionCallbackUrl", () => {
|
describe("resolveInteractionCallbackUrl", () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
setInteractionCallbackUrl("resolve-test", "");
|
for (const accountId of ["cached", "default", "acct", "myaccount"]) {
|
||||||
|
setInteractionCallbackUrl(accountId, "");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("prefers cached URL from registry", () => {
|
it("prefers cached URL from registry", () => {
|
||||||
@@ -144,6 +147,14 @@ describe("resolveInteractionCallbackUrl", () => {
|
|||||||
expect(resolveInteractionCallbackUrl("cached")).toBe("http://cached:1234/path");
|
expect(resolveInteractionCallbackUrl("cached")).toBe("http://cached:1234/path");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("recomputes from config when bypassing the cache explicitly", () => {
|
||||||
|
setInteractionCallbackUrl("acct", "http://cached:1234/path");
|
||||||
|
const url = computeInteractionCallbackUrl("acct", {
|
||||||
|
gateway: { port: 9999, customBindHost: "gateway.internal" },
|
||||||
|
});
|
||||||
|
expect(url).toBe("http://gateway.internal:9999/mattermost/interactions/acct");
|
||||||
|
});
|
||||||
|
|
||||||
it("uses interactions.callbackBaseUrl when configured", () => {
|
it("uses interactions.callbackBaseUrl when configured", () => {
|
||||||
const url = resolveInteractionCallbackUrl("default", {
|
const url = resolveInteractionCallbackUrl("default", {
|
||||||
channels: {
|
channels: {
|
||||||
|
|||||||
@@ -67,17 +67,12 @@ function normalizeCallbackBaseUrl(baseUrl: string): string {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve the interaction callback URL for an account.
|
* Resolve the interaction callback URL for an account.
|
||||||
* Prefers the in-memory registered URL (set by the gateway monitor).
|
|
||||||
* Falls back to computing it from interactions.callbackBaseUrl or gateway host config.
|
* Falls back to computing it from interactions.callbackBaseUrl or gateway host config.
|
||||||
*/
|
*/
|
||||||
export function resolveInteractionCallbackUrl(
|
export function computeInteractionCallbackUrl(
|
||||||
accountId: string,
|
accountId: string,
|
||||||
cfg?: InteractionCallbackConfig,
|
cfg?: InteractionCallbackConfig,
|
||||||
): string {
|
): string {
|
||||||
const cached = callbackUrls.get(accountId);
|
|
||||||
if (cached) {
|
|
||||||
return cached;
|
|
||||||
}
|
|
||||||
const path = resolveInteractionCallbackPath(accountId);
|
const path = resolveInteractionCallbackPath(accountId);
|
||||||
// Prefer merged per-account config when available, but keep the top-level path for
|
// Prefer merged per-account config when available, but keep the top-level path for
|
||||||
// callers/tests that still pass the root Mattermost config shape directly.
|
// callers/tests that still pass the root Mattermost config shape directly.
|
||||||
@@ -101,6 +96,22 @@ export function resolveInteractionCallbackUrl(
|
|||||||
return `http://${host}:${port}${path}`;
|
return `http://${host}:${port}${path}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the interaction callback URL for an account.
|
||||||
|
* Prefers the in-memory registered URL (set by the gateway monitor) so callers outside the
|
||||||
|
* monitor lifecycle can reuse the runtime-validated callback destination.
|
||||||
|
*/
|
||||||
|
export function resolveInteractionCallbackUrl(
|
||||||
|
accountId: string,
|
||||||
|
cfg?: InteractionCallbackConfig,
|
||||||
|
): string {
|
||||||
|
const cached = callbackUrls.get(accountId);
|
||||||
|
if (cached) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
return computeInteractionCallbackUrl(accountId, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
// ── HMAC token management ──────────────────────────────────────────────
|
// ── HMAC token management ──────────────────────────────────────────────
|
||||||
// Secret is derived from the bot token so it's stable across CLI and gateway processes.
|
// Secret is derived from the bot token so it's stable across CLI and gateway processes.
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ import {
|
|||||||
type MattermostUser,
|
type MattermostUser,
|
||||||
} from "./client.js";
|
} from "./client.js";
|
||||||
import {
|
import {
|
||||||
|
computeInteractionCallbackUrl,
|
||||||
createMattermostInteractionHandler,
|
createMattermostInteractionHandler,
|
||||||
resolveInteractionCallbackUrl,
|
|
||||||
resolveInteractionCallbackPath,
|
resolveInteractionCallbackPath,
|
||||||
setInteractionCallbackUrl,
|
setInteractionCallbackUrl,
|
||||||
setInteractionSecret,
|
setInteractionSecret,
|
||||||
@@ -456,7 +456,9 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
|||||||
// Register HTTP callback endpoint for interactive button clicks.
|
// Register HTTP callback endpoint for interactive button clicks.
|
||||||
// Mattermost POSTs to this URL when a user clicks a button action.
|
// Mattermost POSTs to this URL when a user clicks a button action.
|
||||||
const interactionPath = resolveInteractionCallbackPath(account.accountId);
|
const interactionPath = resolveInteractionCallbackPath(account.accountId);
|
||||||
const callbackUrl = resolveInteractionCallbackUrl(account.accountId, {
|
// Recompute from config on each monitor start so reconnects or config reloads can refresh the
|
||||||
|
// cached callback URL for downstream callers such as `message action=send`.
|
||||||
|
const callbackUrl = computeInteractionCallbackUrl(account.accountId, {
|
||||||
gateway: cfg.gateway,
|
gateway: cfg.gateway,
|
||||||
interactions: account.config.interactions,
|
interactions: account.config.interactions,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user