slidge-whatsapp 0.3.0b0__cp313-cp313-manylinux_2_36_aarch64.whl → 0.3.4__cp313-cp313-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-313-aarch64-linux-gnu.h +206 -206
  4. slidge_whatsapp/generated/_whatsapp.cpython-313-aarch64-linux-gnu.so +0 -0
  5. slidge_whatsapp/generated/build.py +166 -166
  6. slidge_whatsapp/generated/go.py +1 -1
  7. slidge_whatsapp/generated/whatsapp.c +1557 -1557
  8. slidge_whatsapp/generated/whatsapp.go +1227 -1227
  9. slidge_whatsapp/generated/whatsapp.py +1382 -1382
  10. slidge_whatsapp/generated/whatsapp_go.h +206 -206
  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
@@ -10,12 +10,19 @@ import (
10
10
  "time"
11
11
  )
12
12
 
13
+ func zeroSafeUnixToTime(val int64, fn func(int64) time.Time) time.Time {
14
+ if val == 0 {
15
+ return time.Time{}
16
+ }
17
+ return fn(val)
18
+ }
19
+
13
20
  func UM(time time.Time) UnixMilli {
14
21
  return UnixMilli{Time: time}
15
22
  }
16
23
 
17
24
  func UMInt(ts int64) UnixMilli {
18
- return UM(time.UnixMilli(ts))
25
+ return UM(zeroSafeUnixToTime(ts, time.UnixMilli))
19
26
  }
20
27
 
21
28
  func UnixMilliNow() UnixMilli {
@@ -26,8 +33,8 @@ func UMicro(time time.Time) UnixMicro {
26
33
  return UnixMicro{Time: time}
27
34
  }
28
35
 
29
- func UMicroInto(ts int64) UnixMicro {
30
- return UMicro(time.UnixMicro(ts))
36
+ func UMicroInt(ts int64) UnixMicro {
37
+ return UMicro(zeroSafeUnixToTime(ts, time.UnixMicro))
31
38
  }
32
39
 
33
40
  func UnixMicroNow() UnixMicro {
@@ -39,7 +46,9 @@ func UN(time time.Time) UnixNano {
39
46
  }
40
47
 
41
48
  func UNInt(ts int64) UnixNano {
42
- return UN(time.Unix(0, ts))
49
+ return UN(zeroSafeUnixToTime(ts, func(i int64) time.Time {
50
+ return time.Unix(0, i)
51
+ }))
43
52
  }
44
53
 
45
54
  func UnixNanoNow() UnixNano {
@@ -51,7 +60,9 @@ func U(time time.Time) Unix {
51
60
  }
52
61
 
53
62
  func UInt(ts int64) Unix {
54
- return U(time.Unix(ts, 0))
63
+ return U(zeroSafeUnixToTime(ts, func(i int64) time.Time {
64
+ return time.Unix(i, 0)
65
+ }))
55
66
  }
56
67
 
57
68
  func UnixNow() Unix {
@@ -57,6 +57,13 @@ func anyIntegerToTime(src any, unixConv func(int64) time.Time, into *time.Time)
57
57
  return nil
58
58
  }
59
59
 
60
+ func zeroSafeUnix(t time.Time, method func(time.Time) int64) int64 {
61
+ if t.IsZero() {
62
+ return 0
63
+ }
64
+ return method(t)
65
+ }
66
+
60
67
  var _ sql.Scanner = &UnixMilli{}
61
68
  var _ driver.Valuer = UnixMilli{}
62
69
 
@@ -65,9 +72,6 @@ type UnixMilli struct {
65
72
  }
66
73
 
67
74
  func (um UnixMilli) MarshalJSON() ([]byte, error) {
68
- if um.IsZero() {
69
- return []byte{'0'}, nil
70
- }
71
75
  return json.Marshal(um.UnixMilli())
72
76
  }
73
77
 
@@ -83,6 +87,11 @@ func (um *UnixMilli) Scan(src any) error {
83
87
  return anyIntegerToTime(src, time.UnixMilli, &um.Time)
84
88
  }
85
89
 
90
+ func (um UnixMilli) Unix() int64 { return zeroSafeUnix(um.Time, time.Time.Unix) }
91
+ func (um UnixMilli) UnixMilli() int64 { return zeroSafeUnix(um.Time, time.Time.UnixMilli) }
92
+ func (um UnixMilli) UnixMicro() int64 { return zeroSafeUnix(um.Time, time.Time.UnixMicro) }
93
+ func (um UnixMilli) UnixNano() int64 { return zeroSafeUnix(um.Time, time.Time.UnixNano) }
94
+
86
95
  var _ sql.Scanner = &UnixMicro{}
87
96
  var _ driver.Valuer = UnixMicro{}
88
97
 
@@ -91,9 +100,6 @@ type UnixMicro struct {
91
100
  }
92
101
 
93
102
  func (um UnixMicro) MarshalJSON() ([]byte, error) {
94
- if um.IsZero() {
95
- return []byte{'0'}, nil
96
- }
97
103
  return json.Marshal(um.UnixMicro())
98
104
  }
99
105
 
@@ -109,6 +115,11 @@ func (um *UnixMicro) Scan(src any) error {
109
115
  return anyIntegerToTime(src, time.UnixMicro, &um.Time)
110
116
  }
111
117
 
118
+ func (um UnixMicro) Unix() int64 { return zeroSafeUnix(um.Time, time.Time.Unix) }
119
+ func (um UnixMicro) UnixMilli() int64 { return zeroSafeUnix(um.Time, time.Time.UnixMilli) }
120
+ func (um UnixMicro) UnixMicro() int64 { return zeroSafeUnix(um.Time, time.Time.UnixMicro) }
121
+ func (um UnixMicro) UnixNano() int64 { return zeroSafeUnix(um.Time, time.Time.UnixNano) }
122
+
112
123
  var _ sql.Scanner = &UnixNano{}
113
124
  var _ driver.Valuer = UnixNano{}
114
125
 
@@ -117,9 +128,6 @@ type UnixNano struct {
117
128
  }
118
129
 
119
130
  func (un UnixNano) MarshalJSON() ([]byte, error) {
120
- if un.IsZero() {
121
- return []byte{'0'}, nil
122
- }
123
131
  return json.Marshal(un.UnixNano())
124
132
  }
125
133
 
@@ -139,14 +147,16 @@ func (un *UnixNano) Scan(src any) error {
139
147
  }, &un.Time)
140
148
  }
141
149
 
150
+ func (un UnixNano) Unix() int64 { return zeroSafeUnix(un.Time, time.Time.Unix) }
151
+ func (un UnixNano) UnixMilli() int64 { return zeroSafeUnix(un.Time, time.Time.UnixMilli) }
152
+ func (un UnixNano) UnixMicro() int64 { return zeroSafeUnix(un.Time, time.Time.UnixMicro) }
153
+ func (un UnixNano) UnixNano() int64 { return zeroSafeUnix(un.Time, time.Time.UnixNano) }
154
+
142
155
  type Unix struct {
143
156
  time.Time
144
157
  }
145
158
 
146
159
  func (u Unix) MarshalJSON() ([]byte, error) {
147
- if u.IsZero() {
148
- return []byte{'0'}, nil
149
- }
150
160
  return json.Marshal(u.Unix())
151
161
  }
152
162
 
@@ -168,3 +178,8 @@ func (u *Unix) Scan(src any) error {
168
178
  return time.Unix(i, 0)
169
179
  }, &u.Time)
170
180
  }
181
+
182
+ func (u Unix) Unix() int64 { return zeroSafeUnix(u.Time, time.Time.Unix) }
183
+ func (u Unix) UnixMilli() int64 { return zeroSafeUnix(u.Time, time.Time.UnixMilli) }
184
+ func (u Unix) UnixMicro() int64 { return zeroSafeUnix(u.Time, time.Time.UnixMicro) }
185
+ func (u Unix) UnixNano() int64 { return zeroSafeUnix(u.Time, time.Time.UnixNano) }
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2023 Tulir Asokan
1
+ // Copyright (c) 2025 Tulir Asokan
2
2
  //
3
3
  // This Source Code Form is subject to the terms of the Mozilla Public
4
4
  // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -10,20 +10,52 @@ import (
10
10
  "encoding/binary"
11
11
  "hash/crc32"
12
12
  "strings"
13
- "unsafe"
13
+
14
+ "go.mau.fi/util/exbytes"
14
15
  )
15
16
 
16
17
  const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
17
18
 
18
19
  // StringBytes generates a random string of the given length and returns it as a byte array.
19
20
  func StringBytes(n int) []byte {
21
+ return StringBytesCharset(n, letters)
22
+ }
23
+
24
+ // AppendSequence generates a random sequence of the given length using the given character set
25
+ // and appends it to the given output slice.
26
+ func AppendSequence[T any](n int, charset, output []T) []T {
27
+ if n <= 0 {
28
+ return output
29
+ }
30
+ if output == nil {
31
+ output = make([]T, 0, n)
32
+ }
33
+ // If risk of modulo bias is too high, use 32-bit integers as source instead of 16-bit.
34
+ if 65536%len(charset) < 200 {
35
+ input := Bytes(n * 2)
36
+ for i := 0; i < n; i++ {
37
+ output = append(output, charset[binary.BigEndian.Uint16(input[i*2:])%uint16(len(charset))])
38
+ }
39
+ } else {
40
+ input := Bytes(n * 4)
41
+ for i := 0; i < n; i++ {
42
+ output = append(output, charset[binary.BigEndian.Uint32(input[i*4:])%uint32(len(charset))])
43
+ }
44
+ }
45
+ return output
46
+ }
47
+
48
+ // StringBytesCharset generates a random string of the given length using the given character set and returns it as a byte array.
49
+ // Note that the character set must be ASCII. For arbitrary Unicode, use [AppendSequence] with a `[]rune`.
50
+ func StringBytesCharset(n int, charset string) []byte {
20
51
  if n <= 0 {
21
52
  return []byte{}
22
53
  }
23
54
  input := Bytes(n * 2)
24
55
  for i := 0; i < n; i++ {
25
- // Risk of modulo bias is only 2 in 65535, values between 0 and 65533 are uniformly distributed
26
- input[i] = letters[binary.BigEndian.Uint16(input[i*2:])%uint16(len(letters))]
56
+ // The risk of modulo bias is (65536 % len(charset)) / 65536.
57
+ // For the default charset, that's 2 in 65536 or 0.003 %.
58
+ input[i] = charset[binary.BigEndian.Uint16(input[i*2:])%uint16(len(charset))]
27
59
  }
28
60
  input = input[:n]
29
61
  return input
@@ -34,8 +66,16 @@ func String(n int) string {
34
66
  if n <= 0 {
35
67
  return ""
36
68
  }
37
- str := StringBytes(n)
38
- return *(*string)(unsafe.Pointer(&str))
69
+ return exbytes.UnsafeString(StringBytes(n))
70
+ }
71
+
72
+ // StringCharset generates a random string of the given length using the given character set.
73
+ // Note that the character set must be ASCII. For arbitrary Unicode, use [AppendSequence] with a `[]rune`.
74
+ func StringCharset(n int, charset string) string {
75
+ if n <= 0 {
76
+ return ""
77
+ }
78
+ return exbytes.UnsafeString(StringBytesCharset(n, charset))
39
79
  }
40
80
 
41
81
  func base62Encode(val uint32, minWidth int) []byte {
@@ -65,7 +105,7 @@ func Token(namespace string, randomLength int) string {
65
105
  token[len(namespace)+randomLength+1] = '_'
66
106
  checksum := base62Encode(crc32.ChecksumIEEE(token[:len(token)-7]), 6)
67
107
  copy(token[len(token)-6:], checksum)
68
- return *(*string)(unsafe.Pointer(&token))
108
+ return exbytes.UnsafeString(token)
69
109
  }
70
110
 
71
111
  // GetTokenPrefix parses the given token generated with Token, validates the checksum and returns the prefix namespace.
@@ -166,6 +166,7 @@ func (proc *Processor) decodeMutations(ctx context.Context, mutations []*waServe
166
166
  out.Mutations = append(out.Mutations, Mutation{
167
167
  Operation: mutation.GetOperation(),
168
168
  Action: syncAction.GetValue(),
169
+ Version: syncAction.GetVersion(),
169
170
  Index: index,
170
171
  IndexMAC: indexMAC,
171
172
  ValueMAC: valueMAC,
@@ -45,7 +45,11 @@ func BuildMute(target types.JID, mute bool, muteDuration time.Duration) PatchInf
45
45
  if muteDuration > 0 {
46
46
  muteEndTimestamp = proto.Int64(time.Now().Add(muteDuration).UnixMilli())
47
47
  }
48
+ return BuildMuteAbs(target, mute, muteEndTimestamp)
49
+ }
48
50
 
51
+ // BuildMuteAbs builds an app state patch for muting or unmuting a chat with an absolute timestamp.
52
+ func BuildMuteAbs(target types.JID, mute bool, muteEndTimestamp *int64) PatchInfo {
49
53
  return PatchInfo{
50
54
  Type: WAPatchRegularHigh,
51
55
  Mutations: []MutationInfo{{
@@ -89,30 +93,18 @@ func BuildPin(target types.JID, pin bool) PatchInfo {
89
93
  //
90
94
  // Archiving a chat will also unpin it automatically.
91
95
  func BuildArchive(target types.JID, archive bool, lastMessageTimestamp time.Time, lastMessageKey *waCommon.MessageKey) PatchInfo {
92
- if lastMessageTimestamp.IsZero() {
93
- lastMessageTimestamp = time.Now()
94
- }
95
96
  archiveMutationInfo := MutationInfo{
96
97
  Index: []string{IndexArchive, target.String()},
97
98
  Version: 3,
98
99
  Value: &waSyncAction.SyncActionValue{
99
100
  ArchiveChatAction: &waSyncAction.ArchiveChatAction{
100
- Archived: &archive,
101
- MessageRange: &waSyncAction.SyncActionMessageRange{
102
- LastMessageTimestamp: proto.Int64(lastMessageTimestamp.Unix()),
103
- // TODO set LastSystemMessageTimestamp?
104
- },
101
+ Archived: &archive,
102
+ MessageRange: newMessageRange(lastMessageTimestamp, lastMessageKey),
103
+ // TODO set LastSystemMessageTimestamp?
105
104
  },
106
105
  },
107
106
  }
108
107
 
109
- if lastMessageKey != nil {
110
- archiveMutationInfo.Value.ArchiveChatAction.MessageRange.Messages = []*waSyncAction.SyncActionMessage{{
111
- Key: lastMessageKey,
112
- Timestamp: proto.Int64(lastMessageTimestamp.Unix()),
113
- }}
114
- }
115
-
116
108
  mutations := []MutationInfo{archiveMutationInfo}
117
109
  if archive {
118
110
  mutations = append(mutations, newPinMutationInfo(target, false))
@@ -126,6 +118,25 @@ func BuildArchive(target types.JID, archive bool, lastMessageTimestamp time.Time
126
118
  return result
127
119
  }
128
120
 
121
+ // BuildMarkChatAsRead builds an app state patch for marking a chat as read or unread.
122
+ func BuildMarkChatAsRead(target types.JID, read bool, lastMessageTimestamp time.Time, lastMessageKey *waCommon.MessageKey) PatchInfo {
123
+ action := &waSyncAction.MarkChatAsReadAction{
124
+ Read: proto.Bool(read),
125
+ MessageRange: newMessageRange(lastMessageTimestamp, lastMessageKey),
126
+ }
127
+
128
+ return PatchInfo{
129
+ Type: WAPatchRegularLow,
130
+ Mutations: []MutationInfo{{
131
+ Index: []string{IndexMarkChatAsRead, target.String()},
132
+ Version: 3,
133
+ Value: &waSyncAction.SyncActionValue{
134
+ MarkChatAsReadAction: action,
135
+ },
136
+ }},
137
+ }
138
+ }
139
+
129
140
  func newLabelChatMutation(target types.JID, labelID string, labeled bool) MutationInfo {
130
141
  return MutationInfo{
131
142
  Index: []string{IndexLabelAssociationChat, labelID, target.String()},
@@ -321,3 +332,37 @@ func (proc *Processor) EncodePatch(ctx context.Context, keyID []byte, state Hash
321
332
 
322
333
  return result, nil
323
334
  }
335
+
336
+ // BuildDeleteChat builds an app state patch for deleting a chat.
337
+ func BuildDeleteChat(target types.JID, lastMessageTimestamp time.Time, lastMessageKey *waCommon.MessageKey) PatchInfo {
338
+ action := &waSyncAction.DeleteChatAction{
339
+ MessageRange: newMessageRange(lastMessageTimestamp, lastMessageKey),
340
+ }
341
+
342
+ return PatchInfo{
343
+ Type: WAPatchRegular,
344
+ Mutations: []MutationInfo{{
345
+ Index: []string{IndexDeleteChat, target.String()},
346
+ Version: 6,
347
+ Value: &waSyncAction.SyncActionValue{
348
+ DeleteChatAction: action,
349
+ },
350
+ }},
351
+ }
352
+ }
353
+
354
+ func newMessageRange(lastMessageTimestamp time.Time, lastMessageKey *waCommon.MessageKey) *waSyncAction.SyncActionMessageRange {
355
+ if lastMessageTimestamp.IsZero() {
356
+ lastMessageTimestamp = time.Now()
357
+ }
358
+ messageRange := &waSyncAction.SyncActionMessageRange{
359
+ LastMessageTimestamp: proto.Int64(lastMessageTimestamp.Unix()),
360
+ }
361
+ if lastMessageKey != nil {
362
+ messageRange.Messages = []*waSyncAction.SyncActionMessage{{
363
+ Key: lastMessageKey,
364
+ Timestamp: proto.Int64(lastMessageTimestamp.Unix()),
365
+ }}
366
+ }
367
+ return messageRange
368
+ }
@@ -22,6 +22,7 @@ import (
22
22
  type Mutation struct {
23
23
  Operation waServerSync.SyncdMutation_SyncdOperation
24
24
  Action *waSyncAction.SyncActionValue
25
+ Version int32
25
26
  Index []string
26
27
  IndexMAC []byte
27
28
  ValueMAC []byte
@@ -13,6 +13,8 @@ import (
13
13
  "fmt"
14
14
  "time"
15
15
 
16
+ "github.com/rs/zerolog"
17
+
16
18
  "go.mau.fi/whatsmeow/appstate"
17
19
  waBinary "go.mau.fi/whatsmeow/binary"
18
20
  "go.mau.fi/whatsmeow/proto/waE2E"
@@ -110,6 +112,7 @@ func (cli *Client) filterContacts(mutations []appstate.Mutation) ([]appstate.Mut
110
112
  }
111
113
 
112
114
  func (cli *Client) dispatchAppState(ctx context.Context, mutation appstate.Mutation, fullSync bool, emitOnFullSync bool) {
115
+ zerolog.Ctx(ctx).Trace().Any("mutation", mutation).Msg("Dispatching app state mutation")
113
116
  dispatchEvts := !fullSync || emitOnFullSync
114
117
 
115
118
  if mutation.Operation != waServerSync.SyncdMutation_SET {
@@ -348,13 +351,17 @@ func (cli *Client) requestAppStateKeys(ctx context.Context, rawKeyIDs [][]byte)
348
351
  }
349
352
  }
350
353
 
351
- // SendAppState sends the given app state patch, then resyncs that app state type from the server
354
+ // SendAppState sends the given app state patch, then triggers a background resync of that app state type
352
355
  // to update local caches and send events for the updates.
353
356
  //
354
357
  // You can use the Build methods in the appstate package to build the parameter for this method, e.g.
355
358
  //
356
359
  // cli.SendAppState(ctx, appstate.BuildMute(targetJID, true, 24 * time.Hour))
357
360
  func (cli *Client) SendAppState(ctx context.Context, patch appstate.PatchInfo) error {
361
+ return cli.sendAppState(ctx, patch, false)
362
+ }
363
+
364
+ func (cli *Client) sendAppState(ctx context.Context, patch appstate.PatchInfo, waitForSync bool) error {
358
365
  if cli == nil {
359
366
  return ErrClientIsNil
360
367
  }
@@ -409,5 +416,16 @@ func (cli *Client) SendAppState(ctx context.Context, patch appstate.PatchInfo) e
409
416
  return fmt.Errorf("%w: %s", ErrAppStateUpdate, respCollection.XMLString())
410
417
  }
411
418
 
412
- return cli.FetchAppState(ctx, patch.Type, false, false)
419
+ if waitForSync {
420
+ return cli.FetchAppState(ctx, patch.Type, false, false)
421
+ }
422
+
423
+ go func() {
424
+ err := cli.FetchAppState(ctx, patch.Type, false, false)
425
+ if err != nil {
426
+ cli.Log.Errorf("Failed to resync app state %s after sending update: %v", patch.Type, err)
427
+ }
428
+ }()
429
+
430
+ return nil
413
431
  }
@@ -22,10 +22,11 @@ import (
22
22
  "go.mau.fi/whatsmeow/types/events"
23
23
  )
24
24
 
25
- func (cli *Client) handleDecryptedArmadillo(ctx context.Context, info *types.MessageInfo, decrypted []byte, retryCount int) (handled, handlerFailed bool) {
25
+ func (cli *Client) handleDecryptedArmadillo(ctx context.Context, info *types.MessageInfo, decrypted []byte, retryCount int) (handlerFailed, protobufFailed bool) {
26
26
  dec, err := decodeArmadillo(decrypted)
27
27
  if err != nil {
28
28
  cli.Log.Warnf("Failed to decode armadillo message from %s: %v", info.SourceString(), err)
29
+ protobufFailed = true
29
30
  return
30
31
  }
31
32
  dec.Info = *info
@@ -41,7 +42,6 @@ func (cli *Client) handleDecryptedArmadillo(ctx context.Context, info *types.Mes
41
42
  if dec.Message != nil || dec.FBApplication != nil {
42
43
  handlerFailed = cli.dispatchEvent(&dec)
43
44
  }
44
- handled = true
45
45
  return
46
46
  }
47
47
 
@@ -29,6 +29,12 @@ func (cli *Client) handleCallEvent(node *waBinary.Node) {
29
29
  CallID: cag.String("call-id"),
30
30
  GroupJID: cag.OptionalJIDOrEmpty("group-jid"),
31
31
  }
32
+ if basicMeta.CallCreator.Server == types.HiddenUserServer {
33
+ basicMeta.CallCreatorAlt = cag.OptionalJIDOrEmpty("caller_pn")
34
+ } else {
35
+ // This may not actually exist
36
+ basicMeta.CallCreatorAlt = cag.OptionalJIDOrEmpty("caller_lid")
37
+ }
32
38
  switch child.Tag {
33
39
  case "offer":
34
40
  cli.dispatchEvent(&events.CallOffer{
@@ -145,6 +145,7 @@ var (
145
145
  ErrOriginalMessageSecretNotFound = errors.New("original message secret key not found")
146
146
  ErrNotEncryptedReactionMessage = errors.New("given message isn't an encrypted reaction message")
147
147
  ErrNotEncryptedCommentMessage = errors.New("given message isn't an encrypted comment message")
148
+ ErrNotSecretEncryptedMessage = errors.New("given message isn't a secret encrypted message")
148
149
  ErrNotPollUpdateMessage = errors.New("given message isn't a poll update message")
149
150
  )
150
151
 
@@ -493,8 +493,8 @@ func (cli *Client) JoinGroupWithLink(code string) (types.JID, error) {
493
493
  }
494
494
 
495
495
  // GetJoinedGroups returns the list of groups the user is participating in.
496
- func (cli *Client) GetJoinedGroups() ([]*types.GroupInfo, error) {
497
- resp, err := cli.sendGroupIQ(context.TODO(), iqGet, types.GroupServerJID, waBinary.Node{
496
+ func (cli *Client) GetJoinedGroups(ctx context.Context) ([]*types.GroupInfo, error) {
497
+ resp, err := cli.sendGroupIQ(ctx, iqGet, types.GroupServerJID, waBinary.Node{
498
498
  Tag: "participating",
499
499
  Content: []waBinary.Node{
500
500
  {Tag: "participants"},
@@ -510,6 +510,8 @@ func (cli *Client) GetJoinedGroups() ([]*types.GroupInfo, error) {
510
510
  }
511
511
  children := groups.GetChildren()
512
512
  infos := make([]*types.GroupInfo, 0, len(children))
513
+ var allLIDPairs []store.LIDMapping
514
+ var allRedactedPhones []store.RedactedPhoneEntry
513
515
  for _, child := range children {
514
516
  if child.Tag != "group" {
515
517
  cli.Log.Debugf("Unexpected child in group list response: %s", child.XMLString())
@@ -519,8 +521,19 @@ func (cli *Client) GetJoinedGroups() ([]*types.GroupInfo, error) {
519
521
  if parseErr != nil {
520
522
  cli.Log.Warnf("Error parsing group %s: %v", parsed.JID, parseErr)
521
523
  }
524
+ lidPairs, redactedPhones := cli.cacheGroupInfo(parsed, true)
525
+ allLIDPairs = append(allLIDPairs, lidPairs...)
526
+ allRedactedPhones = append(allRedactedPhones, redactedPhones...)
522
527
  infos = append(infos, parsed)
523
528
  }
529
+ err = cli.Store.LIDs.PutManyLIDMappings(ctx, allLIDPairs)
530
+ if err != nil {
531
+ cli.Log.Warnf("Failed to store LID mappings from joined groups: %v", err)
532
+ }
533
+ err = cli.Store.Contacts.PutManyRedactedPhones(ctx, allRedactedPhones)
534
+ if err != nil {
535
+ cli.Log.Warnf("Failed to store redacted phones from joined groups: %v", err)
536
+ }
524
537
  return infos, nil
525
538
  }
526
539
 
@@ -572,6 +585,37 @@ func (cli *Client) GetGroupInfo(jid types.JID) (*types.GroupInfo, error) {
572
585
  return cli.getGroupInfo(context.TODO(), jid, true)
573
586
  }
574
587
 
588
+ func (cli *Client) cacheGroupInfo(groupInfo *types.GroupInfo, lock bool) ([]store.LIDMapping, []store.RedactedPhoneEntry) {
589
+ participants := make([]types.JID, len(groupInfo.Participants))
590
+ lidPairs := make([]store.LIDMapping, len(groupInfo.Participants))
591
+ redactedPhones := make([]store.RedactedPhoneEntry, 0)
592
+ for i, part := range groupInfo.Participants {
593
+ participants[i] = part.JID
594
+ if !part.PhoneNumber.IsEmpty() && !part.LID.IsEmpty() {
595
+ lidPairs[i] = store.LIDMapping{
596
+ LID: part.LID,
597
+ PN: part.PhoneNumber,
598
+ }
599
+ }
600
+ if part.DisplayName != "" && !part.LID.IsEmpty() {
601
+ redactedPhones = append(redactedPhones, store.RedactedPhoneEntry{
602
+ JID: part.LID,
603
+ RedactedPhone: part.DisplayName,
604
+ })
605
+ }
606
+ }
607
+ if lock {
608
+ cli.groupCacheLock.Lock()
609
+ defer cli.groupCacheLock.Unlock()
610
+ }
611
+ cli.groupCache[groupInfo.JID] = &groupMetaCache{
612
+ AddressingMode: groupInfo.AddressingMode,
613
+ CommunityAnnouncementGroup: groupInfo.IsAnnounce && groupInfo.IsDefaultSubGroup,
614
+ Members: participants,
615
+ }
616
+ return lidPairs, redactedPhones
617
+ }
618
+
575
619
  func (cli *Client) getGroupInfo(ctx context.Context, jid types.JID, lockParticipantCache bool) (*types.GroupInfo, error) {
576
620
  res, err := cli.sendGroupIQ(ctx, iqGet, jid, waBinary.Node{
577
621
  Tag: "query",
@@ -593,30 +637,15 @@ func (cli *Client) getGroupInfo(ctx context.Context, jid types.JID, lockParticip
593
637
  if err != nil {
594
638
  return groupInfo, err
595
639
  }
596
- if lockParticipantCache {
597
- cli.groupCacheLock.Lock()
598
- defer cli.groupCacheLock.Unlock()
599
- }
600
- participants := make([]types.JID, len(groupInfo.Participants))
601
- lidPairs := make([]store.LIDMapping, len(groupInfo.Participants))
602
- for i, part := range groupInfo.Participants {
603
- participants[i] = part.JID
604
- if !part.PhoneNumber.IsEmpty() && !part.LID.IsEmpty() {
605
- lidPairs[i] = store.LIDMapping{
606
- LID: part.LID,
607
- PN: part.PhoneNumber,
608
- }
609
- }
610
- }
611
- cli.groupCache[jid] = &groupMetaCache{
612
- AddressingMode: groupInfo.AddressingMode,
613
- CommunityAnnouncementGroup: groupInfo.IsAnnounce && groupInfo.IsDefaultSubGroup,
614
- Members: participants,
615
- }
640
+ lidPairs, redactedPhones := cli.cacheGroupInfo(groupInfo, lockParticipantCache)
616
641
  err = cli.Store.LIDs.PutManyLIDMappings(ctx, lidPairs)
617
642
  if err != nil {
618
643
  cli.Log.Warnf("Failed to store LID mappings for members of %s: %v", jid, err)
619
644
  }
645
+ err = cli.Store.Contacts.PutManyRedactedPhones(ctx, redactedPhones)
646
+ if err != nil {
647
+ cli.Log.Warnf("Failed to store redacted phones for members of %s: %v", jid, err)
648
+ }
620
649
  return groupInfo, nil
621
650
  }
622
651
 
@@ -670,8 +699,8 @@ func (cli *Client) parseGroupNode(groupNode *waBinary.Node) (*types.GroupInfo, e
670
699
  group.OwnerJID = ag.OptionalJIDOrEmpty("creator")
671
700
  group.OwnerPN = ag.OptionalJIDOrEmpty("creator_pn")
672
701
 
673
- group.Name = ag.String("subject")
674
- group.NameSetAt = ag.UnixTime("s_t")
702
+ group.Name = ag.OptionalString("subject")
703
+ group.NameSetAt = ag.OptionalUnixTime("s_t")
675
704
  group.NameSetBy = ag.OptionalJIDOrEmpty("s_o")
676
705
  group.NameSetByPN = ag.OptionalJIDOrEmpty("s_o_pn")
677
706
 
@@ -738,8 +767,8 @@ func parseGroupLinkTargetNode(groupNode *waBinary.Node) (types.GroupLinkTarget,
738
767
  return types.GroupLinkTarget{
739
768
  JID: jidKey,
740
769
  GroupName: types.GroupName{
741
- Name: ag.String("subject"),
742
- NameSetAt: ag.UnixTime("s_t"),
770
+ Name: ag.OptionalString("subject"),
771
+ NameSetAt: ag.OptionalUnixTime("s_t"),
743
772
  },
744
773
  GroupIsDefaultSub: types.GroupIsDefaultSub{
745
774
  IsDefaultSubGroup: groupNode.GetChildByTag("default_sub_group").Tag == "default_sub_group",
@@ -777,10 +806,10 @@ func parseParticipantList(node *waBinary.Node) (participants []types.JID, lidPai
777
806
  return
778
807
  }
779
808
 
780
- func (cli *Client) parseGroupCreate(parentNode, node *waBinary.Node) (*events.JoinedGroup, []store.LIDMapping, error) {
809
+ func (cli *Client) parseGroupCreate(parentNode, node *waBinary.Node) (*events.JoinedGroup, []store.LIDMapping, []store.RedactedPhoneEntry, error) {
781
810
  groupNode, ok := node.GetOptionalChildByTag("group")
782
811
  if !ok {
783
- return nil, nil, fmt.Errorf("group create notification didn't contain group info")
812
+ return nil, nil, nil, fmt.Errorf("group create notification didn't contain group info")
784
813
  }
785
814
  var evt events.JoinedGroup
786
815
  pag := parentNode.AttrGetter()
@@ -793,19 +822,11 @@ func (cli *Client) parseGroupCreate(parentNode, node *waBinary.Node) (*events.Jo
793
822
  evt.Notify = pag.OptionalString("notify")
794
823
  info, err := cli.parseGroupNode(&groupNode)
795
824
  if err != nil {
796
- return nil, nil, fmt.Errorf("failed to parse group info in create notification: %w", err)
825
+ return nil, nil, nil, fmt.Errorf("failed to parse group info in create notification: %w", err)
797
826
  }
798
827
  evt.GroupInfo = *info
799
- lidPairs := make([]store.LIDMapping, 0, len(info.Participants))
800
- for _, pcp := range info.Participants {
801
- if !pcp.PhoneNumber.IsEmpty() && !pcp.LID.IsEmpty() {
802
- lidPairs = append(lidPairs, store.LIDMapping{
803
- LID: pcp.LID,
804
- PN: pcp.PhoneNumber,
805
- })
806
- }
807
- }
808
- return &evt, lidPairs, nil
828
+ lidPairs, redactedPhones := cli.cacheGroupInfo(info, true)
829
+ return &evt, lidPairs, redactedPhones, nil
809
830
  }
810
831
 
811
832
  func (cli *Client) parseGroupChange(node *waBinary.Node) (*events.GroupInfo, []store.LIDMapping, error) {
@@ -965,17 +986,17 @@ Outer:
965
986
  }
966
987
  }
967
988
 
968
- func (cli *Client) parseGroupNotification(node *waBinary.Node) (any, []store.LIDMapping, error) {
989
+ func (cli *Client) parseGroupNotification(node *waBinary.Node) (any, []store.LIDMapping, []store.RedactedPhoneEntry, error) {
969
990
  children := node.GetChildren()
970
991
  if len(children) == 1 && children[0].Tag == "create" {
971
992
  return cli.parseGroupCreate(node, &children[0])
972
993
  } else {
973
994
  groupChange, lidPairs, err := cli.parseGroupChange(node)
974
995
  if err != nil {
975
- return nil, nil, err
996
+ return nil, nil, nil, err
976
997
  }
977
998
  cli.updateGroupParticipantCache(groupChange)
978
- return groupChange, lidPairs, nil
999
+ return groupChange, lidPairs, nil, nil
979
1000
  }
980
1001
  }
981
1002