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)
pull/275/head
Wim 7 years ago
parent 90a61f15cc
commit ed01820722

@ -69,6 +69,10 @@ 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
}

@ -14,6 +14,7 @@ const (
EVENT_FAILURE = "failure"
EVENT_REJOIN_CHANNELS = "rejoin_channels"
EVENT_USER_ACTION = "user_action"
EVENT_MSG_DELETE = "msg_delete"
)
type Message struct {

@ -66,6 +66,7 @@ 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)
@ -129,6 +130,13 @@ 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
@ -152,6 +160,17 @@ 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
@ -223,6 +242,7 @@ 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
}

@ -106,6 +106,17 @@ 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)

@ -129,6 +129,10 @@ 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)

@ -76,6 +76,10 @@ 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 {

@ -25,6 +25,7 @@ type MMMessage struct {
Username string
UserID string
ID string
Event string
}
type Bmattermost struct {
@ -168,6 +169,12 @@ 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)
}
@ -188,7 +195,7 @@ 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
@ -215,7 +222,7 @@ 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 {
@ -231,6 +238,9 @@ 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

@ -58,6 +58,10 @@ 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

@ -166,6 +166,16 @@ 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)
@ -231,7 +241,7 @@ 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
@ -250,6 +260,12 @@ 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
}
}
@ -276,7 +292,7 @@ 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

@ -70,6 +70,10 @@ 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

@ -80,6 +80,10 @@ 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

@ -1,6 +1,9 @@
# 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

@ -299,7 +299,7 @@ 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:
@ -476,6 +476,14 @@ 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()

Loading…
Cancel
Save