diff options
-rw-r--r-- | bridge/discord/discord.go | 4 | ||||
-rw-r--r-- | bridge/discord/webhook.go | 2 | ||||
-rw-r--r-- | bridge/helper/helper.go | 13 | ||||
-rw-r--r-- | bridge/helper/helper_test.go | 157 | ||||
-rw-r--r-- | bridge/irc/irc.go | 16 | ||||
-rw-r--r-- | bridge/mumble/mumble.go | 4 | ||||
-rw-r--r-- | bridge/slack/slack.go | 2 | ||||
-rw-r--r-- | matterbridge.toml.sample | 31 |
8 files changed, 124 insertions, 105 deletions
diff --git a/bridge/discord/discord.go b/bridge/discord/discord.go index 2fcf0abc..0ac2b50c 100644 --- a/bridge/discord/discord.go +++ b/bridge/discord/discord.go @@ -283,7 +283,7 @@ func (b *Bdiscord) handleEventBotUser(msg *config.Message, channelID string) (st // Upload a file if it exists if msg.Extra != nil { for _, rmsg := range helper.HandleExtra(msg, b.General) { - rmsg.Text = helper.ClipMessage(rmsg.Text, MessageLength) + rmsg.Text = helper.ClipMessage(rmsg.Text, MessageLength, b.GetString("MessageClipped")) if _, err := b.c.ChannelMessageSend(channelID, rmsg.Username+rmsg.Text); err != nil { b.Log.Errorf("Could not send message %#v: %s", rmsg, err) } @@ -294,7 +294,7 @@ func (b *Bdiscord) handleEventBotUser(msg *config.Message, channelID string) (st } } - msg.Text = helper.ClipMessage(msg.Text, MessageLength) + msg.Text = helper.ClipMessage(msg.Text, MessageLength, b.GetString("MessageClipped")) msg.Text = b.replaceUserMentions(msg.Text) // Edit message diff --git a/bridge/discord/webhook.go b/bridge/discord/webhook.go index 9177db07..7b136bcb 100644 --- a/bridge/discord/webhook.go +++ b/bridge/discord/webhook.go @@ -116,7 +116,7 @@ func (b *Bdiscord) handleEventWebhook(msg *config.Message, channelID string) (st return "", nil } - msg.Text = helper.ClipMessage(msg.Text, MessageLength) + msg.Text = helper.ClipMessage(msg.Text, MessageLength, b.GetString("MessageClipped")) msg.Text = b.replaceUserMentions(msg.Text) // discord username must be [0..32] max if len(msg.Username) > 32 { diff --git a/bridge/helper/helper.go b/bridge/helper/helper.go index 0ad31457..1bdd8a40 100644 --- a/bridge/helper/helper.go +++ b/bridge/helper/helper.go @@ -82,8 +82,10 @@ func DownloadFileAuthRocket(url, token, userID string) (*[]byte, error) { // TODO: The current implementation has the inconvenient that it disregards // word boundaries when splitting but this is hard to solve without potentially // breaking formatting and other stylistic effects. -func GetSubLines(message string, maxLineLength int) []string { - const clippingMessage = " <clipped message>" +func GetSubLines(message string, maxLineLength int, clippingMessage string) []string { + if clippingMessage == "" { + clippingMessage = " <clipped message>" + } var lines []string for _, line := range strings.Split(strings.TrimSpace(message), "\n") { @@ -193,8 +195,11 @@ func RemoveEmptyNewLines(msg string) string { // ClipMessage trims a message to the specified length if it exceeds it and adds a warning // to the message in case it does so. -func ClipMessage(text string, length int) string { - const clippingMessage = " <clipped message>" +func ClipMessage(text string, length int, clippingMessage string) string { + if clippingMessage == "" { + clippingMessage = " <clipped message>" + } + if len(text) > length { text = text[:length-len(clippingMessage)] if r, size := utf8.DecodeLastRuneInString(text); r == utf8.RuneError { diff --git a/bridge/helper/helper_test.go b/bridge/helper/helper_test.go index 48f33b10..76e548e4 100644 --- a/bridge/helper/helper_test.go +++ b/bridge/helper/helper_test.go @@ -10,98 +10,96 @@ import ( const testLineLength = 64 -var ( - lineSplittingTestCases = map[string]struct { - input string - splitOutput []string - nonSplitOutput []string - }{ - "Short single-line message": { - input: "short", - splitOutput: []string{"short"}, - nonSplitOutput: []string{"short"}, +var lineSplittingTestCases = map[string]struct { + input string + splitOutput []string + nonSplitOutput []string +}{ + "Short single-line message": { + input: "short", + splitOutput: []string{"short"}, + nonSplitOutput: []string{"short"}, + }, + "Long single-line message": { + input: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + splitOutput: []string{ + "Lorem ipsum dolor sit amet, consectetur adipis <clipped message>", + "cing elit, sed do eiusmod tempor incididunt ut <clipped message>", + " labore et dolore magna aliqua.", }, - "Long single-line message": { - input: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - splitOutput: []string{ - "Lorem ipsum dolor sit amet, consectetur adipis <clipped message>", - "cing elit, sed do eiusmod tempor incididunt ut <clipped message>", - " labore et dolore magna aliqua.", - }, - nonSplitOutput: []string{"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."}, + nonSplitOutput: []string{"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."}, + }, + "Short multi-line message": { + input: "I\ncan't\nget\nno\nsatisfaction!", + splitOutput: []string{ + "I", + "can't", + "get", + "no", + "satisfaction!", }, - "Short multi-line message": { - input: "I\ncan't\nget\nno\nsatisfaction!", - splitOutput: []string{ - "I", - "can't", - "get", - "no", - "satisfaction!", - }, - nonSplitOutput: []string{ - "I", - "can't", - "get", - "no", - "satisfaction!", - }, + nonSplitOutput: []string{ + "I", + "can't", + "get", + "no", + "satisfaction!", }, - "Long multi-line message": { - input: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n" + - "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n" + - "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n" + - "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", - splitOutput: []string{ - "Lorem ipsum dolor sit amet, consectetur adipis <clipped message>", - "cing elit, sed do eiusmod tempor incididunt ut <clipped message>", - " labore et dolore magna aliqua.", - "Ut enim ad minim veniam, quis nostrud exercita <clipped message>", - "tion ullamco laboris nisi ut aliquip ex ea com <clipped message>", - "modo consequat.", - "Duis aute irure dolor in reprehenderit in volu <clipped message>", - "ptate velit esse cillum dolore eu fugiat nulla <clipped message>", - " pariatur.", - "Excepteur sint occaecat cupidatat non proident <clipped message>", - ", sunt in culpa qui officia deserunt mollit an <clipped message>", - "im id est laborum.", - }, - nonSplitOutput: []string{ - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", - "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", - "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", - }, + }, + "Long multi-line message": { + input: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n" + + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n" + + "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n" + + "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + splitOutput: []string{ + "Lorem ipsum dolor sit amet, consectetur adipis <clipped message>", + "cing elit, sed do eiusmod tempor incididunt ut <clipped message>", + " labore et dolore magna aliqua.", + "Ut enim ad minim veniam, quis nostrud exercita <clipped message>", + "tion ullamco laboris nisi ut aliquip ex ea com <clipped message>", + "modo consequat.", + "Duis aute irure dolor in reprehenderit in volu <clipped message>", + "ptate velit esse cillum dolore eu fugiat nulla <clipped message>", + " pariatur.", + "Excepteur sint occaecat cupidatat non proident <clipped message>", + ", sunt in culpa qui officia deserunt mollit an <clipped message>", + "im id est laborum.", }, - "Message ending with new-line.": { - input: "Newline ending\n", - splitOutput: []string{"Newline ending"}, - nonSplitOutput: []string{"Newline ending"}, + nonSplitOutput: []string{ + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", + "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", + "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", }, - "Long message containing UTF-8 multi-byte runes": { - input: "不布人個我此而及單石業喜資富下我河下日沒一我臺空達的常景便物沒為……子大我別名解成?生賣的全直黑,我自我結毛分洲了世當,是政福那是東;斯說", - splitOutput: []string{ - "不布人個我此而及單石業喜資富下 <clipped message>", - "我河下日沒一我臺空達的常景便物 <clipped message>", - "沒為……子大我別名解成?生賣的 <clipped message>", - "全直黑,我自我結毛分洲了世當, <clipped message>", - "是政福那是東;斯說", - }, - nonSplitOutput: []string{"不布人個我此而及單石業喜資富下我河下日沒一我臺空達的常景便物沒為……子大我別名解成?生賣的全直黑,我自我結毛分洲了世當,是政福那是東;斯說"}, + }, + "Message ending with new-line.": { + input: "Newline ending\n", + splitOutput: []string{"Newline ending"}, + nonSplitOutput: []string{"Newline ending"}, + }, + "Long message containing UTF-8 multi-byte runes": { + input: "不布人個我此而及單石業喜資富下我河下日沒一我臺空達的常景便物沒為……子大我別名解成?生賣的全直黑,我自我結毛分洲了世當,是政福那是東;斯說", + splitOutput: []string{ + "不布人個我此而及單石業喜資富下 <clipped message>", + "我河下日沒一我臺空達的常景便物 <clipped message>", + "沒為……子大我別名解成?生賣的 <clipped message>", + "全直黑,我自我結毛分洲了世當, <clipped message>", + "是政福那是東;斯說", }, - } -) + nonSplitOutput: []string{"不布人個我此而及單石業喜資富下我河下日沒一我臺空達的常景便物沒為……子大我別名解成?生賣的全直黑,我自我結毛分洲了世當,是政福那是東;斯說"}, + }, +} func TestGetSubLines(t *testing.T) { for testname, testcase := range lineSplittingTestCases { - splitLines := GetSubLines(testcase.input, testLineLength) + splitLines := GetSubLines(testcase.input, testLineLength, "") assert.Equalf(t, testcase.splitOutput, splitLines, "'%s' testcase should give expected lines with splitting.", testname) for _, splitLine := range splitLines { byteLength := len([]byte(splitLine)) assert.True(t, byteLength <= testLineLength, "Splitted line '%s' of testcase '%s' should not exceed the maximum byte-length (%d vs. %d).", splitLine, testcase, byteLength, testLineLength) } - nonSplitLines := GetSubLines(testcase.input, 0) + nonSplitLines := GetSubLines(testcase.input, 0, "") assert.Equalf(t, testcase.nonSplitOutput, nonSplitLines, "'%s' testcase should give expected lines without splitting.", testname) } } @@ -110,16 +108,19 @@ func TestConvertWebPToPNG(t *testing.T) { if os.Getenv("LOCAL_TEST") == "" { t.Skip() } + input, err := ioutil.ReadFile("test.webp") if err != nil { t.Fail() } + d := &input err = ConvertWebPToPNG(d) if err != nil { t.Fail() } - err = ioutil.WriteFile("test.png", *d, 0644) + + err = ioutil.WriteFile("test.png", *d, 0o644) // nolint:gosec if err != nil { t.Fail() } diff --git a/bridge/irc/irc.go b/bridge/irc/irc.go index 4ccdee95..e54f8030 100644 --- a/bridge/irc/irc.go +++ b/bridge/irc/irc.go @@ -167,9 +167,9 @@ func (b *Birc) Send(msg config.Message) (string, error) { } if b.GetBool("MessageSplit") { - msgLines = helper.GetSubLines(msg.Text, b.MessageLength) + msgLines = helper.GetSubLines(msg.Text, b.MessageLength, b.GetString("MessageClipped")) } else { - msgLines = helper.GetSubLines(msg.Text, 0) + msgLines = helper.GetSubLines(msg.Text, 0, b.GetString("MessageClipped")) } for i := range msgLines { if len(b.Local) >= b.MessageQueue { @@ -316,12 +316,16 @@ func (b *Birc) endNames(client *girc.Client, event girc.Event) { sort.Strings(b.names[channel]) maxNamesPerPost := (300 / b.nicksPerRow()) * b.nicksPerRow() for len(b.names[channel]) > maxNamesPerPost { - b.Remote <- config.Message{Username: b.Nick, Text: b.formatnicks(b.names[channel][0:maxNamesPerPost]), - Channel: channel, Account: b.Account} + b.Remote <- config.Message{ + Username: b.Nick, Text: b.formatnicks(b.names[channel][0:maxNamesPerPost]), + Channel: channel, Account: b.Account, + } b.names[channel] = b.names[channel][maxNamesPerPost:] } - b.Remote <- config.Message{Username: b.Nick, Text: b.formatnicks(b.names[channel]), - Channel: channel, Account: b.Account} + b.Remote <- config.Message{ + Username: b.Nick, Text: b.formatnicks(b.names[channel]), + Channel: channel, Account: b.Account, + } b.names[channel] = nil b.i.Handlers.Clear(girc.RPL_NAMREPLY) b.i.Handlers.Clear(girc.RPL_ENDOFNAMES) diff --git a/bridge/mumble/mumble.go b/bridge/mumble/mumble.go index 2281d1c2..d678e0fb 100644 --- a/bridge/mumble/mumble.go +++ b/bridge/mumble/mumble.go @@ -248,9 +248,9 @@ func (b *Bmumble) processMessage(msg *config.Message) { // If there is a maximum message length, split and truncate the lines var msgLines []string if maxLength := b.serverConfig.MaximumMessageLength; maxLength != nil { - msgLines = helper.GetSubLines(msg.Text, *maxLength-len(msg.Username)) + msgLines = helper.GetSubLines(msg.Text, *maxLength-len(msg.Username), b.GetString("MessageClipped")) } else { - msgLines = helper.GetSubLines(msg.Text, 0) + msgLines = helper.GetSubLines(msg.Text, 0, b.GetString("MessageClipped")) } // Send the individual lindes for i := range msgLines { diff --git a/bridge/slack/slack.go b/bridge/slack/slack.go index 37ddd853..457312cd 100644 --- a/bridge/slack/slack.go +++ b/bridge/slack/slack.go @@ -195,7 +195,7 @@ func (b *Bslack) Send(msg config.Message) (string, error) { b.Log.Debugf("=> Receiving %#v", msg) } - msg.Text = helper.ClipMessage(msg.Text, messageLength) + msg.Text = helper.ClipMessage(msg.Text, messageLength, b.GetString("MessageClipped")) msg.Text = b.replaceCodeFence(msg.Text) // Make a action /me of the message diff --git a/matterbridge.toml.sample b/matterbridge.toml.sample index 2819b287..a1b8a5fc 100644 --- a/matterbridge.toml.sample +++ b/matterbridge.toml.sample @@ -76,20 +76,24 @@ MessageDelay=1300 #Maximum amount of messages to hold in queue. If queue is full #messages will be dropped. -#<message clipped> will be add to the message that fills the queue. +#<clipped message> will be add to the message that fills the queue. #OPTIONAL (default 30) MessageQueue=30 #Maximum length of message sent to irc server. If it exceeds -#<message clipped> will be add to the message. +#<clipped message> will be add to the message. #OPTIONAL (default 400) MessageLength=400 -#Split messages on MessageLength instead of showing the <message clipped> +#Split messages on MessageLength instead of showing the <clipped message> #WARNING: this could lead to flooding #OPTIONAL (default false) MessageSplit=false +#Message to show when a message is too big +#Default "<clipped message>" +MessageClipped="<clipped message>" + #Delay in seconds to rejoin a channel when kicked #OPTIONAL (default 0) RejoinDelay=0 @@ -826,6 +830,10 @@ PreserveThreading=false #OPTIONAL (default false) ShowUserTyping=false +#Message to show when a message is too big +#Default "<clipped message>" +MessageClipped="<clipped message>" + ################################################################### #discord section ################################################################### @@ -961,6 +969,10 @@ ShowTopicChange=false # Supported from the following bridges: slack SyncTopic=false +#Message to show when a message is too big +#Default "<clipped message>" +MessageClipped="<clipped message>" + ################################################################### #telegram section ################################################################### @@ -1435,9 +1447,7 @@ StripNick=false ShowTopicChange=false ################################################################### -# # NCTalk (Nextcloud Talk) -# ################################################################### [nctalk.bridge] @@ -1460,9 +1470,7 @@ Password = "talkuserpass" GuestSuffix = " (Guest)" ################################################################### -# # Mumble -# ################################################################### [mumble.bridge] @@ -1505,9 +1513,14 @@ TLSCACertificate=mumble-ca.crt # OPTIONAL (default false) SkipTLSVerify=false +#Message to show when a message is too big +#Default "<clipped message>" +MessageClipped="<clipped message>" + ################################################################### #VK ################################################################### +# [vk.myvk] #Group access token #See https://vk.com/dev/bots_docs @@ -1518,9 +1531,7 @@ Token="Yourtokenhere" GroupID=123456789 ################################################################### -# # WhatsApp -# ################################################################### [whatsapp.bridge] @@ -1547,9 +1558,7 @@ Label="Organization" ################################################################### -# # zulip -# ################################################################### [zulip] |