mirror of
https://github.com/cwinfo/matterbridge.git
synced 2024-11-09 16:50:30 +00:00
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)
This commit is contained in:
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) {
|
func (b *Api) Send(msg config.Message) (string, error) {
|
||||||
b.Lock()
|
b.Lock()
|
||||||
defer b.Unlock()
|
defer b.Unlock()
|
||||||
|
// ignore delete messages
|
||||||
|
if msg.Event == config.EVENT_MSG_DELETE {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
b.Messages.Enqueue(&msg)
|
b.Messages.Enqueue(&msg)
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ const (
|
|||||||
EVENT_FAILURE = "failure"
|
EVENT_FAILURE = "failure"
|
||||||
EVENT_REJOIN_CHANNELS = "rejoin_channels"
|
EVENT_REJOIN_CHANNELS = "rejoin_channels"
|
||||||
EVENT_USER_ACTION = "user_action"
|
EVENT_USER_ACTION = "user_action"
|
||||||
|
EVENT_MSG_DELETE = "msg_delete"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
|
@ -66,6 +66,7 @@ func (b *bdiscord) Connect() error {
|
|||||||
b.c.AddHandler(b.messageCreate)
|
b.c.AddHandler(b.messageCreate)
|
||||||
b.c.AddHandler(b.memberUpdate)
|
b.c.AddHandler(b.memberUpdate)
|
||||||
b.c.AddHandler(b.messageUpdate)
|
b.c.AddHandler(b.messageUpdate)
|
||||||
|
b.c.AddHandler(b.messageDelete)
|
||||||
err = b.c.Open()
|
err = b.c.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
flog.Debugf("%#v", err)
|
flog.Debugf("%#v", err)
|
||||||
@ -129,6 +130,13 @@ func (b *bdiscord) Send(msg config.Message) (string, error) {
|
|||||||
|
|
||||||
if wID == "" {
|
if wID == "" {
|
||||||
flog.Debugf("Broadcasting using token (API)")
|
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 != "" {
|
if msg.ID != "" {
|
||||||
_, err := b.c.ChannelMessageEdit(channelID, msg.ID, msg.Username+msg.Text)
|
_, err := b.c.ChannelMessageEdit(channelID, msg.ID, msg.Username+msg.Text)
|
||||||
return msg.ID, err
|
return msg.ID, err
|
||||||
@ -152,6 +160,17 @@ func (b *bdiscord) Send(msg config.Message) (string, error) {
|
|||||||
return "", err
|
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) {
|
func (b *bdiscord) messageUpdate(s *discordgo.Session, m *discordgo.MessageUpdate) {
|
||||||
if b.Config.EditDisable {
|
if b.Config.EditDisable {
|
||||||
return
|
return
|
||||||
@ -223,6 +242,7 @@ func (b *bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat
|
|||||||
|
|
||||||
rmsg.Text = text
|
rmsg.Text = text
|
||||||
flog.Debugf("Sending message from %s on %s to gateway", m.Author.Username, b.Account)
|
flog.Debugf("Sending message from %s on %s to gateway", m.Author.Username, b.Account)
|
||||||
|
flog.Debugf("Message is %#v", rmsg)
|
||||||
b.Remote <- 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)
|
flog.Errorf("Could not find roomID for %v", msg.Channel)
|
||||||
return "", nil
|
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 != "" {
|
if msg.ID != "" {
|
||||||
flog.Debugf("updating message with id %s", msg.ID)
|
flog.Debugf("updating message with id %s", msg.ID)
|
||||||
_, err := b.c.UpdateMessage(roomID, msg.ID, msg.Username+msg.Text)
|
_, 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) {
|
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)
|
flog.Debugf("Receiving %#v", msg)
|
||||||
if strings.HasPrefix(msg.Text, "!") {
|
if strings.HasPrefix(msg.Text, "!") {
|
||||||
b.Command(&msg)
|
b.Command(&msg)
|
||||||
|
@ -76,6 +76,10 @@ func (b *Bmatrix) JoinChannel(channel config.ChannelInfo) error {
|
|||||||
|
|
||||||
func (b *Bmatrix) Send(msg config.Message) (string, error) {
|
func (b *Bmatrix) Send(msg config.Message) (string, error) {
|
||||||
flog.Debugf("Receiving %#v", msg)
|
flog.Debugf("Receiving %#v", msg)
|
||||||
|
// ignore delete messages
|
||||||
|
if msg.Event == config.EVENT_MSG_DELETE {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
channel := b.getRoomID(msg.Channel)
|
channel := b.getRoomID(msg.Channel)
|
||||||
flog.Debugf("Sending to channel %s", channel)
|
flog.Debugf("Sending to channel %s", channel)
|
||||||
if msg.Event == config.EVENT_USER_ACTION {
|
if msg.Event == config.EVENT_USER_ACTION {
|
||||||
|
@ -25,6 +25,7 @@ type MMMessage struct {
|
|||||||
Username string
|
Username string
|
||||||
UserID string
|
UserID string
|
||||||
ID string
|
ID string
|
||||||
|
Event string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Bmattermost struct {
|
type Bmattermost struct {
|
||||||
@ -168,6 +169,12 @@ func (b *Bmattermost) Send(msg config.Message) (string, error) {
|
|||||||
}
|
}
|
||||||
return "", nil
|
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 != "" {
|
if msg.ID != "" {
|
||||||
return b.mc.EditMessage(msg.ID, message)
|
return b.mc.EditMessage(msg.ID, message)
|
||||||
}
|
}
|
||||||
@ -188,7 +195,7 @@ func (b *Bmattermost) handleMatter() {
|
|||||||
go b.handleMatterClient(mchan)
|
go b.handleMatterClient(mchan)
|
||||||
}
|
}
|
||||||
for message := range 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)
|
text, ok := b.replaceAction(message.Text)
|
||||||
if ok {
|
if ok {
|
||||||
rmsg.Event = config.EVENT_USER_ACTION
|
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
|
// do not post our own messages back to irc
|
||||||
// only listen to message from our team
|
// 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 {
|
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 the message has reactions don't repost it (for now, until we can correlate reaction with message)
|
||||||
if message.Post.HasReactions {
|
if message.Post.HasReactions {
|
||||||
@ -231,6 +238,9 @@ func (b *Bmattermost) handleMatterClient(mchan chan *MMMessage) {
|
|||||||
if message.Raw.Event == "post_edited" && !b.Config.EditDisable {
|
if message.Raw.Event == "post_edited" && !b.Config.EditDisable {
|
||||||
m.Text = message.Text + b.Config.EditSuffix
|
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 {
|
if len(message.Post.FileIds) > 0 {
|
||||||
for _, link := range b.mc.GetFileLinks(message.Post.FileIds) {
|
for _, link := range b.mc.GetFileLinks(message.Post.FileIds) {
|
||||||
m.Text = m.Text + "\n" + link
|
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) {
|
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)
|
flog.Debugf("Receiving %#v", msg)
|
||||||
matterMessage := matterhook.OMessage{IconURL: b.Config.IconURL}
|
matterMessage := matterhook.OMessage{IconURL: b.Config.IconURL}
|
||||||
matterMessage.Channel = msg.Channel
|
matterMessage.Channel = msg.Channel
|
||||||
|
@ -166,6 +166,16 @@ func (b *Bslack) Send(msg config.Message) (string, error) {
|
|||||||
// replace mentions
|
// replace mentions
|
||||||
np.LinkNames = 1
|
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 we have no ID it means we're creating a new message, not updating an existing one
|
||||||
if msg.ID != "" {
|
if msg.ID != "" {
|
||||||
ts := strings.Fields(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 {
|
if b.Config.WebhookURL == "" && b.Config.WebhookBindAddress == "" && message.Username == b.si.User.Name {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if message.Text == "" || message.Username == "" {
|
if (message.Text == "" || message.Username == "") && message.Raw.SubType != "message_deleted" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
text := message.Text
|
text := message.Text
|
||||||
@ -250,6 +260,12 @@ func (b *Bslack) handleSlack() {
|
|||||||
if message.Raw.SubMessage != nil {
|
if message.Raw.SubMessage != nil {
|
||||||
msg.ID = "slack " + message.Raw.SubMessage.Timestamp
|
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
|
b.Remote <- msg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -276,7 +292,7 @@ func (b *Bslack) handleSlackClient(mchan chan *MMMessage) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
m := &MMMessage{}
|
m := &MMMessage{}
|
||||||
if ev.BotID == "" {
|
if ev.BotID == "" && ev.SubType != "message_deleted" {
|
||||||
user, err := b.rtm.GetUserInfo(ev.User)
|
user, err := b.rtm.GetUserInfo(ev.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
|
@ -70,6 +70,10 @@ func (b *Bsteam) JoinChannel(channel config.ChannelInfo) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bsteam) Send(msg config.Message) (string, 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)
|
id, err := steamid.NewId(msg.Channel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -80,6 +80,10 @@ func (b *Bxmpp) JoinChannel(channel config.ChannelInfo) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bxmpp) Send(msg config.Message) (string, 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)
|
flog.Debugf("Receiving %#v", msg)
|
||||||
b.xc.Send(xmpp.Chat{Type: "groupchat", Remote: msg.Channel + "@" + b.Config.Muc, Text: msg.Username + msg.Text})
|
b.xc.Send(xmpp.Chat{Type: "groupchat", Remote: msg.Channel + "@" + b.Config.Muc, Text: msg.Username + msg.Text})
|
||||||
return "", nil
|
return "", nil
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
# v1.1.2
|
# v1.1.2
|
||||||
|
## New features
|
||||||
* general: also build darwin binaries
|
* general: also build darwin binaries
|
||||||
* mattermost: add support for mattermost 4.2.x
|
* mattermost: add support for mattermost 4.2.x
|
||||||
|
|
||||||
|
## Bugfix
|
||||||
* mattermost: Send images when text is empty regression. (mattermost). Closes #254
|
* mattermost: Send images when text is empty regression. (mattermost). Closes #254
|
||||||
* slack: also send the first messsage after connect. #252
|
* slack: also send the first messsage after connect. #252
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ func (m *MMClient) WsReceiver() {
|
|||||||
|
|
||||||
func (m *MMClient) parseMessage(rmsg *Message) {
|
func (m *MMClient) parseMessage(rmsg *Message) {
|
||||||
switch rmsg.Raw.Event {
|
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)
|
m.parseActionPost(rmsg)
|
||||||
/*
|
/*
|
||||||
case model.ACTION_USER_REMOVED:
|
case model.ACTION_USER_REMOVED:
|
||||||
@ -476,6 +476,14 @@ func (m *MMClient) EditMessage(postId string, text string) (string, error) {
|
|||||||
return res.Id, nil
|
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 {
|
func (m *MMClient) JoinChannel(channelId string) error {
|
||||||
m.RLock()
|
m.RLock()
|
||||||
defer m.RUnlock()
|
defer m.RUnlock()
|
||||||
|
Loading…
Reference in New Issue
Block a user