Thumbnail

rani/matterbridge.git

Clone URL: https://git.buni.party/rani/matterbridge.git

commit a645052badc9567a1051138f2274e118ae96d743 Author: Wim <wim@42.be> Date: Mon Sep 11 22:45:15 2017 +0000 Add support for deleting messages across bridges. Currently fully support mattermost,slack and discord. Message deleted on the bridge or received from other bridges will be deleted. Partially support for Gitter. Gitter bridge will delete messages received from other bridges. But if you delete a message on gitter, this deletion will not be sent to other bridges (this is a gitter API limitation, it doesn't propogate edits or deletes via the API) diff --git a/bridge/api/api.go b/bridge/api/api.go index ca28d90..ab473af 100644 --- a/bridge/api/api.go +++ b/bridge/api/api.go @@ -696 +6910 @@ func (b *Api) JoinChannel(channel config.ChannelInfo) error {  func (b *Api) Send(msg config.Message) (string, error) {   b.Lock()   defer b.Unlock() + // ignore delete messages + if msg.Event == config.EVENT_MSG_DELETE { + return "", nil + }   b.Messages.Enqueue(&msg)   return "", nil  } diff --git a/bridge/config/config.go b/bridge/config/config.go index c5925a1..812ce18 100644 --- a/bridge/config/config.go +++ b/bridge/config/config.go @@ -146 +147 @@ const (   EVENT_FAILURE = "failure"   EVENT_REJOIN_CHANNELS = "rejoin_channels"   EVENT_USER_ACTION = "user_action" + EVENT_MSG_DELETE = "msg_delete"  )    type Message struct { diff --git a/bridge/discord/discord.go b/bridge/discord/discord.go index ffbada4..d8320c7 100644 --- a/bridge/discord/discord.go +++ b/bridge/discord/discord.go @@ -666 +667 @@ func (b *bdiscord) Connect() error {   b.c.AddHandler(b.messageCreate)   b.c.AddHandler(b.memberUpdate)   b.c.AddHandler(b.messageUpdate) + b.c.AddHandler(b.messageDelete)   err = b.c.Open()   if err != nil {   flog.Debugf("%#v", err) @@ -1296 +13013 @@ func (b *bdiscord) Send(msg config.Message) (string, error) {     if wID == "" {   flog.Debugf("Broadcasting using token (API)") + if msg.Event == config.EVENT_MSG_DELETE { + if msg.ID == "" { + return "", nil + } + err := b.c.ChannelMessageDelete(channelID, msg.ID) + return "", err + }   if msg.ID != "" {   _, err := b.c.ChannelMessageEdit(channelID, msg.ID, msg.Username+msg.Text)   return msg.ID, err @@ -1526 +16017 @@ func (b *bdiscord) Send(msg config.Message) (string, error) {   return "", err  }   +func (b *bdiscord) messageDelete(s *discordgo.Session, m *discordgo.MessageDelete) { + rmsg := config.Message{Account: b.Account, ID: m.ID, Event: config.EVENT_MSG_DELETE, Text: config.EVENT_MSG_DELETE} + rmsg.Channel = b.getChannelName(m.ChannelID) + if b.UseChannelID { + rmsg.Channel = "ID:" + m.ChannelID + } + flog.Debugf("Sending message from %s to gateway", b.Account) + flog.Debugf("Message is %#v", rmsg) + b.Remote <- rmsg +} +  func (b *bdiscord) messageUpdate(s *discordgo.Session, m *discordgo.MessageUpdate) {   if b.Config.EditDisable {   return @@ -2236 +2427 @@ func (b *bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat     rmsg.Text = text   flog.Debugf("Sending message from %s on %s to gateway", m.Author.Username, b.Account) + flog.Debugf("Message is %#v", rmsg)   b.Remote <- rmsg  }   diff --git a/bridge/gitter/gitter.go b/bridge/gitter/gitter.go index 9a7b3bf..b1d6873 100644 --- a/bridge/gitter/gitter.go +++ b/bridge/gitter/gitter.go @@ -1066 +10617 @@ func (b *Bgitter) Send(msg config.Message) (string, error) {   flog.Errorf("Could not find roomID for %v", msg.Channel)   return "", nil   } + if msg.Event == config.EVENT_MSG_DELETE { + if msg.ID == "" { + return "", nil + } + // gitter has no delete message api + _, err := b.c.UpdateMessage(roomID, msg.ID, "") + if err != nil { + return "", err + } + return "", nil + }   if msg.ID != "" {   flog.Debugf("updating message with id %s", msg.ID)   _, err := b.c.UpdateMessage(roomID, msg.ID, msg.Username+msg.Text) diff --git a/bridge/irc/irc.go b/bridge/irc/irc.go index d62fe31..1e0101f 100644 --- a/bridge/irc/irc.go +++ b/bridge/irc/irc.go @@ -1296 +12910 @@ func (b *Birc) JoinChannel(channel config.ChannelInfo) error {  }    func (b *Birc) Send(msg config.Message) (string, error) { + // ignore delete messages + if msg.Event == config.EVENT_MSG_DELETE { + return "", nil + }   flog.Debugf("Receiving %#v", msg)   if strings.HasPrefix(msg.Text, "!") {   b.Command(&msg) diff --git a/bridge/matrix/matrix.go b/bridge/matrix/matrix.go index 1cad622..bbf85e9 100644 --- a/bridge/matrix/matrix.go +++ b/bridge/matrix/matrix.go @@ -766 +7610 @@ func (b *Bmatrix) JoinChannel(channel config.ChannelInfo) error {    func (b *Bmatrix) Send(msg config.Message) (string, error) {   flog.Debugf("Receiving %#v", msg) + // ignore delete messages + if msg.Event == config.EVENT_MSG_DELETE { + return "", nil + }   channel := b.getRoomID(msg.Channel)   flog.Debugf("Sending to channel %s", channel)   if msg.Event == config.EVENT_USER_ACTION { diff --git a/bridge/mattermost/mattermost.go b/bridge/mattermost/mattermost.go index 30e3804..6e5b3d3 100644 --- a/bridge/mattermost/mattermost.go +++ b/bridge/mattermost/mattermost.go @@ -256 +257 @@ type MMMessage struct {   Username string   UserID string   ID string + Event string  }    type Bmattermost struct { @@ -1686 +16912 @@ func (b *Bmattermost) Send(msg config.Message) (string, error) {   }   return "", nil   } + if msg.Event == config.EVENT_MSG_DELETE { + if msg.ID == "" { + return "", nil + } + return msg.ID, b.mc.DeleteMessage(msg.ID) + }   if msg.ID != "" {   return b.mc.EditMessage(msg.ID, message)   } @@ -1887 +1957 @@ func (b *Bmattermost) handleMatter() {   go b.handleMatterClient(mchan)   }   for message := range mchan { - rmsg := config.Message{Username: message.Username, Channel: message.Channel, Account: b.Account, UserID: message.UserID, ID: message.ID} + rmsg := config.Message{Username: message.Username, Channel: message.Channel, Account: b.Account, UserID: message.UserID, ID: message.ID, Event: message.Event}   text, ok := b.replaceAction(message.Text)   if ok {   rmsg.Event = config.EVENT_USER_ACTION @@ -2157 +2227 @@ func (b *Bmattermost) handleMatterClient(mchan chan *MMMessage) {   }   // do not post our own messages back to irc   // only listen to message from our team - if (message.Raw.Event == "posted" || message.Raw.Event == "post_edited") && + if (message.Raw.Event == "posted" || message.Raw.Event == "post_edited" || message.Raw.Event == "post_deleted") &&   b.mc.User.Username != message.Username && message.Raw.Data["team_id"].(string) == b.TeamId {   // if the message has reactions don't repost it (for now, until we can correlate reaction with message)   if message.Post.HasReactions { @@ -2316 +2389 @@ func (b *Bmattermost) handleMatterClient(mchan chan *MMMessage) {   if message.Raw.Event == "post_edited" && !b.Config.EditDisable {   m.Text = message.Text + b.Config.EditSuffix   } + if message.Raw.Event == "post_deleted" { + m.Event = config.EVENT_MSG_DELETE + }   if len(message.Post.FileIds) > 0 {   for _, link := range b.mc.GetFileLinks(message.Post.FileIds) {   m.Text = m.Text + "\n" + link diff --git a/bridge/rocketchat/rocketchat.go b/bridge/rocketchat/rocketchat.go index 1e534c2..eac754f 100644 --- a/bridge/rocketchat/rocketchat.go +++ b/bridge/rocketchat/rocketchat.go @@ -586 +5810 @@ func (b *Brocketchat) JoinChannel(channel config.ChannelInfo) error {  }    func (b *Brocketchat) Send(msg config.Message) (string, error) { + // ignore delete messages + if msg.Event == config.EVENT_MSG_DELETE { + return "", nil + }   flog.Debugf("Receiving %#v", msg)   matterMessage := matterhook.OMessage{IconURL: b.Config.IconURL}   matterMessage.Channel = msg.Channel diff --git a/bridge/slack/slack.go b/bridge/slack/slack.go index c720546..fa847db 100644 --- a/bridge/slack/slack.go +++ b/bridge/slack/slack.go @@ -1666 +16616 @@ func (b *Bslack) Send(msg config.Message) (string, error) {   // replace mentions   np.LinkNames = 1   + if msg.Event == config.EVENT_MSG_DELETE { + // some protocols echo deletes, but with empty ID + if msg.ID == "" { + return "", nil + } + // we get a "slack <ID>", split it + ts := strings.Fields(msg.ID) + b.sc.DeleteMessage(schannel.ID, ts[1]) + return "", nil + }   // if we have no ID it means we're creating a new message, not updating an existing one   if msg.ID != "" {   ts := strings.Fields(msg.ID) @@ -2317 +2417 @@ func (b *Bslack) handleSlack() {   if b.Config.WebhookURL == "" && b.Config.WebhookBindAddress == "" && message.Username == b.si.User.Name {   continue   } - if message.Text == "" || message.Username == "" { + if (message.Text == "" || message.Username == "") && message.Raw.SubType != "message_deleted" {   continue   }   text := message.Text @@ -2506 +26012 @@ func (b *Bslack) handleSlack() {   if message.Raw.SubMessage != nil {   msg.ID = "slack " + message.Raw.SubMessage.Timestamp   } + if message.Raw.SubType == "message_deleted" { + msg.Text = config.EVENT_MSG_DELETE + msg.Event = config.EVENT_MSG_DELETE + msg.ID = "slack " + message.Raw.DeletedTimestamp + } + flog.Debugf("Message is %#v", msg)   b.Remote <- msg   }  } @@ -2767 +2927 @@ func (b *Bslack) handleSlackClient(mchan chan *MMMessage) {   continue   }   m := &MMMessage{} - if ev.BotID == "" { + if ev.BotID == "" && ev.SubType != "message_deleted" {   user, err := b.rtm.GetUserInfo(ev.User)   if err != nil {   continue diff --git a/bridge/steam/steam.go b/bridge/steam/steam.go index 25291ff..60b2f1b 100644 --- a/bridge/steam/steam.go +++ b/bridge/steam/steam.go @@ -706 +7010 @@ func (b *Bsteam) JoinChannel(channel config.ChannelInfo) error {  }    func (b *Bsteam) Send(msg config.Message) (string, error) { + // ignore delete messages + if msg.Event == config.EVENT_MSG_DELETE { + return "", nil + }   id, err := steamid.NewId(msg.Channel)   if err != nil {   return "", err diff --git a/bridge/xmpp/xmpp.go b/bridge/xmpp/xmpp.go index d453706..6999e80 100644 --- a/bridge/xmpp/xmpp.go +++ b/bridge/xmpp/xmpp.go @@ -806 +8010 @@ func (b *Bxmpp) JoinChannel(channel config.ChannelInfo) error {  }    func (b *Bxmpp) Send(msg config.Message) (string, error) { + // ignore delete messages + if msg.Event == config.EVENT_MSG_DELETE { + return "", nil + }   flog.Debugf("Receiving %#v", msg)   b.xc.Send(xmpp.Chat{Type: "groupchat", Remote: msg.Channel + "@" + b.Config.Muc, Text: msg.Username + msg.Text})   return "", nil diff --git a/changelog.md b/changelog.md index 9171658..882878b 100644 --- a/changelog.md +++ b/changelog.md @@ -16 +19 @@  # v1.1.2 +## New features  * general: also build darwin binaries  * mattermost: add support for mattermost 4.2.x + +## Bugfix  * mattermost: Send images when text is empty regression. (mattermost). Closes #254  * slack: also send the first messsage after connect. #252   diff --git a/matterclient/matterclient.go b/matterclient/matterclient.go index e348b76..732c9e3 100644 --- a/matterclient/matterclient.go +++ b/matterclient/matterclient.go @@ -2997 +2997 @@ func (m *MMClient) WsReceiver() {    func (m *MMClient) parseMessage(rmsg *Message) {   switch rmsg.Raw.Event { - case model.WEBSOCKET_EVENT_POSTED, model.WEBSOCKET_EVENT_POST_EDITED: + case model.WEBSOCKET_EVENT_POSTED, model.WEBSOCKET_EVENT_POST_EDITED, model.WEBSOCKET_EVENT_POST_DELETED:   m.parseActionPost(rmsg)   /*   case model.ACTION_USER_REMOVED: @@ -4766 +47614 @@ func (m *MMClient) EditMessage(postId string, text string) (string, error) {   return res.Id, nil  }   +func (m *MMClient) DeleteMessage(postId string) error { + _, resp := m.Client.DeletePost(postId) + if resp.Error != nil { + return resp.Error + } + return nil +} +  func (m *MMClient) JoinChannel(channelId string) error {   m.RLock()   defer m.RUnlock()