diff --git a/README.md b/README.md index 6f06c7c..17a5ec7 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ If you want to change them - check available options in the help message (`!pm h > The following section is visible to the mailbox owners only * **`!pm spam:list`** - Show comma-separated spamlist of the room, eg: `spammer@example.com,*@spammer.org,spam@*` -* **`!pm spam:add`** - Mark an email address (or pattern) as spam +* **`!pm spam:add`** - Mark an email address (or pattern) as spam (or you can react to the email with emoji: ⛔️,🛑, or 🚫) * **`!pm spam:remove`** - Unmark an email address (or pattern) as spam * **`!pm spam:reset`** - Reset spamlist diff --git a/bot/command.go b/bot/command.go index 0973b9f..2ee2361 100644 --- a/bot/command.go +++ b/bot/command.go @@ -223,7 +223,7 @@ func (b *Bot) initCommands() commandList { }, { key: commandSpamlistAdd, - description: "Mark an email address (or pattern) as spam", + description: "Mark an email address (or pattern) as spam (or you can react to the email with emoji: ⛔️,🛑, or 🚫)", allowed: b.allowOwner, }, { diff --git a/bot/reaction.go b/bot/reaction.go new file mode 100644 index 0000000..0599488 --- /dev/null +++ b/bot/reaction.go @@ -0,0 +1,43 @@ +package bot + +import ( + "context" + + "maunium.net/go/mautrix/event" + + "gitlab.com/etke.cc/postmoogle/utils" +) + +var supportedReactions = map[string]string{ + "⛔️": commandSpamlistAdd, + "🛑": commandSpamlistAdd, + "🚫": commandSpamlistAdd, + "spam": commandSpamlistAdd, +} + +func (b *Bot) handleReaction(ctx context.Context) { + evt := eventFromContext(ctx) + content := evt.Content.AsReaction() + action, ok := supportedReactions[content.GetRelatesTo().Key] + if !ok { // cannot do anything with it + return + } + + srcID := content.GetRelatesTo().EventID + srcEvt, err := b.lp.GetClient().GetEvent(evt.RoomID, srcID) + if err != nil { + b.Error(ctx, evt.RoomID, "cannot find event %s: %v", srcID, err) + return + } + utils.ParseContent(evt, event.EventMessage) + + switch action { + case commandSpamlistAdd: + sender := utils.EventField[string](&srcEvt.Content, eventFromKey) + if sender == "" { + b.Error(ctx, evt.RoomID, "cannot get sender of the email") + return + } + b.runSpamlistAdd(ctx, []string{commandSpamlistAdd, utils.EventField[string](&srcEvt.Content, eventFromKey)}) + } +} diff --git a/bot/sync.go b/bot/sync.go index 68f73a9..a1ef8cf 100644 --- a/bot/sync.go +++ b/bot/sync.go @@ -21,7 +21,14 @@ func (b *Bot) initSync() { event.EventMessage, func(_ mautrix.EventSource, evt *event.Event) { go b.onMessage(evt) - }) + }, + ) + b.lp.OnEventType( + event.EventReaction, + func(_ mautrix.EventSource, evt *event.Event) { + go b.onReaction(evt) + }, + ) } // joinPermit is called by linkpearl when processing "invite" events and deciding if rooms should be auto-joined or not @@ -69,6 +76,20 @@ func (b *Bot) onMessage(evt *event.Event) { b.handle(ctx) } +func (b *Bot) onReaction(evt *event.Event) { + // ignore own messages + if evt.Sender == b.lp.GetClient().UserID { + return + } + // mautrix 0.15.x migration + if b.ignoreBefore >= evt.Timestamp { + return + } + + ctx := newContext(evt) + b.handleReaction(ctx) +} + // onBotJoin handles the "bot joined the room" event func (b *Bot) onBotJoin(ctx context.Context) { evt := eventFromContext(ctx)