mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 18:04:59 +00:00
Verified: - pnpm install --frozen-lockfile - pnpm build - pnpm check - pnpm test:macmini
This commit is contained in:
@@ -82,6 +82,7 @@ Docs: https://docs.openclaw.ai
|
|||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
|
- Slack/Bot attachment-only messages: when `allowBots: true`, bot messages with empty `text` now include non-forwarded attachment `text`/`fallback` content so webhook alerts are not silently dropped. (#27616)
|
||||||
- Slack/Security ingress mismatch guard: drop slash-command and interaction payloads when app/team identifiers do not match the active Slack account context (including nested `team.id` interaction payloads), preventing cross-app or cross-workspace payload injection into system-event handling. (#29091) Thanks @Solvely-Colin.
|
- Slack/Security ingress mismatch guard: drop slash-command and interaction payloads when app/team identifiers do not match the active Slack account context (including nested `team.id` interaction payloads), preventing cross-app or cross-workspace payload injection into system-event handling. (#29091) Thanks @Solvely-Colin.
|
||||||
- Cron/Failure alerts: add configurable repeated-failure alerting with per-job overrides and Web UI cron editor support (`inherit|disabled|custom` with threshold/cooldown/channel/target fields). (#24789) Thanks xbrak.
|
- Cron/Failure alerts: add configurable repeated-failure alerting with per-job overrides and Web UI cron editor support (`inherit|disabled|custom` with threshold/cooldown/channel/target fields). (#24789) Thanks xbrak.
|
||||||
- Cron/Isolated model defaults: resolve isolated cron `subagents.model` (including object-form `primary`) through allowlist-aware model selection so isolated cron runs honor subagent model defaults unless explicitly overridden by job payload model. (#11474) Thanks @AnonO6.
|
- Cron/Isolated model defaults: resolve isolated cron `subagents.model` (including object-form `primary`) through allowlist-aware model selection so isolated cron runs honor subagent model defaults unless explicitly overridden by job payload model. (#11474) Thanks @AnonO6.
|
||||||
|
|||||||
@@ -255,6 +255,36 @@ describe("slack prepareSlackMessage inbound contract", () => {
|
|||||||
expect(prepared!.ctxPayload.RawBody).toContain("[Slack file: file]");
|
expect(prepared!.ctxPayload.RawBody).toContain("[Slack file: file]");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("extracts attachment text for bot messages with empty text when allowBots is true (#27616)", async () => {
|
||||||
|
const slackCtx = createInboundSlackCtx({
|
||||||
|
cfg: {
|
||||||
|
channels: {
|
||||||
|
slack: { enabled: true },
|
||||||
|
},
|
||||||
|
} as OpenClawConfig,
|
||||||
|
defaultRequireMention: false,
|
||||||
|
});
|
||||||
|
// oxlint-disable-next-line typescript/no-explicit-any
|
||||||
|
slackCtx.resolveUserName = async () => ({ name: "Bot" }) as any;
|
||||||
|
|
||||||
|
const account = createSlackAccount({ allowBots: true });
|
||||||
|
const message = createSlackMessage({
|
||||||
|
text: "",
|
||||||
|
bot_id: "B0AGV8EQYA3",
|
||||||
|
subtype: "bot_message",
|
||||||
|
attachments: [
|
||||||
|
{
|
||||||
|
text: "Readiness probe failed: Get http://10.42.13.132:8000/status: context deadline exceeded",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const prepared = await prepareMessageWith(slackCtx, account, message);
|
||||||
|
|
||||||
|
expect(prepared).toBeTruthy();
|
||||||
|
expect(prepared!.ctxPayload.RawBody).toContain("Readiness probe failed");
|
||||||
|
});
|
||||||
|
|
||||||
it("keeps channel metadata out of GroupSystemPrompt", async () => {
|
it("keeps channel metadata out of GroupSystemPrompt", async () => {
|
||||||
const slackCtx = createInboundSlackCtx({
|
const slackCtx = createInboundSlackCtx({
|
||||||
cfg: {
|
cfg: {
|
||||||
|
|||||||
@@ -357,8 +357,25 @@ export async function prepareSlackMessage(params: {
|
|||||||
: undefined;
|
: undefined;
|
||||||
const fileOnlyPlaceholder = fileOnlyFallback ? `[Slack file: ${fileOnlyFallback}]` : undefined;
|
const fileOnlyPlaceholder = fileOnlyFallback ? `[Slack file: ${fileOnlyFallback}]` : undefined;
|
||||||
|
|
||||||
|
// Bot messages (e.g. Prometheus, Gatus webhooks) often carry content only in
|
||||||
|
// non-forwarded attachments (is_share !== true). Extract their text/fallback
|
||||||
|
// so the message isn't silently dropped when `allowBots: true` (#27616).
|
||||||
|
const botAttachmentText =
|
||||||
|
isBotMessage && !attachmentContent?.text
|
||||||
|
? (message.attachments ?? [])
|
||||||
|
.map((a) => a.text?.trim() || a.fallback?.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
.join("\n")
|
||||||
|
: undefined;
|
||||||
|
|
||||||
const rawBody =
|
const rawBody =
|
||||||
[(message.text ?? "").trim(), attachmentContent?.text, mediaPlaceholder, fileOnlyPlaceholder]
|
[
|
||||||
|
(message.text ?? "").trim(),
|
||||||
|
attachmentContent?.text,
|
||||||
|
botAttachmentText,
|
||||||
|
mediaPlaceholder,
|
||||||
|
fileOnlyPlaceholder,
|
||||||
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join("\n") || "";
|
.join("\n") || "";
|
||||||
if (!rawBody) {
|
if (!rawBody) {
|
||||||
|
|||||||
Reference in New Issue
Block a user