slidge-whatsapp 0.3.0b0__cp312-cp312-manylinux_2_36_aarch64.whl → 0.3.1__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 (132) 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 +195 -195
  4. slidge_whatsapp/generated/_whatsapp.cpython-312-aarch64-linux-gnu.so +0 -0
  5. slidge_whatsapp/generated/build.py +148 -148
  6. slidge_whatsapp/generated/whatsapp.c +1542 -1542
  7. slidge_whatsapp/generated/whatsapp.go +1210 -1210
  8. slidge_whatsapp/generated/whatsapp.py +1355 -1355
  9. slidge_whatsapp/generated/whatsapp_go.h +195 -195
  10. slidge_whatsapp/go.mod +5 -5
  11. slidge_whatsapp/go.sum +14 -14
  12. slidge_whatsapp/session.go +4 -4
  13. slidge_whatsapp/vendor/github.com/ebitengine/purego/README.md +21 -5
  14. slidge_whatsapp/vendor/github.com/ebitengine/purego/abi_loong64.h +60 -0
  15. slidge_whatsapp/vendor/github.com/ebitengine/purego/cgo.go +1 -1
  16. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlerror.go +1 -1
  17. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlfcn.go +1 -1
  18. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlfcn_netbsd.go +15 -0
  19. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlfcn_nocgo_netbsd.go +9 -0
  20. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlfcn_stubs.s +1 -1
  21. slidge_whatsapp/vendor/github.com/ebitengine/purego/func.go +113 -60
  22. slidge_whatsapp/vendor/github.com/ebitengine/purego/gen.go +6 -0
  23. slidge_whatsapp/vendor/github.com/ebitengine/purego/go_runtime.go +1 -1
  24. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/cgo/dlfcn_cgo_unix.go +2 -2
  25. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/cgo/syscall_cgo_unix.go +2 -2
  26. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/abi_loong64.h +60 -0
  27. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/asm_loong64.s +40 -0
  28. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/callbacks.go +1 -1
  29. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/doc.go +1 -1
  30. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_libinit.go +1 -1
  31. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_loong64.go +92 -0
  32. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_netbsd.go +106 -0
  33. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_setenv.go +1 -1
  34. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_util.go +1 -1
  35. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/iscgo.go +1 -1
  36. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo.go +1 -1
  37. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_darwin.go +4 -0
  38. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_freebsd.go +4 -0
  39. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_linux.go +4 -0
  40. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_netbsd.go +26 -0
  41. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/netbsd.go +23 -0
  42. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/setenv.go +1 -1
  43. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols.go +11 -1
  44. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_darwin.go +1 -0
  45. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_freebsd.go +1 -0
  46. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_linux.go +1 -0
  47. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_netbsd.go +30 -0
  48. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_loong64.s +71 -0
  49. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_stubs.s +5 -1
  50. slidge_whatsapp/vendor/github.com/ebitengine/purego/nocgo.go +1 -1
  51. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_amd64.go +8 -4
  52. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_arm64.go +16 -6
  53. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_loong64.go +190 -0
  54. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_other.go +6 -2
  55. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_amd64.s +1 -1
  56. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_arm64.s +1 -1
  57. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_loong64.s +96 -0
  58. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_unix_arm64.s +1 -1
  59. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_unix_loong64.s +75 -0
  60. slidge_whatsapp/vendor/github.com/ebitengine/purego/syscall.go +6 -3
  61. slidge_whatsapp/vendor/github.com/ebitengine/purego/syscall_cgo_linux.go +3 -3
  62. slidge_whatsapp/vendor/github.com/ebitengine/purego/syscall_sysv.go +13 -10
  63. slidge_whatsapp/vendor/github.com/ebitengine/purego/syscall_windows.go +1 -1
  64. slidge_whatsapp/vendor/github.com/ebitengine/purego/zcallback_amd64.s +2002 -2002
  65. slidge_whatsapp/vendor/github.com/ebitengine/purego/zcallback_arm64.s +4002 -4002
  66. slidge_whatsapp/vendor/github.com/ebitengine/purego/zcallback_loong64.s +4014 -0
  67. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/log.go +1 -0
  68. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/module.go +118 -0
  69. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/upgradetable.go +0 -34
  70. slidge_whatsapp/vendor/go.mau.fi/util/exbytes/string.go +20 -0
  71. slidge_whatsapp/vendor/go.mau.fi/util/exbytes/writer.go +78 -0
  72. slidge_whatsapp/vendor/go.mau.fi/util/exslices/cast.go +42 -0
  73. slidge_whatsapp/vendor/go.mau.fi/util/exslices/chunk.go +28 -0
  74. slidge_whatsapp/vendor/go.mau.fi/util/exslices/deduplicate.go +67 -0
  75. slidge_whatsapp/vendor/go.mau.fi/util/exslices/diff.go +63 -0
  76. slidge_whatsapp/vendor/go.mau.fi/util/exsync/event.go +15 -1
  77. slidge_whatsapp/vendor/go.mau.fi/util/random/string.go +47 -7
  78. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate/decode.go +1 -0
  79. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate/encode.go +34 -0
  80. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate/hash.go +1 -0
  81. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate.go +3 -0
  82. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/armadillomessage.go +1 -2
  83. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/call.go +6 -0
  84. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/errors.go +1 -0
  85. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/group.go +63 -42
  86. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/internals.go +14 -10
  87. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/message.go +45 -18
  88. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/msgsecret.go +23 -0
  89. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/notification.go +5 -1
  90. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/pair.go +3 -7
  91. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waAICommon/WAAICommon.pb.go +7747 -0
  92. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/{waBotMetadata/WABotMetadata.proto → waAICommon/WAAICommon.proto} +269 -9
  93. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waDeviceCapabilities/WAProtobufsDeviceCapabilities.pb.go +128 -14
  94. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waDeviceCapabilities/WAProtobufsDeviceCapabilities.proto +10 -0
  95. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.pb.go +3236 -4732
  96. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.proto +125 -273
  97. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waHistorySync/WAWebProtobufsHistorySync.pb.go +11 -2
  98. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waHistorySync/WAWebProtobufsHistorySync.proto +1 -0
  99. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waStatusAttributions/WAStatusAttributions.pb.go +220 -81
  100. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waStatusAttributions/WAStatusAttributions.proto +13 -0
  101. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.pb.go +705 -449
  102. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.proto +23 -0
  103. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWa6/WAWebProtobufsWa6.pb.go +78 -24
  104. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWa6/WAWebProtobufsWa6.proto +6 -0
  105. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.pb.go +516 -267
  106. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.proto +22 -0
  107. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/receipt.go +2 -0
  108. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/request.go +4 -0
  109. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/retry.go +2 -3
  110. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/send.go +110 -28
  111. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/clientpayload.go +1 -1
  112. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/noop.go +12 -0
  113. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/lidmap.go +82 -4
  114. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/store.go +112 -55
  115. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/00-latest-schema.sql +8 -7
  116. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/11-redacted-phone-contacts.sql +2 -0
  117. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/store.go +20 -0
  118. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/call.go +6 -5
  119. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/message.go +7 -1
  120. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/user.go +3 -0
  121. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/user.go +31 -2
  122. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/filedesc/desc.go +35 -17
  123. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go +14 -0
  124. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go +20 -0
  125. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/version/version.go +1 -1
  126. slidge_whatsapp/vendor/modules.txt +8 -6
  127. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.1.dist-info}/METADATA +4 -3
  128. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.1.dist-info}/RECORD +131 -107
  129. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.1.dist-info}/WHEEL +1 -1
  130. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waBotMetadata/WABotMetadata.pb.go +0 -5156
  131. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.1.dist-info}/entry_points.txt +0 -0
  132. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.1.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,17 @@ message MessageAddOn {
468
471
  optional LegacyMessage legacyMessage = 8;
469
472
  }
470
473
 
474
+ message GroupHistoryBundleInfo {
475
+ enum ProcessState {
476
+ NOT_DOWNLOADED = 0;
477
+ DOWNLOADED = 1;
478
+ DOWNLOAD_FAILED = 2;
479
+ }
480
+
481
+ optional WAWebProtobufsE2E.MessageHistoryBundle deprecatedMessageHistoryBundle = 1;
482
+ optional ProcessState processState = 2;
483
+ }
484
+
471
485
  message CommentMetadata {
472
486
  optional WACommon.MessageKey commentParentKey = 1;
473
487
  optional uint32 replyCount = 2;
@@ -535,6 +549,10 @@ message PollAdditionalMetadata {
535
549
  optional bool pollInvalidated = 1;
536
550
  }
537
551
 
552
+ message InteractiveMessageAdditionalMetadata {
553
+ optional bool isGalaxyFlowCompleted = 1;
554
+ }
555
+
538
556
  message EventAdditionalMetadata {
539
557
  optional bool isStale = 1;
540
558
  }
@@ -579,3 +597,7 @@ message Citation {
579
597
  required string cmsID = 3;
580
598
  required string imageURL = 4;
581
599
  }
600
+
601
+ message GroupHistoryIndividualMessageInfo {
602
+ optional WACommon.MessageKey bundleMessageKey = 1;
603
+ }
@@ -239,6 +239,8 @@ func (cli *Client) sendMessageReceipt(info *types.MessageInfo) {
239
239
  }
240
240
  if info.IsFromMe {
241
241
  attrs["type"] = string(types.ReceiptTypeSender)
242
+ } else if info.Type == "peer_msg" {
243
+ attrs["type"] = string(types.ReceiptTypePeerMsg)
242
244
  } else if cli.sendActiveReceipts.Load() == 0 {
243
245
  attrs["type"] = string(types.ReceiptTypeInactive)
244
246
  }
@@ -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{
@@ -29,7 +29,7 @@ import (
29
29
  "google.golang.org/protobuf/proto"
30
30
 
31
31
  waBinary "go.mau.fi/whatsmeow/binary"
32
- "go.mau.fi/whatsmeow/proto/waBotMetadata"
32
+ "go.mau.fi/whatsmeow/proto/waAICommon"
33
33
  "go.mau.fi/whatsmeow/proto/waCommon"
34
34
  "go.mau.fi/whatsmeow/proto/waE2E"
35
35
  "go.mau.fi/whatsmeow/types"
@@ -74,7 +74,8 @@ func GenerateMessageID() types.MessageID {
74
74
  }
75
75
 
76
76
  type MessageDebugTimings struct {
77
- Queue time.Duration
77
+ LIDFetch time.Duration
78
+ Queue time.Duration
78
79
 
79
80
  Marshal time.Duration
80
81
  GetParticipants time.Duration
@@ -88,6 +89,9 @@ type MessageDebugTimings struct {
88
89
  }
89
90
 
90
91
  func (mdt MessageDebugTimings) MarshalZerologObject(evt *zerolog.Event) {
92
+ if mdt.LIDFetch != 0 {
93
+ evt.Dur("lid_fetch", mdt.LIDFetch)
94
+ }
91
95
  evt.Dur("queue", mdt.Queue)
92
96
  evt.Dur("marshal", mdt.Marshal)
93
97
  if mdt.GetParticipants != 0 {
@@ -149,6 +153,8 @@ type SendRequestExtra struct {
149
153
  MediaHandle string
150
154
 
151
155
  Meta *types.MsgMetaInfo
156
+ // use this only if you know what you are doing
157
+ AdditionalNodes *[]waBinary.Node
152
158
  }
153
159
 
154
160
  // SendMessage sends the given message.
@@ -238,7 +244,7 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, message *waE2E
238
244
 
239
245
  if isBotMode {
240
246
  if message.MessageContextInfo.BotMetadata == nil {
241
- message.MessageContextInfo.BotMetadata = &waBotMetadata.BotMetadata{
247
+ message.MessageContextInfo.BotMetadata = &waAICommon.BotMetadata{
242
248
  PersonaID: proto.String("867051314767696$760019659443059"),
243
249
  }
244
250
  }
@@ -272,7 +278,11 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, message *waE2E
272
278
  return
273
279
  }
274
280
 
275
- participantNodes, _ := cli.encryptMessageForDevices(ctx, []types.JID{req.InlineBotJID}, resp.ID, messagePlaintext, nil, waBinary.Attrs{})
281
+ var participantNodes []waBinary.Node
282
+ participantNodes, _, err = cli.encryptMessageForDevices(ctx, []types.JID{req.InlineBotJID}, resp.ID, messagePlaintext, nil, waBinary.Attrs{})
283
+ if err != nil {
284
+ return
285
+ }
276
286
  extraParams.botNode = &waBinary.Node{
277
287
  Tag: "bot",
278
288
  Attrs: nil,
@@ -311,6 +321,28 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, message *waE2E
311
321
  resp.DebugTimings.GetParticipants = time.Since(start)
312
322
  } else if to.Server == types.HiddenUserServer {
313
323
  ownID = cli.getOwnLID()
324
+ } else if to.Server == types.DefaultUserServer && cli.Store.LIDMigrationTimestamp > 0 {
325
+ start := time.Now()
326
+ var toLID types.JID
327
+ toLID, err = cli.Store.LIDs.GetLIDForPN(ctx, to)
328
+ if err != nil {
329
+ err = fmt.Errorf("failed to get LID for PN %s: %w", to, err)
330
+ return
331
+ } else if toLID.IsEmpty() {
332
+ var info map[types.JID]types.UserInfo
333
+ info, err = cli.GetUserInfo([]types.JID{to})
334
+ if err != nil {
335
+ err = fmt.Errorf("failed to get user info for %s to fill LID cache: %w", to, err)
336
+ return
337
+ } else if toLID = info[to].LID; toLID.IsEmpty() {
338
+ err = fmt.Errorf("no LID found for %s from server", to)
339
+ return
340
+ }
341
+ }
342
+ resp.DebugTimings.LIDFetch = time.Since(start)
343
+ cli.Log.Debugf("Replacing SendMessage destination with LID as migration timestamp is set %s -> %s", to, toLID)
344
+ to = toLID
345
+ ownID = cli.getOwnLID()
314
346
  }
315
347
  if req.Meta != nil {
316
348
  extraParams.metaNode = &waBinary.Node{
@@ -326,6 +358,10 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, message *waE2E
326
358
  }
327
359
  }
328
360
 
361
+ if req.AdditionalNodes != nil {
362
+ extraParams.additionalNodes = req.AdditionalNodes
363
+ }
364
+
329
365
  resp.Sender = ownID
330
366
 
331
367
  start := time.Now()
@@ -582,6 +618,9 @@ func ParseDisappearingTimerString(val string) (time.Duration, bool) {
582
618
  func (cli *Client) SetDisappearingTimer(chat types.JID, timer time.Duration, settingTS time.Time) (err error) {
583
619
  switch chat.Server {
584
620
  case types.DefaultUserServer, types.HiddenUserServer:
621
+ if settingTS.IsZero() {
622
+ settingTS = time.Now()
623
+ }
585
624
  _, err = cli.SendMessage(context.TODO(), chat, &waE2E.Message{
586
625
  ProtocolMessage: &waE2E.ProtocolMessage{
587
626
  Type: waE2E.ProtocolMessage_EPHEMERAL_SETTING.Enum(),
@@ -673,9 +712,10 @@ func (cli *Client) sendNewsletter(
673
712
  }
674
713
 
675
714
  type nodeExtraParams struct {
676
- botNode *waBinary.Node
677
- metaNode *waBinary.Node
678
- addressingMode types.AddressingMode
715
+ botNode *waBinary.Node
716
+ metaNode *waBinary.Node
717
+ additionalNodes *[]waBinary.Node
718
+ addressingMode types.AddressingMode
679
719
  }
680
720
 
681
721
  func (cli *Client) sendGroup(
@@ -1001,7 +1041,7 @@ func (cli *Client) preparePeerMessageNode(
1001
1041
  }
1002
1042
  }
1003
1043
  start = time.Now()
1004
- encrypted, isPreKey, err := cli.encryptMessageForDevice(ctx, plaintext, encryptionIdentity, nil, nil)
1044
+ encrypted, isPreKey, err := cli.encryptMessageForDevice(ctx, plaintext, encryptionIdentity, nil, nil, nil)
1005
1045
  timings.PeerEncrypt = time.Since(start)
1006
1046
  if err != nil {
1007
1047
  return nil, fmt.Errorf("failed to encrypt peer message for %s: %v", to, err)
@@ -1047,6 +1087,9 @@ func (cli *Client) getMessageContent(
1047
1087
  if extraParams.metaNode != nil {
1048
1088
  content = append(content, *extraParams.metaNode)
1049
1089
  }
1090
+ if extraParams.additionalNodes != nil {
1091
+ content = append(content, *extraParams.additionalNodes...)
1092
+ }
1050
1093
 
1051
1094
  if buttonType := getButtonTypeFromMessage(message); buttonType != "" {
1052
1095
  content = append(content, waBinary.Node{
@@ -1101,10 +1144,13 @@ func (cli *Client) prepareMessageNode(
1101
1144
  }
1102
1145
 
1103
1146
  start = time.Now()
1104
- participantNodes, includeIdentity := cli.encryptMessageForDevices(
1147
+ participantNodes, includeIdentity, err := cli.encryptMessageForDevices(
1105
1148
  ctx, allDevices, id, plaintext, dsmPlaintext, encAttrs,
1106
1149
  )
1107
1150
  timings.PeerEncrypt = time.Since(start)
1151
+ if err != nil {
1152
+ return nil, nil, err
1153
+ }
1108
1154
  participantNode := waBinary.Node{
1109
1155
  Tag: "participants",
1110
1156
  Content: participantNodes,
@@ -1162,11 +1208,43 @@ func (cli *Client) encryptMessageForDevices(
1162
1208
  id string,
1163
1209
  msgPlaintext, dsmPlaintext []byte,
1164
1210
  encAttrs waBinary.Attrs,
1165
- ) ([]waBinary.Node, bool) {
1211
+ ) ([]waBinary.Node, bool, error) {
1166
1212
  ownJID := cli.getOwnID()
1167
1213
  ownLID := cli.getOwnLID()
1168
1214
  includeIdentity := false
1169
1215
  participantNodes := make([]waBinary.Node, 0, len(allDevices))
1216
+
1217
+ var pnDevices []types.JID
1218
+ for _, jid := range allDevices {
1219
+ if jid.Server == types.DefaultUserServer {
1220
+ pnDevices = append(pnDevices, jid)
1221
+ }
1222
+ }
1223
+ lidMappings, err := cli.Store.LIDs.GetManyLIDsForPNs(ctx, pnDevices)
1224
+ if err != nil {
1225
+ return nil, false, fmt.Errorf("failed to fetch LID mappings: %w", err)
1226
+ }
1227
+
1228
+ encryptionIdentities := make(map[types.JID]types.JID, len(allDevices))
1229
+ var sessionAddresses []string
1230
+ for _, jid := range allDevices {
1231
+ encryptionIdentity := jid
1232
+ if jid.Server == types.DefaultUserServer {
1233
+ // TODO query LID from server for missing entries
1234
+ if lidForPN, ok := lidMappings[jid]; ok && !lidForPN.IsEmpty() {
1235
+ cli.migrateSessionStore(ctx, jid, lidForPN)
1236
+ encryptionIdentity = lidForPN
1237
+ }
1238
+ }
1239
+ encryptionIdentities[jid] = encryptionIdentity
1240
+ sessionAddresses = append(sessionAddresses, encryptionIdentity.SignalAddress().String())
1241
+ }
1242
+
1243
+ existingSessions, err := cli.Store.Sessions.HasManySessions(ctx, sessionAddresses)
1244
+ if err != nil {
1245
+ return nil, false, fmt.Errorf("failed to check which sessions exist: %w", err)
1246
+ }
1247
+
1170
1248
  var retryDevices, retryEncryptionIdentities []types.JID
1171
1249
  for _, jid := range allDevices {
1172
1250
  plaintext := msgPlaintext
@@ -1176,19 +1254,10 @@ func (cli *Client) encryptMessageForDevices(
1176
1254
  }
1177
1255
  plaintext = dsmPlaintext
1178
1256
  }
1179
- encryptionIdentity := jid
1180
- 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() {
1185
- cli.migrateSessionStore(ctx, jid, lidForPN)
1186
- encryptionIdentity = lidForPN
1187
- }
1188
- }
1257
+ encryptionIdentity := encryptionIdentities[jid]
1189
1258
 
1190
1259
  encrypted, isPreKey, err := cli.encryptMessageForDeviceAndWrap(
1191
- ctx, plaintext, jid, encryptionIdentity, nil, encAttrs,
1260
+ ctx, plaintext, jid, encryptionIdentity, nil, encAttrs, existingSessions,
1192
1261
  )
1193
1262
  if errors.Is(err, ErrNoSession) {
1194
1263
  retryDevices = append(retryDevices, jid)
@@ -1197,6 +1266,9 @@ func (cli *Client) encryptMessageForDevices(
1197
1266
  } else if err != nil {
1198
1267
  // TODO return these errors if it's a fatal one (like context cancellation or database)
1199
1268
  cli.Log.Warnf("Failed to encrypt %s for %s: %v", id, jid, err)
1269
+ if ctx.Err() != nil {
1270
+ return nil, false, err
1271
+ }
1200
1272
  continue
1201
1273
  }
1202
1274
 
@@ -1221,7 +1293,7 @@ func (cli *Client) encryptMessageForDevices(
1221
1293
  plaintext = dsmPlaintext
1222
1294
  }
1223
1295
  encrypted, isPreKey, err := cli.encryptMessageForDeviceAndWrap(
1224
- ctx, plaintext, jid, retryEncryptionIdentities[i], resp.bundle, encAttrs,
1296
+ ctx, plaintext, jid, retryEncryptionIdentities[i], resp.bundle, encAttrs, nil,
1225
1297
  )
1226
1298
  if err != nil {
1227
1299
  // TODO return these errors if it's a fatal one (like context cancellation or database)
@@ -1235,7 +1307,7 @@ func (cli *Client) encryptMessageForDevices(
1235
1307
  }
1236
1308
  }
1237
1309
  }
1238
- return participantNodes, includeIdentity
1310
+ return participantNodes, includeIdentity, nil
1239
1311
  }
1240
1312
 
1241
1313
  func (cli *Client) encryptMessageForDeviceAndWrap(
@@ -1245,9 +1317,10 @@ func (cli *Client) encryptMessageForDeviceAndWrap(
1245
1317
  encryptionIdentity types.JID,
1246
1318
  bundle *prekey.Bundle,
1247
1319
  encAttrs waBinary.Attrs,
1320
+ existingSessions map[string]bool,
1248
1321
  ) (*waBinary.Node, bool, error) {
1249
1322
  node, includeDeviceIdentity, err := cli.encryptMessageForDevice(
1250
- ctx, plaintext, encryptionIdentity, bundle, encAttrs,
1323
+ ctx, plaintext, encryptionIdentity, bundle, encAttrs, existingSessions,
1251
1324
  )
1252
1325
  if err != nil {
1253
1326
  return nil, false, err
@@ -1271,6 +1344,7 @@ func (cli *Client) encryptMessageForDevice(
1271
1344
  to types.JID,
1272
1345
  bundle *prekey.Bundle,
1273
1346
  extraAttrs waBinary.Attrs,
1347
+ existingSessions map[string]bool,
1274
1348
  ) (*waBinary.Node, bool, error) {
1275
1349
  builder := session.NewBuilderFromSignal(cli.Store, to.SignalAddress(), pbSerializer)
1276
1350
  if bundle != nil {
@@ -1287,10 +1361,18 @@ func (cli *Client) encryptMessageForDevice(
1287
1361
  if err != nil {
1288
1362
  return nil, false, fmt.Errorf("failed to process prekey bundle: %w", err)
1289
1363
  }
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())
1364
+ } else {
1365
+ sessionExists, checked := existingSessions[to.SignalAddress().String()]
1366
+ if !checked {
1367
+ var err error
1368
+ sessionExists, err = cli.Store.ContainsSession(ctx, to.SignalAddress())
1369
+ if err != nil {
1370
+ return nil, false, err
1371
+ }
1372
+ }
1373
+ if !sessionExists {
1374
+ return nil, false, fmt.Errorf("%w with %s", ErrNoSession, to.SignalAddress().String())
1375
+ }
1294
1376
  }
1295
1377
  cipher := session.NewCipher(builder, to.SignalAddress())
1296
1378
  ciphertext, err := cipher.Encrypt(ctx, padMessage(plaintext))
@@ -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, 1027949008}
80
80
 
81
81
  // waVersionHash is the md5 hash of a dot-separated waVersion
82
82
  var waVersionHash [16]byte
@@ -68,6 +68,10 @@ func (n *NoopStore) HasSession(ctx context.Context, address string) (bool, error
68
68
  return false, n.Error
69
69
  }
70
70
 
71
+ func (n *NoopStore) HasManySessions(ctx context.Context, addresses []string) (map[string]bool, error) {
72
+ return nil, n.Error
73
+ }
74
+
71
75
  func (n *NoopStore) PutSession(ctx context.Context, address string, session []byte) error {
72
76
  return n.Error
73
77
  }
@@ -168,6 +172,10 @@ func (n *NoopStore) PutAllContactNames(ctx context.Context, contacts []ContactEn
168
172
  return n.Error
169
173
  }
170
174
 
175
+ func (n *NoopStore) PutManyRedactedPhones(ctx context.Context, entries []RedactedPhoneEntry) error {
176
+ return n.Error
177
+ }
178
+
171
179
  func (n *NoopStore) GetContact(ctx context.Context, user types.JID) (types.ContactInfo, error) {
172
180
  return types.ContactInfo{}, n.Error
173
181
  }
@@ -244,6 +252,10 @@ func (n *NoopStore) GetLIDForPN(ctx context.Context, pn types.JID) (types.JID, e
244
252
  return types.JID{}, n.Error
245
253
  }
246
254
 
255
+ func (n *NoopStore) GetManyLIDsForPNs(ctx context.Context, pns []types.JID) (map[types.JID]types.JID, error) {
256
+ return nil, n.Error
257
+ }
258
+
247
259
  func (n *NoopStore) GetPNForLID(ctx context.Context, lid types.JID) (types.JID, error) {
248
260
  return types.JID{}, n.Error
249
261
  }
@@ -13,10 +13,12 @@ import (
13
13
  "errors"
14
14
  "fmt"
15
15
  "slices"
16
+ "strings"
16
17
  "sync"
17
18
 
18
19
  "github.com/rs/zerolog"
19
20
  "go.mau.fi/util/dbutil"
21
+ "go.mau.fi/util/exslices"
20
22
 
21
23
  "go.mau.fi/whatsmeow/store"
22
24
  "go.mau.fi/whatsmeow/types"
@@ -61,18 +63,30 @@ func (s *CachedLIDMap) FillCache(ctx context.Context) error {
61
63
  if err != nil {
62
64
  return err
63
65
  }
64
- defer rows.Close()
66
+ err = s.scanManyLids(rows, nil)
67
+ s.cacheFilled = err == nil
68
+ return err
69
+ }
70
+
71
+ func (s *CachedLIDMap) scanManyLids(rows dbutil.Rows, fn func(lid, pn string)) error {
72
+ if fn == nil {
73
+ fn = func(lid, pn string) {}
74
+ }
65
75
  for rows.Next() {
66
76
  var lid, pn string
67
- err = rows.Scan(&lid, &pn)
77
+ err := rows.Scan(&lid, &pn)
68
78
  if err != nil {
69
79
  return err
70
80
  }
71
81
  s.pnToLIDCache[pn] = lid
72
82
  s.lidToPNCache[lid] = pn
83
+ fn(lid, pn)
73
84
  }
74
- s.cacheFilled = true
75
- return nil
85
+ err := rows.Close()
86
+ if err != nil {
87
+ return err
88
+ }
89
+ return rows.Err()
76
90
  }
77
91
 
78
92
  func (s *CachedLIDMap) getLIDMapping(ctx context.Context, source types.JID, targetServer, query string, sourceToTarget, targetToSource map[string]string) (types.JID, error) {
@@ -122,6 +136,69 @@ func (s *CachedLIDMap) GetPNForLID(ctx context.Context, lid types.JID) (types.JI
122
136
  )
123
137
  }
124
138
 
139
+ func (s *CachedLIDMap) GetManyLIDsForPNs(ctx context.Context, pns []types.JID) (map[types.JID]types.JID, error) {
140
+ if len(pns) == 0 {
141
+ return nil, nil
142
+ }
143
+
144
+ result := make(map[types.JID]types.JID, len(pns))
145
+
146
+ s.lidCacheLock.RLock()
147
+ missingPNs := make([]string, 0, len(pns))
148
+ missingPNDevices := make(map[string][]types.JID)
149
+ for _, pn := range pns {
150
+ if pn.Server != types.DefaultUserServer {
151
+ continue
152
+ }
153
+ if lidUser, ok := s.pnToLIDCache[pn.User]; ok && lidUser != "" {
154
+ result[pn] = types.JID{User: lidUser, Device: pn.Device, Server: types.HiddenUserServer}
155
+ } else if !s.cacheFilled {
156
+ missingPNs = append(missingPNs, pn.User)
157
+ missingPNDevices[pn.User] = append(missingPNDevices[pn.User], pn)
158
+ }
159
+ }
160
+ s.lidCacheLock.RUnlock()
161
+
162
+ if len(missingPNs) == 0 {
163
+ return result, nil
164
+ }
165
+
166
+ s.lidCacheLock.Lock()
167
+ defer s.lidCacheLock.Unlock()
168
+
169
+ var rows dbutil.Rows
170
+ var err error
171
+ if s.db.Dialect == dbutil.Postgres && PostgresArrayWrapper != nil {
172
+ rows, err = s.db.Query(
173
+ ctx,
174
+ `SELECT lid, pn FROM whatsmeow_lid_map WHERE pn = ANY($1)`,
175
+ PostgresArrayWrapper(missingPNs),
176
+ )
177
+ } else {
178
+ placeholders := make([]string, len(missingPNs))
179
+ for i := range missingPNs {
180
+ placeholders[i] = fmt.Sprintf("$%d", i+1)
181
+ }
182
+ rows, err = s.db.Query(
183
+ ctx,
184
+ fmt.Sprintf(`SELECT lid, pn FROM whatsmeow_lid_map WHERE pn IN (%s)`, strings.Join(placeholders, ",")),
185
+ exslices.CastToAny(missingPNs)...,
186
+ )
187
+ }
188
+ if err != nil {
189
+ return nil, err
190
+ }
191
+ err = s.scanManyLids(rows, func(lid, pn string) {
192
+ for _, dev := range missingPNDevices[pn] {
193
+ lidDev := dev
194
+ lidDev.Server = types.HiddenUserServer
195
+ lidDev.User = lid
196
+ result[dev] = lidDev.ToNonAD()
197
+ }
198
+ })
199
+ return result, err
200
+ }
201
+
125
202
  func (s *CachedLIDMap) PutLIDMapping(ctx context.Context, lid, pn types.JID) error {
126
203
  if lid.Server != types.HiddenUserServer || pn.Server != types.DefaultUserServer {
127
204
  return fmt.Errorf("invalid PutLIDMapping call %s/%s", lid, pn)
@@ -154,6 +231,7 @@ func (s *CachedLIDMap) PutManyLIDMappings(ctx context.Context, mappings []store.
154
231
  }
155
232
  return false
156
233
  })
234
+ mappings = exslices.DeduplicateUnsortedOverwrite(mappings)
157
235
  if len(mappings) == 0 {
158
236
  return nil
159
237
  }