From 3d281b3316a68a265efb0f024755e8d1c3863bd5 Mon Sep 17 00:00:00 2001 From: Patrick Connolly Date: Fri, 9 Nov 2018 03:45:40 +0800 Subject: [PATCH] Add ability to show when user is typing across Slack bridges (#559) --- bridge/config/config.go | 2 ++ bridge/slack/handlers.go | 30 +++++++++++++++++++++++++++++- bridge/slack/slack.go | 11 ++++++++++- gateway/gateway.go | 9 ++++++++- matterbridge.toml.sample | 6 ++++++ 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/bridge/config/config.go b/bridge/config/config.go index bdf77f88..9d335cac 100644 --- a/bridge/config/config.go +++ b/bridge/config/config.go @@ -23,6 +23,7 @@ const ( EVENT_USER_ACTION = "user_action" EVENT_MSG_DELETE = "msg_delete" EVENT_API_CONNECTED = "api_connected" + EVENT_USER_TYPING = "user_typing" ) type Message struct { @@ -110,6 +111,7 @@ type Protocol struct { Server string // IRC,mattermost,XMPP,discord ShowJoinPart bool // all protocols ShowTopicChange bool // slack + ShowUserTyping bool // slack ShowEmbeds bool // discord SkipTLSVerify bool // IRC, mattermost StripNick bool // all protocols diff --git a/bridge/slack/handlers.go b/bridge/slack/handlers.go index 4307e7b9..0f5e1402 100644 --- a/bridge/slack/handlers.go +++ b/bridge/slack/handlers.go @@ -23,7 +23,9 @@ func (b *Bslack) handleSlack() { time.Sleep(time.Second) b.Log.Debug("Start listening for Slack messages") for message := range messages { - b.Log.Debugf("<= Sending message from %s on %s to gateway", message.Username, b.Account) + if message.Event != config.EVENT_USER_TYPING { + b.Log.Debugf("<= Sending message from %s on %s to gateway", message.Username, b.Account) + } // cleanup the message message.Text = b.replaceMention(message.Text) @@ -46,6 +48,14 @@ func (b *Bslack) handleSlackClient(messages chan *config.Message) { b.Log.Debugf("== Receiving event %#v", msg.Data) } switch ev := msg.Data.(type) { + case *slack.UserTypingEvent: + rmsg, err := b.handleTypingEvent(ev) + if err != nil { + b.Log.Errorf("%#v", err) + continue + } + + messages <- rmsg case *slack.MessageEvent: if b.skipMessageEvent(ev) { b.Log.Debugf("Skipped message: %#v", ev) @@ -225,6 +235,24 @@ func (b *Bslack) handleAttachments(ev *slack.MessageEvent, rmsg *config.Message) var commentRE = regexp.MustCompile(`.*?commented: (.*)`) +func (b *Bslack) handleTypingEvent(ev *slack.UserTypingEvent) (*config.Message, error) { + var err error + // use our own func because rtm.GetChannelInfo doesn't work for private channels + channelInfo, err := b.getChannelByID(ev.Channel) + if err != nil { + return nil, err + } + + rmsg := config.Message{ + Channel: channelInfo.Name, + Account: b.Account, + Event: config.EVENT_USER_TYPING, + } + + return &rmsg, nil + +} + // handleDownloadFile handles file download func (b *Bslack) handleDownloadFile(rmsg *config.Message, file *slack.File) error { if b.fileIsAvailable(file) { diff --git a/bridge/slack/slack.go b/bridge/slack/slack.go index 8c96837e..701f4769 100644 --- a/bridge/slack/slack.go +++ b/bridge/slack/slack.go @@ -187,7 +187,10 @@ func (b *Bslack) Reload(cfg *bridge.Config) (string, error) { } func (b *Bslack) Send(msg config.Message) (string, error) { - b.Log.Debugf("=> Receiving %#v", msg) + // Too noisy to log like other events + if msg.Event != config.EVENT_USER_TYPING { + b.Log.Debugf("=> Receiving %#v", msg) + } // Make a action /me of the message if msg.Event == config.EVENT_USER_ACTION { @@ -266,6 +269,12 @@ func (b *Bslack) sendRTM(msg config.Message) (string, error) { if err != nil { return "", fmt.Errorf("could not send message: %v", err) } + if msg.Event == config.EVENT_USER_TYPING { + if b.GetBool("ShowUserTyping") { + b.rtm.SendMessage(b.rtm.NewTypingMessage(channelInfo.ID)) + } + return "", nil + } // Delete message if msg.Event == config.EVENT_MSG_DELETE { diff --git a/gateway/gateway.go b/gateway/gateway.go index d4c84650..3a6fa1e0 100644 --- a/gateway/gateway.go +++ b/gateway/gateway.go @@ -297,7 +297,11 @@ func (gw *Gateway) handleMessage(msg config.Message, dest *bridge.Bridge) []*BrM continue } } - flog.Debugf("=> Sending %#v from %s (%s) to %s (%s)", msg, msg.Account, originchannel, dest.Account, channel.Name) + + // Too noisy to log like other events + if msg.Event != config.EVENT_USER_TYPING { + flog.Debugf("=> Sending %#v from %s (%s) to %s (%s)", msg, msg.Account, originchannel, dest.Account, channel.Name) + } msg.Channel = channel.Name msg.Avatar = gw.modifyAvatar(origmsg, dest) @@ -337,6 +341,9 @@ func (gw *Gateway) ignoreMessage(msg *config.Message) bool { // check if we need to ignore a empty message if msg.Text == "" { + if msg.Event == config.EVENT_USER_TYPING { + return false + } // we have an attachment or actual bytes, do not ignore if msg.Extra != nil && (msg.Extra["attachments"] != nil || diff --git a/matterbridge.toml.sample b/matterbridge.toml.sample index 441a333c..d4b2fbbe 100644 --- a/matterbridge.toml.sample +++ b/matterbridge.toml.sample @@ -665,6 +665,12 @@ ShowTopicChange=false #OPTIONAL (default false) PreserveThreading=false +#Enable showing "user_typing" events from across gateway when available. +#Hint: Set your bot/user's "Full Name" to be "Someone", +#and so the message will say "Someone is typing". +#OPTIONAL (default false) +ShowUserTyping=false + ################################################################### #discord section ###################################################################