Thumbnail

rani/matterbridge.git

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

commit a1f298422dba001862460a8037e4879da3a9914c Author: Simon THOBY <simonthoby@live.fr> Date: Sat Nov 14 05:08:09 2020 +0000 Update webhook messages via new endpoint (discord) When using the webhook, the previous method to edit a message was to delete the old one via the classical API, and to create a new message via the webhook. While this works, this means that editing "old" messages lead to a mess where the chronological order is no longer respected. This uses an hidden API explained in https://support.discord.com/hc/en-us/community/posts/360034557771 to achieve a proper edition using the webhook API. The obvious downside of this approach is that since it is an undocumented API for now, so there is no stability guarantee :/ diff --git a/bridge/discord/discord.go b/bridge/discord/discord.go index 245b87c..0df0321 100644 --- a/bridge/discord/discord.go +++ b/bridge/discord/discord.go @@ -348 +346 @@ type Bdiscord struct {   membersMutex sync.RWMutex   userMemberMap map[string]*discordgo.Member   nickMemberMap map[string]*discordgo.Member - webhookCache map[string]string - webhookMutex sync.RWMutex  }    func New(cfg *bridge.Config) bridge.Bridger { @@ -437 +416 @@ func New(cfg *bridge.Config) bridge.Bridger {   b.userMemberMap = make(map[string]*discordgo.Member)   b.nickMemberMap = make(map[string]*discordgo.Member)   b.channelInfoMap = make(map[string]*config.ChannelInfo) - b.webhookCache = make(map[string]string)   if b.GetString("WebhookURL") != "" {   b.Log.Debug("Configuring Discord Incoming Webhook")   b.webhookID, b.webhookToken = b.splitURL(b.GetString("WebhookURL")) @@ -1918 +1886 @@ func (b *Bdiscord) JoinChannel(channel config.ChannelInfo) error {  func (b *Bdiscord) Send(msg config.Message) (string, error) {   b.Log.Debugf("=> Receiving %#v", msg)   - origMsgID := msg.ID -   channelID := b.getChannelID(msg.Channel)   if channelID == "" {   return "", fmt.Errorf("Could not find channelID for %v", msg.Channel) @@ -23318 +2286 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {   return "", nil   }   - // If we are editing a message, delete the old message - if msg.ID != "" { - msg.ID = b.getCacheID(msg.ID) - b.Log.Debugf("Deleting edited webhook message") - err := b.c.ChannelMessageDelete(channelID, msg.ID) - if err != nil { - b.Log.Errorf("Could not delete edited webhook message: %s", err) - } - } - - b.Log.Debugf("Broadcasting using Webhook") -   // skip empty messages   if msg.Text == "" && (msg.Extra == nil || len(msg.Extra["file"]) == 0) {   b.Log.Debugf("Skipping empty message %#v", msg) @@ -25711 +24025 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {   if len(msg.Username) > 32 {   msg.Username = msg.Username[0:32]   } + + if msg.ID != "" { + b.Log.Debugf("Editing webhook message") + uri := discordgo.EndpointWebhookToken(wID, wToken) + "/messages/" + msg.ID + _, err := b.c.RequestWithBucketID("PATCH", uri, discordgo.WebhookParams{ + Content: msg.Text, + Username: msg.Username, + }, discordgo.EndpointWebhookToken("", "")) + if err == nil { + return msg.ID, nil + } + b.Log.Errorf("Could not edit webhook message: %s", err) + } + + b.Log.Debugf("Broadcasting using Webhook") +   // if we have a global webhook for this Discord account, and permission   // to modify webhooks (previously verified), then set its channel to - // the message channel before using it - // TODO: this isn't necessary if the last message from this webhook was - // sent to the current channel + // the message channel before using it.   if isGlobalWebhook && b.canEditWebhooks {   b.Log.Debugf("Setting webhook channel to \"%s\"", msg.Channel)   _, err := b.c.WebhookEdit(wID, "", "", channelID) @@ -2807 +2776 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {   return "", nil   }   - b.updateCacheID(origMsgID, msg.ID)   return msg.ID, nil   }   @@ -2917 +2876 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {   if msg.ID == "" {   return "", nil   } - msg.ID = b.getCacheID(msg.ID)   err := b.c.ChannelMessageDelete(channelID, msg.ID)   return "", err   } diff --git a/bridge/discord/helpers.go b/bridge/discord/helpers.go index e183165..73536cf 100644 --- a/bridge/discord/helpers.go +++ b/bridge/discord/helpers.go @@ -20940 +2096 @@ func (b *Bdiscord) splitURL(url string) (string, string) {   return webhookURLSplit[webhookIdxID], webhookURLSplit[webhookIdxToken]  }   -// getcacheID tries to find a corresponding msgID in the webhook cache. -// if not found returns the original request. -func (b *Bdiscord) getCacheID(msgID string) string { - b.webhookMutex.RLock() - defer b.webhookMutex.RUnlock() - for k, v := range b.webhookCache { - if msgID == k { - return v - } - } - return msgID -} - -// updateCacheID updates the cache so that the newID takes the place of -// the original ID. This is used for edit/deletes in combination with webhooks -// as editing a message via webhook means deleting the message and creating a -// new message (with a new ID). This ID needs to be set instead of the original ID -func (b *Bdiscord) updateCacheID(origID, newID string) { - b.webhookMutex.Lock() - match := false - for k, v := range b.webhookCache { - if v == origID { - delete(b.webhookCache, k) - b.webhookCache[origID] = newID - match = true - continue - } - } - if !match && origID != "" { - b.webhookCache[origID] = newID - } - b.webhookMutex.Unlock() -} -  func enumerateUsernames(s string) []string {   onlySpace := true   for _, r := range s {