Skip to content

Commit

Permalink
add reaction handler
Browse files Browse the repository at this point in the history
  • Loading branch information
CubicrootXYZ committed Feb 4, 2024
1 parent 4cced5d commit 7286478
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 2 deletions.
3 changes: 3 additions & 0 deletions internal/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ func assembleMatrixConfig(config *Config, icalConnector ical.Service) *matrix.Co
&message.RegenICalTokenAction{},
&message.DeleteEventAction{},
&message.SetDailyReminderAction{},
&message.ListEventsAction{},
&message.RegenICalTokenAction{},
&message.ChangeEventAction{},
)

cfg.BridgeServices = &matrix.BridgeServices{
Expand Down
2 changes: 1 addition & 1 deletion internal/connectors/matrix/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (service *service) startListener() error {
}

syncer.OnEventType(event.EventMessage, service.MessageEventHandler)
/* TODO syncer.OnEventType(event.EventReaction, reactionHandler.NewEvent)*/
syncer.OnEventType(event.EventReaction, service.ReactionEventHandler)
syncer.OnEventType(event.StateMember, service.EventStateHandler)

return service.client.Sync()
Expand Down
2 changes: 1 addition & 1 deletion internal/connectors/matrix/message_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type MessageEvent struct {
Channel *database.Channel
}

func (service *service) MessageEventHandler(source mautrix.EventSource, evt *event.Event) {
func (service *service) MessageEventHandler(_ mautrix.EventSource, evt *event.Event) {
logger := service.logger.WithFields(map[string]any{
"sender": evt.Sender,
"room": evt.RoomID,
Expand Down
141 changes: 141 additions & 0 deletions internal/connectors/matrix/reaction_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package matrix

import (
matrixdb "github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/connectors/matrix/database"
"github.com/CubicrootXYZ/matrix-reminder-and-calendar-bot/internal/database"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/event"
)

// TODO tests

type ReactionEvent struct {
Event *event.Event
Content *event.ReactionEventContent
IsEncrypted bool
Room *matrixdb.MatrixRoom
Input *database.Input
Channel *database.Channel
}

func (service *service) ReactionEventHandler(_ mautrix.EventSource, evt *event.Event) {
logger := service.logger.WithFields(map[string]any{
"sender": evt.Sender,
"room": evt.RoomID,
"event_timestamp": evt.Timestamp,
})
logger.Debugf("new reaction received")

// Do not answer our own and old messages
if evt.Sender.String() == service.botname || evt.Timestamp/1000 <= service.lastMessageFrom.Unix() {
return
}

room, err := service.matrixDatabase.GetRoomByRoomID(string(evt.RoomID))
if err != nil {
logger.Debugf("do not know room, ignoring message")
return
}

isUserKnown := false
userStr := evt.Sender.String()
for i := range room.Users {
if room.Users[i].ID == userStr {
isUserKnown = true
break
}
}
if !isUserKnown {
logger.Debugf("do not know user, ignoring message")
return
}

content, ok := evt.Content.Parsed.(*event.ReactionEventContent)
if !ok {
logger.Infof("Event is not a reaction event. Can not handle it.")
return
}

if content.RelatesTo.EventID.String() == "" {
logger.Infof("Reaction with no relating message. Can not handle that.")
return
}

message, err := service.matrixDatabase.GetMessageByID(content.RelatesTo.EventID.String())
if err != nil {
logger.Infof("Do not know the message related to the reaction.")
return
}

if message.Room.RoomID != room.RoomID {
// Should never happen.
logger.Infof("Ignore reaction from room %s referring to event from room %s.", message.Room.RoomID, room.RoomID)
return
}

reactionEvent, err := service.parseReactionEvent(evt, room)
if err != nil {
logger.Errorf("Can not parse reaction event: %s", err.Error())
return
}

// Find fitting action.
for i := range service.config.ReactionActions {
for _, reaction := range service.config.ReactionActions[i].Selector() {
if reaction == content.RelatesTo.Key {
service.config.ReactionActions[i].HandleEvent(reactionEvent, message)
return
}
}
}

logger.Infof("No action found matching key %s", content.RelatesTo.Key)
}

func (service *service) parseReactionEvent(evt *event.Event, room *matrixdb.MatrixRoom) (*ReactionEvent, error) {
reactionEvent := ReactionEvent{
Event: evt,
Room: room,
}

input, err := service.database.GetInputByType(room.ID, InputType)
if err != nil {
return nil, err
}

channel, err := service.database.GetChannelByID(input.ChannelID)
if err != nil {
return nil, err
}
reactionEvent.Channel = channel
reactionEvent.Input = input

content, ok := evt.Content.Parsed.(*event.ReactionEventContent)
if ok {
reactionEvent.Content = content
reactionEvent.IsEncrypted = false
return &reactionEvent, nil
}

if !service.crypto.enabled {
return nil, ErrUnknowEvent
}

_, ok = evt.Content.Parsed.(*event.EncryptedEventContent)
if ok {
decrypted, err := service.crypto.olm.DecryptMegolmEvent(evt)

if err != nil {
return nil, err
}

content, ok = decrypted.Content.Parsed.(*event.ReactionEventContent)
if ok {
reactionEvent.Content = content
reactionEvent.IsEncrypted = true
return &reactionEvent, nil
}
}

return nil, ErrUnknowEvent
}
8 changes: 8 additions & 0 deletions internal/connectors/matrix/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ type ReplyAction interface {
Configure(logger gologger.Logger, client mautrixcl.Client, messenger messenger.Messenger, matrixDB matrixdb.Service, db database.Service, bridgeServices *BridgeServices)
}

type ReactionAction interface {
Selector() []string
Name() string
HandleEvent(event *ReactionEvent, reactionToMessage *matrixdb.MatrixMessage)
Configure(logger gologger.Logger, client mautrixcl.Client, messenger messenger.Messenger, matrixDB matrixdb.Service, db database.Service, bridgeServices *BridgeServices)
}

// Config holds information for the matrix connector.
type Config struct {
Username string
Expand All @@ -69,6 +76,7 @@ type Config struct {
DefaultMessageAction MessageAction
ReplyActions []ReplyAction
DefaultReplyAction ReplyAction
ReactionActions []ReactionAction

AllowInvites bool
RoomLimit uint
Expand Down

0 comments on commit 7286478

Please sign in to comment.