From 3190703dc8618896c932a23d8ca155fbbf6fab13 Mon Sep 17 00:00:00 2001 From: Wim Date: Sat, 23 Feb 2019 16:35:54 +0100 Subject: Support rewriting messages from relaybots using ExtractNicks. Fixes #466 (#730) some examples: this replaces a message like "Relaybot: something interesting" to "relayeduser: something interesting" ExtractNicks=[ [ "Relaybot", "<(.*?)>\\s+" ] ] you can use multiple entries for multiplebots this also replaces a message like "otherbot: (relayeduser) something else" to "relayeduser: something else" ExtractNicks=[ [ "Relaybot", "<(.*?)>\\s+" ],[ "otherbot","\\((.*?)\\)\\s+" ] OPTIONAL (default empty) ExtractNicks=[ ["otherbot","<(.*?)>\\s+" ] ] --- gateway/gateway.go | 2 ++ gateway/handlers.go | 39 +++++++++++++++++++++++++ gateway/handlers_test.go | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 gateway/handlers_test.go (limited to 'gateway') diff --git a/gateway/gateway.go b/gateway/gateway.go index 0c04a167..2f797734 100644 --- a/gateway/gateway.go +++ b/gateway/gateway.go @@ -351,6 +351,8 @@ func (gw *Gateway) modifyMessage(msg *config.Message) { msg.Text = re.ReplaceAllString(msg.Text, replace) } + gw.handleExtractNicks(msg) + // messages from api have Gateway specified, don't overwrite if msg.Protocol != apiProtocol { msg.Gateway = gw.Name diff --git a/gateway/handlers.go b/gateway/handlers.go index 5af13c14..dfec2ab6 100644 --- a/gateway/handlers.go +++ b/gateway/handlers.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" "regexp" + "strings" "time" "github.com/42wim/matterbridge/bridge" @@ -225,3 +226,41 @@ func (gw *Gateway) handleMessage(msg config.Message, dest *bridge.Bridge) []*BrM } return brMsgIDs } + +func (gw *Gateway) handleExtractNicks(msg *config.Message) { + var err error + br := gw.Bridges[msg.Account] + for _, outer := range br.GetStringSlice2D("ExtractNicks") { + search := outer[0] + replace := outer[1] + msg.Username, msg.Text, err = extractNick(search, replace, msg.Username, msg.Text) + if err != nil { + flog.Errorf("regexp in %s failed: %s", msg.Account, err) + break + } + } +} + +// extractNick searches for a username (based on "search" a regular expression). +// if this matches it extracts a nick (based on "extract" another regular expression) from text +// and replaces username with this result. +// returns error if the regexp doesn't compile. +func extractNick(search, extract, username, text string) (string, string, error) { + re, err := regexp.Compile(search) + if err != nil { + return username, text, err + } + if re.MatchString(username) { + re, err = regexp.Compile(extract) + if err != nil { + return username, text, err + } + res := re.FindAllStringSubmatch(text, 1) + // only replace if we have exactly 1 match + if len(res) > 0 && len(res[0]) == 2 { + username = res[0][1] + text = strings.Replace(text, res[0][0], "", 1) + } + } + return username, text, nil +} diff --git a/gateway/handlers_test.go b/gateway/handlers_test.go new file mode 100644 index 00000000..db7988a9 --- /dev/null +++ b/gateway/handlers_test.go @@ -0,0 +1,75 @@ +package gateway + +import ( + "github.com/42wim/matterbridge/bridge" + "github.com/42wim/matterbridge/bridge/config" + "github.com/stretchr/testify/assert" + + "testing" +) + +func TestIgnoreEvent(t *testing.T) { + eventTests := map[string]struct { + input string + dest *bridge.Bridge + output bool + }{ + "avatar mattermost": { + input: config.EventAvatarDownload, + dest: &bridge.Bridge{Protocol: "mattermost"}, + output: false, + }, + "avatar slack": { + input: config.EventAvatarDownload, + dest: &bridge.Bridge{Protocol: "slack"}, + output: true, + }, + "avatar telegram": { + input: config.EventAvatarDownload, + dest: &bridge.Bridge{Protocol: "telegram"}, + output: false, + }, + } + gw := &Gateway{} + for testname, testcase := range eventTests { + output := gw.ignoreEvent(testcase.input, testcase.dest) + assert.Equalf(t, testcase.output, output, "case '%s' failed", testname) + } + +} + +func TestExtractNick(t *testing.T) { + eventTests := map[string]struct { + search string + extract string + username string + text string + resultUsername string + resultText string + }{ + "test1": { + search: "fromgitter", + extract: "<(.*?)>\\s+", + username: "fromgitter", + text: " blahblah", + resultUsername: "userx", + resultText: "blahblah", + }, + "test2": { + search: "<.*?bot>", + //extract: `\((.*?)\)\s+`, + extract: "\\((.*?)\\)\\s+", + username: "", + text: "(userx) blahblah (abc) test", + resultUsername: "userx", + resultText: "blahblah (abc) test", + }, + } + // gw := &Gateway{} + for testname, testcase := range eventTests { + resultUsername, resultText, _ := extractNick(testcase.search, testcase.extract, testcase.username, testcase.text) + assert.Equalf(t, testcase.resultUsername, resultUsername, "case '%s' failed", testname) + assert.Equalf(t, testcase.resultText, resultText, "case '%s' failed", testname) + } + +} -- cgit v1.2.3