mirror of
https://github.com/mautrix/whatsapp.git
synced 2026-08-22 12:04:55 -04:00
Compare commits
12 changed files with 94 additions and 122 deletions
8
.github/workflows/go.yml
vendored
8
.github/workflows/go.yml
vendored
|
|
@ -11,14 +11,14 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
go-version: ["1.26", "1.27"]
|
||||
name: Lint ${{ matrix.go-version == '1.27' && '(latest)' || '(old)' }}
|
||||
go-version: ["1.25", "1.26"]
|
||||
name: Lint ${{ matrix.go-version == '1.26' && '(latest)' || '(old)' }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v7
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
cache: true
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
# v26.08
|
||||
|
||||
* Switched direct chats to use LIDs instead of phone numbers.
|
||||
|
||||
# v26.07
|
||||
|
||||
* Updated Docker image to Alpine 3.24.
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ var m = mxmain.BridgeMain{
|
|||
Name: "mautrix-whatsapp",
|
||||
URL: "https://github.com/mautrix/whatsapp",
|
||||
Description: "A Matrix-WhatsApp puppeting bridge.",
|
||||
Version: "26.08",
|
||||
Version: "26.07",
|
||||
SemCalVer: true,
|
||||
Connector: &connector.WhatsAppConnector{},
|
||||
}
|
||||
|
|
|
|||
30
go.mod
30
go.mod
|
|
@ -1,8 +1,8 @@
|
|||
module go.mau.fi/mautrix-whatsapp
|
||||
|
||||
go 1.26.0
|
||||
go 1.25.0
|
||||
|
||||
toolchain go1.27.0
|
||||
toolchain go1.26.5
|
||||
|
||||
tool go.mau.fi/util/cmd/maubuild
|
||||
|
||||
|
|
@ -10,15 +10,15 @@ require (
|
|||
github.com/lib/pq v1.12.3
|
||||
github.com/rs/zerolog v1.35.1
|
||||
github.com/tidwall/gjson v1.19.0
|
||||
go.mau.fi/util v0.10.1-0.20260820140024-eb612d936fde
|
||||
go.mau.fi/util v0.9.12-0.20260719092501-f9c03d846391
|
||||
go.mau.fi/webp v0.3.0
|
||||
go.mau.fi/whatsmeow v0.0.0-20260821141805-33cfac511629
|
||||
golang.org/x/image v0.45.0
|
||||
golang.org/x/net v0.58.0
|
||||
go.mau.fi/whatsmeow v0.0.0-20260805124304-6723e556f35a
|
||||
golang.org/x/image v0.44.0
|
||||
golang.org/x/net v0.57.0
|
||||
golang.org/x/sync v0.22.0
|
||||
google.golang.org/protobuf v1.36.12
|
||||
google.golang.org/protobuf v1.36.11
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
maunium.net/go/mautrix v0.30.1-0.20260820142923-ae00f2c62e1e
|
||||
maunium.net/go/mautrix v0.29.1-0.20260804113340-56938b8a508d
|
||||
)
|
||||
|
||||
require (
|
||||
|
|
@ -31,8 +31,8 @@ require (
|
|||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.49 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20260816044145-ed329add6b1b // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.48 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20260713124913-97594f28f5ca // indirect
|
||||
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||
github.com/rs/xid v1.6.0 // indirect
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
|
||||
|
|
@ -40,14 +40,14 @@ require (
|
|||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tidwall/sjson v1.2.5 // indirect
|
||||
github.com/vektah/gqlparser/v2 v2.5.27 // indirect
|
||||
github.com/yuin/goldmark v1.8.5 // indirect
|
||||
github.com/yuin/goldmark v1.8.4 // indirect
|
||||
go.mau.fi/libsignal v0.2.2 // indirect
|
||||
go.mau.fi/zeroconfig v0.2.0 // indirect
|
||||
golang.org/x/crypto v0.55.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20260813180055-c1d0aacb2297 // indirect
|
||||
golang.org/x/mod v0.40.0 // indirect
|
||||
golang.org/x/crypto v0.54.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20260709172345-9ea1abe57597 // indirect
|
||||
golang.org/x/mod v0.38.0 // indirect
|
||||
golang.org/x/sys v0.47.0 // indirect
|
||||
golang.org/x/text v0.41.0 // indirect
|
||||
golang.org/x/text v0.40.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
maunium.net/go/mauflag v1.0.0 // indirect
|
||||
|
|
|
|||
52
go.sum
52
go.sum
|
|
@ -34,10 +34,10 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP
|
|||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.49 h1:B8jBHC3xhxZgxztrgruTuLucebnULQnx4W7cF7SAE9w=
|
||||
github.com/mattn/go-sqlite3 v1.14.49/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
|
||||
github.com/petermattis/goid v0.0.0-20260816044145-ed329add6b1b h1:sS7HLzwS+dO+gxATgQfeZDEdUZe2pKAB3nGoUwP5zU0=
|
||||
github.com/petermattis/goid v0.0.0-20260816044145-ed329add6b1b/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
|
||||
github.com/mattn/go-sqlite3 v1.14.48 h1:7XHIgl0a8HwOaiK4E47ozLkST78rR9+OtNGx27D/TFs=
|
||||
github.com/mattn/go-sqlite3 v1.14.48/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
|
||||
github.com/petermattis/goid v0.0.0-20260713124913-97594f28f5ca h1:GHSUVE4yOgX4E7kTRzpxCPbCOYkd3Kj8Dgdod30OI1E=
|
||||
github.com/petermattis/goid v0.0.0-20260713124913-97594f28f5ca/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
|
|
@ -67,37 +67,37 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
|||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/vektah/gqlparser/v2 v2.5.27 h1:RHPD3JOplpk5mP5JGX8RKZkt2/Vwj/PZv0HxTdwFp0s=
|
||||
github.com/vektah/gqlparser/v2 v2.5.27/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo=
|
||||
github.com/yuin/goldmark v1.8.5 h1:r6N5afV5qj/5S4UTch8agZHJ8UxNCMwX7WjkkJam2NA=
|
||||
github.com/yuin/goldmark v1.8.5/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
||||
github.com/yuin/goldmark v1.8.4 h1:oat/nd3U6NeQqFEL3xpEJq7d7c86NI+DbSNGAs4xnjA=
|
||||
github.com/yuin/goldmark v1.8.4/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
||||
go.mau.fi/libsignal v0.2.2 h1:QV+XdzQkm3x3aSG7FcqfGSZuFXz83pRZPBFaPygHbOU=
|
||||
go.mau.fi/libsignal v0.2.2/go.mod h1:CRlIQg2J8uYTfDFvNoO8/KcZjs5cey0vbc6oj/bssY0=
|
||||
go.mau.fi/util v0.10.1-0.20260820140024-eb612d936fde h1:eMHY9dMDkNuDMWhfTbMZHbbsxj7G6mfujjKei1HaFQM=
|
||||
go.mau.fi/util v0.10.1-0.20260820140024-eb612d936fde/go.mod h1:z0ZZNt4hq3FZbUKnunexE/QscCx7VkLvQSvtggc/aE8=
|
||||
go.mau.fi/util v0.9.12-0.20260719092501-f9c03d846391 h1:lsvBEY8MJfYdV61YbwikiQvb0Al/onbmLW5wfl/0tag=
|
||||
go.mau.fi/util v0.9.12-0.20260719092501-f9c03d846391/go.mod h1:xunp/oIQfFD68HHcNHfG0pOiHkvEtDhTweeIwKJ//+Q=
|
||||
go.mau.fi/webp v0.3.0 h1:gVHQZtz21Ziwj+CDuklbX9mqpsnDIFKxs/BJyV7iZzA=
|
||||
go.mau.fi/webp v0.3.0/go.mod h1:rlZFTev+dYxhvk+XNBP/5GcTt4gXmzAB4DU0aGUYIQo=
|
||||
go.mau.fi/whatsmeow v0.0.0-20260821141805-33cfac511629 h1:99p9fTS1G73a1aifCVaV5MX4hDq0lVUKWGoUNoXyE3A=
|
||||
go.mau.fi/whatsmeow v0.0.0-20260821141805-33cfac511629/go.mod h1:aMd13H2xFFGH9cskcvxo4Aae+TmyFN38yw+HvsrpwVg=
|
||||
go.mau.fi/whatsmeow v0.0.0-20260805124304-6723e556f35a h1:TTRND9Dvq7YfT9vwJVQK4Zrit/sm3FHE74B5FWe8CgA=
|
||||
go.mau.fi/whatsmeow v0.0.0-20260805124304-6723e556f35a/go.mod h1:Iy/xVSuVU2payR26MB1hv0UZUWRraEn4qKZ7+VRHulg=
|
||||
go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU=
|
||||
go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w=
|
||||
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
|
||||
golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
|
||||
golang.org/x/exp v0.0.0-20260813180055-c1d0aacb2297 h1:YXnL44eJ77R+ji4/ooy8UsXIhz+lbi2Qgdlc8iRN0gY=
|
||||
golang.org/x/exp v0.0.0-20260813180055-c1d0aacb2297/go.mod h1:Mkmymgv+uMpSQ/XxJ/7GpdrdYoqm3u72jEbpCLiJmNk=
|
||||
golang.org/x/image v0.45.0 h1:FMb1nTbH5H9vF55SriQHgFw5GnNL9Jg6L25BwXKzhB0=
|
||||
golang.org/x/image v0.45.0/go.mod h1:n62x/7RqlwXDvGsSU4u6IUTUf6KghUZ9Bt7cG/T9Fx4=
|
||||
golang.org/x/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs=
|
||||
golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE=
|
||||
golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
|
||||
golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
|
||||
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
|
||||
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
|
||||
golang.org/x/exp v0.0.0-20260709172345-9ea1abe57597 h1:qLvzZeaANDgyVOA8pyHCOStGlXn0rseXma+GQjeuv2g=
|
||||
golang.org/x/exp v0.0.0-20260709172345-9ea1abe57597/go.mod h1:EdfpwwqSu+0Li0mzskwHU6FWDV3t9Q+RZDo3QMUtL3Q=
|
||||
golang.org/x/image v0.44.0 h1:+tDekMZED9+LrtB3G5xzRggpVh9CARjZqROla3R3R+I=
|
||||
golang.org/x/image v0.44.0/go.mod h1:V8K3KE9KKKE+pLpQDOeN18w9oacNSvy1tDOirTu4xtY=
|
||||
golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
|
||||
golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
|
||||
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
|
||||
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
|
||||
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
|
||||
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
|
||||
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
|
||||
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
|
||||
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
|
||||
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
|
||||
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
|
@ -107,5 +107,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M=
|
||||
maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
|
||||
maunium.net/go/mautrix v0.30.1-0.20260820142923-ae00f2c62e1e h1:ATvERyBIUXJrnL7ezP2xCLLGCNmGClmfzoQq4N3jBcA=
|
||||
maunium.net/go/mautrix v0.30.1-0.20260820142923-ae00f2c62e1e/go.mod h1:Y02sBiAvfEVqK24bwVGCprmLATRZ7prWel3ZpB413e0=
|
||||
maunium.net/go/mautrix v0.29.1-0.20260804113340-56938b8a508d h1:jbC6tXphot/X1UngnZLv7LcDTzaHBi2phwxrpyhtfrs=
|
||||
maunium.net/go/mautrix v0.29.1-0.20260804113340-56938b8a508d/go.mod h1:PeLuIih5jnbwb2xKNNi0Te7AtINEQE2Uv3p6iG3RV80=
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"go.mau.fi/util/exmaps"
|
||||
"go.mau.fi/util/ptr"
|
||||
"go.mau.fi/whatsmeow"
|
||||
"go.mau.fi/whatsmeow/proto/waE2E"
|
||||
|
|
@ -247,14 +246,12 @@ func (wa *WhatsAppClient) handleWAHistorySync(
|
|||
return c.Stringer("chat_jid", jid)
|
||||
})
|
||||
|
||||
var firstItemTime, lastItemTime time.Time
|
||||
var minTime, maxTime, firstItemTime, lastItemTime time.Time
|
||||
var minTimeIndex, maxTimeIndex int
|
||||
|
||||
ignoredTypes := 0
|
||||
rawMessages := conv.GetMessages()
|
||||
messages := make([]*wadb.HistorySyncMessageTuple, 0, len(rawMessages))
|
||||
allowClamp := conv.GetCommentsCount() == 0
|
||||
var newerTS uint64
|
||||
for i, rawMsg := range rawMessages {
|
||||
messages := make([]*wadb.HistorySyncMessageTuple, 0, len(conv.GetMessages()))
|
||||
for i, rawMsg := range conv.GetMessages() {
|
||||
// Don't store messages that will just be skipped.
|
||||
msgEvt, err := wa.Client.ParseWebMessage(jid, rawMsg.GetMessage())
|
||||
if err != nil {
|
||||
|
|
@ -272,30 +269,20 @@ func (wa *WhatsAppClient) handleWAHistorySync(
|
|||
firstItemTime = msgEvt.Info.Timestamp
|
||||
}
|
||||
lastItemTime = msgEvt.Info.Timestamp
|
||||
if minTime.IsZero() || msgEvt.Info.Timestamp.Before(minTime) {
|
||||
minTime = msgEvt.Info.Timestamp
|
||||
minTimeIndex = i
|
||||
}
|
||||
if maxTime.IsZero() || msgEvt.Info.Timestamp.After(maxTime) {
|
||||
maxTime = msgEvt.Info.Timestamp
|
||||
maxTimeIndex = i
|
||||
}
|
||||
|
||||
msgType := getMessageType(msgEvt.Message)
|
||||
if msgType == "ignore" || strings.HasPrefix(msgType, "unknown_protocol_") {
|
||||
ignoredTypes++
|
||||
continue
|
||||
}
|
||||
// Comments (replies) in announcement groups are not ordered by timestamp, so don't clamp them.
|
||||
if rawMsg.GetMessage().GetCommentMetadata().GetCommentParentKey() != nil {
|
||||
allowClamp = false
|
||||
}
|
||||
// WhatsApp has bugs where some random messages will have timestamps decades in the future.
|
||||
// To ensure they don't mess up our ordering, require timestamps of older messages to be
|
||||
// before the previous (newer) message.
|
||||
if currentTS := rawMsg.GetMessage().GetMessageTimestamp(); newerTS > 0 && allowClamp && currentTS > newerTS {
|
||||
log.Warn().
|
||||
Time("current_ts", time.Unix(int64(currentTS), 0)).
|
||||
Time("prev_ts", time.Unix(int64(newerTS), 0)).
|
||||
Int("msg_index", i).
|
||||
Str("msg_id", rawMsg.GetMessage().GetKey().GetID()).
|
||||
Msg("Clamping message timestamp")
|
||||
rawMsg.Message.MessageTimestamp = ptr.Ptr(newerTS)
|
||||
msgEvt.Info.Timestamp = time.Unix(int64(newerTS), 0)
|
||||
}
|
||||
newerTS = rawMsg.GetMessage().GetMessageTimestamp()
|
||||
marshaled, err := proto.Marshal(rawMsg)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).
|
||||
|
|
@ -310,8 +297,13 @@ func (wa *WhatsAppClient) handleWAHistorySync(
|
|||
log.Debug().
|
||||
Int("wrapped_count", len(messages)).
|
||||
Int("ignored_msg_type_count", ignoredTypes).
|
||||
Time("lowest_time", minTime).
|
||||
Int("lowest_time_index", minTimeIndex).
|
||||
Time("highest_time", maxTime).
|
||||
Int("highest_time_index", maxTimeIndex).
|
||||
Time("first_item_time", firstItemTime).
|
||||
Time("last_item_time", lastItemTime).
|
||||
Bool("highest_time_mismatch", firstItemTime != maxTime).
|
||||
Dict("metadata", zerolog.Dict().
|
||||
Uint32("ephemeral_expiration", conv.GetEphemeralExpiration()).
|
||||
Int64("ephemeral_setting_timestamp", conv.GetEphemeralSettingTimestamp()).
|
||||
|
|
@ -327,7 +319,7 @@ func (wa *WhatsAppClient) handleWAHistorySync(
|
|||
Msg("Collected messages to save from history sync conversation")
|
||||
|
||||
if len(messages) > 0 {
|
||||
err = wa.Main.DB.Conversation.Put(ctx, wadb.NewConversation(wa.UserLogin.ID, jid, conv, firstItemTime))
|
||||
err = wa.Main.DB.Conversation.Put(ctx, wadb.NewConversation(wa.UserLogin.ID, jid, conv, maxTime))
|
||||
if err != nil {
|
||||
if stopOnError {
|
||||
return fmt.Errorf("failed to save conversation metadata for %s: %w", jid, err)
|
||||
|
|
@ -605,7 +597,6 @@ func (wa *WhatsAppClient) convertHistorySyncMessages(
|
|||
newestTS := messages[0].GetMessageTimestamp()
|
||||
convertedMessages := make([]*bridgev2.BackfillMessage, 0, len(messages))
|
||||
var mediaRequests []*wadb.MediaRequest
|
||||
dups := make(exmaps.Set[networkid.MessageID])
|
||||
for i, msg := range messages {
|
||||
evt, err := wa.Client.ParseWebMessage(portalJID, msg)
|
||||
if err != nil {
|
||||
|
|
@ -636,11 +627,6 @@ func (wa *WhatsAppClient) convertHistorySyncMessages(
|
|||
converted, mediaReq := wa.convertHistorySyncMessage(
|
||||
ctx, portal, &evt.Info, evt.Message, evt.RawMessage, isViewOnce, msg.Reactions,
|
||||
)
|
||||
// This is a hack to remove duplicates where the same message is inserted with both the LID and phone number sender
|
||||
// TODO prevent those being inserted in the first place instead of hacking around it here
|
||||
if !dups.Add(converted.ID) {
|
||||
continue
|
||||
}
|
||||
convertedMessages = append(convertedMessages, converted)
|
||||
if mediaReq != nil {
|
||||
mediaRequests = append(mediaRequests, mediaReq)
|
||||
|
|
|
|||
|
|
@ -284,13 +284,14 @@ func (wa *WhatsAppClient) wrapGroupInfo(ctx context.Context, info *types.GroupIn
|
|||
Ban: ptr.Ptr(nobodyPL),
|
||||
// TODO allow invites if bridge config says to allow them, or maybe if relay mode is enabled?
|
||||
Events: map[event.Type]int{
|
||||
event.StateRoomName: metaChangePL,
|
||||
event.StateRoomAvatar: metaChangePL,
|
||||
event.StateTopic: metaChangePL,
|
||||
event.EventReaction: defaultPL,
|
||||
event.EventRedaction: defaultPL,
|
||||
event.EventUnstablePollResponse: defaultPL,
|
||||
event.StateRoomName: metaChangePL,
|
||||
event.StateRoomAvatar: metaChangePL,
|
||||
event.StateTopic: metaChangePL,
|
||||
event.EventReaction: defaultPL,
|
||||
event.EventRedaction: defaultPL,
|
||||
|
||||
event.StateBeeperDisappearingTimer: metaChangePL,
|
||||
// TODO always allow poll responses
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -550,12 +551,12 @@ func (wa *WhatsAppClient) wrapNewsletterInfo(ctx context.Context, info *types.Ne
|
|||
StateDefault: ptr.Ptr(nobodyPL),
|
||||
Ban: ptr.Ptr(nobodyPL),
|
||||
Events: map[event.Type]int{
|
||||
event.StateRoomName: adminPL,
|
||||
event.StateRoomAvatar: adminPL,
|
||||
event.StateTopic: adminPL,
|
||||
event.EventReaction: defaultPL,
|
||||
event.EventRedaction: defaultPL,
|
||||
event.EventUnstablePollResponse: defaultPL,
|
||||
event.StateRoomName: adminPL,
|
||||
event.StateRoomAvatar: adminPL,
|
||||
event.StateTopic: adminPL,
|
||||
event.EventReaction: defaultPL,
|
||||
event.EventRedaction: defaultPL,
|
||||
// TODO always allow poll responses
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -54,9 +54,8 @@ func (wa *WhatsAppConnector) LoadUserLogin(ctx context.Context, login *bridgev2.
|
|||
directMediaRetries: make(map[networkid.MessageID]*directMediaRetry),
|
||||
mediaRetryLock: semaphore.NewWeighted(wa.Config.HistorySync.MediaRequests.MaxAsyncHandle),
|
||||
pushNamesSynced: exsync.NewEvent(),
|
||||
createDedup: exsync.NewSet[types.MessageID](),
|
||||
appStateFullSyncAttempted: make(map[appstate.WAPatchName]time.Time),
|
||||
|
||||
disableNewsletter: store.BaseClientPayload.GetUserAgent().GetPlatform() == waWa6.ClientPayload_UserAgent_MACOS,
|
||||
}
|
||||
login.Client = w
|
||||
|
||||
|
|
@ -121,8 +120,7 @@ type WhatsAppClient struct {
|
|||
isNewLogin bool
|
||||
pushNamesSynced *exsync.Event
|
||||
lastPresence types.Presence
|
||||
|
||||
disableNewsletter bool
|
||||
createDedup *exsync.Set[types.MessageID]
|
||||
|
||||
appStateRecoveryLock sync.Mutex
|
||||
appStateFullSyncAttempted map[appstate.WAPatchName]time.Time
|
||||
|
|
|
|||
|
|
@ -285,9 +285,6 @@ func (wa *WhatsAppClient) handleWAMessage(ctx context.Context, evt *events.Messa
|
|||
if evt.Info.Chat == types.StatusBroadcastJID && !wa.Main.Config.EnableStatusBroadcast {
|
||||
return
|
||||
}
|
||||
if evt.Info.Chat.Server == types.NewsletterServer && wa.disableNewsletter {
|
||||
return
|
||||
}
|
||||
if !wa.ensureAltJIDs(ctx, &evt.Info.MessageSource, true) {
|
||||
return false
|
||||
}
|
||||
|
|
@ -770,6 +767,9 @@ func (wa *WhatsAppClient) handleWAGroupInfoChange(ctx context.Context, evt *even
|
|||
}
|
||||
|
||||
func (wa *WhatsAppClient) handleWAJoinedGroup(ctx context.Context, evt *events.JoinedGroup) bool {
|
||||
if wa.createDedup.Pop(evt.CreateKey) {
|
||||
return true
|
||||
}
|
||||
return wa.UserLogin.QueueRemoteEvent(&simplevent.ChatResync{
|
||||
EventMeta: simplevent.EventMeta{
|
||||
Type: bridgev2.RemoteEventChatResync,
|
||||
|
|
@ -782,9 +782,6 @@ func (wa *WhatsAppClient) handleWAJoinedGroup(ctx context.Context, evt *events.J
|
|||
}
|
||||
|
||||
func (wa *WhatsAppClient) handleWANewsletterJoin(ctx context.Context, evt *events.NewsletterJoin) bool {
|
||||
if wa.disableNewsletter {
|
||||
return true
|
||||
}
|
||||
return wa.UserLogin.QueueRemoteEvent(&simplevent.ChatResync{
|
||||
EventMeta: simplevent.EventMeta{
|
||||
Type: bridgev2.RemoteEventChatResync,
|
||||
|
|
@ -883,12 +880,7 @@ func (wa *WhatsAppClient) handleWAAppStateSyncComplete(ctx context.Context, evt
|
|||
} else {
|
||||
log.Info().
|
||||
Time("recovery_ts", ts).
|
||||
Bool("recovery_evt", evt.Recovery).
|
||||
Msg("Unmarked app state recovery as attempted after successful full sync")
|
||||
wa.UserLogin.TrackAnalytics("WhatsApp Appstate Recovery Success", map[string]any{
|
||||
"patch_name": evt.Name,
|
||||
"from_recovery": evt.Recovery,
|
||||
})
|
||||
}
|
||||
} else if ts, exists = wa.appStateFullSyncAttempted[evt.Name]; exists {
|
||||
delete(wa.appStateFullSyncAttempted, evt.Name)
|
||||
|
|
@ -945,9 +937,6 @@ func (wa *WhatsAppClient) handleWAAppStateSyncError(ctx context.Context, evt *ev
|
|||
if err != nil {
|
||||
log.Err(err).Msg("Failed to save login metadata after marking app state recovery as attempted")
|
||||
}
|
||||
wa.UserLogin.TrackAnalytics("WhatsApp Appstate Recovery Request", map[string]any{
|
||||
"patch_name": evt.Name,
|
||||
})
|
||||
go func() {
|
||||
resp, err := wa.Client.SendPeerMessage(ctx, whatsmeow.BuildAppStateRecoveryRequest(evt.Name))
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -135,8 +135,7 @@ var (
|
|||
_ bridgev2.LoginProcessWebAuthn = (*WALogin)(nil)
|
||||
)
|
||||
|
||||
const LoginConnectWait = 30 * time.Second
|
||||
const LoginPairPhoneWait = 30 * time.Second
|
||||
const LoginConnectWait = 15 * time.Second
|
||||
|
||||
func (wl *WALogin) Start(ctx context.Context) (*bridgev2.LoginStep, error) {
|
||||
wl.Main.firstClientConnectOnce.Do(wl.Main.onFirstClientConnect)
|
||||
|
|
@ -194,21 +193,19 @@ func (wl *WALogin) StartWithOverride(ctx context.Context, old *bridgev2.UserLogi
|
|||
}
|
||||
|
||||
func (wl *WALogin) SubmitUserInput(ctx context.Context, input map[string]string) (*bridgev2.LoginStep, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, LoginConnectWait)
|
||||
defer cancel()
|
||||
err := wl.Client.Connect()
|
||||
if err != nil {
|
||||
wl.Log.Err(err).Msg("Failed to connect to WhatsApp for phone code login")
|
||||
return nil, err
|
||||
}
|
||||
connectCtx, cancelConnect := context.WithTimeout(ctx, LoginConnectWait)
|
||||
err = wl.WaitForQRs.Wait(connectCtx)
|
||||
cancelConnect()
|
||||
err = wl.WaitForQRs.Wait(ctx)
|
||||
if err != nil {
|
||||
wl.Log.Warn().Err(err).Msg("Timed out waiting for connection")
|
||||
return nil, fmt.Errorf("failed to wait for connection: %w", err)
|
||||
}
|
||||
pairCtx, cancelPair := context.WithTimeout(ctx, LoginPairPhoneWait)
|
||||
defer cancelPair()
|
||||
pairingCode, err := wl.Client.PairPhone(pairCtx, input["phone_number"], true, whatsmeow.PairClientChrome, "Chrome (Linux)")
|
||||
pairingCode, err := wl.Client.PairPhone(ctx, input["phone_number"], true, whatsmeow.PairClientChrome, "Chrome (Linux)")
|
||||
if err != nil {
|
||||
wl.Log.Err(err).Msg("Failed to request phone code login")
|
||||
if errors.Is(err, whatsmeow.ErrPhoneNumberTooShort) {
|
||||
|
|
|
|||
|
|
@ -246,9 +246,14 @@ func (wa *WhatsAppClient) getContactList(ctx context.Context, filter string, onl
|
|||
}
|
||||
|
||||
func (wa *WhatsAppClient) CreateGroup(ctx context.Context, params *bridgev2.GroupCreateParams) (*bridgev2.CreateChatResponse, error) {
|
||||
createKey := wa.Client.GenerateMessageID()
|
||||
if params.RoomID != "" {
|
||||
wa.createDedup.Add(createKey)
|
||||
}
|
||||
req := whatsmeow.ReqCreateGroup{
|
||||
Name: ptr.Val(params.Name).Name,
|
||||
Participants: make([]types.JID, len(params.Participants)),
|
||||
CreateKey: createKey,
|
||||
}
|
||||
for i, participant := range params.Participants {
|
||||
jid := waid.ParseUserID(participant)
|
||||
|
|
|
|||
|
|
@ -96,12 +96,12 @@ func (mq *MessageQuery) GetBetween(ctx context.Context, loginID networkid.UserLo
|
|||
args := []any{mq.BridgeID, loginID, chatJID}
|
||||
argNum := 4
|
||||
if startTime != nil {
|
||||
whereClauses += fmt.Sprintf(" AND timestamp > $%d", argNum)
|
||||
whereClauses += fmt.Sprintf(" AND timestamp >= $%d", argNum)
|
||||
args = append(args, startTime.Unix())
|
||||
argNum++
|
||||
}
|
||||
if endTime != nil {
|
||||
whereClauses += fmt.Sprintf(" AND timestamp < $%d", argNum)
|
||||
whereClauses += fmt.Sprintf(" AND timestamp <= $%d", argNum)
|
||||
args = append(args, endTime.Unix())
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue