slidge-whatsapp 0.3.0b0__cp312-cp312-manylinux_2_36_aarch64.whl → 0.3.4__cp312-cp312-manylinux_2_36_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of slidge-whatsapp might be problematic. Click here for more details.

Files changed (167) hide show
  1. slidge_whatsapp/contact.py +2 -0
  2. slidge_whatsapp/event.go +72 -22
  3. slidge_whatsapp/generated/_whatsapp.cpython-312-aarch64-linux-gnu.h +175 -175
  4. slidge_whatsapp/generated/_whatsapp.cpython-312-aarch64-linux-gnu.so +0 -0
  5. slidge_whatsapp/generated/build.py +139 -139
  6. slidge_whatsapp/generated/go.py +1 -1
  7. slidge_whatsapp/generated/whatsapp.c +1513 -1513
  8. slidge_whatsapp/generated/whatsapp.go +1227 -1227
  9. slidge_whatsapp/generated/whatsapp.py +1382 -1382
  10. slidge_whatsapp/generated/whatsapp_go.h +175 -175
  11. slidge_whatsapp/go.mod +11 -11
  12. slidge_whatsapp/go.sum +26 -26
  13. slidge_whatsapp/session.go +4 -4
  14. slidge_whatsapp/vendor/github.com/ebitengine/purego/README.md +21 -5
  15. slidge_whatsapp/vendor/github.com/ebitengine/purego/abi_loong64.h +60 -0
  16. slidge_whatsapp/vendor/github.com/ebitengine/purego/cgo.go +1 -1
  17. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlerror.go +1 -1
  18. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlfcn.go +1 -1
  19. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlfcn_netbsd.go +15 -0
  20. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlfcn_nocgo_netbsd.go +9 -0
  21. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlfcn_stubs.s +1 -1
  22. slidge_whatsapp/vendor/github.com/ebitengine/purego/func.go +113 -60
  23. slidge_whatsapp/vendor/github.com/ebitengine/purego/gen.go +6 -0
  24. slidge_whatsapp/vendor/github.com/ebitengine/purego/go_runtime.go +1 -1
  25. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/cgo/dlfcn_cgo_unix.go +2 -2
  26. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/cgo/syscall_cgo_unix.go +2 -2
  27. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/abi_loong64.h +60 -0
  28. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/asm_loong64.s +40 -0
  29. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/callbacks.go +1 -1
  30. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/doc.go +1 -1
  31. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_libinit.go +1 -1
  32. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_loong64.go +92 -0
  33. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_netbsd.go +106 -0
  34. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_setenv.go +1 -1
  35. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_util.go +1 -1
  36. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/iscgo.go +1 -1
  37. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo.go +1 -1
  38. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_darwin.go +4 -0
  39. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_freebsd.go +4 -0
  40. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_linux.go +4 -0
  41. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_netbsd.go +26 -0
  42. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/netbsd.go +23 -0
  43. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/setenv.go +1 -1
  44. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols.go +11 -1
  45. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_darwin.go +1 -0
  46. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_freebsd.go +1 -0
  47. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_linux.go +1 -0
  48. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_netbsd.go +30 -0
  49. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_loong64.s +71 -0
  50. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_stubs.s +5 -1
  51. slidge_whatsapp/vendor/github.com/ebitengine/purego/nocgo.go +1 -1
  52. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_amd64.go +8 -4
  53. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_arm64.go +16 -6
  54. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_loong64.go +190 -0
  55. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_other.go +6 -2
  56. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_amd64.s +1 -1
  57. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_arm64.s +1 -1
  58. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_loong64.s +96 -0
  59. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_unix_arm64.s +1 -1
  60. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_unix_loong64.s +75 -0
  61. slidge_whatsapp/vendor/github.com/ebitengine/purego/syscall.go +6 -3
  62. slidge_whatsapp/vendor/github.com/ebitengine/purego/syscall_cgo_linux.go +3 -3
  63. slidge_whatsapp/vendor/github.com/ebitengine/purego/syscall_sysv.go +13 -10
  64. slidge_whatsapp/vendor/github.com/ebitengine/purego/syscall_windows.go +1 -1
  65. slidge_whatsapp/vendor/github.com/ebitengine/purego/zcallback_amd64.s +2002 -2002
  66. slidge_whatsapp/vendor/github.com/ebitengine/purego/zcallback_arm64.s +4002 -4002
  67. slidge_whatsapp/vendor/github.com/ebitengine/purego/zcallback_loong64.s +4014 -0
  68. slidge_whatsapp/vendor/go.mau.fi/libsignal/session/SessionCipher.go +7 -2
  69. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/log.go +1 -0
  70. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/module.go +119 -0
  71. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/upgradetable.go +3 -34
  72. slidge_whatsapp/vendor/go.mau.fi/util/exbytes/string.go +20 -0
  73. slidge_whatsapp/vendor/go.mau.fi/util/exbytes/writer.go +78 -0
  74. slidge_whatsapp/vendor/go.mau.fi/util/exslices/cast.go +42 -0
  75. slidge_whatsapp/vendor/go.mau.fi/util/exslices/chunk.go +28 -0
  76. slidge_whatsapp/vendor/go.mau.fi/util/exslices/deduplicate.go +67 -0
  77. slidge_whatsapp/vendor/go.mau.fi/util/exslices/diff.go +63 -0
  78. slidge_whatsapp/vendor/go.mau.fi/util/exsync/event.go +15 -1
  79. slidge_whatsapp/vendor/go.mau.fi/util/exsync/syncmap.go +48 -7
  80. slidge_whatsapp/vendor/go.mau.fi/util/exsync/syncset.go +13 -0
  81. slidge_whatsapp/vendor/go.mau.fi/util/jsontime/helpers.go +16 -5
  82. slidge_whatsapp/vendor/go.mau.fi/util/jsontime/integer.go +27 -12
  83. slidge_whatsapp/vendor/go.mau.fi/util/random/string.go +47 -7
  84. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate/decode.go +1 -0
  85. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate/encode.go +60 -15
  86. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate/hash.go +1 -0
  87. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate.go +20 -2
  88. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/armadillomessage.go +2 -2
  89. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/call.go +6 -0
  90. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/errors.go +1 -0
  91. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/group.go +63 -42
  92. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/internals.go +31 -15
  93. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/message.go +77 -26
  94. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/msgsecret.go +23 -0
  95. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/notification.go +5 -1
  96. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/pair.go +22 -23
  97. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/prekeys.go +21 -0
  98. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waAICommon/WAAICommon.pb.go +7747 -0
  99. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/{waBotMetadata/WABotMetadata.proto → waAICommon/WAAICommon.proto} +269 -9
  100. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waDeviceCapabilities/WAProtobufsDeviceCapabilities.pb.go +128 -14
  101. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waDeviceCapabilities/WAProtobufsDeviceCapabilities.proto +10 -0
  102. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.pb.go +8953 -10087
  103. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.proto +216 -330
  104. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waHistorySync/WAWebProtobufsHistorySync.pb.go +11 -2
  105. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waHistorySync/WAWebProtobufsHistorySync.proto +1 -0
  106. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waStatusAttributions/WAStatusAttributions.pb.go +226 -83
  107. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waStatusAttributions/WAStatusAttributions.proto +14 -0
  108. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.pb.go +709 -449
  109. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.proto +24 -0
  110. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWa6/WAWebProtobufsWa6.pb.go +78 -24
  111. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWa6/WAWebProtobufsWa6.proto +6 -0
  112. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.pb.go +528 -267
  113. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.proto +24 -0
  114. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/receipt.go +47 -14
  115. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/request.go +4 -0
  116. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/retry.go +6 -13
  117. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/send.go +130 -62
  118. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/sendfb.go +33 -32
  119. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/clientpayload.go +1 -1
  120. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/noop.go +16 -0
  121. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sessioncache.go +125 -0
  122. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/signal.go +8 -0
  123. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/lidmap.go +82 -4
  124. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/store.go +135 -55
  125. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/00-latest-schema.sql +8 -7
  126. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/11-redacted-phone-contacts.sql +2 -0
  127. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/store.go +24 -2
  128. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/call.go +6 -5
  129. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/jid.go +24 -9
  130. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/message.go +7 -1
  131. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/user.go +3 -0
  132. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/user.go +43 -3
  133. slidge_whatsapp/vendor/golang.org/x/crypto/curve25519/curve25519.go +7 -4
  134. slidge_whatsapp/vendor/golang.org/x/net/http2/config.go +11 -6
  135. slidge_whatsapp/vendor/golang.org/x/net/http2/config_go125.go +15 -0
  136. slidge_whatsapp/vendor/golang.org/x/net/http2/config_go126.go +15 -0
  137. slidge_whatsapp/vendor/golang.org/x/net/http2/frame.go +24 -1
  138. slidge_whatsapp/vendor/golang.org/x/net/http2/http2.go +0 -1
  139. slidge_whatsapp/vendor/golang.org/x/net/http2/server.go +35 -26
  140. slidge_whatsapp/vendor/golang.org/x/net/http2/transport.go +4 -2
  141. slidge_whatsapp/vendor/golang.org/x/net/http2/writesched.go +2 -0
  142. slidge_whatsapp/vendor/golang.org/x/net/http2/{writesched_priority.go → writesched_priority_rfc7540.go} +52 -52
  143. slidge_whatsapp/vendor/golang.org/x/net/http2/writesched_priority_rfc9128.go +209 -0
  144. slidge_whatsapp/vendor/golang.org/x/net/http2/writesched_roundrobin.go +1 -1
  145. slidge_whatsapp/vendor/golang.org/x/net/internal/httpcommon/request.go +2 -2
  146. slidge_whatsapp/vendor/golang.org/x/net/internal/socks/socks.go +1 -1
  147. slidge_whatsapp/vendor/golang.org/x/sys/unix/affinity_linux.go +9 -0
  148. slidge_whatsapp/vendor/golang.org/x/sys/unix/fdset.go +1 -3
  149. slidge_whatsapp/vendor/golang.org/x/sys/unix/ifreq_linux.go +1 -3
  150. slidge_whatsapp/vendor/golang.org/x/sys/unix/mkall.sh +1 -0
  151. slidge_whatsapp/vendor/golang.org/x/sys/unix/syscall_linux.go +1 -3
  152. slidge_whatsapp/vendor/golang.org/x/sys/unix/syscall_netbsd.go +17 -0
  153. slidge_whatsapp/vendor/golang.org/x/sys/windows/syscall_windows.go +2 -0
  154. slidge_whatsapp/vendor/golang.org/x/sys/windows/types_windows.go +16 -0
  155. slidge_whatsapp/vendor/golang.org/x/sys/windows/zsyscall_windows.go +18 -0
  156. slidge_whatsapp/vendor/golang.org/x/text/unicode/bidi/core.go +2 -9
  157. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/filedesc/desc.go +35 -17
  158. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go +14 -0
  159. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go +20 -0
  160. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/version/version.go +1 -1
  161. slidge_whatsapp/vendor/modules.txt +15 -13
  162. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.4.dist-info}/METADATA +4 -3
  163. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.4.dist-info}/RECORD +166 -138
  164. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.4.dist-info}/WHEEL +1 -1
  165. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waBotMetadata/WABotMetadata.pb.go +0 -5156
  166. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.4.dist-info}/entry_points.txt +0 -0
  167. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.4.dist-info/licenses}/LICENSE +0 -0
@@ -307,6 +307,9 @@ message WebMessageInfo {
307
307
  repeated string statusMentionSources = 71;
308
308
  repeated Citation supportAiCitations = 72;
309
309
  optional string botTargetID = 73;
310
+ optional GroupHistoryIndividualMessageInfo groupHistoryIndividualMessageInfo = 74;
311
+ optional GroupHistoryBundleInfo groupHistoryBundleInfo = 75;
312
+ optional InteractiveMessageAdditionalMetadata interactiveMessageAdditionalMetadata = 76;
310
313
  }
311
314
 
312
315
  message PaymentInfo {
@@ -468,6 +471,18 @@ message MessageAddOn {
468
471
  optional LegacyMessage legacyMessage = 8;
469
472
  }
470
473
 
474
+ message GroupHistoryBundleInfo {
475
+ enum ProcessState {
476
+ NOT_INJECTED = 0;
477
+ INJECTED = 1;
478
+ INJECTED_PARTIAL = 2;
479
+ INJECTION_FAILED = 3;
480
+ }
481
+
482
+ optional WAWebProtobufsE2E.MessageHistoryBundle deprecatedMessageHistoryBundle = 1;
483
+ optional ProcessState processState = 2;
484
+ }
485
+
471
486
  message CommentMetadata {
472
487
  optional WACommon.MessageKey commentParentKey = 1;
473
488
  optional uint32 replyCount = 2;
@@ -535,6 +550,10 @@ message PollAdditionalMetadata {
535
550
  optional bool pollInvalidated = 1;
536
551
  }
537
552
 
553
+ message InteractiveMessageAdditionalMetadata {
554
+ optional bool isGalaxyFlowCompleted = 1;
555
+ }
556
+
538
557
  message EventAdditionalMetadata {
539
558
  optional bool isStale = 1;
540
559
  }
@@ -579,3 +598,8 @@ message Citation {
579
598
  required string cmsID = 3;
580
599
  required string imageURL = 4;
581
600
  }
601
+
602
+ message GroupHistoryIndividualMessageInfo {
603
+ optional WACommon.MessageKey bundleMessageKey = 1;
604
+ optional bool editedAfterReceivedAsHistory = 2;
605
+ }
@@ -101,6 +101,14 @@ func (cli *Client) parseReceipt(node *waBinary.Node) (*events.Receipt, error) {
101
101
  return &receipt, nil
102
102
  }
103
103
 
104
+ func (cli *Client) backgroundIfAsyncAck(fn func()) {
105
+ if cli.SynchronousAck {
106
+ fn()
107
+ } else {
108
+ go fn()
109
+ }
110
+ }
111
+
104
112
  func (cli *Client) maybeDeferredAck(ctx context.Context, node *waBinary.Node) func(cancelled ...*bool) {
105
113
  if cli.SynchronousAck {
106
114
  return func(cancelled ...*bool) {
@@ -113,15 +121,31 @@ func (cli *Client) maybeDeferredAck(ctx context.Context, node *waBinary.Node) fu
113
121
  Msg("Not sending ack for node")
114
122
  return
115
123
  }
116
- cli.sendAck(node)
124
+ cli.sendAck(node, 0)
117
125
  }
118
126
  } else {
119
- go cli.sendAck(node)
127
+ go cli.sendAck(node, 0)
120
128
  return func(...*bool) {}
121
129
  }
122
130
  }
123
131
 
124
- func (cli *Client) sendAck(node *waBinary.Node) {
132
+ const (
133
+ NackParsingError = 487
134
+ NackUnrecognizedStanza = 488
135
+ NackUnrecognizedStanzaClass = 489
136
+ NackUnrecognizedStanzaType = 490
137
+ NackInvalidProtobuf = 491
138
+ NackInvalidHostedCompanionStanza = 493
139
+ NackMissingMessageSecret = 495
140
+ NackSignalErrorOldCounter = 496
141
+ NackMessageDeletedOnPeer = 499
142
+ NackUnhandledError = 500
143
+ NackUnsupportedAdminRevoke = 550
144
+ NackUnsupportedLIDGroup = 551
145
+ NackDBOperationFailed = 552
146
+ )
147
+
148
+ func (cli *Client) sendAck(node *waBinary.Node, error int) {
125
149
  attrs := waBinary.Attrs{
126
150
  "class": node.Tag,
127
151
  "id": node.Attrs["id"],
@@ -145,6 +169,9 @@ func (cli *Client) sendAck(node *waBinary.Node) {
145
169
  if receiptType, ok := node.Attrs["type"]; node.Tag != "message" && ok {
146
170
  attrs["type"] = receiptType
147
171
  }
172
+ if error != 0 {
173
+ attrs["error"] = error
174
+ }
148
175
  err := cli.sendNode(waBinary.Node{
149
176
  Tag: "ack",
150
177
  Attrs: attrs,
@@ -233,24 +260,30 @@ func (cli *Client) SetForceActiveDeliveryReceipts(active bool) {
233
260
  }
234
261
  }
235
262
 
236
- func (cli *Client) sendMessageReceipt(info *types.MessageInfo) {
263
+ func buildBaseReceipt(id string, node *waBinary.Node) waBinary.Attrs {
237
264
  attrs := waBinary.Attrs{
238
- "id": info.ID,
265
+ "id": id,
266
+ "to": node.Attrs["from"],
239
267
  }
268
+ if recipient, ok := node.Attrs["recipient"]; ok {
269
+ attrs["recipient"] = recipient
270
+ }
271
+ if participant, ok := node.Attrs["participant"]; ok {
272
+ attrs["participant"] = participant
273
+ }
274
+ return attrs
275
+ }
276
+
277
+ func (cli *Client) sendMessageReceipt(info *types.MessageInfo, node *waBinary.Node) {
278
+ attrs := buildBaseReceipt(info.ID, node)
240
279
  if info.IsFromMe {
241
280
  attrs["type"] = string(types.ReceiptTypeSender)
281
+ if info.Type == "peer_msg" {
282
+ attrs["type"] = string(types.ReceiptTypePeerMsg)
283
+ }
242
284
  } else if cli.sendActiveReceipts.Load() == 0 {
243
285
  attrs["type"] = string(types.ReceiptTypeInactive)
244
286
  }
245
- attrs["to"] = info.Chat
246
- if info.IsGroup {
247
- attrs["participant"] = info.Sender
248
- } else if info.IsFromMe {
249
- attrs["recipient"] = info.Sender
250
- } else {
251
- // Override the to attribute with the JID version with a device number
252
- attrs["to"] = info.Sender
253
- }
254
287
  err := cli.sendNode(waBinary.Node{
255
288
  Tag: "receipt",
256
289
  Attrs: attrs,
@@ -98,6 +98,7 @@ type infoQuery struct {
98
98
  To types.JID
99
99
  Target types.JID
100
100
  ID string
101
+ SMaxID string
101
102
  Content interface{}
102
103
 
103
104
  Timeout time.Duration
@@ -118,6 +119,9 @@ func (cli *Client) sendIQAsyncAndGetData(query *infoQuery) (<-chan *waBinary.Nod
118
119
  "xmlns": query.Namespace,
119
120
  "type": string(query.Type),
120
121
  }
122
+ if query.SMaxID != "" {
123
+ attrs["smax_id"] = query.SMaxID
124
+ }
121
125
  if !query.To.IsEmpty() {
122
126
  attrs["to"] = query.To
123
127
  }
@@ -157,8 +157,7 @@ func (cli *Client) handleRetryReceipt(ctx context.Context, receipt *events.Recei
157
157
  signalSKDMessage, err := builder.Create(ctx, senderKeyName)
158
158
  if err != nil {
159
159
  cli.Log.Warnf("Failed to create sender key distribution message to include in retry of %s in %s to %s: %v", messageID, receipt.Chat, receipt.Sender, err)
160
- }
161
- if msg.wa != nil {
160
+ } else if msg.wa != nil {
162
161
  msg.wa.SenderKeyDistributionMessage = &waE2E.SenderKeyDistributionMessage{
163
162
  GroupID: proto.String(receipt.Chat.String()),
164
163
  AxolotlSenderKeyDistributionMessage: signalSKDMessage.Serialize(),
@@ -252,7 +251,7 @@ func (cli *Client) handleRetryReceipt(ctx context.Context, receipt *events.Recei
252
251
  encryptionIdentity = lidForPN
253
252
  }
254
253
  }
255
- encrypted, includeDeviceIdentity, err = cli.encryptMessageForDevice(ctx, plaintext, encryptionIdentity, bundle, encAttrs)
254
+ encrypted, includeDeviceIdentity, err = cli.encryptMessageForDevice(ctx, plaintext, encryptionIdentity, bundle, encAttrs, nil)
256
255
  } else {
257
256
  encrypted, err = cli.encryptMessageForDeviceV3(ctx, &waMsgTransport.MessageTransport_Payload{
258
257
  ApplicationPayload: &waCommon.SubProtocol{
@@ -408,16 +407,10 @@ func (cli *Client) sendRetryReceipt(ctx context.Context, node *waBinary.Node, in
408
407
 
409
408
  var registrationIDBytes [4]byte
410
409
  binary.BigEndian.PutUint32(registrationIDBytes[:], cli.Store.RegistrationID)
411
- attrs := waBinary.Attrs{
412
- "id": id,
413
- "type": "retry",
414
- "to": node.Attrs["from"],
415
- }
416
- if recipient, ok := node.Attrs["recipient"]; ok {
417
- attrs["recipient"] = recipient
418
- }
419
- if participant, ok := node.Attrs["participant"]; ok {
420
- attrs["participant"] = participant
410
+ attrs := buildBaseReceipt(info.ID, node)
411
+ attrs["type"] = "retry"
412
+ if info.Type == "peer_msg" && info.IsFromMe {
413
+ attrs["category"] = "peer"
421
414
  }
422
415
  payload := waBinary.Node{
423
416
  Tag: "receipt",
@@ -14,6 +14,7 @@ import (
14
14
  "encoding/hex"
15
15
  "errors"
16
16
  "fmt"
17
+ "slices"
17
18
  "sort"
18
19
  "strconv"
19
20
  "strings"
@@ -29,7 +30,7 @@ import (
29
30
  "google.golang.org/protobuf/proto"
30
31
 
31
32
  waBinary "go.mau.fi/whatsmeow/binary"
32
- "go.mau.fi/whatsmeow/proto/waBotMetadata"
33
+ "go.mau.fi/whatsmeow/proto/waAICommon"
33
34
  "go.mau.fi/whatsmeow/proto/waCommon"
34
35
  "go.mau.fi/whatsmeow/proto/waE2E"
35
36
  "go.mau.fi/whatsmeow/types"
@@ -74,7 +75,8 @@ func GenerateMessageID() types.MessageID {
74
75
  }
75
76
 
76
77
  type MessageDebugTimings struct {
77
- Queue time.Duration
78
+ LIDFetch time.Duration
79
+ Queue time.Duration
78
80
 
79
81
  Marshal time.Duration
80
82
  GetParticipants time.Duration
@@ -88,6 +90,9 @@ type MessageDebugTimings struct {
88
90
  }
89
91
 
90
92
  func (mdt MessageDebugTimings) MarshalZerologObject(evt *zerolog.Event) {
93
+ if mdt.LIDFetch != 0 {
94
+ evt.Dur("lid_fetch", mdt.LIDFetch)
95
+ }
91
96
  evt.Dur("queue", mdt.Queue)
92
97
  evt.Dur("marshal", mdt.Marshal)
93
98
  if mdt.GetParticipants != 0 {
@@ -149,6 +154,8 @@ type SendRequestExtra struct {
149
154
  MediaHandle string
150
155
 
151
156
  Meta *types.MsgMetaInfo
157
+ // use this only if you know what you are doing
158
+ AdditionalNodes *[]waBinary.Node
152
159
  }
153
160
 
154
161
  // SendMessage sends the given message.
@@ -238,7 +245,7 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, message *waE2E
238
245
 
239
246
  if isBotMode {
240
247
  if message.MessageContextInfo.BotMetadata == nil {
241
- message.MessageContextInfo.BotMetadata = &waBotMetadata.BotMetadata{
248
+ message.MessageContextInfo.BotMetadata = &waAICommon.BotMetadata{
242
249
  PersonaID: proto.String("867051314767696$760019659443059"),
243
250
  }
244
251
  }
@@ -272,7 +279,11 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, message *waE2E
272
279
  return
273
280
  }
274
281
 
275
- participantNodes, _ := cli.encryptMessageForDevices(ctx, []types.JID{req.InlineBotJID}, resp.ID, messagePlaintext, nil, waBinary.Attrs{})
282
+ var participantNodes []waBinary.Node
283
+ participantNodes, _, err = cli.encryptMessageForDevices(ctx, []types.JID{req.InlineBotJID}, resp.ID, messagePlaintext, nil, waBinary.Attrs{})
284
+ if err != nil {
285
+ return
286
+ }
276
287
  extraParams.botNode = &waBinary.Node{
277
288
  Tag: "bot",
278
289
  Attrs: nil,
@@ -311,6 +322,28 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, message *waE2E
311
322
  resp.DebugTimings.GetParticipants = time.Since(start)
312
323
  } else if to.Server == types.HiddenUserServer {
313
324
  ownID = cli.getOwnLID()
325
+ } else if to.Server == types.DefaultUserServer && cli.Store.LIDMigrationTimestamp > 0 {
326
+ start := time.Now()
327
+ var toLID types.JID
328
+ toLID, err = cli.Store.LIDs.GetLIDForPN(ctx, to)
329
+ if err != nil {
330
+ err = fmt.Errorf("failed to get LID for PN %s: %w", to, err)
331
+ return
332
+ } else if toLID.IsEmpty() {
333
+ var info map[types.JID]types.UserInfo
334
+ info, err = cli.GetUserInfo([]types.JID{to})
335
+ if err != nil {
336
+ err = fmt.Errorf("failed to get user info for %s to fill LID cache: %w", to, err)
337
+ return
338
+ } else if toLID = info[to].LID; toLID.IsEmpty() {
339
+ err = fmt.Errorf("no LID found for %s from server", to)
340
+ return
341
+ }
342
+ }
343
+ resp.DebugTimings.LIDFetch = time.Since(start)
344
+ cli.Log.Debugf("Replacing SendMessage destination with LID as migration timestamp is set %s -> %s", to, toLID)
345
+ to = toLID
346
+ ownID = cli.getOwnLID()
314
347
  }
315
348
  if req.Meta != nil {
316
349
  extraParams.metaNode = &waBinary.Node{
@@ -326,10 +359,16 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, message *waE2E
326
359
  }
327
360
  }
328
361
 
362
+ if req.AdditionalNodes != nil {
363
+ extraParams.additionalNodes = req.AdditionalNodes
364
+ }
365
+
329
366
  resp.Sender = ownID
330
367
 
331
368
  start := time.Now()
332
369
  // Sending multiple messages at a time can cause weird issues and makes it harder to retry safely
370
+ // This is also required for the session prefetching that makes group sends faster
371
+ // (everything will explode if you send a message to the same user twice in parallel)
333
372
  cli.messageSendLock.Lock()
334
373
  resp.DebugTimings.Queue = time.Since(start)
335
374
  defer cli.messageSendLock.Unlock()
@@ -582,6 +621,9 @@ func ParseDisappearingTimerString(val string) (time.Duration, bool) {
582
621
  func (cli *Client) SetDisappearingTimer(chat types.JID, timer time.Duration, settingTS time.Time) (err error) {
583
622
  switch chat.Server {
584
623
  case types.DefaultUserServer, types.HiddenUserServer:
624
+ if settingTS.IsZero() {
625
+ settingTS = time.Now()
626
+ }
585
627
  _, err = cli.SendMessage(context.TODO(), chat, &waE2E.Message{
586
628
  ProtocolMessage: &waE2E.ProtocolMessage{
587
629
  Type: waE2E.ProtocolMessage_EPHEMERAL_SETTING.Enum(),
@@ -673,9 +715,10 @@ func (cli *Client) sendNewsletter(
673
715
  }
674
716
 
675
717
  type nodeExtraParams struct {
676
- botNode *waBinary.Node
677
- metaNode *waBinary.Node
678
- addressingMode types.AddressingMode
718
+ botNode *waBinary.Node
719
+ metaNode *waBinary.Node
720
+ additionalNodes *[]waBinary.Node
721
+ addressingMode types.AddressingMode
679
722
  }
680
723
 
681
724
  func (cli *Client) sendGroup(
@@ -1001,7 +1044,7 @@ func (cli *Client) preparePeerMessageNode(
1001
1044
  }
1002
1045
  }
1003
1046
  start = time.Now()
1004
- encrypted, isPreKey, err := cli.encryptMessageForDevice(ctx, plaintext, encryptionIdentity, nil, nil)
1047
+ encrypted, isPreKey, err := cli.encryptMessageForDevice(ctx, plaintext, encryptionIdentity, nil, nil, nil)
1005
1048
  timings.PeerEncrypt = time.Since(start)
1006
1049
  if err != nil {
1007
1050
  return nil, fmt.Errorf("failed to encrypt peer message for %s: %v", to, err)
@@ -1047,6 +1090,9 @@ func (cli *Client) getMessageContent(
1047
1090
  if extraParams.metaNode != nil {
1048
1091
  content = append(content, *extraParams.metaNode)
1049
1092
  }
1093
+ if extraParams.additionalNodes != nil {
1094
+ content = append(content, *extraParams.additionalNodes...)
1095
+ }
1050
1096
 
1051
1097
  if buttonType := getButtonTypeFromMessage(message); buttonType != "" {
1052
1098
  content = append(content, waBinary.Node{
@@ -1077,6 +1123,12 @@ func (cli *Client) prepareMessageNode(
1077
1123
  return nil, nil, fmt.Errorf("failed to get device list: %w", err)
1078
1124
  }
1079
1125
 
1126
+ if to.Server == types.GroupServer {
1127
+ allDevices = slices.DeleteFunc(allDevices, func(jid types.JID) bool {
1128
+ return jid.Server == types.HostedServer || jid.Server == types.HostedLIDServer
1129
+ })
1130
+ }
1131
+
1080
1132
  msgType := getTypeFromMessage(message)
1081
1133
  encAttrs := waBinary.Attrs{}
1082
1134
  // Only include encMediaType for 1:1 messages (groups don't have a device-sent message plaintext)
@@ -1101,10 +1153,13 @@ func (cli *Client) prepareMessageNode(
1101
1153
  }
1102
1154
 
1103
1155
  start = time.Now()
1104
- participantNodes, includeIdentity := cli.encryptMessageForDevices(
1156
+ participantNodes, includeIdentity, err := cli.encryptMessageForDevices(
1105
1157
  ctx, allDevices, id, plaintext, dsmPlaintext, encAttrs,
1106
1158
  )
1107
1159
  timings.PeerEncrypt = time.Since(start)
1160
+ if err != nil {
1161
+ return nil, nil, err
1162
+ }
1108
1163
  participantNode := waBinary.Node{
1109
1164
  Tag: "participants",
1110
1165
  Content: participantNodes,
@@ -1162,41 +1217,70 @@ func (cli *Client) encryptMessageForDevices(
1162
1217
  id string,
1163
1218
  msgPlaintext, dsmPlaintext []byte,
1164
1219
  encAttrs waBinary.Attrs,
1165
- ) ([]waBinary.Node, bool) {
1220
+ ) ([]waBinary.Node, bool, error) {
1166
1221
  ownJID := cli.getOwnID()
1167
1222
  ownLID := cli.getOwnLID()
1168
1223
  includeIdentity := false
1169
1224
  participantNodes := make([]waBinary.Node, 0, len(allDevices))
1170
- var retryDevices, retryEncryptionIdentities []types.JID
1225
+
1226
+ var pnDevices []types.JID
1171
1227
  for _, jid := range allDevices {
1172
- plaintext := msgPlaintext
1173
- if (jid.User == ownJID.User || jid.User == ownLID.User) && dsmPlaintext != nil {
1174
- if jid == ownJID || jid == ownLID {
1175
- continue
1176
- }
1177
- plaintext = dsmPlaintext
1228
+ if jid.Server == types.DefaultUserServer {
1229
+ pnDevices = append(pnDevices, jid)
1178
1230
  }
1231
+ }
1232
+ lidMappings, err := cli.Store.LIDs.GetManyLIDsForPNs(ctx, pnDevices)
1233
+ if err != nil {
1234
+ return nil, false, fmt.Errorf("failed to fetch LID mappings: %w", err)
1235
+ }
1236
+
1237
+ encryptionIdentities := make(map[types.JID]types.JID, len(allDevices))
1238
+ sessionAddressToJID := make(map[string]types.JID, len(allDevices))
1239
+ sessionAddresses := make([]string, 0, len(allDevices))
1240
+ for _, jid := range allDevices {
1179
1241
  encryptionIdentity := jid
1180
1242
  if jid.Server == types.DefaultUserServer {
1181
- lidForPN, err := cli.Store.LIDs.GetLIDForPN(ctx, jid)
1182
- if err != nil {
1183
- cli.Log.Warnf("Failed to get LID for %s: %v", jid, err)
1184
- } else if !lidForPN.IsEmpty() {
1243
+ // TODO query LID from server for missing entries
1244
+ if lidForPN, ok := lidMappings[jid]; ok && !lidForPN.IsEmpty() {
1185
1245
  cli.migrateSessionStore(ctx, jid, lidForPN)
1186
1246
  encryptionIdentity = lidForPN
1187
1247
  }
1188
1248
  }
1249
+ encryptionIdentities[jid] = encryptionIdentity
1250
+ addr := encryptionIdentity.SignalAddress().String()
1251
+ sessionAddresses = append(sessionAddresses, addr)
1252
+ sessionAddressToJID[addr] = jid
1253
+ }
1254
+
1255
+ existingSessions, ctx, err := cli.Store.WithCachedSessions(ctx, sessionAddresses)
1256
+ if err != nil {
1257
+ return nil, false, fmt.Errorf("failed to prefetch sessions: %w", err)
1258
+ }
1259
+ var retryDevices []types.JID
1260
+ for addr, exists := range existingSessions {
1261
+ if !exists {
1262
+ retryDevices = append(retryDevices, sessionAddressToJID[addr])
1263
+ }
1264
+ }
1265
+ bundles := cli.fetchPreKeysNoError(ctx, retryDevices)
1189
1266
 
1267
+ for _, jid := range allDevices {
1268
+ plaintext := msgPlaintext
1269
+ if (jid.User == ownJID.User || jid.User == ownLID.User) && dsmPlaintext != nil {
1270
+ if jid == ownJID || jid == ownLID {
1271
+ continue
1272
+ }
1273
+ plaintext = dsmPlaintext
1274
+ }
1190
1275
  encrypted, isPreKey, err := cli.encryptMessageForDeviceAndWrap(
1191
- ctx, plaintext, jid, encryptionIdentity, nil, encAttrs,
1276
+ ctx, plaintext, jid, encryptionIdentities[jid], bundles[jid], encAttrs, existingSessions,
1192
1277
  )
1193
- if errors.Is(err, ErrNoSession) {
1194
- retryDevices = append(retryDevices, jid)
1195
- retryEncryptionIdentities = append(retryEncryptionIdentities, encryptionIdentity)
1196
- continue
1197
- } else if err != nil {
1278
+ if err != nil {
1198
1279
  // TODO return these errors if it's a fatal one (like context cancellation or database)
1199
1280
  cli.Log.Warnf("Failed to encrypt %s for %s: %v", id, jid, err)
1281
+ if ctx.Err() != nil {
1282
+ return nil, false, err
1283
+ }
1200
1284
  continue
1201
1285
  }
1202
1286
 
@@ -1205,37 +1289,11 @@ func (cli *Client) encryptMessageForDevices(
1205
1289
  includeIdentity = true
1206
1290
  }
1207
1291
  }
1208
- if len(retryDevices) > 0 {
1209
- bundles, err := cli.fetchPreKeys(ctx, retryDevices)
1210
- if err != nil {
1211
- cli.Log.Warnf("Failed to fetch prekeys for %v to retry encryption: %v", retryDevices, err)
1212
- } else {
1213
- for i, jid := range retryDevices {
1214
- resp := bundles[jid]
1215
- if resp.err != nil {
1216
- cli.Log.Warnf("Failed to fetch prekey for %s: %v", jid, resp.err)
1217
- continue
1218
- }
1219
- plaintext := msgPlaintext
1220
- if (jid.User == ownJID.User || jid.User == ownLID.User) && dsmPlaintext != nil {
1221
- plaintext = dsmPlaintext
1222
- }
1223
- encrypted, isPreKey, err := cli.encryptMessageForDeviceAndWrap(
1224
- ctx, plaintext, jid, retryEncryptionIdentities[i], resp.bundle, encAttrs,
1225
- )
1226
- if err != nil {
1227
- // TODO return these errors if it's a fatal one (like context cancellation or database)
1228
- cli.Log.Warnf("Failed to encrypt %s for %s (retry): %v", id, jid, err)
1229
- continue
1230
- }
1231
- participantNodes = append(participantNodes, *encrypted)
1232
- if isPreKey {
1233
- includeIdentity = true
1234
- }
1235
- }
1236
- }
1292
+ err = cli.Store.PutCachedSessions(ctx)
1293
+ if err != nil {
1294
+ return nil, false, fmt.Errorf("failed to save cached sessions: %w", err)
1237
1295
  }
1238
- return participantNodes, includeIdentity
1296
+ return participantNodes, includeIdentity, nil
1239
1297
  }
1240
1298
 
1241
1299
  func (cli *Client) encryptMessageForDeviceAndWrap(
@@ -1245,9 +1303,10 @@ func (cli *Client) encryptMessageForDeviceAndWrap(
1245
1303
  encryptionIdentity types.JID,
1246
1304
  bundle *prekey.Bundle,
1247
1305
  encAttrs waBinary.Attrs,
1306
+ existingSessions map[string]bool,
1248
1307
  ) (*waBinary.Node, bool, error) {
1249
1308
  node, includeDeviceIdentity, err := cli.encryptMessageForDevice(
1250
- ctx, plaintext, encryptionIdentity, bundle, encAttrs,
1309
+ ctx, plaintext, encryptionIdentity, bundle, encAttrs, existingSessions,
1251
1310
  )
1252
1311
  if err != nil {
1253
1312
  return nil, false, err
@@ -1271,6 +1330,7 @@ func (cli *Client) encryptMessageForDevice(
1271
1330
  to types.JID,
1272
1331
  bundle *prekey.Bundle,
1273
1332
  extraAttrs waBinary.Attrs,
1333
+ existingSessions map[string]bool,
1274
1334
  ) (*waBinary.Node, bool, error) {
1275
1335
  builder := session.NewBuilderFromSignal(cli.Store, to.SignalAddress(), pbSerializer)
1276
1336
  if bundle != nil {
@@ -1287,10 +1347,18 @@ func (cli *Client) encryptMessageForDevice(
1287
1347
  if err != nil {
1288
1348
  return nil, false, fmt.Errorf("failed to process prekey bundle: %w", err)
1289
1349
  }
1290
- } else if contains, err := cli.Store.ContainsSession(ctx, to.SignalAddress()); err != nil {
1291
- return nil, false, err
1292
- } else if !contains {
1293
- return nil, false, fmt.Errorf("%w with %s", ErrNoSession, to.SignalAddress().String())
1350
+ } else {
1351
+ sessionExists, checked := existingSessions[to.SignalAddress().String()]
1352
+ if !checked {
1353
+ var err error
1354
+ sessionExists, err = cli.Store.ContainsSession(ctx, to.SignalAddress())
1355
+ if err != nil {
1356
+ return nil, false, err
1357
+ }
1358
+ }
1359
+ if !sessionExists {
1360
+ return nil, false, fmt.Errorf("%w with %s", ErrNoSession, to.SignalAddress().String())
1361
+ }
1294
1362
  }
1295
1363
  cipher := session.NewCipher(builder, to.SignalAddress())
1296
1364
  ciphertext, err := cipher.Encrypt(ctx, padMessage(plaintext))
@@ -468,7 +468,10 @@ func (cli *Client) prepareMessageNodeV3(
468
468
  }
469
469
 
470
470
  start = time.Now()
471
- participantNodes := cli.encryptMessageForDevicesV3(ctx, allDevices, ownID, id, payload, skdm, dsm, encAttrs)
471
+ participantNodes, err := cli.encryptMessageForDevicesV3(ctx, allDevices, ownID, id, payload, skdm, dsm, encAttrs)
472
+ if err != nil {
473
+ return nil, nil, err
474
+ }
472
475
  timings.PeerEncrypt = time.Since(start)
473
476
  content := make([]waBinary.Node, 0, 4)
474
477
  content = append(content, waBinary.Node{
@@ -518,9 +521,28 @@ func (cli *Client) encryptMessageForDevicesV3(
518
521
  skdm *waMsgTransport.MessageTransport_Protocol_Ancillary_SenderKeyDistributionMessage,
519
522
  dsm *waMsgTransport.MessageTransport_Protocol_Integral_DeviceSentMessage,
520
523
  encAttrs waBinary.Attrs,
521
- ) []waBinary.Node {
524
+ ) ([]waBinary.Node, error) {
522
525
  participantNodes := make([]waBinary.Node, 0, len(allDevices))
526
+
527
+ sessionAddressToJID := make(map[string]types.JID, len(allDevices))
528
+ sessionAddresses := make([]string, 0, len(allDevices))
529
+ for _, jid := range allDevices {
530
+ addr := jid.SignalAddress().String()
531
+ sessionAddresses = append(sessionAddresses, addr)
532
+ sessionAddressToJID[addr] = jid
533
+ }
534
+ existingSessions, ctx, err := cli.Store.WithCachedSessions(ctx, sessionAddresses)
535
+ if err != nil {
536
+ return nil, fmt.Errorf("failed to prefetch sessions: %w", err)
537
+ }
523
538
  var retryDevices []types.JID
539
+ for addr, exists := range existingSessions {
540
+ if !exists {
541
+ retryDevices = append(retryDevices, sessionAddressToJID[addr])
542
+ }
543
+ }
544
+ bundles := cli.fetchPreKeysNoError(ctx, retryDevices)
545
+
524
546
  for _, jid := range allDevices {
525
547
  var dsmForDevice *waMsgTransport.MessageTransport_Protocol_Integral_DeviceSentMessage
526
548
  if jid.User == ownID.User {
@@ -529,43 +551,22 @@ func (cli *Client) encryptMessageForDevicesV3(
529
551
  }
530
552
  dsmForDevice = dsm
531
553
  }
532
- encrypted, err := cli.encryptMessageForDeviceAndWrapV3(ctx, payload, skdm, dsmForDevice, jid, nil, encAttrs)
533
- if errors.Is(err, ErrNoSession) {
534
- retryDevices = append(retryDevices, jid)
535
- continue
536
- } else if err != nil {
554
+ encrypted, err := cli.encryptMessageForDeviceAndWrapV3(ctx, payload, skdm, dsmForDevice, jid, bundles[jid], encAttrs)
555
+ if err != nil {
537
556
  // TODO return these errors if it's a fatal one (like context cancellation or database)
538
557
  cli.Log.Warnf("Failed to encrypt %s for %s: %v", id, jid, err)
558
+ if ctx.Err() != nil {
559
+ return nil, err
560
+ }
539
561
  continue
540
562
  }
541
563
  participantNodes = append(participantNodes, *encrypted)
542
564
  }
543
- if len(retryDevices) > 0 {
544
- bundles, err := cli.fetchPreKeys(ctx, retryDevices)
545
- if err != nil {
546
- cli.Log.Warnf("Failed to fetch prekeys for %v to retry encryption: %v", retryDevices, err)
547
- } else {
548
- for _, jid := range retryDevices {
549
- resp := bundles[jid]
550
- if resp.err != nil {
551
- cli.Log.Warnf("Failed to fetch prekey for %s: %v", jid, resp.err)
552
- continue
553
- }
554
- var dsmForDevice *waMsgTransport.MessageTransport_Protocol_Integral_DeviceSentMessage
555
- if jid.User == ownID.User {
556
- dsmForDevice = dsm
557
- }
558
- encrypted, err := cli.encryptMessageForDeviceAndWrapV3(ctx, payload, skdm, dsmForDevice, jid, resp.bundle, encAttrs)
559
- if err != nil {
560
- // TODO return these errors if it's a fatal one (like context cancellation or database)
561
- cli.Log.Warnf("Failed to encrypt %s for %s (retry): %v", id, jid, err)
562
- continue
563
- }
564
- participantNodes = append(participantNodes, *encrypted)
565
- }
566
- }
565
+ err = cli.Store.PutCachedSessions(ctx)
566
+ if err != nil {
567
+ return nil, fmt.Errorf("failed to save cached sessions: %w", err)
567
568
  }
568
- return participantNodes
569
+ return participantNodes, nil
569
570
  }
570
571
 
571
572
  func (cli *Client) encryptMessageForDeviceAndWrapV3(
@@ -76,7 +76,7 @@ func (vc WAVersionContainer) ProtoAppVersion() *waWa6.ClientPayload_UserAgent_Ap
76
76
  }
77
77
 
78
78
  // waVersion is the WhatsApp web client version
79
- var waVersion = WAVersionContainer{2, 3000, 1026436087}
79
+ var waVersion = WAVersionContainer{2, 3000, 1028259376}
80
80
 
81
81
  // waVersionHash is the md5 hash of a dot-separated waVersion
82
82
  var waVersionHash [16]byte