Skip to content

Commit 8e885b5

Browse files
committed
fix: skip ack when DisabledFeatures.Signal is set
The library was acking inbound `<message>` envelopes when DisabledFeatures.Signal was on, on the rationale of "tell the server to stop retrying." That's wrong: the runner has not actually received or decrypted the message — only the downstream client (e.g. a Baileys behind a proxy) has. Acking on its behalf prematurely tells WA the message was delivered, defeating retry semantics and offline-buffer flows where the downstream client may not be reachable yet. With this change, the disabled branch is a true no-op for message delivery. The ack travels back through the same path the message went out (e.g. customer's Baileys → Bartender → SendNode on the runner's whatsmeow → real WA) once the downstream client confirms processing. Godoc on DisabledFeatures.Signal updated to match the new behavior.
1 parent 534b7c5 commit 8e885b5

2 files changed

Lines changed: 11 additions & 10 deletions

File tree

client.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,13 @@ type RawNodeHandler func(ctx context.Context, node *waBinary.Node) (modified *wa
7171
// the library assumes is running. Toggle deliberately; the surrounding
7272
// code does not paper over the resulting gaps.
7373
type DisabledFeatures struct {
74-
// Signal disables the library's Signal-session machinery. When set,
75-
// incoming `<message>` envelopes are not decrypted (the library acks
76-
// them so the server stops retrying, but no plaintext is produced
77-
// and no UndecryptableMessage event is dispatched for the skip),
78-
// and the periodic prekey-upload loop becomes a no-op. Combine with
79-
// [RawNodeHandler] to forward the raw envelopes to the system that
80-
// actually owns the Signal session.
74+
// Signal disables the library's Signal-session machinery. When set:
75+
// - Incoming `<message>` envelopes are not decrypted and not
76+
// ack'd. The actual decrypting client downstream is responsible
77+
// for ack'ing once it has processed the message.
78+
// - The periodic prekey-upload loop is a no-op.
79+
// Combine with [RawNodeHandler] to forward the raw envelopes to the
80+
// system that actually owns the Signal session.
8181
Signal bool
8282
}
8383

message.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,10 @@ func (cli *Client) handleEncryptedMessage(ctx context.Context, node *waBinary.No
6161
defer cli.maybeDeferredAck(ctx, node)(&cancelled)
6262
cancelled = cli.handlePlaintextMessage(ctx, info, node)
6363
} else if cli.DisabledFeatures.Signal {
64-
// External system owns the Signal session; ack so the server
65-
// stops retrying but skip all local decrypt + identity work.
66-
cli.sendAck(ctx, node, 0)
64+
// External system owns the Signal session. We do not decrypt
65+
// and we do not ack: the actual decrypting client (e.g. a
66+
// downstream Baileys behind a proxy) is responsible for
67+
// ack'ing once it has received and processed the message.
6768
} else {
6869
cli.decryptMessages(ctx, info, node)
6970
}

0 commit comments

Comments
 (0)