mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-30 01:06:11 +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
|
||||
|
||||
- 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.
|
||||
- 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.
|
||||
|
||||
@@ -255,6 +255,36 @@ describe("slack prepareSlackMessage inbound contract", () => {
|
||||
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 () => {
|
||||
const slackCtx = createInboundSlackCtx({
|
||||
cfg: {
|
||||
|
||||
@@ -357,8 +357,25 @@ export async function prepareSlackMessage(params: {
|
||||
: 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 =
|
||||
[(message.text ?? "").trim(), attachmentContent?.text, mediaPlaceholder, fileOnlyPlaceholder]
|
||||
[
|
||||
(message.text ?? "").trim(),
|
||||
attachmentContent?.text,
|
||||
botAttachmentText,
|
||||
mediaPlaceholder,
|
||||
fileOnlyPlaceholder,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n") || "";
|
||||
if (!rawBody) {
|
||||
|
||||
Reference in New Issue
Block a user