push.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Copyright (c) 2024 Tulir Asokan
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. package whatsmeow
  7. import (
  8. "context"
  9. "encoding/base64"
  10. "go.mau.fi/util/random"
  11. waBinary "go.mau.fi/whatsmeow/binary"
  12. "go.mau.fi/whatsmeow/types"
  13. )
  14. type PushConfig interface {
  15. GetPushConfigAttrs() waBinary.Attrs
  16. }
  17. type FCMPushConfig struct {
  18. Token string `json:"token"`
  19. }
  20. func (fpc *FCMPushConfig) GetPushConfigAttrs() waBinary.Attrs {
  21. return waBinary.Attrs{
  22. "id": fpc.Token,
  23. "num_acc": 1,
  24. "platform": "gcm",
  25. }
  26. }
  27. type APNsPushConfig struct {
  28. Token string `json:"token"`
  29. VoIPToken string `json:"voip_token"`
  30. MsgIDEncKey []byte `json:"msg_id_enc_key"`
  31. }
  32. func (apc *APNsPushConfig) GetPushConfigAttrs() waBinary.Attrs {
  33. if len(apc.MsgIDEncKey) != 32 {
  34. apc.MsgIDEncKey = random.Bytes(32)
  35. }
  36. attrs := waBinary.Attrs{
  37. "id": apc.Token,
  38. "platform": "apple",
  39. "version": 2,
  40. "reg_push": 1,
  41. "preview": 1,
  42. "pkey": base64.RawURLEncoding.EncodeToString(apc.MsgIDEncKey),
  43. "background_location": 1, // or 0
  44. "call": "Opening.m4r",
  45. "default": "note.m4r",
  46. "groups": "note.m4r",
  47. "lg": "en",
  48. "lc": "US",
  49. "nse_call": 0,
  50. "nse_ver": 2,
  51. "nse_read": 0,
  52. "voip_payload_type": 2,
  53. }
  54. if apc.VoIPToken != "" {
  55. attrs["voip"] = apc.VoIPToken
  56. }
  57. return attrs
  58. }
  59. type WebPushConfig struct {
  60. Endpoint string `json:"endpoint"`
  61. Auth []byte `json:"auth"`
  62. P256DH []byte `json:"p256dh"`
  63. }
  64. func (wpc *WebPushConfig) GetPushConfigAttrs() waBinary.Attrs {
  65. return waBinary.Attrs{
  66. "platform": "web",
  67. "endpoint": wpc.Endpoint,
  68. "auth": base64.StdEncoding.EncodeToString(wpc.Auth),
  69. "p256dh": base64.StdEncoding.EncodeToString(wpc.P256DH),
  70. }
  71. }
  72. func (cli *Client) GetServerPushNotificationConfig(ctx context.Context) (*waBinary.Node, error) {
  73. resp, err := cli.sendIQ(ctx, infoQuery{
  74. Namespace: "urn:xmpp:whatsapp:push",
  75. Type: iqGet,
  76. To: types.ServerJID,
  77. Content: []waBinary.Node{{Tag: "settings"}},
  78. })
  79. return resp, err
  80. }
  81. // RegisterForPushNotifications registers a token to receive push notifications for new WhatsApp messages.
  82. //
  83. // This is generally not necessary for anything. Don't use this if you don't know what you're doing.
  84. func (cli *Client) RegisterForPushNotifications(ctx context.Context, pc PushConfig) error {
  85. _, err := cli.sendIQ(ctx, infoQuery{
  86. Namespace: "urn:xmpp:whatsapp:push",
  87. Type: iqSet,
  88. To: types.ServerJID,
  89. Content: []waBinary.Node{{
  90. Tag: "config",
  91. Attrs: pc.GetPushConfigAttrs(),
  92. }},
  93. })
  94. return err
  95. }