handle reactions in encrypted rooms
This commit is contained in:
@@ -445,7 +445,7 @@ func (b *Bot) getParentEvent(evt *event.Event) (id.EventID, *event.Event) {
|
|||||||
b.log.Error().Err(err).Msg("cannot get parent event")
|
b.log.Error().Err(err).Msg("cannot get parent event")
|
||||||
return threadID, nil
|
return threadID, nil
|
||||||
}
|
}
|
||||||
linkpearl.ParseContent(parentEvt, parentEvt.Type, b.log)
|
linkpearl.ParseContent(parentEvt, b.log)
|
||||||
|
|
||||||
if !b.lp.GetMachine().StateStore.IsEncrypted(evt.RoomID) {
|
if !b.lp.GetMachine().StateStore.IsEncrypted(evt.RoomID) {
|
||||||
return threadID, parentEvt
|
return threadID, parentEvt
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"gitlab.com/etke.cc/linkpearl"
|
"gitlab.com/etke.cc/linkpearl"
|
||||||
"maunium.net/go/mautrix/event"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var supportedReactions = map[string]string{
|
var supportedReactions = map[string]string{
|
||||||
@@ -28,9 +27,16 @@ func (b *Bot) handleReaction(ctx context.Context) {
|
|||||||
b.Error(ctx, "cannot find event %s: %v", srcID, err)
|
b.Error(ctx, "cannot find event %s: %v", srcID, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
linkpearl.ParseContent(srcEvt, b.log)
|
||||||
|
if b.lp.GetMachine().StateStore.IsEncrypted(evt.RoomID) {
|
||||||
|
decrypted, derr := b.lp.GetClient().Crypto.Decrypt(srcEvt)
|
||||||
|
if derr == nil {
|
||||||
|
srcEvt = decrypted
|
||||||
|
}
|
||||||
|
}
|
||||||
threadID := linkpearl.EventParent(srcID, srcEvt.Content.AsMessage())
|
threadID := linkpearl.EventParent(srcID, srcEvt.Content.AsMessage())
|
||||||
ctx = threadIDToContext(ctx, threadID)
|
ctx = threadIDToContext(ctx, threadID)
|
||||||
linkpearl.ParseContent(evt, event.EventMessage, b.log)
|
linkpearl.ParseContent(evt, b.log)
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
case commandSpamlistAdd:
|
case commandSpamlistAdd:
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -26,7 +26,7 @@ require (
|
|||||||
gitlab.com/etke.cc/go/secgen v1.1.1
|
gitlab.com/etke.cc/go/secgen v1.1.1
|
||||||
gitlab.com/etke.cc/go/trysmtp v1.1.3
|
gitlab.com/etke.cc/go/trysmtp v1.1.3
|
||||||
gitlab.com/etke.cc/go/validator v1.0.6
|
gitlab.com/etke.cc/go/validator v1.0.6
|
||||||
gitlab.com/etke.cc/linkpearl v0.0.0-20230928120707-1e99315dc616
|
gitlab.com/etke.cc/linkpearl v0.0.0-20230929133006-84554ee97edb
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
|
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
|
||||||
maunium.net/go/mautrix v0.16.1
|
maunium.net/go/mautrix v0.16.1
|
||||||
)
|
)
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -111,8 +111,8 @@ gitlab.com/etke.cc/go/trysmtp v1.1.3 h1:e2EHond77onMaecqCg6mWumffTSEf+ycgj88nbee
|
|||||||
gitlab.com/etke.cc/go/trysmtp v1.1.3/go.mod h1:lOO7tTdAE0a3ETV3wN3GJ7I1Tqewu7YTpPWaOmTteV0=
|
gitlab.com/etke.cc/go/trysmtp v1.1.3/go.mod h1:lOO7tTdAE0a3ETV3wN3GJ7I1Tqewu7YTpPWaOmTteV0=
|
||||||
gitlab.com/etke.cc/go/validator v1.0.6 h1:w0Muxf9Pqw7xvF7NaaswE6d7r9U3nB2t2l5PnFMrecQ=
|
gitlab.com/etke.cc/go/validator v1.0.6 h1:w0Muxf9Pqw7xvF7NaaswE6d7r9U3nB2t2l5PnFMrecQ=
|
||||||
gitlab.com/etke.cc/go/validator v1.0.6/go.mod h1:Id0SxRj0J3IPhiKlj0w1plxVLZfHlkwipn7HfRZsDts=
|
gitlab.com/etke.cc/go/validator v1.0.6/go.mod h1:Id0SxRj0J3IPhiKlj0w1plxVLZfHlkwipn7HfRZsDts=
|
||||||
gitlab.com/etke.cc/linkpearl v0.0.0-20230928120707-1e99315dc616 h1:Gvhmq84VmAJN1xRzRBK79XJVObAvVcx9Q3s6K+Zo644=
|
gitlab.com/etke.cc/linkpearl v0.0.0-20230929133006-84554ee97edb h1:QoabJtxrQg7P2kuxwOp3iU6uKoep+5QQAtMomajXcpA=
|
||||||
gitlab.com/etke.cc/linkpearl v0.0.0-20230928120707-1e99315dc616/go.mod h1:IZ0TE+ZnIdJLb538owDMxhtpWH7blfW+oR7e5XRXxNY=
|
gitlab.com/etke.cc/linkpearl v0.0.0-20230929133006-84554ee97edb/go.mod h1:IZ0TE+ZnIdJLb538owDMxhtpWH7blfW+oR7e5XRXxNY=
|
||||||
go.mau.fi/util v0.1.0 h1:BwIFWIOEeO7lsiI2eWKFkWTfc5yQmoe+0FYyOFVyaoE=
|
go.mau.fi/util v0.1.0 h1:BwIFWIOEeO7lsiI2eWKFkWTfc5yQmoe+0FYyOFVyaoE=
|
||||||
go.mau.fi/util v0.1.0/go.mod h1:AxuJUMCxpzgJ5eV9JbPWKRH8aAJJidxetNdUj7qcb84=
|
go.mau.fi/util v0.1.0/go.mod h1:AxuJUMCxpzgJ5eV9JbPWKRH8aAJJidxetNdUj7qcb84=
|
||||||
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
|||||||
13
vendor/gitlab.com/etke.cc/linkpearl/sync.go
generated
vendored
13
vendor/gitlab.com/etke.cc/linkpearl/sync.go
generated
vendored
@@ -1,6 +1,7 @@
|
|||||||
package linkpearl
|
package linkpearl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"maunium.net/go/mautrix"
|
"maunium.net/go/mautrix"
|
||||||
@@ -65,14 +66,22 @@ func (l *Linkpearl) onInvite(evt *event.Event) {
|
|||||||
l.tryLeave(evt.RoomID, 0)
|
l.tryLeave(evt.RoomID, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: https://spec.matrix.org/v1.8/client-server-api/#post_matrixclientv3joinroomidoralias
|
||||||
|
// endpoint supports server_name param and tells "The servers to attempt to join the room through. One of the servers must be participating in the room.",
|
||||||
|
// meaning you can specify more than 1 server. It is not clear, what format should be used "example.com,example.org", or "example.com example.org", or whatever else.
|
||||||
|
// Moreover, it is not clear if the following values can be used together with that field: l.api.UserID.Homeserver() and evt.Sender.Homeserver()
|
||||||
func (l *Linkpearl) tryJoin(roomID id.RoomID, retry int) {
|
func (l *Linkpearl) tryJoin(roomID id.RoomID, retry int) {
|
||||||
if retry >= l.maxretries {
|
if retry >= l.maxretries {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := l.api.JoinRoomByID(roomID)
|
_, err := l.api.JoinRoom(roomID.String(), "", nil)
|
||||||
|
err = UnwrapError(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.log.Error().Err(err).Str("roomID", roomID.String()).Msg("cannot join room")
|
l.log.Error().Err(err).Str("roomID", roomID.String()).Msg("cannot join room")
|
||||||
|
if strings.HasPrefix(err.Error(), "403") { // no permission to join, no need to retry
|
||||||
|
return
|
||||||
|
}
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
l.log.Error().Err(err).Str("roomID", roomID.String()).Int("retry", retry+1).Msg("trying to join again")
|
l.log.Error().Err(err).Str("roomID", roomID.String()).Int("retry", retry+1).Msg("trying to join again")
|
||||||
l.tryJoin(roomID, retry+1)
|
l.tryJoin(roomID, retry+1)
|
||||||
@@ -85,6 +94,7 @@ func (l *Linkpearl) tryLeave(roomID id.RoomID, retry int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, err := l.api.LeaveRoom(roomID)
|
_, err := l.api.LeaveRoom(roomID)
|
||||||
|
err = UnwrapError(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.log.Error().Err(err).Str("roomID", roomID.String()).Msg("cannot leave room")
|
l.log.Error().Err(err).Str("roomID", roomID.String()).Msg("cannot leave room")
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
@@ -99,6 +109,7 @@ func (l *Linkpearl) onEmpty(evt *event.Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
members, err := l.api.StateStore.GetRoomJoinedOrInvitedMembers(evt.RoomID)
|
members, err := l.api.StateStore.GetRoomJoinedOrInvitedMembers(evt.RoomID)
|
||||||
|
err = UnwrapError(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.log.Error().Err(err).Str("roomID", evt.RoomID.String()).Msg("cannot get joined or invited members")
|
l.log.Error().Err(err).Str("roomID", evt.RoomID.String()).Msg("cannot get joined or invited members")
|
||||||
return
|
return
|
||||||
|
|||||||
70
vendor/gitlab.com/etke.cc/linkpearl/utils.go
generated
vendored
70
vendor/gitlab.com/etke.cc/linkpearl/utils.go
generated
vendored
@@ -7,6 +7,17 @@ import (
|
|||||||
"maunium.net/go/mautrix/id"
|
"maunium.net/go/mautrix/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// EventRelatesTo uses evt as source for EventParent() and RelatesTo()
|
||||||
|
func EventRelatesTo(evt *event.Event) *event.RelatesTo {
|
||||||
|
ParseContent(evt, nil)
|
||||||
|
relatable, ok := evt.Content.Parsed.(event.Relatable)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return RelatesTo(EventParent(evt.ID, relatable))
|
||||||
|
}
|
||||||
|
|
||||||
// RelatesTo returns relation object of a matrix event (either threads with reply-to fallback or plain reply-to)
|
// RelatesTo returns relation object of a matrix event (either threads with reply-to fallback or plain reply-to)
|
||||||
func RelatesTo(parentID id.EventID, noThreads ...bool) *event.RelatesTo {
|
func RelatesTo(parentID id.EventID, noThreads ...bool) *event.RelatesTo {
|
||||||
if parentID == "" {
|
if parentID == "" {
|
||||||
@@ -36,34 +47,58 @@ func RelatesTo(parentID id.EventID, noThreads ...bool) *event.RelatesTo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EventParent returns parent event ID (either from thread or from reply-to relation)
|
// GetParent is nil-safe version of evt.Content.AsMessage().RelatesTo.(GetThreadParent()|GetReplyTo())
|
||||||
func EventParent(currentID id.EventID, content *event.MessageEventContent) id.EventID {
|
func GetParent(evt *event.Event) id.EventID {
|
||||||
if content == nil {
|
ParseContent(evt, nil)
|
||||||
return currentID
|
content, ok := evt.Content.Parsed.(event.Relatable)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
relation := content.OptionalGetRelatesTo()
|
relation := content.GetRelatesTo()
|
||||||
if relation == nil {
|
if relation == nil {
|
||||||
return currentID
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
threadParent := relation.GetThreadParent()
|
if parentID := relation.GetThreadParent(); parentID != "" {
|
||||||
if threadParent != "" {
|
return parentID
|
||||||
return threadParent
|
}
|
||||||
|
if parentID := relation.GetReplyTo(); parentID != "" {
|
||||||
|
return parentID
|
||||||
}
|
}
|
||||||
|
|
||||||
replyParent := relation.GetReplyTo()
|
return ""
|
||||||
if replyParent != "" {
|
}
|
||||||
return replyParent
|
|
||||||
|
// EventParent returns parent event ID (either from thread or from reply-to relation), like GetRelatesTo(), but with content and default return value
|
||||||
|
func EventParent(currentID id.EventID, content event.Relatable) id.EventID {
|
||||||
|
if parentID := GetParent(&event.Event{Content: event.Content{Parsed: content}}); parentID != "" {
|
||||||
|
return parentID
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentID
|
return currentID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EventContains checks if raw event content contains specified field with specified values
|
||||||
|
func EventContains[T comparable](evt *event.Event, field string, value T) bool {
|
||||||
|
if evt.Content.Raw == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if EventField[T](&evt.Content, field) != value {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// EventField returns field value from raw event content
|
// EventField returns field value from raw event content
|
||||||
func EventField[T any](content *event.Content, field string) T {
|
func EventField[T comparable](content *event.Content, field string) T {
|
||||||
var zero T
|
var zero T
|
||||||
raw := content.Raw[field]
|
raw, ok := content.Raw[field]
|
||||||
|
if !ok {
|
||||||
|
return zero
|
||||||
|
}
|
||||||
|
|
||||||
if raw == nil {
|
if raw == nil {
|
||||||
return zero
|
return zero
|
||||||
}
|
}
|
||||||
@@ -76,12 +111,13 @@ func EventField[T any](content *event.Content, field string) T {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseContent(evt *event.Event, eventType event.Type, log *zerolog.Logger) {
|
// ParseContent parses event content according to evt.Type
|
||||||
|
func ParseContent(evt *event.Event, log *zerolog.Logger) {
|
||||||
if evt.Content.Parsed != nil {
|
if evt.Content.Parsed != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
perr := evt.Content.ParseRaw(eventType)
|
perr := evt.Content.ParseRaw(evt.Type)
|
||||||
if perr != nil {
|
if perr != nil && log != nil {
|
||||||
log.Error().Err(perr).Msg("cannot parse event content")
|
log.Error().Err(perr).Msg("cannot parse event content")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -144,7 +144,7 @@ gitlab.com/etke.cc/go/trysmtp
|
|||||||
# gitlab.com/etke.cc/go/validator v1.0.6
|
# gitlab.com/etke.cc/go/validator v1.0.6
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
gitlab.com/etke.cc/go/validator
|
gitlab.com/etke.cc/go/validator
|
||||||
# gitlab.com/etke.cc/linkpearl v0.0.0-20230928120707-1e99315dc616
|
# gitlab.com/etke.cc/linkpearl v0.0.0-20230929133006-84554ee97edb
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
gitlab.com/etke.cc/linkpearl
|
gitlab.com/etke.cc/linkpearl
|
||||||
# go.mau.fi/util v0.1.0
|
# go.mau.fi/util v0.1.0
|
||||||
|
|||||||
Reference in New Issue
Block a user