slidge-whatsapp 0.2.3__tar.gz → 0.2.4__tar.gz

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 (22) hide show
  1. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/PKG-INFO +2 -3
  2. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/pyproject.toml +2 -3
  3. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/__init__.py +1 -1
  4. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/event.go +51 -0
  5. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/go.mod +11 -9
  6. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/go.sum +16 -16
  7. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/session.go +0 -1
  8. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/session.py +24 -4
  9. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/LICENSE +0 -0
  10. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/README.md +0 -0
  11. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/build.py +0 -0
  12. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/__main__.py +0 -0
  13. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/command.py +0 -0
  14. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/config.py +0 -0
  15. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/contact.py +0 -0
  16. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/gateway.go +0 -0
  17. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/gateway.py +0 -0
  18. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/group.py +0 -0
  19. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/media/ffmpeg.go +0 -0
  20. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/media/media.go +0 -0
  21. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/media/mupdf.go +0 -0
  22. {slidge_whatsapp-0.2.3 → slidge_whatsapp-0.2.4}/slidge_whatsapp/media/stub.go +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: slidge-whatsapp
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: A Whatsapp/XMPP gateway.
5
5
  License: GNU AFFERO GENERAL PUBLIC LICENSE
6
6
  Version 3, 19 November 2007
@@ -669,8 +669,7 @@ Author-email: nicoco@nicoco.fr
669
669
  Requires-Python: >= 3.11
670
670
  Classifier: Topic :: Internet :: XMPP
671
671
  Requires-Dist: linkpreview (>=0.11.0)
672
- Requires-Dist: pybindgen (>=0.22.1)
673
- Requires-Dist: slidge (>=0.2.4)
672
+ Requires-Dist: slidge (>=0.2.4,<0.3)
674
673
  Project-URL: Chat room, https://conference.nicoco.fr:5281/muc_log/slidge/
675
674
  Project-URL: Documentation, https://slidge.im/docs/slidge-whatsapp/main
676
675
  Project-URL: Homepage, https://codeberg.org/slidge/slidge-whatsapp
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "slidge-whatsapp"
3
- version = "v0.2.3"
3
+ version = "v0.2.4"
4
4
  description = "A Whatsapp/XMPP gateway."
5
5
  authors = [
6
6
  {name = "nicoco", email = "nicoco@nicoco.fr"},
@@ -15,8 +15,7 @@ requires-python = ">= 3.11"
15
15
  keywords = ["xmpp", "gateway", "bridge", "instant messaging", "whatsapp"]
16
16
  dependencies = [
17
17
  "linkpreview>=0.11.0",
18
- "pybindgen>=0.22.1",
19
- "slidge>=0.2.4",
18
+ "slidge>=0.2.4,<0.3",
20
19
  ]
21
20
 
22
21
  [project.urls]
@@ -13,5 +13,5 @@ def main():
13
13
  entrypoint("slidge_whatsapp")
14
14
 
15
15
 
16
- __version__ = "v0.2.3"
16
+ __version__ = "v0.2.4"
17
17
  __all__ = "Gateway", "session", "command", "contact", "config", "group", "main"
@@ -145,6 +145,7 @@ const (
145
145
  MessageRevoke
146
146
  MessageReaction
147
147
  MessageAttachment
148
+ MessagePoll
148
149
  )
149
150
 
150
151
  // A Message represents one of many kinds of bidirectional communication payloads, for example, a
@@ -165,6 +166,8 @@ type Message struct {
165
166
  Attachments []Attachment // The list of file (image, video, etc.) attachments contained in this message.
166
167
  Preview Preview // A short description for the URL provided in the message body, if any.
167
168
  Location Location // The location metadata for messages, if any.
169
+ Poll Poll // The multiple-choice poll contained in the message, if any.
170
+ Album Album // The image album message, if any.
168
171
  MentionJIDs []string // A list of JIDs mentioned in this message, if any.
169
172
  Receipts []Receipt // The receipt statuses for the message, typically provided alongside historical messages.
170
173
  Reactions []Message // Reactions attached to message, typically provided alongside historical messages.
@@ -228,6 +231,25 @@ type Location struct {
228
231
  URL string
229
232
  }
230
233
 
234
+ // A Poll represents a multiple-choice question, on which each choice might be voted for one or more
235
+ // times.
236
+ type Poll struct {
237
+ Title string // The human-readable name of this poll.
238
+ Options []PollOption // The list of choices to vote on in the poll.
239
+ }
240
+
241
+ // A PollOption represents an individual choice within a broader poll.
242
+ type PollOption struct {
243
+ Title string // The human-readable name for the poll option.
244
+ }
245
+
246
+ // A Album message represents a collection of media files, typically images and videos.
247
+ type Album struct {
248
+ IsAlbum bool // Whether or not the message is an album, regardless of calculated media counts.
249
+ ImageCount int // The calculated amount of images in the album, might not be accurate.
250
+ VideoCount int // The calculated amount of videos in the album, might not be accurate.
251
+ }
252
+
231
253
  // NewMessageEvent returns event data meant for [Session.propagateEvent] for the primive message
232
254
  // event given. Unknown or invalid messages will return an [EventUnknown] event with nil data.
233
255
  func newMessageEvent(client *whatsmeow.Client, evt *events.Message) (EventKind, *EventPayload) {
@@ -306,6 +328,35 @@ func newMessageEvent(client *whatsmeow.Client, evt *events.Message) (EventKind,
306
328
  return EventMessage, &EventPayload{Message: message}
307
329
  }
308
330
 
331
+ // Handle poll messages.
332
+ for _, p := range []*waE2E.PollCreationMessage{
333
+ evt.Message.GetPollCreationMessageV3(),
334
+ evt.Message.GetPollCreationMessageV2(),
335
+ evt.Message.GetPollCreationMessage(),
336
+ } {
337
+ if p == nil {
338
+ continue
339
+ }
340
+ message.Kind = MessagePoll
341
+ message.Poll = Poll{Title: p.GetName()}
342
+ for _, o := range p.GetOptions() {
343
+ message.Poll.Options = append(message.Poll.Options, PollOption{
344
+ Title: o.GetOptionName(),
345
+ })
346
+ }
347
+ return EventMessage, &EventPayload{Message: message}
348
+ }
349
+
350
+ // Handle "album" messages, denoting a grouping of media messages to follow.
351
+ if a := evt.Message.GetAlbumMessage(); a != nil {
352
+ message.Album = Album{
353
+ IsAlbum: true,
354
+ ImageCount: int(a.GetExpectedImageCount()),
355
+ VideoCount: int(a.GetExpectedVideoCount()),
356
+ }
357
+ return EventMessage, &EventPayload{Message: message}
358
+ }
359
+
309
360
  // Handle message attachments, if any.
310
361
  if attach, context, err := getMessageAttachments(client, evt.Message); err != nil {
311
362
  client.Log.Errorf("Failed getting message attachments: %s", err)
@@ -1,15 +1,17 @@
1
1
  module codeberg.org/slidge/slidge-whatsapp/slidge_whatsapp
2
2
 
3
- go 1.22.0
3
+ go 1.23.0
4
+
5
+ toolchain go1.24.1
4
6
 
5
7
  require (
6
8
  github.com/gen2brain/go-fitz v1.24.14
7
9
  github.com/go-python/gopy v0.4.11-0.20241206185020-5f285b890023
8
10
  github.com/h2non/filetype v1.1.3
9
11
  github.com/mattn/go-sqlite3 v1.14.24
10
- go.mau.fi/libsignal v0.1.1
11
- go.mau.fi/whatsmeow v0.0.0-20250104105216-918c879fcd19
12
- golang.org/x/image v0.23.0
12
+ go.mau.fi/libsignal v0.1.2
13
+ go.mau.fi/whatsmeow v0.0.0-20250307203951-daf102be9698
14
+ golang.org/x/image v0.25.0
13
15
  )
14
16
 
15
17
  require (
@@ -21,9 +23,9 @@ require (
21
23
  github.com/mattn/go-colorable v0.1.14 // indirect
22
24
  github.com/mattn/go-isatty v0.0.20 // indirect
23
25
  github.com/rs/zerolog v1.33.0 // indirect
24
- go.mau.fi/util v0.8.4 // indirect
25
- golang.org/x/crypto v0.32.0 // indirect
26
- golang.org/x/net v0.34.0 // indirect
27
- golang.org/x/sys v0.29.0 // indirect
28
- google.golang.org/protobuf v1.36.4 // indirect
26
+ go.mau.fi/util v0.8.5 // indirect
27
+ golang.org/x/crypto v0.36.0 // indirect
28
+ golang.org/x/net v0.37.0 // indirect
29
+ golang.org/x/sys v0.31.0 // indirect
30
+ google.golang.org/protobuf v1.36.5 // indirect
29
31
  )
@@ -37,26 +37,26 @@ github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
37
37
  github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
38
38
  github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
39
39
  github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
40
- go.mau.fi/libsignal v0.1.1 h1:m/0PGBh4QKP/I1MQ44ti4C0fMbLMuHb95cmDw01FIpI=
41
- go.mau.fi/libsignal v0.1.1/go.mod h1:QLs89F/OA3ThdSL2Wz2p+o+fi8uuQUz0e1BRa6ExdBw=
42
- go.mau.fi/util v0.8.4 h1:mVKlJcXWfVo8ZW3f4vqtjGpqtZqJvX4ETekxawt2vnQ=
43
- go.mau.fi/util v0.8.4/go.mod h1:MOfGTs1CBuK6ERTcSL4lb5YU7/ujz09eOPVEDckuazY=
44
- go.mau.fi/whatsmeow v0.0.0-20250104105216-918c879fcd19 h1:uVS+Zct5fF8rSXV9lfs87zoXdge0JXTzVGNkjmZ61UU=
45
- go.mau.fi/whatsmeow v0.0.0-20250104105216-918c879fcd19/go.mod h1:TLzm2XkwgufONEmiVAsFny+9uBqyEZnUoPrQAfMyuSU=
46
- golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
47
- golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
48
- golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68=
49
- golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY=
50
- golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
51
- golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
40
+ go.mau.fi/libsignal v0.1.2 h1:Vs16DXWxSKyzVtI+EEXLCSy5pVWzzCzp/2eqFGvLyP0=
41
+ go.mau.fi/libsignal v0.1.2/go.mod h1:JpnLSSJptn/s1sv7I56uEMywvz8x4YzxeF5OzdPb6PE=
42
+ go.mau.fi/util v0.8.5 h1:PwCAAtcfK0XxZ4sdErJyfBMkTEWoQU33aB7QqDDzQRI=
43
+ go.mau.fi/util v0.8.5/go.mod h1:Ycug9mrbztlahHPEJ6H5r8Nu/xqZaWbE5vPHVWmfz6M=
44
+ go.mau.fi/whatsmeow v0.0.0-20250307203951-daf102be9698 h1:JRng1Qa5ZyOx59Cprle+DNf8LN0MAT2WJZis38hwuHQ=
45
+ go.mau.fi/whatsmeow v0.0.0-20250307203951-daf102be9698/go.mod h1:6hRrUtDWI2wTRClOd6m17GwrFE2a8/p5R4pjJsIVn+U=
46
+ golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
47
+ golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
48
+ golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ=
49
+ golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs=
50
+ golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
51
+ golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
52
52
  golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
53
53
  golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
54
54
  golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
55
- golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
56
- golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
55
+ golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
56
+ golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
57
57
  golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
58
58
  golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
59
- google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
60
- google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
59
+ google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
60
+ google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
61
61
  gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
62
62
  gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@@ -305,7 +305,6 @@ func (s *Session) getMessagePayload(message Message) *waE2E.Message {
305
305
  }
306
306
 
307
307
  payload.ExtendedTextMessage.MatchedText = &message.Preview.URL
308
- payload.ExtendedTextMessage.CanonicalURL = &message.Preview.URL
309
308
  payload.ExtendedTextMessage.Title = &message.Preview.Title
310
309
  payload.ExtendedTextMessage.Description = &message.Preview.Description
311
310
 
@@ -138,12 +138,12 @@ class Session(BaseSession[str, Recipient]):
138
138
  # not updated.
139
139
  if self.__connected.done():
140
140
  if data.Connect.Error != "":
141
+ self.send_gateway_status("Connection error", show="dnd")
142
+ self.send_gateway_message(data.Connect.Error)
143
+ else:
141
144
  self.send_gateway_status(
142
145
  self.__get_connected_status_message(), show="chat"
143
146
  )
144
- else:
145
- self.send_gateway_status("Connection error", show="dnd")
146
- self.send_gateway_message(data.Connect.Error)
147
147
  elif data.Connect.Error != "":
148
148
  self.xmpp.loop.call_soon_threadsafe(
149
149
  self.__connected.set_exception,
@@ -160,7 +160,9 @@ class Session(BaseSession[str, Recipient]):
160
160
  self.send_gateway_message(MESSAGE_LOGGED_OUT)
161
161
  self.send_gateway_status("Logged out", show="away")
162
162
  elif event == whatsapp.EventContact:
163
- await self.contacts.add_whatsapp_contact(data.Contact)
163
+ contact = await self.contacts.add_whatsapp_contact(data.Contact)
164
+ if contact is not None:
165
+ await contact.add_to_roster()
164
166
  elif event == whatsapp.EventGroup:
165
167
  await self.bookmarks.add_whatsapp_group(data.Group)
166
168
  elif event == whatsapp.EventPresence:
@@ -263,6 +265,17 @@ class Session(BaseSession[str, Recipient]):
263
265
  contact.react(
264
266
  legacy_msg_id=message.ID, emojis=emojis, carbon=message.IsCarbon
265
267
  )
268
+ elif message.Kind == whatsapp.MessagePoll:
269
+ body = "🗳 %s" % message.Poll.Title
270
+ for option in message.Poll.Options:
271
+ body = body + "\n☐ %s" % option.Title
272
+ contact.send_text(
273
+ body=body,
274
+ legacy_msg_id=message.ID,
275
+ when=message_timestamp,
276
+ reply_to=reply_to,
277
+ carbon=message.IsCarbon,
278
+ )
266
279
  for receipt in message.Receipts:
267
280
  await self.handle_receipt(receipt)
268
281
  for reaction in message.Reactions:
@@ -560,6 +573,13 @@ class Session(BaseSession[str, Recipient]):
560
573
  body = body + ";u=%d" % message.Location.Accuracy
561
574
  if message.IsForwarded:
562
575
  body = "↱ Forwarded message:\n " + add_quote_prefix(body)
576
+ if message.Album.IsAlbum:
577
+ body = body + "Album: "
578
+ if message.Album.ImageCount > 0:
579
+ body = body + "%d photos, " % message.Album.ImageCount
580
+ if message.Album.VideoCount > 0:
581
+ body = body + "%d videos" % message.Album.VideoCount
582
+ body = body.rstrip(" ,:")
563
583
  return body
564
584
 
565
585
  async def __get_reply_to(
File without changes