diff --git a/bridge/discord/discord.go b/bridge/discord/discord.go index a59735ad..614512f3 100644 --- a/bridge/discord/discord.go +++ b/bridge/discord/discord.go @@ -34,6 +34,8 @@ 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 { @@ -41,6 +43,7 @@ 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")) @@ -188,6 +191,8 @@ 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) @@ -230,6 +235,7 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) { // 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 { @@ -273,6 +279,8 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) { if msg == nil { return "", nil } + + b.updateCacheID(origMsgID, msg.ID) return msg.ID, nil } @@ -283,6 +291,7 @@ 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 9ef234c5..00592f3a 100644 --- a/bridge/discord/helpers.go +++ b/bridge/discord/helpers.go @@ -208,6 +208,40 @@ 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 {