slidge-whatsapp 0.2.2__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.
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/PKG-INFO +6 -7
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/README.md +3 -3
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/pyproject.toml +8 -6
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/__init__.py +1 -1
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/contact.py +1 -1
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/event.go +56 -0
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/go.mod +11 -9
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/go.sum +16 -16
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/group.py +7 -2
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/media/media.go +8 -3
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/session.go +4 -5
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/session.py +53 -31
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/LICENSE +0 -0
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/build.py +0 -0
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/__main__.py +0 -0
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/command.py +0 -0
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/config.py +0 -0
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/gateway.go +0 -0
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/gateway.py +0 -0
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/media/ffmpeg.go +0 -0
- {slidge_whatsapp-0.2.2 → slidge_whatsapp-0.2.4}/slidge_whatsapp/media/mupdf.go +0 -0
- {slidge_whatsapp-0.2.2 → 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
|
+
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,10 +669,9 @@ 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:
|
|
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
|
-
Project-URL: Documentation, https://slidge.
|
|
674
|
+
Project-URL: Documentation, https://slidge.im/docs/slidge-whatsapp/main
|
|
676
675
|
Project-URL: Homepage, https://codeberg.org/slidge/slidge-whatsapp
|
|
677
676
|
Project-URL: Issues, https://codeberg.org/slidge/slidge-whatsapp/issues
|
|
678
677
|
Project-URL: Repository, https://codeberg.org/slidge/slidge-whatsapp
|
|
@@ -694,7 +693,7 @@ A
|
|
|
694
693
|
|
|
695
694
|
## Installation
|
|
696
695
|
|
|
697
|
-
Refer to the [slidge admin documentation](https://slidge.im/
|
|
696
|
+
Refer to the [slidge admin documentation](https://slidge.im/docs/slidge/main/admin/)
|
|
698
697
|
for general info on how to set up an XMPP server component.
|
|
699
698
|
|
|
700
699
|
### Containers
|
|
@@ -702,8 +701,8 @@ for general info on how to set up an XMPP server component.
|
|
|
702
701
|
From [the codeberg package registry](https://codeberg.org/slidge/-/packages?q=&type=container)
|
|
703
702
|
|
|
704
703
|
```sh
|
|
705
|
-
# use ravermeister/slidge-whatsapp for arm64 (thanks raver! <3)
|
|
706
|
-
docker run
|
|
704
|
+
# use docker.io/ravermeister/slidge-whatsapp for arm64 (thanks raver! <3)
|
|
705
|
+
docker run codeberg.org/slidge/slidge-whatsapp
|
|
707
706
|
```
|
|
708
707
|
|
|
709
708
|
### Python package
|
|
@@ -14,7 +14,7 @@ A
|
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
17
|
-
Refer to the [slidge admin documentation](https://slidge.im/
|
|
17
|
+
Refer to the [slidge admin documentation](https://slidge.im/docs/slidge/main/admin/)
|
|
18
18
|
for general info on how to set up an XMPP server component.
|
|
19
19
|
|
|
20
20
|
### Containers
|
|
@@ -22,8 +22,8 @@ for general info on how to set up an XMPP server component.
|
|
|
22
22
|
From [the codeberg package registry](https://codeberg.org/slidge/-/packages?q=&type=container)
|
|
23
23
|
|
|
24
24
|
```sh
|
|
25
|
-
# use ravermeister/slidge-whatsapp for arm64 (thanks raver! <3)
|
|
26
|
-
docker run
|
|
25
|
+
# use docker.io/ravermeister/slidge-whatsapp for arm64 (thanks raver! <3)
|
|
26
|
+
docker run codeberg.org/slidge/slidge-whatsapp
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
### Python package
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "slidge-whatsapp"
|
|
3
|
-
version = "v0.2.
|
|
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
|
-
"
|
|
19
|
-
"slidge>=0.2.4",
|
|
18
|
+
"slidge>=0.2.4,<0.3",
|
|
20
19
|
]
|
|
21
20
|
|
|
22
21
|
[project.urls]
|
|
@@ -24,7 +23,7 @@ Homepage = "https://codeberg.org/slidge/slidge-whatsapp"
|
|
|
24
23
|
Issues = "https://codeberg.org/slidge/slidge-whatsapp/issues"
|
|
25
24
|
Repository = "https://codeberg.org/slidge/slidge-whatsapp"
|
|
26
25
|
"Chat room" = "https://conference.nicoco.fr:5281/muc_log/slidge/"
|
|
27
|
-
Documentation = "https://slidge.
|
|
26
|
+
Documentation = "https://slidge.im/docs/slidge-whatsapp/main"
|
|
28
27
|
|
|
29
28
|
[project.scripts]
|
|
30
29
|
slidge-whatsapp = "slidge_whatsapp:main"
|
|
@@ -108,8 +107,9 @@ body = """
|
|
|
108
107
|
{% for commit in commits %}
|
|
109
108
|
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
|
|
110
109
|
{% if commit.breaking %}[**breaking**] {% endif %}\
|
|
111
|
-
{{ commit.message | upper_first }}\
|
|
112
|
-
{% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif %}\
|
|
110
|
+
{{ commit.message | split(pat="\n") | first | upper_first | trim }}\
|
|
111
|
+
{% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif %} \
|
|
112
|
+
[`{{ commit.id | truncate(length=7, end="") }}`](./commit/{{ commit.id }})\
|
|
113
113
|
{% endfor %}
|
|
114
114
|
{% endfor %}\n
|
|
115
115
|
"""
|
|
@@ -118,6 +118,8 @@ footer = """
|
|
|
118
118
|
"""
|
|
119
119
|
|
|
120
120
|
[tool.git-cliff.git]
|
|
121
|
+
conventional_commits = true
|
|
122
|
+
filter_unconventional = false
|
|
121
123
|
commit_parsers = [
|
|
122
124
|
{ message = "^feat", group = "<!-- 0 -->🚀 Features" },
|
|
123
125
|
{ message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
|
|
@@ -57,7 +57,7 @@ class Roster(LegacyRoster[str, Contact]):
|
|
|
57
57
|
avatar = self.session.whatsapp.GetAvatar(data.JID, contact.avatar or "")
|
|
58
58
|
if avatar.URL and contact.avatar != avatar.ID:
|
|
59
59
|
await contact.set_avatar(avatar.URL, avatar.ID)
|
|
60
|
-
elif avatar.URL == "":
|
|
60
|
+
elif avatar.URL == "" and avatar.ID == "":
|
|
61
61
|
await contact.set_avatar(None)
|
|
62
62
|
except RuntimeError as err:
|
|
63
63
|
self.session.log.error(
|
|
@@ -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)
|
|
@@ -578,6 +629,7 @@ func convertAttachment(attach *Attachment) error {
|
|
|
578
629
|
// these are some times misdetected as such.
|
|
579
630
|
if s.VideoWidth == 0 && s.VideoHeight == 0 && s.AudioSampleRate > 0 && s.Duration > 0 {
|
|
580
631
|
spec = voiceMessageSpec
|
|
632
|
+
spec.SourceMIME = media.TypeM4A
|
|
581
633
|
}
|
|
582
634
|
}
|
|
583
635
|
default:
|
|
@@ -586,6 +638,10 @@ func convertAttachment(attach *Attachment) error {
|
|
|
586
638
|
}
|
|
587
639
|
|
|
588
640
|
// Convert attachment between file-types, if source MIME matches the known list of convertable types.
|
|
641
|
+
if spec.SourceMIME == "" {
|
|
642
|
+
spec.SourceMIME = detectedMIME
|
|
643
|
+
}
|
|
644
|
+
|
|
589
645
|
data, err := media.Convert(ctx, attach.Data, &spec)
|
|
590
646
|
if err != nil {
|
|
591
647
|
return fmt.Errorf("failed converting attachment: %w", err)
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
module codeberg.org/slidge/slidge-whatsapp/slidge_whatsapp
|
|
2
2
|
|
|
3
|
-
go 1.
|
|
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.
|
|
11
|
-
go.mau.fi/whatsmeow v0.0.0-
|
|
12
|
-
golang.org/x/image v0.
|
|
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.
|
|
25
|
-
golang.org/x/crypto v0.
|
|
26
|
-
golang.org/x/net v0.
|
|
27
|
-
golang.org/x/sys v0.
|
|
28
|
-
google.golang.org/protobuf v1.36.
|
|
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.
|
|
41
|
-
go.mau.fi/libsignal v0.1.
|
|
42
|
-
go.mau.fi/util v0.8.
|
|
43
|
-
go.mau.fi/util v0.8.
|
|
44
|
-
go.mau.fi/whatsmeow v0.0.0-
|
|
45
|
-
go.mau.fi/whatsmeow v0.0.0-
|
|
46
|
-
golang.org/x/crypto v0.
|
|
47
|
-
golang.org/x/crypto v0.
|
|
48
|
-
golang.org/x/image v0.
|
|
49
|
-
golang.org/x/image v0.
|
|
50
|
-
golang.org/x/net v0.
|
|
51
|
-
golang.org/x/net v0.
|
|
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.
|
|
56
|
-
golang.org/x/sys v0.
|
|
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.
|
|
60
|
-
google.golang.org/protobuf v1.36.
|
|
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=
|
|
@@ -25,14 +25,13 @@ class MUC(LegacyMUC[str, str, Participant, str]):
|
|
|
25
25
|
|
|
26
26
|
HAS_DESCRIPTION = False
|
|
27
27
|
REACTIONS_SINGLE_EMOJI = True
|
|
28
|
-
_ALL_INFO_FILLED_ON_STARTUP = True
|
|
29
28
|
|
|
30
29
|
async def update_info(self):
|
|
31
30
|
try:
|
|
32
31
|
avatar = self.session.whatsapp.GetAvatar(self.legacy_id, self.avatar or "")
|
|
33
32
|
if avatar.URL and self.avatar != avatar.ID:
|
|
34
33
|
await self.set_avatar(avatar.URL, avatar.ID)
|
|
35
|
-
elif avatar.URL == "":
|
|
34
|
+
elif avatar.URL == "" and avatar.ID == "":
|
|
36
35
|
await self.set_avatar(None)
|
|
37
36
|
except RuntimeError as err:
|
|
38
37
|
self.session.log.error(
|
|
@@ -95,6 +94,12 @@ class MUC(LegacyMUC[str, str, Participant, str]):
|
|
|
95
94
|
if name := participant.nickname:
|
|
96
95
|
self.subject_setter = name
|
|
97
96
|
self.session.whatsapp_participants[self.legacy_id] = info.Participants
|
|
97
|
+
self.n_participants = len(info.Participants)
|
|
98
|
+
# Since whatsmeow does always emit a whatsapp.Group event even for participant changes,
|
|
99
|
+
# we need to do that to actually update the participant list.
|
|
100
|
+
if self._participants_filled:
|
|
101
|
+
async for _ in self.fill_participants():
|
|
102
|
+
pass
|
|
98
103
|
|
|
99
104
|
async def fill_participants(self) -> AsyncIterator[Participant]:
|
|
100
105
|
await self.session.bookmarks.ready
|
|
@@ -107,6 +107,8 @@ type Spec struct {
|
|
|
107
107
|
VideoHeight int // The height of the video stream, in pixels.
|
|
108
108
|
VideoFilter string // A complex filter to apply to the video stream.
|
|
109
109
|
|
|
110
|
+
Duration time.Duration // The duration of the audio or video stream.
|
|
111
|
+
|
|
110
112
|
ImageWidth int // The width of the image, in pixels.
|
|
111
113
|
ImageHeight int // The height of the image, in pixels.
|
|
112
114
|
ImageQuality int // Image quality for lossy image formats, typically a value from 1 to 100.
|
|
@@ -114,8 +116,8 @@ type Spec struct {
|
|
|
114
116
|
|
|
115
117
|
DocumentPage int // The number of pages for the document.
|
|
116
118
|
|
|
117
|
-
|
|
118
|
-
StripMetadata bool
|
|
119
|
+
SourceMIME MIMEType // The MIME type for the source data. If not set, this is derived from the source data.
|
|
120
|
+
StripMetadata bool // Whether or not to remove any container-level metadata present in the stream.
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
// CommandLineArgs returns the current [Spec] as a list of command-line arguments meant for FFMPEG
|
|
@@ -216,7 +218,10 @@ func (s Spec) commandLineArgs() ([]string, error) {
|
|
|
216
218
|
// specification given. For information on how these definitions affect media conversions, see the
|
|
217
219
|
// documentation for the [Spec] type.
|
|
218
220
|
func Convert(ctx context.Context, data []byte, spec *Spec) ([]byte, error) {
|
|
219
|
-
var from, to =
|
|
221
|
+
var from, to = spec.SourceMIME, spec.MIME.BaseMediaType()
|
|
222
|
+
if from == "" {
|
|
223
|
+
from = DetectMIMEType(data)
|
|
224
|
+
}
|
|
220
225
|
switch from {
|
|
221
226
|
case TypeOgg, TypeM4A:
|
|
222
227
|
switch to {
|
|
@@ -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
|
|
|
@@ -535,15 +534,15 @@ func (s *Session) GetAvatar(resourceID, avatarID string) (Avatar, error) {
|
|
|
535
534
|
}
|
|
536
535
|
|
|
537
536
|
p, err := s.client.GetProfilePictureInfo(jid, &whatsmeow.GetProfilePictureParams{ExistingID: avatarID})
|
|
538
|
-
if err
|
|
539
|
-
|
|
540
|
-
|
|
537
|
+
if errors.Is(err, whatsmeow.ErrProfilePictureNotSet) || errors.Is(err, whatsmeow.ErrProfilePictureUnauthorized) {
|
|
538
|
+
return Avatar{}, nil
|
|
539
|
+
} else if err != nil {
|
|
541
540
|
return Avatar{}, fmt.Errorf("Could not get avatar: %s", err)
|
|
542
541
|
} else if p != nil {
|
|
543
542
|
return Avatar{ID: p.ID, URL: p.URL}, nil
|
|
544
543
|
}
|
|
545
544
|
|
|
546
|
-
return Avatar{}, nil
|
|
545
|
+
return Avatar{ID: avatarID}, nil
|
|
547
546
|
}
|
|
548
547
|
|
|
549
548
|
// SetAvatar updates the profile picture for the Contact or Group JID given; it can also update the
|
|
@@ -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(
|
|
@@ -590,30 +610,32 @@ class Session(BaseSession[str, Recipient]):
|
|
|
590
610
|
if not match:
|
|
591
611
|
return None
|
|
592
612
|
url = match.group("url")
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
613
|
+
try:
|
|
614
|
+
async with self.http.get(url) as resp:
|
|
615
|
+
if resp.status != 200:
|
|
616
|
+
self.log.debug(
|
|
617
|
+
"Could not generate a preview for %s because response status was %s",
|
|
618
|
+
url,
|
|
619
|
+
resp.status,
|
|
620
|
+
)
|
|
621
|
+
return None
|
|
622
|
+
if resp.content_type != "text/html":
|
|
623
|
+
self.log.debug(
|
|
624
|
+
"Could not generate a preview for %s because content type is %s",
|
|
625
|
+
url,
|
|
626
|
+
resp.content_type,
|
|
627
|
+
)
|
|
628
|
+
return None
|
|
629
|
+
try:
|
|
630
|
+
html = await resp.text()
|
|
631
|
+
except Exception as e:
|
|
632
|
+
self.log.debug(
|
|
633
|
+
"Could not generate a preview for %s", url, exc_info=e
|
|
634
|
+
)
|
|
635
|
+
return None
|
|
636
|
+
preview = LinkPreview(Link(url, html))
|
|
637
|
+
if not preview.title:
|
|
638
|
+
return None
|
|
617
639
|
thumbnail = (
|
|
618
640
|
await get_url_bytes(self.http, preview.image)
|
|
619
641
|
if preview.image
|
|
@@ -635,9 +657,9 @@ class Session(BaseSession[str, Recipient]):
|
|
|
635
657
|
else go.Slice_byte()
|
|
636
658
|
),
|
|
637
659
|
)
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
660
|
+
except Exception as e:
|
|
661
|
+
self.log.debug("Could not generate a preview for %s", url, exc_info=e)
|
|
662
|
+
return None
|
|
641
663
|
|
|
642
664
|
async def __get_location(self, text: str) -> Optional[whatsapp.Location]:
|
|
643
665
|
match = search(GEO_URI_SEARCH_REGEX, text)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|