slidge-whatsapp 0.3.7__cp312-cp312-manylinux_2_41_aarch64.whl → 0.3.8__cp312-cp312-manylinux_2_41_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.
Files changed (164) hide show
  1. slidge_whatsapp/config.py +7 -2
  2. slidge_whatsapp/contact.py +3 -2
  3. slidge_whatsapp/event.go +14 -9
  4. slidge_whatsapp/gateway.go +7 -1
  5. slidge_whatsapp/generated/_whatsapp.cpython-312-aarch64-linux-gnu.h +182 -178
  6. slidge_whatsapp/generated/_whatsapp.cpython-312-aarch64-linux-gnu.so +0 -0
  7. slidge_whatsapp/generated/build.py +146 -142
  8. slidge_whatsapp/generated/whatsapp.c +1456 -1376
  9. slidge_whatsapp/generated/whatsapp.go +1069 -1045
  10. slidge_whatsapp/generated/whatsapp.py +1324 -1298
  11. slidge_whatsapp/generated/whatsapp_go.h +182 -178
  12. slidge_whatsapp/go.mod +6 -6
  13. slidge_whatsapp/go.sum +12 -12
  14. slidge_whatsapp/group.py +25 -0
  15. slidge_whatsapp/session.go +69 -67
  16. slidge_whatsapp/session.py +11 -1
  17. slidge_whatsapp/vendor/github.com/coder/websocket/LICENSE.txt +13 -0
  18. slidge_whatsapp/vendor/github.com/coder/websocket/Makefile +18 -0
  19. slidge_whatsapp/vendor/github.com/coder/websocket/README.md +162 -0
  20. slidge_whatsapp/vendor/github.com/coder/websocket/accept.go +378 -0
  21. slidge_whatsapp/vendor/github.com/coder/websocket/close.go +335 -0
  22. slidge_whatsapp/vendor/github.com/coder/websocket/compress.go +234 -0
  23. slidge_whatsapp/vendor/github.com/coder/websocket/conn.go +306 -0
  24. slidge_whatsapp/vendor/github.com/coder/websocket/dial.go +347 -0
  25. slidge_whatsapp/vendor/github.com/coder/websocket/doc.go +33 -0
  26. slidge_whatsapp/vendor/github.com/coder/websocket/errors.go +8 -0
  27. slidge_whatsapp/vendor/github.com/coder/websocket/frame.go +173 -0
  28. slidge_whatsapp/vendor/github.com/coder/websocket/hijack.go +33 -0
  29. slidge_whatsapp/vendor/github.com/coder/websocket/internal/bpool/bpool.go +25 -0
  30. slidge_whatsapp/vendor/github.com/coder/websocket/internal/errd/wrap.go +14 -0
  31. slidge_whatsapp/vendor/github.com/coder/websocket/internal/util/util.go +15 -0
  32. slidge_whatsapp/vendor/github.com/coder/websocket/internal/wsjs/wsjs_js.go +169 -0
  33. slidge_whatsapp/vendor/github.com/coder/websocket/mask.go +128 -0
  34. slidge_whatsapp/vendor/github.com/coder/websocket/mask_amd64.s +127 -0
  35. slidge_whatsapp/vendor/github.com/coder/websocket/mask_arm64.s +72 -0
  36. slidge_whatsapp/vendor/github.com/coder/websocket/mask_asm.go +26 -0
  37. slidge_whatsapp/vendor/github.com/coder/websocket/mask_go.go +7 -0
  38. slidge_whatsapp/vendor/github.com/coder/websocket/netconn.go +233 -0
  39. slidge_whatsapp/vendor/github.com/coder/websocket/netconn_js.go +11 -0
  40. slidge_whatsapp/vendor/github.com/coder/websocket/netconn_notjs.go +19 -0
  41. slidge_whatsapp/vendor/github.com/coder/websocket/read.go +540 -0
  42. slidge_whatsapp/vendor/github.com/coder/websocket/stringer.go +91 -0
  43. slidge_whatsapp/vendor/github.com/coder/websocket/write.go +384 -0
  44. slidge_whatsapp/vendor/github.com/coder/websocket/ws_js.go +598 -0
  45. slidge_whatsapp/vendor/github.com/ebitengine/purego/func.go +1 -1
  46. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_amd64.go +1 -1
  47. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_arm64.go +3 -1
  48. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_loong64.go +1 -1
  49. slidge_whatsapp/vendor/github.com/vektah/gqlparser/v2/ast/directive.go +3 -0
  50. slidge_whatsapp/vendor/github.com/vektah/gqlparser/v2/ast/selection.go +3 -0
  51. slidge_whatsapp/vendor/github.com/vektah/gqlparser/v2/ast/value.go +4 -3
  52. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate/encode.go +3 -0
  53. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate.go +18 -4
  54. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/broadcast.go +3 -3
  55. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/call.go +6 -4
  56. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/client.go +90 -80
  57. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/connectionevents.go +14 -11
  58. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/download.go +4 -1
  59. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/group.go +47 -48
  60. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/handshake.go +3 -2
  61. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/internals.go +79 -75
  62. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/keepalive.go +8 -6
  63. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/mediaconn.go +1 -2
  64. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/mediaretry.go +2 -2
  65. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/message.go +42 -40
  66. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/newsletter.go +35 -32
  67. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/notification.go +2 -3
  68. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/pair-code.go +2 -4
  69. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/pair.go +19 -19
  70. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/prekeys.go +9 -8
  71. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/presence.go +9 -9
  72. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/privacysettings.go +4 -5
  73. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloAddMessage/InstamadilloAddMessage.pb.go +1 -1
  74. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeActionLog/InstamadilloCoreTypeActionLog.pb.go +1 -1
  75. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeAdminMessage/InstamadilloCoreTypeAdminMessage.pb.go +1 -1
  76. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeCollection/InstamadilloCoreTypeCollection.pb.go +1 -1
  77. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeLink/InstamadilloCoreTypeLink.pb.go +1 -1
  78. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeMedia/InstamadilloCoreTypeMedia.pb.go +1 -1
  79. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloCoreTypeText/InstamadilloCoreTypeText.pb.go +1 -1
  80. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloDeleteMessage/InstamadilloDeleteMessage.pb.go +1 -1
  81. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloSupplementMessage/InstamadilloSupplementMessage.pb.go +1 -1
  82. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloTransportPayload/InstamadilloTransportPayload.pb.go +1 -1
  83. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/instamadilloXmaContentRef/InstamadilloXmaContentRef.pb.go +1 -1
  84. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waAICommon/WAAICommon.pb.go +1145 -335
  85. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waAICommon/WAAICommon.proto +78 -0
  86. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waAdv/WAAdv.pb.go +1 -1
  87. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waArmadilloApplication/WAArmadilloApplication.pb.go +1 -1
  88. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waArmadilloXMA/WAArmadilloXMA.pb.go +1 -1
  89. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waCert/WACert.pb.go +1 -1
  90. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waChatLockSettings/WAProtobufsChatLockSettings.pb.go +1 -1
  91. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waCommon/WACommon.pb.go +1 -1
  92. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waCompanionReg/WACompanionReg.pb.go +22 -4
  93. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waCompanionReg/WACompanionReg.proto +2 -0
  94. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waConsumerApplication/WAConsumerApplication.pb.go +1 -1
  95. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waDeviceCapabilities/WAProtobufsDeviceCapabilities.pb.go +104 -30
  96. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waDeviceCapabilities/WAProtobufsDeviceCapabilities.proto +7 -0
  97. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.pb.go +1037 -963
  98. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.proto +15 -8
  99. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waHistorySync/WAWebProtobufsHistorySync.pb.go +1 -1
  100. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waLidMigrationSyncPayload/WAWebProtobufLidMigrationSyncPayload.pb.go +1 -1
  101. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMediaTransport/WAMediaTransport.pb.go +1 -1
  102. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMmsRetry/WAMmsRetry.pb.go +1 -1
  103. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMsgApplication/WAMsgApplication.pb.go +1 -1
  104. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMsgTransport/WAMsgTransport.pb.go +1 -1
  105. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waMultiDevice/WAMultiDevice.pb.go +1 -1
  106. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waServerSync/WAServerSync.pb.go +1 -1
  107. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waStatusAttributions/WAStatusAttributions.pb.go +40 -35
  108. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waStatusAttributions/WAStatusAttributions.proto +1 -0
  109. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.pb.go +921 -653
  110. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.proto +44 -15
  111. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waUserPassword/WAProtobufsUserPassword.pb.go +1 -1
  112. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waVnameCert/WAWebProtobufsVnameCert.pb.go +1 -1
  113. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWa6/WAWebProtobufsWa6.pb.go +9 -5
  114. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWa6/WAWebProtobufsWa6.proto +1 -0
  115. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.pb.go +193 -115
  116. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.proto +9 -0
  117. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/push.go +2 -4
  118. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/receipt.go +12 -12
  119. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/request.go +25 -19
  120. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/retry.go +2 -2
  121. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/send.go +43 -27
  122. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/sendfb.go +4 -4
  123. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/socket/constants.go +1 -1
  124. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/socket/framesocket.go +43 -56
  125. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/socket/noisehandshake.go +9 -3
  126. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/socket/noisesocket.go +36 -22
  127. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/clientpayload.go +24 -4
  128. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/store.go +12 -0
  129. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/events/appstate.go +2 -1
  130. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/upload.go +1 -1
  131. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/user.go +79 -40
  132. slidge_whatsapp/vendor/golang.org/x/sys/unix/mkerrors.sh +2 -0
  133. slidge_whatsapp/vendor/golang.org/x/sys/unix/syscall_linux.go +6 -0
  134. slidge_whatsapp/vendor/golang.org/x/sys/unix/zerrors_linux.go +359 -0
  135. slidge_whatsapp/vendor/golang.org/x/sys/unix/zsyscall_linux.go +10 -0
  136. slidge_whatsapp/vendor/golang.org/x/sys/unix/ztypes_linux.go +31 -0
  137. slidge_whatsapp/vendor/golang.org/x/sys/windows/syscall_windows.go +15 -0
  138. slidge_whatsapp/vendor/golang.org/x/sys/windows/types_windows.go +76 -0
  139. slidge_whatsapp/vendor/golang.org/x/sys/windows/zsyscall_windows.go +37 -0
  140. slidge_whatsapp/vendor/modules.txt +12 -8
  141. {slidge_whatsapp-0.3.7.dist-info → slidge_whatsapp-0.3.8.dist-info}/METADATA +1 -1
  142. {slidge_whatsapp-0.3.7.dist-info → slidge_whatsapp-0.3.8.dist-info}/RECORD +145 -136
  143. slidge_whatsapp/vendor/github.com/gorilla/websocket/.gitignore +0 -25
  144. slidge_whatsapp/vendor/github.com/gorilla/websocket/AUTHORS +0 -9
  145. slidge_whatsapp/vendor/github.com/gorilla/websocket/LICENSE +0 -22
  146. slidge_whatsapp/vendor/github.com/gorilla/websocket/README.md +0 -33
  147. slidge_whatsapp/vendor/github.com/gorilla/websocket/client.go +0 -434
  148. slidge_whatsapp/vendor/github.com/gorilla/websocket/compression.go +0 -148
  149. slidge_whatsapp/vendor/github.com/gorilla/websocket/conn.go +0 -1238
  150. slidge_whatsapp/vendor/github.com/gorilla/websocket/doc.go +0 -227
  151. slidge_whatsapp/vendor/github.com/gorilla/websocket/join.go +0 -42
  152. slidge_whatsapp/vendor/github.com/gorilla/websocket/json.go +0 -60
  153. slidge_whatsapp/vendor/github.com/gorilla/websocket/mask.go +0 -55
  154. slidge_whatsapp/vendor/github.com/gorilla/websocket/mask_safe.go +0 -16
  155. slidge_whatsapp/vendor/github.com/gorilla/websocket/prepared.go +0 -102
  156. slidge_whatsapp/vendor/github.com/gorilla/websocket/proxy.go +0 -77
  157. slidge_whatsapp/vendor/github.com/gorilla/websocket/server.go +0 -365
  158. slidge_whatsapp/vendor/github.com/gorilla/websocket/tls_handshake.go +0 -21
  159. slidge_whatsapp/vendor/github.com/gorilla/websocket/tls_handshake_116.go +0 -21
  160. slidge_whatsapp/vendor/github.com/gorilla/websocket/util.go +0 -298
  161. slidge_whatsapp/vendor/github.com/gorilla/websocket/x_net_proxy.go +0 -473
  162. {slidge_whatsapp-0.3.7.dist-info → slidge_whatsapp-0.3.8.dist-info}/WHEEL +0 -0
  163. {slidge_whatsapp-0.3.7.dist-info → slidge_whatsapp-0.3.8.dist-info}/entry_points.txt +0 -0
  164. {slidge_whatsapp-0.3.7.dist-info → slidge_whatsapp-0.3.8.dist-info}/licenses/LICENSE +0 -0
@@ -68,7 +68,7 @@ func (cli *Client) cancelResponse(reqID string, ch chan *waBinary.Node) {
68
68
  cli.responseWaitersLock.Unlock()
69
69
  }
70
70
 
71
- func (cli *Client) receiveResponse(data *waBinary.Node) bool {
71
+ func (cli *Client) receiveResponse(ctx context.Context, data *waBinary.Node) bool {
72
72
  id, ok := data.Attrs["id"].(string)
73
73
  if !ok || (data.Tag != "iq" && data.Tag != "ack") {
74
74
  return false
@@ -81,7 +81,10 @@ func (cli *Client) receiveResponse(data *waBinary.Node) bool {
81
81
  }
82
82
  delete(cli.responseWaiters, id)
83
83
  cli.responseWaitersLock.Unlock()
84
- waiter <- data
84
+ select {
85
+ case waiter <- data:
86
+ case <-ctx.Done():
87
+ }
85
88
  return true
86
89
  }
87
90
 
@@ -103,10 +106,9 @@ type infoQuery struct {
103
106
 
104
107
  Timeout time.Duration
105
108
  NoRetry bool
106
- Context context.Context
107
109
  }
108
110
 
109
- func (cli *Client) sendIQAsyncAndGetData(query *infoQuery) (<-chan *waBinary.Node, []byte, error) {
111
+ func (cli *Client) sendIQAsyncAndGetData(ctx context.Context, query *infoQuery) (<-chan *waBinary.Node, []byte, error) {
110
112
  if cli == nil {
111
113
  return nil, nil, ErrClientIsNil
112
114
  }
@@ -128,7 +130,7 @@ func (cli *Client) sendIQAsyncAndGetData(query *infoQuery) (<-chan *waBinary.Nod
128
130
  if !query.Target.IsEmpty() {
129
131
  attrs["target"] = query.Target
130
132
  }
131
- data, err := cli.sendNodeAndGetData(waBinary.Node{
133
+ data, err := cli.sendNodeAndGetData(ctx, waBinary.Node{
132
134
  Tag: "iq",
133
135
  Attrs: attrs,
134
136
  Content: query.Content,
@@ -140,23 +142,20 @@ func (cli *Client) sendIQAsyncAndGetData(query *infoQuery) (<-chan *waBinary.Nod
140
142
  return waiter, data, nil
141
143
  }
142
144
 
143
- func (cli *Client) sendIQAsync(query infoQuery) (<-chan *waBinary.Node, error) {
144
- ch, _, err := cli.sendIQAsyncAndGetData(&query)
145
+ func (cli *Client) sendIQAsync(ctx context.Context, query infoQuery) (<-chan *waBinary.Node, error) {
146
+ ch, _, err := cli.sendIQAsyncAndGetData(ctx, &query)
145
147
  return ch, err
146
148
  }
147
149
 
148
150
  const defaultRequestTimeout = 75 * time.Second
149
151
 
150
- func (cli *Client) sendIQ(query infoQuery) (*waBinary.Node, error) {
151
- resChan, data, err := cli.sendIQAsyncAndGetData(&query)
152
- if err != nil {
153
- return nil, err
154
- }
152
+ func (cli *Client) sendIQ(ctx context.Context, query infoQuery) (*waBinary.Node, error) {
155
153
  if query.Timeout == 0 {
156
154
  query.Timeout = defaultRequestTimeout
157
155
  }
158
- if query.Context == nil {
159
- query.Context = context.Background()
156
+ resChan, data, err := cli.sendIQAsyncAndGetData(ctx, &query)
157
+ if err != nil {
158
+ return nil, err
160
159
  }
161
160
  select {
162
161
  case res := <-resChan:
@@ -164,7 +163,7 @@ func (cli *Client) sendIQ(query infoQuery) (*waBinary.Node, error) {
164
163
  if query.NoRetry {
165
164
  return nil, &DisconnectedError{Action: "info query", Node: res}
166
165
  }
167
- res, err = cli.retryFrame("info query", query.ID, data, res, query.Context, query.Timeout)
166
+ res, err = cli.retryFrame(ctx, "info query", query.ID, data, res, query.Timeout)
168
167
  if err != nil {
169
168
  return nil, err
170
169
  }
@@ -176,14 +175,21 @@ func (cli *Client) sendIQ(query infoQuery) (*waBinary.Node, error) {
176
175
  return res, parseIQError(res)
177
176
  }
178
177
  return res, nil
179
- case <-query.Context.Done():
180
- return nil, query.Context.Err()
178
+ case <-ctx.Done():
179
+ return nil, ctx.Err()
181
180
  case <-time.After(query.Timeout):
182
181
  return nil, ErrIQTimedOut
183
182
  }
184
183
  }
185
184
 
186
- func (cli *Client) retryFrame(reqType, id string, data []byte, origResp *waBinary.Node, ctx context.Context, timeout time.Duration) (*waBinary.Node, error) {
185
+ func (cli *Client) retryFrame(
186
+ ctx context.Context,
187
+ reqType,
188
+ id string,
189
+ data []byte,
190
+ origResp *waBinary.Node,
191
+ timeout time.Duration,
192
+ ) (*waBinary.Node, error) {
187
193
  if isAuthErrorDisconnect(origResp) {
188
194
  cli.Log.Debugf("%s (%s) was interrupted by websocket disconnection (%s), not retrying as it looks like an auth error", id, reqType, origResp.XMLString())
189
195
  return nil, &DisconnectedError{Action: reqType, Node: origResp}
@@ -203,7 +209,7 @@ func (cli *Client) retryFrame(reqType, id string, data []byte, origResp *waBinar
203
209
  }
204
210
 
205
211
  respChan := cli.waitResponse(id)
206
- err := sock.SendFrame(data)
212
+ err := sock.SendFrame(ctx, data)
207
213
  if err != nil {
208
214
  cli.cancelResponse(id, respChan)
209
215
  return nil, err
@@ -295,7 +295,7 @@ func (cli *Client) handleRetryReceipt(ctx context.Context, receipt *events.Recei
295
295
  {Tag: "franking", Content: []waBinary.Node{{Tag: "franking_tag", Content: frankingTag}}},
296
296
  }
297
297
  }
298
- err = cli.sendNode(waBinary.Node{
298
+ err = cli.sendNode(ctx, waBinary.Node{
299
299
  Tag: "message",
300
300
  Attrs: attrs,
301
301
  Content: content,
@@ -444,7 +444,7 @@ func (cli *Client) sendRetryReceipt(ctx context.Context, node *waBinary.Node, in
444
444
  })
445
445
  }
446
446
  }
447
- err := cli.sendNode(payload)
447
+ err := cli.sendNode(ctx, payload)
448
448
  if err != nil {
449
449
  cli.Log.Errorf("Failed to send retry receipt for %s: %v", id, err)
450
450
  }
@@ -331,7 +331,7 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, message *waE2E
331
331
  return
332
332
  } else if toLID.IsEmpty() {
333
333
  var info map[types.JID]types.UserInfo
334
- info, err = cli.GetUserInfo([]types.JID{to})
334
+ info, err = cli.GetUserInfo(ctx, []types.JID{to})
335
335
  if err != nil {
336
336
  err = fmt.Errorf("failed to get user info for %s to fill LID cache: %w", to, err)
337
337
  return
@@ -396,10 +396,10 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, message *waE2E
396
396
  if req.Peer {
397
397
  data, err = cli.sendPeerMessage(ctx, to, req.ID, message, &resp.DebugTimings)
398
398
  } else {
399
- data, err = cli.sendDM(ctx, ownID, to, req.ID, message, &resp.DebugTimings, extraParams)
399
+ phash, data, err = cli.sendDM(ctx, ownID, to, req.ID, message, &resp.DebugTimings, extraParams)
400
400
  }
401
401
  case types.NewsletterServer:
402
- data, err = cli.sendNewsletter(to, req.ID, message, req.MediaHandle, &resp.DebugTimings)
402
+ data, err = cli.sendNewsletter(ctx, to, req.ID, message, req.MediaHandle, &resp.DebugTimings)
403
403
  default:
404
404
  err = fmt.Errorf("%w %s", ErrUnknownServer, to.Server)
405
405
  }
@@ -429,7 +429,7 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, message *waE2E
429
429
  resp.DebugTimings.Resp = time.Since(start)
430
430
  if isDisconnectNode(respNode) {
431
431
  start = time.Now()
432
- respNode, err = cli.retryFrame("message send", req.ID, data, respNode, ctx, 0)
432
+ respNode, err = cli.retryFrame(ctx, "message send", req.ID, data, respNode, 0)
433
433
  resp.DebugTimings.Retry = time.Since(start)
434
434
  if err != nil {
435
435
  return
@@ -443,11 +443,20 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, message *waE2E
443
443
  }
444
444
  expectedPHash := ag.OptionalString("phash")
445
445
  if len(expectedPHash) > 0 && phash != expectedPHash {
446
- cli.Log.Warnf("Server returned different participant list hash when sending to %s. Some devices may not have received the message.", to)
447
- // TODO also invalidate device list caches
448
- cli.groupCacheLock.Lock()
449
- delete(cli.groupCache, to)
450
- cli.groupCacheLock.Unlock()
446
+ cli.Log.Warnf("Server returned different participant list hash (%s != %s) when sending to %s. Some devices may not have received the message.", phash, expectedPHash, to)
447
+ switch to.Server {
448
+ case types.GroupServer:
449
+ // TODO also invalidate device list caches
450
+ cli.groupCacheLock.Lock()
451
+ delete(cli.groupCache, to)
452
+ cli.groupCacheLock.Unlock()
453
+ case types.BroadcastServer:
454
+ // TODO do something
455
+ case types.DefaultUserServer, types.HiddenUserServer, types.BotServer, types.HostedServer, types.HostedLIDServer:
456
+ cli.userDevicesCacheLock.Lock()
457
+ delete(cli.userDevicesCache, to)
458
+ cli.userDevicesCacheLock.Unlock()
459
+ }
451
460
  }
452
461
  return
453
462
  }
@@ -458,8 +467,8 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, message *waE2E
458
467
  // The return value is the timestamp of the message from the server.
459
468
  //
460
469
  // Deprecated: This method is deprecated in favor of BuildRevoke
461
- func (cli *Client) RevokeMessage(chat types.JID, id types.MessageID) (SendResponse, error) {
462
- return cli.SendMessage(context.TODO(), chat, cli.BuildRevoke(chat, types.EmptyJID, id))
470
+ func (cli *Client) RevokeMessage(ctx context.Context, chat types.JID, id types.MessageID) (SendResponse, error) {
471
+ return cli.SendMessage(ctx, chat, cli.BuildRevoke(chat, types.EmptyJID, id))
463
472
  }
464
473
 
465
474
  // BuildMessageKey builds a MessageKey object, which is used to refer to previous messages
@@ -618,13 +627,13 @@ func ParseDisappearingTimerString(val string) (time.Duration, bool) {
618
627
  // and in groups the server will just reject the change. You can use the DisappearingTimer<Duration> constants for convenience.
619
628
  //
620
629
  // In groups, the server will echo the change as a notification, so it'll show up as a *events.GroupInfo update.
621
- func (cli *Client) SetDisappearingTimer(chat types.JID, timer time.Duration, settingTS time.Time) (err error) {
630
+ func (cli *Client) SetDisappearingTimer(ctx context.Context, chat types.JID, timer time.Duration, settingTS time.Time) (err error) {
622
631
  switch chat.Server {
623
632
  case types.DefaultUserServer, types.HiddenUserServer:
624
633
  if settingTS.IsZero() {
625
634
  settingTS = time.Now()
626
635
  }
627
- _, err = cli.SendMessage(context.TODO(), chat, &waE2E.Message{
636
+ _, err = cli.SendMessage(ctx, chat, &waE2E.Message{
628
637
  ProtocolMessage: &waE2E.ProtocolMessage{
629
638
  Type: waE2E.ProtocolMessage_EPHEMERAL_SETTING.Enum(),
630
639
  EphemeralExpiration: proto.Uint32(uint32(timer.Seconds())),
@@ -633,9 +642,9 @@ func (cli *Client) SetDisappearingTimer(chat types.JID, timer time.Duration, set
633
642
  })
634
643
  case types.GroupServer:
635
644
  if timer == 0 {
636
- _, err = cli.sendGroupIQ(context.TODO(), iqSet, chat, waBinary.Node{Tag: "not_ephemeral"})
645
+ _, err = cli.sendGroupIQ(ctx, iqSet, chat, waBinary.Node{Tag: "not_ephemeral"})
637
646
  } else {
638
- _, err = cli.sendGroupIQ(context.TODO(), iqSet, chat, waBinary.Node{
647
+ _, err = cli.sendGroupIQ(ctx, iqSet, chat, waBinary.Node{
639
648
  Tag: "ephemeral",
640
649
  Attrs: waBinary.Attrs{
641
650
  "expiration": strconv.Itoa(int(timer.Seconds())),
@@ -663,6 +672,7 @@ func participantListHashV2(participants []types.JID) string {
663
672
  }
664
673
 
665
674
  func (cli *Client) sendNewsletter(
675
+ ctx context.Context,
666
676
  to types.JID,
667
677
  id types.MessageID,
668
678
  message *waE2E.Message,
@@ -706,7 +716,7 @@ func (cli *Client) sendNewsletter(
706
716
  Content: []waBinary.Node{plaintextNode},
707
717
  }
708
718
  start = time.Now()
709
- data, err := cli.sendNodeAndGetData(node)
719
+ data, err := cli.sendNodeAndGetData(ctx, node)
710
720
  timings.Send = time.Since(start)
711
721
  if err != nil {
712
722
  return nil, fmt.Errorf("failed to send message node: %w", err)
@@ -787,7 +797,7 @@ func (cli *Client) sendGroup(
787
797
  }
788
798
 
789
799
  start = time.Now()
790
- data, err := cli.sendNodeAndGetData(*node)
800
+ data, err := cli.sendNodeAndGetData(ctx, *node)
791
801
  timings.Send = time.Since(start)
792
802
  if err != nil {
793
803
  return "", nil, fmt.Errorf("failed to send message node: %w", err)
@@ -807,7 +817,7 @@ func (cli *Client) sendPeerMessage(
807
817
  return nil, err
808
818
  }
809
819
  start := time.Now()
810
- data, err := cli.sendNodeAndGetData(*node)
820
+ data, err := cli.sendNodeAndGetData(ctx, *node)
811
821
  timings.Send = time.Since(start)
812
822
  if err != nil {
813
823
  return nil, fmt.Errorf("failed to send message node: %w", err)
@@ -823,21 +833,22 @@ func (cli *Client) sendDM(
823
833
  message *waE2E.Message,
824
834
  timings *MessageDebugTimings,
825
835
  extraParams nodeExtraParams,
826
- ) ([]byte, error) {
836
+ ) (string, []byte, error) {
827
837
  start := time.Now()
828
838
  messagePlaintext, deviceSentMessagePlaintext, err := marshalMessage(to, message)
829
839
  timings.Marshal = time.Since(start)
830
840
  if err != nil {
831
- return nil, err
841
+ return "", nil, err
832
842
  }
833
843
 
834
- node, _, err := cli.prepareMessageNode(
844
+ node, allDevices, err := cli.prepareMessageNode(
835
845
  ctx, to, id, message, []types.JID{to, ownID.ToNonAD()},
836
846
  messagePlaintext, deviceSentMessagePlaintext, timings, extraParams,
837
847
  )
838
848
  if err != nil {
839
- return nil, err
849
+ return "", nil, err
840
850
  }
851
+ phash := participantListHashV2(allDevices)
841
852
 
842
853
  if cli.shouldIncludeReportingToken(message) && message.GetMessageContextInfo().GetMessageSecret() != nil {
843
854
  node.Content = append(node.GetChildren(), cli.getMessageReportingToken(messagePlaintext, message, ownID, to, id))
@@ -853,12 +864,12 @@ func (cli *Client) sendDM(
853
864
  }
854
865
 
855
866
  start = time.Now()
856
- data, err := cli.sendNodeAndGetData(*node)
867
+ data, err := cli.sendNodeAndGetData(ctx, *node)
857
868
  timings.Send = time.Since(start)
858
869
  if err != nil {
859
- return nil, fmt.Errorf("failed to send message node: %w", err)
870
+ return "", nil, fmt.Errorf("failed to send message node: %w", err)
860
871
  }
861
- return data, nil
872
+ return phash, data, nil
862
873
  }
863
874
 
864
875
  func getTypeFromMessage(msg *waE2E.Message) string {
@@ -1049,7 +1060,12 @@ func (cli *Client) preparePeerMessageNode(
1049
1060
  if err != nil {
1050
1061
  return nil, fmt.Errorf("failed to encrypt peer message for %s: %v", to, err)
1051
1062
  }
1052
- content := []waBinary.Node{*encrypted}
1063
+ content := []waBinary.Node{{
1064
+ Tag: "meta",
1065
+ Attrs: waBinary.Attrs{
1066
+ "appdata": "default",
1067
+ },
1068
+ }, *encrypted}
1053
1069
  if isPreKey && cli.MessengerConfig == nil {
1054
1070
  content = append(content, cli.makeDeviceIdentityNode())
1055
1071
  }
@@ -1117,7 +1133,7 @@ func (cli *Client) prepareMessageNode(
1117
1133
  extraParams nodeExtraParams,
1118
1134
  ) (*waBinary.Node, []types.JID, error) {
1119
1135
  start := time.Now()
1120
- allDevices, err := cli.GetUserDevicesContext(ctx, participants)
1136
+ allDevices, err := cli.GetUserDevices(ctx, participants)
1121
1137
  timings.GetDevices = time.Since(start)
1122
1138
  if err != nil {
1123
1139
  return nil, nil, fmt.Errorf("failed to get device list: %w", err)
@@ -182,7 +182,7 @@ func (cli *Client) SendFBMessage(
182
182
  resp.DebugTimings.Resp = time.Since(start)
183
183
  if isDisconnectNode(respNode) {
184
184
  start = time.Now()
185
- respNode, err = cli.retryFrame("message send", req.ID, data, respNode, ctx, 0)
185
+ respNode, err = cli.retryFrame(ctx, "message send", req.ID, data, respNode, 0)
186
186
  resp.DebugTimings.Retry = time.Since(start)
187
187
  if err != nil {
188
188
  return
@@ -293,7 +293,7 @@ func (cli *Client) sendGroupV3(
293
293
  node.Content = append(node.GetChildren(), skMsg)
294
294
 
295
295
  start = time.Now()
296
- data, err := cli.sendNodeAndGetData(*node)
296
+ data, err := cli.sendNodeAndGetData(ctx, *node)
297
297
  timings.Send = time.Since(start)
298
298
  if err != nil {
299
299
  return "", nil, fmt.Errorf("failed to send message node: %w", err)
@@ -324,7 +324,7 @@ func (cli *Client) sendDMV3(
324
324
  return nil, "", err
325
325
  }
326
326
  start := time.Now()
327
- data, err := cli.sendNodeAndGetData(*node)
327
+ data, err := cli.sendNodeAndGetData(ctx, *node)
328
328
  timings.Send = time.Since(start)
329
329
  if err != nil {
330
330
  return nil, "", fmt.Errorf("failed to send message node: %w", err)
@@ -439,7 +439,7 @@ func (cli *Client) prepareMessageNodeV3(
439
439
  timings *MessageDebugTimings,
440
440
  ) (*waBinary.Node, []types.JID, error) {
441
441
  start := time.Now()
442
- allDevices, err := cli.GetUserDevicesContext(ctx, participants)
442
+ allDevices, err := cli.GetUserDevices(ctx, participants)
443
443
  timings.GetDevices = time.Since(start)
444
444
  if err != nil {
445
445
  return nil, nil, fmt.Errorf("failed to get device list: %w", err)
@@ -32,7 +32,7 @@ const (
32
32
  var WAConnHeader = []byte{'W', 'A', WAMagicValue, token.DictVersion}
33
33
 
34
34
  const (
35
- FrameMaxSize = 2 << 23
35
+ FrameMaxSize = 1 << 24
36
36
  FrameLengthSize = 3
37
37
  )
38
38
 
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2021 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
@@ -12,29 +12,30 @@ import (
12
12
  "fmt"
13
13
  "net/http"
14
14
  "sync"
15
- "time"
16
15
 
17
- "github.com/gorilla/websocket"
16
+ "github.com/coder/websocket"
18
17
 
19
18
  waLog "go.mau.fi/whatsmeow/util/log"
20
19
  )
21
20
 
22
21
  type FrameSocket struct {
23
- conn *websocket.Conn
24
- ctx context.Context
25
- cancel func()
26
- log waLog.Logger
27
- lock sync.Mutex
22
+ parentCtx context.Context
23
+ cancelCtx context.Context
24
+ cancel context.CancelFunc
25
+ conn *websocket.Conn
26
+ log waLog.Logger
27
+ lock sync.Mutex
28
28
 
29
29
  URL string
30
30
  HTTPHeaders http.Header
31
+ HTTPClient *http.Client
31
32
 
32
33
  Frames chan []byte
33
- OnDisconnect func(remote bool)
34
- WriteTimeout time.Duration
34
+ OnDisconnect func(ctx context.Context, remote bool)
35
35
 
36
36
  Header []byte
37
- Dialer websocket.Dialer
37
+
38
+ closed bool
38
39
 
39
40
  incomingLength int
40
41
  receivedLength int
@@ -42,17 +43,15 @@ type FrameSocket struct {
42
43
  partialHeader []byte
43
44
  }
44
45
 
45
- func NewFrameSocket(log waLog.Logger, dialer websocket.Dialer) *FrameSocket {
46
+ func NewFrameSocket(log waLog.Logger, client *http.Client) *FrameSocket {
46
47
  return &FrameSocket{
47
- conn: nil,
48
48
  log: log,
49
49
  Header: WAConnHeader,
50
50
  Frames: make(chan []byte),
51
51
 
52
52
  URL: URL,
53
53
  HTTPHeaders: http.Header{"Origin": {Origin}},
54
-
55
- Dialer: dialer,
54
+ HTTPClient: client,
56
55
  }
57
56
  }
58
57
 
@@ -60,11 +59,7 @@ func (fs *FrameSocket) IsConnected() bool {
60
59
  return fs.conn != nil
61
60
  }
62
61
 
63
- func (fs *FrameSocket) Context() context.Context {
64
- return fs.ctx
65
- }
66
-
67
- func (fs *FrameSocket) Close(code int) {
62
+ func (fs *FrameSocket) Close(code websocket.StatusCode) {
68
63
  fs.lock.Lock()
69
64
  defer fs.lock.Unlock()
70
65
 
@@ -72,58 +67,56 @@ func (fs *FrameSocket) Close(code int) {
72
67
  return
73
68
  }
74
69
 
70
+ fs.closed = true
75
71
  if code > 0 {
76
- message := websocket.FormatCloseMessage(code, "")
77
- err := fs.conn.WriteControl(websocket.CloseMessage, message, time.Now().Add(time.Second))
72
+ err := fs.conn.Close(code, "")
78
73
  if err != nil {
79
- fs.log.Warnf("Error sending close message: %v", err)
74
+ fs.log.Warnf("Error sending close to websocket: %v", err)
75
+ }
76
+ } else {
77
+ err := fs.conn.CloseNow()
78
+ if err != nil {
79
+ fs.log.Debugf("Error force closing websocket: %v", err)
80
80
  }
81
- }
82
-
83
- fs.cancel()
84
- err := fs.conn.Close()
85
- if err != nil {
86
- fs.log.Errorf("Error closing websocket: %v", err)
87
81
  }
88
82
  fs.conn = nil
89
- fs.ctx = nil
83
+ fs.cancel()
90
84
  fs.cancel = nil
91
85
  if fs.OnDisconnect != nil {
92
- go fs.OnDisconnect(code == 0)
86
+ go fs.OnDisconnect(fs.parentCtx, code == 0)
93
87
  }
94
88
  }
95
89
 
96
- func (fs *FrameSocket) Connect() error {
90
+ func (fs *FrameSocket) Connect(ctx context.Context) error {
97
91
  fs.lock.Lock()
98
92
  defer fs.lock.Unlock()
99
-
100
93
  if fs.conn != nil {
101
94
  return ErrSocketAlreadyOpen
102
95
  }
103
- ctx, cancel := context.WithCancel(context.Background())
96
+ fs.parentCtx = ctx
97
+ fs.cancelCtx, fs.cancel = context.WithCancel(ctx)
104
98
 
105
99
  fs.log.Debugf("Dialing %s", fs.URL)
106
- conn, _, err := fs.Dialer.Dial(fs.URL, fs.HTTPHeaders)
100
+ conn, _, err := websocket.Dial(ctx, fs.URL, &websocket.DialOptions{
101
+ HTTPClient: fs.HTTPClient,
102
+ HTTPHeader: fs.HTTPHeaders,
103
+ })
107
104
  if err != nil {
108
- cancel()
109
- return fmt.Errorf("couldn't dial whatsapp web websocket: %w", err)
105
+ fs.cancel()
106
+ return fmt.Errorf("failed to dial whatsapp web websocket: %w", err)
110
107
  }
108
+ conn.SetReadLimit(FrameMaxSize)
111
109
 
112
- fs.ctx, fs.cancel = ctx, cancel
113
110
  fs.conn = conn
114
- conn.SetCloseHandler(func(code int, text string) error {
115
- fs.log.Debugf("Server closed websocket with status %d/%s", code, text)
116
- cancel()
117
- // from default CloseHandler
118
- message := websocket.FormatCloseMessage(code, "")
119
- _ = conn.WriteControl(websocket.CloseMessage, message, time.Now().Add(time.Second))
120
- return nil
121
- })
122
111
 
123
112
  go fs.readPump(conn, ctx)
124
113
  return nil
125
114
  }
126
115
 
116
+ func (fs *FrameSocket) Context() context.Context {
117
+ return fs.cancelCtx
118
+ }
119
+
127
120
  func (fs *FrameSocket) SendFrame(data []byte) error {
128
121
  conn := fs.conn
129
122
  if conn == nil {
@@ -153,13 +146,7 @@ func (fs *FrameSocket) SendFrame(data []byte) error {
153
146
  // Copy actual frame data
154
147
  copy(wholeFrame[headerLength+FrameLengthSize:], data)
155
148
 
156
- if fs.WriteTimeout > 0 {
157
- err := conn.SetWriteDeadline(time.Now().Add(fs.WriteTimeout))
158
- if err != nil {
159
- fs.log.Warnf("Failed to set write deadline: %v", err)
160
- }
161
- }
162
- return conn.WriteMessage(websocket.BinaryMessage, wholeFrame)
149
+ return conn.Write(fs.cancelCtx, websocket.MessageBinary, wholeFrame)
163
150
  }
164
151
 
165
152
  func (fs *FrameSocket) frameComplete() {
@@ -219,14 +206,14 @@ func (fs *FrameSocket) readPump(conn *websocket.Conn, ctx context.Context) {
219
206
  go fs.Close(0)
220
207
  }()
221
208
  for {
222
- msgType, data, err := conn.ReadMessage()
209
+ msgType, data, err := conn.Read(ctx)
223
210
  if err != nil {
224
211
  // Ignore the error if the context has been closed
225
- if !errors.Is(ctx.Err(), context.Canceled) {
212
+ if !fs.closed && !errors.Is(ctx.Err(), context.Canceled) {
226
213
  fs.log.Errorf("Error reading from websocket: %v", err)
227
214
  }
228
215
  return
229
- } else if msgType != websocket.BinaryMessage {
216
+ } else if msgType != websocket.MessageBinary {
230
217
  fs.log.Warnf("Got unexpected websocket message type %d", msgType)
231
218
  continue
232
219
  }
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2021 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
@@ -7,6 +7,7 @@
7
7
  package socket
8
8
 
9
9
  import (
10
+ "context"
10
11
  "crypto/cipher"
11
12
  "crypto/sha256"
12
13
  "fmt"
@@ -74,14 +75,19 @@ func (nh *NoiseHandshake) Decrypt(ciphertext []byte) (plaintext []byte, err erro
74
75
  return
75
76
  }
76
77
 
77
- func (nh *NoiseHandshake) Finish(fs *FrameSocket, frameHandler FrameHandler, disconnectHandler DisconnectHandler) (*NoiseSocket, error) {
78
+ func (nh *NoiseHandshake) Finish(
79
+ ctx context.Context,
80
+ fs *FrameSocket,
81
+ frameHandler FrameHandler,
82
+ disconnectHandler DisconnectHandler,
83
+ ) (*NoiseSocket, error) {
78
84
  if write, read, err := nh.extractAndExpand(nh.salt, nil); err != nil {
79
85
  return nil, fmt.Errorf("failed to extract final keys: %w", err)
80
86
  } else if writeKey, err := gcmutil.Prepare(write); err != nil {
81
87
  return nil, fmt.Errorf("failed to create final write cipher: %w", err)
82
88
  } else if readKey, err := gcmutil.Prepare(read); err != nil {
83
89
  return nil, fmt.Errorf("failed to create final read cipher: %w", err)
84
- } else if ns, err := newNoiseSocket(fs, writeKey, readKey, frameHandler, disconnectHandler); err != nil {
90
+ } else if ns, err := newNoiseSocket(ctx, fs, writeKey, readKey, frameHandler, disconnectHandler); err != nil {
85
91
  return nil, fmt.Errorf("failed to create noise socket: %w", err)
86
92
  } else {
87
93
  return ns, nil