diff --git a/bridge/config/config.go b/bridge/config/config.go index 21010dbf..cbed4214 100644 --- a/bridge/config/config.go +++ b/bridge/config/config.go @@ -117,6 +117,7 @@ type Protocol struct { ShowEmbeds bool // discord SkipTLSVerify bool // IRC, mattermost StripNick bool // all protocols + SyncTopicChange bool // slack Team string // mattermost Token string // gitter, slack, discord, api Topic string // zulip diff --git a/bridge/slack/handlers.go b/bridge/slack/handlers.go index ede4e8bf..a1c47dc2 100644 --- a/bridge/slack/handlers.go +++ b/bridge/slack/handlers.go @@ -116,6 +116,11 @@ func (b *Bslack) skipMessageEvent(ev *slack.MessageEvent) bool { return b.GetBool(noSendJoinConfig) case sPinnedItem, sUnpinnedItem: return true + case sChannelTopic, sChannelPurpose: + // Skip the event if our bot/user account changed the topic/purpose + if ev.User == b.si.User.ID { + return true + } } // Skip any messages that we made ourselves or from 'slackbot' (see #527). @@ -201,6 +206,7 @@ func (b *Bslack) handleStatusEvent(ev *slack.MessageEvent, rmsg *config.Message) rmsg.Username = sSystemUser rmsg.Event = config.EventJoinLeave case sChannelTopic, sChannelPurpose: + b.populateChannels() rmsg.Event = config.EventTopicChange case sMessageChanged: rmsg.Text = ev.SubMessage.Text diff --git a/bridge/slack/helpers.go b/bridge/slack/helpers.go index b0fdaba1..68f6d799 100644 --- a/bridge/slack/helpers.go +++ b/bridge/slack/helpers.go @@ -266,8 +266,18 @@ var ( channelRE = regexp.MustCompile(`<#[a-zA-Z0-9]+\|(.+?)>`) variableRE = regexp.MustCompile(``) urlRE = regexp.MustCompile(`<(.*?)(\|.*?)?>`) + topicOrPurposeRE = regexp.MustCompile(`(?s)^@.+ set the channel (topic|purpose): (.+?)(\[nosync\])?$`) ) +func (b *Bslack) extractTopicOrPurpose(text string) (updateType string, extracted string) { + r := topicOrPurposeRE.FindStringSubmatch(text) + updateType, extracted, noSync := r[1], r[2], r[3] + if noSync != "" { + return "nosync", "" + } + return updateType, extracted +} + // @see https://api.slack.com/docs/message-formatting#linking_to_channels_and_users func (b *Bslack) replaceMention(text string) string { replaceFunc := func(match string) string { diff --git a/bridge/slack/slack.go b/bridge/slack/slack.go index d054ae81..ee8d76fa 100644 --- a/bridge/slack/slack.go +++ b/bridge/slack/slack.go @@ -280,6 +280,24 @@ func (b *Bslack) sendRTM(msg config.Message) (string, error) { } return "", nil } + if (msg.Event == config.EVENT_TOPIC_CHANGE) && b.GetBool("SyncTopicChange") { + incomingChangeType, text := b.extractTopicOrPurpose(msg.Text) + switch incomingChangeType { + case "topic": + if strings.HasSuffix(channelInfo.Topic.Value, "[nosync]") { + break + } + b.rtm.SetTopicOfConversation(channelInfo.ID, text) + case "purpose": + if strings.HasSuffix(channelInfo.Purpose.Value, "[nosync]") { + break + } + b.rtm.SetPurposeOfConversation(channelInfo.ID, text) + case "nosync": + break + } + return "", nil + } // Handle message deletions. var handled bool diff --git a/matterbridge.toml.sample b/matterbridge.toml.sample index b51f351b..ccd12d5b 100644 --- a/matterbridge.toml.sample +++ b/matterbridge.toml.sample @@ -765,11 +765,17 @@ ShowJoinPart=false #OPTIONAL (default false) StripNick=false -#Enable to show topic changes from other bridges +#Enable to show topic/purpose changes from other bridges #Only works hiding/show topic changes from slack bridge for now #OPTIONAL (default false) ShowTopicChange=false +#Enable to sync topic/purpose changes from other bridges +#Only works syncing topic changes from slack bridge for now +#Appending "[nosync]" to the topic/purpose will protect it from being synced +#OPTIONAL (default false) +SyncTopicChange=false + ################################################################### #telegram section ###################################################################