mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 10:10:45 +00:00
Telegram/documents: avoid synthetic reply bodies
This commit is contained in:
@@ -36,7 +36,7 @@ Docs: https://docs.openclaw.ai
|
||||
- BlueBubbles/inbound: add a persistent file-backed GUID dedupe so MessagePoller webhook replays after BB Server restart or reconnect no longer cause the agent to re-reply to already-handled messages. (#19176, #12053, #66816) Thanks @omarshahine.
|
||||
- Secrets/plugins/status: align SecretRef inspect-vs-strict handling across plugin preload, read-only status/agents surfaces, and runtime auth paths so unresolved refs no longer crash read-only CLI flows while runtime-required non-env refs stay strict. (#66818) Thanks @joshavant.
|
||||
- Memory/dreaming: stop ordinary transcripts that merely quote the dream-diary prompt from being classified as internal dreaming runs and silently dropped from session recall ingestion. (#66852) Thanks @gumadeiras.
|
||||
- Telegram/documents: sanitize binary reply and archive-extraction paths so `.epub` and `.mobi` uploads can no longer leak raw binary into prompt context through reply metadata or `text/plain` coercion. (#66877) Thanks @martinfrancois.
|
||||
- Telegram/documents: sanitize binary reply context and ZIP-like archive extraction so `.epub` and `.mobi` uploads can no longer leak raw binary into prompt context through reply metadata or archive-to-`text/plain` coercion. (#66877) Thanks @martinfrancois.
|
||||
|
||||
## 2026.4.14
|
||||
|
||||
|
||||
@@ -221,14 +221,29 @@ export async function buildTelegramInboundContextPayload(params: {
|
||||
: ""
|
||||
}]\n`
|
||||
: "";
|
||||
const buildReplySupplementalLines = (params: { body?: string }) => {
|
||||
const lines: string[] = [];
|
||||
const forwardAnnotation = replyForwardAnnotation.trimEnd();
|
||||
if (forwardAnnotation) {
|
||||
lines.push(forwardAnnotation);
|
||||
}
|
||||
if (params.body) {
|
||||
lines.push(params.body);
|
||||
}
|
||||
return lines.length > 0 ? `\n${lines.join("\n")}` : "";
|
||||
};
|
||||
const replySuffix = visibleReplyTarget
|
||||
? visibleReplyTarget.kind === "quote"
|
||||
? `\n\n[Quoting ${visibleReplyTarget.sender}${
|
||||
visibleReplyTarget.id ? ` id:${visibleReplyTarget.id}` : ""
|
||||
}]\n${replyForwardAnnotation}"${visibleReplyTarget.body}"\n[/Quoting]`
|
||||
}]${buildReplySupplementalLines({
|
||||
body: visibleReplyTarget.body ? `"${visibleReplyTarget.body}"` : undefined,
|
||||
})}\n[/Quoting]`
|
||||
: `\n\n[Replying to ${visibleReplyTarget.sender}${
|
||||
visibleReplyTarget.id ? ` id:${visibleReplyTarget.id}` : ""
|
||||
}]\n${replyForwardAnnotation}${visibleReplyTarget.body}\n[/Replying]`
|
||||
}]${buildReplySupplementalLines({
|
||||
body: visibleReplyTarget.body,
|
||||
})}\n[/Replying]`
|
||||
: "";
|
||||
const forwardPrefix = visibleForwardOrigin
|
||||
? `[Forwarded from ${visibleForwardOrigin.from}${
|
||||
|
||||
@@ -1280,7 +1280,7 @@ describe("createTelegramBot", () => {
|
||||
expect(payload.ReplyToSender).toBe("Ada");
|
||||
});
|
||||
|
||||
it("filters binary reply captions from ReplyToBody", async () => {
|
||||
it("keeps reply linkage while omitting filtered binary reply captions", async () => {
|
||||
onSpy.mockClear();
|
||||
sendMessageSpy.mockClear();
|
||||
replySpy.mockClear();
|
||||
@@ -1307,7 +1307,8 @@ describe("createTelegramBot", () => {
|
||||
const payload = replySpy.mock.calls[0][0];
|
||||
expect(payload.Body).toContain("[Replying to Ada id:9001]");
|
||||
expect(payload.Body).not.toContain("PK");
|
||||
expect(payload.ReplyToBody).toBe("[unsafe reply text omitted]");
|
||||
expect(payload.Body).not.toContain("unsafe reply text omitted");
|
||||
expect(payload.ReplyToBody).toBeUndefined();
|
||||
expect(payload.ReplyToId).toBe("9001");
|
||||
expect(payload.ReplyToSender).toBe("Ada");
|
||||
});
|
||||
|
||||
@@ -361,7 +361,7 @@ describe("describeReplyTarget", () => {
|
||||
} as any);
|
||||
expect(result?.id).toBe("1");
|
||||
expect(result?.sender).toBe("Alice");
|
||||
expect(result?.body).toBe("[unsafe reply text omitted]");
|
||||
expect(result?.body).toBeUndefined();
|
||||
});
|
||||
|
||||
it("falls back to reply text when quote text is binary", () => {
|
||||
|
||||
@@ -40,7 +40,6 @@ export {
|
||||
};
|
||||
|
||||
const TELEGRAM_GENERAL_TOPIC_ID = 1;
|
||||
const FILTERED_TELEGRAM_REPLY_TEXT = "[unsafe reply text omitted]";
|
||||
|
||||
function hadUnsafeTelegramText(raw: unknown, sanitized: string): boolean {
|
||||
return typeof raw === "string" && raw.trim().length > 0 && sanitized.trim().length === 0;
|
||||
@@ -336,7 +335,7 @@ export type TelegramReplyTarget = {
|
||||
sender: string;
|
||||
senderId?: string;
|
||||
senderUsername?: string;
|
||||
body: string;
|
||||
body?: string;
|
||||
kind: "reply" | "quote";
|
||||
/** Forward context if the reply target was itself a forwarded message (issue #9619). */
|
||||
forwardedFrom?: TelegramForwardedContext;
|
||||
@@ -397,7 +396,7 @@ export function describeReplyTarget(msg: Message): TelegramReplyTarget | null {
|
||||
sender: senderLabel,
|
||||
senderId: replyLike?.from?.id != null ? String(replyLike.from.id) : undefined,
|
||||
senderUsername: replyLike?.from?.username ?? undefined,
|
||||
body: body || FILTERED_TELEGRAM_REPLY_TEXT,
|
||||
body: body || undefined,
|
||||
kind,
|
||||
forwardedFrom,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user