mirror of
https://github.com/42wim/matterbridge.git
synced 2024-11-21 10:12:00 -08:00
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 :/
This commit is contained in:
parent
765e00c949
commit
cbb46293ab
@ -34,8 +34,6 @@ type Bdiscord struct {
|
|||||||
membersMutex sync.RWMutex
|
membersMutex sync.RWMutex
|
||||||
userMemberMap map[string]*discordgo.Member
|
userMemberMap map[string]*discordgo.Member
|
||||||
nickMemberMap map[string]*discordgo.Member
|
nickMemberMap map[string]*discordgo.Member
|
||||||
webhookCache map[string]string
|
|
||||||
webhookMutex sync.RWMutex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(cfg *bridge.Config) bridge.Bridger {
|
func New(cfg *bridge.Config) bridge.Bridger {
|
||||||
@ -43,7 +41,6 @@ func New(cfg *bridge.Config) bridge.Bridger {
|
|||||||
b.userMemberMap = make(map[string]*discordgo.Member)
|
b.userMemberMap = make(map[string]*discordgo.Member)
|
||||||
b.nickMemberMap = make(map[string]*discordgo.Member)
|
b.nickMemberMap = make(map[string]*discordgo.Member)
|
||||||
b.channelInfoMap = make(map[string]*config.ChannelInfo)
|
b.channelInfoMap = make(map[string]*config.ChannelInfo)
|
||||||
b.webhookCache = make(map[string]string)
|
|
||||||
if b.GetString("WebhookURL") != "" {
|
if b.GetString("WebhookURL") != "" {
|
||||||
b.Log.Debug("Configuring Discord Incoming Webhook")
|
b.Log.Debug("Configuring Discord Incoming Webhook")
|
||||||
b.webhookID, b.webhookToken = b.splitURL(b.GetString("WebhookURL"))
|
b.webhookID, b.webhookToken = b.splitURL(b.GetString("WebhookURL"))
|
||||||
@ -191,8 +188,6 @@ func (b *Bdiscord) JoinChannel(channel config.ChannelInfo) error {
|
|||||||
func (b *Bdiscord) Send(msg config.Message) (string, error) {
|
func (b *Bdiscord) Send(msg config.Message) (string, error) {
|
||||||
b.Log.Debugf("=> Receiving %#v", msg)
|
b.Log.Debugf("=> Receiving %#v", msg)
|
||||||
|
|
||||||
origMsgID := msg.ID
|
|
||||||
|
|
||||||
channelID := b.getChannelID(msg.Channel)
|
channelID := b.getChannelID(msg.Channel)
|
||||||
if channelID == "" {
|
if channelID == "" {
|
||||||
return "", fmt.Errorf("Could not find channelID for %v", msg.Channel)
|
return "", fmt.Errorf("Could not find channelID for %v", msg.Channel)
|
||||||
@ -233,18 +228,6 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {
|
|||||||
return "", nil
|
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
|
// skip empty messages
|
||||||
if msg.Text == "" && (msg.Extra == nil || len(msg.Extra["file"]) == 0) {
|
if msg.Text == "" && (msg.Extra == nil || len(msg.Extra["file"]) == 0) {
|
||||||
b.Log.Debugf("Skipping empty message %#v", msg)
|
b.Log.Debugf("Skipping empty message %#v", msg)
|
||||||
@ -257,11 +240,25 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {
|
|||||||
if len(msg.Username) > 32 {
|
if len(msg.Username) > 32 {
|
||||||
msg.Username = msg.Username[0: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
|
// if we have a global webhook for this Discord account, and permission
|
||||||
// to modify webhooks (previously verified), then set its channel to
|
// to modify webhooks (previously verified), then set its channel to
|
||||||
// the message channel before using it
|
// the message channel before using it.
|
||||||
// TODO: this isn't necessary if the last message from this webhook was
|
|
||||||
// sent to the current channel
|
|
||||||
if isGlobalWebhook && b.canEditWebhooks {
|
if isGlobalWebhook && b.canEditWebhooks {
|
||||||
b.Log.Debugf("Setting webhook channel to \"%s\"", msg.Channel)
|
b.Log.Debugf("Setting webhook channel to \"%s\"", msg.Channel)
|
||||||
_, err := b.c.WebhookEdit(wID, "", "", channelID)
|
_, err := b.c.WebhookEdit(wID, "", "", channelID)
|
||||||
@ -280,7 +277,6 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
b.updateCacheID(origMsgID, msg.ID)
|
|
||||||
return msg.ID, nil
|
return msg.ID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,7 +287,6 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {
|
|||||||
if msg.ID == "" {
|
if msg.ID == "" {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
msg.ID = b.getCacheID(msg.ID)
|
|
||||||
err := b.c.ChannelMessageDelete(channelID, msg.ID)
|
err := b.c.ChannelMessageDelete(channelID, msg.ID)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -209,40 +209,6 @@ func (b *Bdiscord) splitURL(url string) (string, string) {
|
|||||||
return webhookURLSplit[webhookIdxID], webhookURLSplit[webhookIdxToken]
|
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 {
|
func enumerateUsernames(s string) []string {
|
||||||
onlySpace := true
|
onlySpace := true
|
||||||
for _, r := range s {
|
for _, r := range s {
|
||||||
|
Loading…
Reference in New Issue
Block a user