Skip to content

Commit 60c0488

Browse files
authored
client: add option to manually acknowledge history syncs (#1100)
1 parent 8528b5e commit 60c0488

3 files changed

Lines changed: 55 additions & 12 deletions

File tree

client.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,10 @@ type Client struct {
100100
appStateProc *appstate.Processor
101101
appStateSyncLock sync.Mutex
102102

103-
historySyncNotifications chan *waE2E.HistorySyncNotification
104-
historySyncHandlerStarted atomic.Bool
105-
ManualHistorySyncDownload bool
103+
historySyncNotifications chan *waE2E.HistorySyncNotification
104+
historySyncHandlerStarted atomic.Bool
105+
ManualHistorySyncDownload bool
106+
DisableManualHistorySyncReceipt bool
106107

107108
uploadPreKeysLock sync.Mutex
108109
lastPreKeyUpload time.Time

internals.go

Lines changed: 0 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

message.go

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,38 @@ func (cli *Client) handleHistorySyncNotificationLoop() {
701701
}
702702
}
703703

704+
// SendHistorySyncServerErrorReceipt sends a history sync server-error receipt, which
705+
// asks the phone to re-upload the referenced history sync payload.
706+
func (cli *Client) SendHistorySyncServerErrorReceipt(ctx context.Context, msgID types.MessageID, mediaKey []byte) error {
707+
ciphertext, iv, err := encryptMediaRetryReceipt(msgID, mediaKey)
708+
if err != nil {
709+
return fmt.Errorf("failed to encrypt history sync server-error receipt: %w", err)
710+
}
711+
ownID := cli.getOwnID().ToNonAD()
712+
if ownID.IsEmpty() {
713+
return ErrNotLoggedIn
714+
}
715+
err = cli.sendNode(ctx, waBinary.Node{
716+
Tag: "receipt",
717+
Attrs: waBinary.Attrs{
718+
"id": string(msgID),
719+
"type": "server-error",
720+
"to": ownID,
721+
"category": "peer",
722+
},
723+
Content: []waBinary.Node{
724+
{Tag: "encrypt", Content: []waBinary.Node{
725+
{Tag: "enc_p", Content: ciphertext},
726+
{Tag: "enc_iv", Content: iv},
727+
}},
728+
},
729+
})
730+
if err != nil {
731+
return fmt.Errorf("Failed to send history sync server-error receipt: %w", err)
732+
}
733+
return nil
734+
}
735+
704736
// DownloadHistorySync will download and parse the history sync blob from the given history sync notification.
705737
//
706738
// You only need to call this manually if you set [Client.ManualHistorySyncDownload] to true.
@@ -815,7 +847,14 @@ func (cli *Client) handleProtocolMessage(ctx context.Context, info *types.Messag
815847
go cli.handleHistorySyncNotificationLoop()
816848
}
817849
}
818-
go cli.sendProtocolMessageReceipt(ctx, info.ID, types.ReceiptTypeHistorySync)
850+
if !(cli.ManualHistorySyncDownload && cli.DisableManualHistorySyncReceipt) {
851+
go func() {
852+
err := cli.SendProtocolMessageReceipt(ctx, info.ID, types.ReceiptTypeHistorySync)
853+
if err != nil {
854+
cli.Log.Warnf("Failed to send acknowledgement for protocol message %s: %v", info.ID, err)
855+
}
856+
}()
857+
}
819858
}
820859

821860
if protoMsg.GetLidMigrationMappingSyncMessage() != nil {
@@ -837,7 +876,12 @@ func (cli *Client) handleProtocolMessage(ctx context.Context, info *types.Messag
837876
}
838877

839878
if info.Category == "peer" {
840-
go cli.sendProtocolMessageReceipt(ctx, info.ID, types.ReceiptTypePeerMsg)
879+
go func() {
880+
err := cli.SendProtocolMessageReceipt(ctx, info.ID, types.ReceiptTypePeerMsg)
881+
if err != nil {
882+
cli.Log.Warnf("Failed to send acknowledgement for protocol message %s: %v", info.ID, err)
883+
}
884+
}()
841885
}
842886
return
843887
}
@@ -1047,9 +1091,10 @@ func (cli *Client) handleDecryptedMessage(ctx context.Context, info *types.Messa
10471091
return cli.dispatchEvent(evt.UnwrapRaw())
10481092
}
10491093

1050-
func (cli *Client) sendProtocolMessageReceipt(ctx context.Context, id types.MessageID, msgType types.ReceiptType) {
1094+
// SendProtocolMessageReceipt sends a receipt for a protocol message back to the phone.
1095+
func (cli *Client) SendProtocolMessageReceipt(ctx context.Context, id types.MessageID, msgType types.ReceiptType) error {
10511096
if len(id) == 0 {
1052-
return
1097+
return nil
10531098
}
10541099
err := cli.sendNode(ctx, waBinary.Node{
10551100
Tag: "receipt",
@@ -1061,6 +1106,7 @@ func (cli *Client) sendProtocolMessageReceipt(ctx context.Context, id types.Mess
10611106
Content: nil,
10621107
})
10631108
if err != nil {
1064-
cli.Log.Warnf("Failed to send acknowledgement for protocol message %s: %v", id, err)
1109+
return err
10651110
}
1111+
return nil
10661112
}

0 commit comments

Comments
 (0)