From c2e1c35dca41cd61d51a5b58d1aa2925fbf3f7d4 Mon Sep 17 00:00:00 2001 From: Gary Kramlich Date: Fri, 11 Feb 2022 02:43:54 -0600 Subject: [PATCH] Add support for edited messages from discord --- bridge/portal.go | 43 ++++++++++++++++++++++++++++++++++++++++++- bridge/user.go | 19 +++++++++++++++++++ database/message.go | 2 +- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/bridge/portal.go b/bridge/portal.go index 1f522fe..e6328f5 100644 --- a/bridge/portal.go +++ b/bridge/portal.go @@ -270,6 +270,8 @@ func (p *Portal) handleDiscordMessages(msg portalDiscordMessage) { switch msg.msg.(type) { case *discordgo.MessageCreate: p.handleDiscordMessageCreate(msg.user, msg.msg.(*discordgo.MessageCreate).Message) + case *discordgo.MessageUpdate: + p.handleDiscordMessagesUpdate(msg.user, msg.msg.(*discordgo.MessageUpdate).Message) case *discordgo.MessageDelete: p.handleDiscordMessageDelete(msg.user, msg.msg.(*discordgo.MessageDelete).Message) case *discordgo.MessageReactionAdd: @@ -329,11 +331,50 @@ func (p *Portal) handleDiscordMessageCreate(user *User, msg *discordgo.Message) resp, err := intent.SendMessageEvent(p.MXID, event.EventMessage, content) if err != nil { p.log.Warnfln("failed to send message %q to matrix: %v", msg.ID, err) + return } ts, _ := msg.Timestamp.Parse() - p.markMessageHandled(nil, msg.ID, resp.EventID, msg.Author.ID, ts) + p.markMessageHandled(existing, msg.ID, resp.EventID, msg.Author.ID, ts) +} + +func (p *Portal) handleDiscordMessagesUpdate(user *User, msg *discordgo.Message) { + if user.ID == msg.Author.ID { + return + } + + if p.MXID == "" { + p.log.Warnln("handle message called without a valid portal") + + return + } + + existing := p.bridge.db.Message.GetByDiscordID(p.Key, msg.ID) + if existing == nil { + p.log.Debugln("failed to find previous message to update", msg.ID) + } + + content := &event.MessageEventContent{ + Body: msg.Content, + MsgType: event.MsgText, + } + + content.SetEdit(existing.MatrixID) + + intent := p.bridge.GetPuppetByID(msg.Author.ID).IntentFor(p) + + _, err := intent.SendMessageEvent(p.MXID, event.EventMessage, content) + if err != nil { + p.log.Warnfln("failed to send message %q to matrix: %v", msg.ID, err) + + return + } + + // It appears that matrix updates only work against the original event id + // so updating it to the new one from an edit makes it so you can't update + // it anyways. So we just don't update anything and we can keep updating + // the message. } func (p *Portal) handleDiscordMessageDelete(user *User, msg *discordgo.Message) { diff --git a/bridge/user.go b/bridge/user.go index a38b54e..72218dd 100644 --- a/bridge/user.go +++ b/bridge/user.go @@ -214,6 +214,7 @@ func (u *User) Connect() error { u.User.Session.AddHandler(u.messageCreateHandler) u.User.Session.AddHandler(u.messageDeleteHandler) + u.User.Session.AddHandler(u.messageUpdateHandler) u.User.Session.AddHandler(u.reactionAddHandler) u.User.Session.AddHandler(u.reactionRemoveHandler) @@ -321,6 +322,24 @@ func (u *User) messageDeleteHandler(s *discordgo.Session, m *discordgo.MessageDe portal.discordMessages <- msg } +func (u *User) messageUpdateHandler(s *discordgo.Session, m *discordgo.MessageUpdate) { + if m.GuildID != "" { + u.log.Debugln("ignoring message update for guild message") + + return + } + + key := database.NewPortalKey(m.ChannelID, u.ID) + portal := u.bridge.GetPortalByID(key) + + msg := portalDiscordMessage{ + msg: m, + user: u, + } + + portal.discordMessages <- msg +} + func (u *User) reactionAddHandler(s *discordgo.Session, m *discordgo.MessageReactionAdd) { if m.GuildID != "" { u.log.Debugln("ignoring reaction for guild message") diff --git a/database/message.go b/database/message.go index 044b555..59dde3e 100644 --- a/database/message.go +++ b/database/message.go @@ -69,7 +69,7 @@ func (m *Message) Delete() { func (m *Message) UpdateMatrixID(mxid id.EventID) { query := "UPDATE message SET matrix_message_id=$1 WHERE channel_id=$2" + - "AND receiver=$3 AND discord_message_id=$4" + " AND receiver=$3 AND discord_message_id=$4" m.MatrixID = mxid _, err := m.db.Exec(query, m.MatrixID, m.Channel.ChannelID, m.Channel.Receiver, m.DiscordID)