|
|
|
@ -2,6 +2,7 @@ package bdiscord
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"github.com/42wim/matterbridge/bridge/config"
|
|
|
|
|
"github.com/42wim/matterbridge/bridge/helper"
|
|
|
|
@ -42,13 +43,65 @@ func (b *Bdiscord) maybeGetLocalAvatar(msg *config.Message) string {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (b *Bdiscord) webhookSendTextOnly(msg *config.Message, channelID string) (string, error) {
|
|
|
|
|
msgParts := helper.ClipOrSplitMessage(msg.Text, MessageLength, b.GetString("MessageClipped"), b.GetInt("MessageSplitMaxCount"))
|
|
|
|
|
var msgIds = []string{}
|
|
|
|
|
for _, msgPart := range msgParts {
|
|
|
|
|
res, err := b.transmitter.Send(
|
|
|
|
|
channelID,
|
|
|
|
|
&discordgo.WebhookParams{
|
|
|
|
|
Content: msgPart,
|
|
|
|
|
Username: msg.Username,
|
|
|
|
|
AvatarURL: msg.Avatar,
|
|
|
|
|
AllowedMentions: b.getAllowedMentions(),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
} else {
|
|
|
|
|
msgIds = append(msgIds, res.ID)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Exploit that a discord message ID is actually just a large number, so we encode a list of IDs by separating them with ";".
|
|
|
|
|
return strings.Join(msgIds, ";"), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (b *Bdiscord) webhookSendFilesOnly(msg *config.Message, channelID string) error {
|
|
|
|
|
for _, f := range msg.Extra["file"] {
|
|
|
|
|
fi := f.(config.FileInfo)
|
|
|
|
|
file := discordgo.File{
|
|
|
|
|
Name: fi.Name,
|
|
|
|
|
ContentType: "",
|
|
|
|
|
Reader: bytes.NewReader(*fi.Data),
|
|
|
|
|
}
|
|
|
|
|
content := fi.Comment
|
|
|
|
|
|
|
|
|
|
// Cannot use the resulting ID for any edits anyway, so throw it away.
|
|
|
|
|
// This has to be re-enabled when we implement message deletion.
|
|
|
|
|
_, err := b.transmitter.Send(
|
|
|
|
|
channelID,
|
|
|
|
|
&discordgo.WebhookParams{
|
|
|
|
|
Username: msg.Username,
|
|
|
|
|
AvatarURL: msg.Avatar,
|
|
|
|
|
Files: []*discordgo.File{&file},
|
|
|
|
|
Content: content,
|
|
|
|
|
AllowedMentions: b.getAllowedMentions(),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
b.Log.Errorf("Could not send file %#v for message %#v: %s", file, msg, err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// webhookSend send one or more message via webhook, taking care of file
|
|
|
|
|
// uploads (from slack, telegram or mattermost).
|
|
|
|
|
// Returns messageID and error.
|
|
|
|
|
func (b *Bdiscord) webhookSend(msg *config.Message, channelID string) (*discordgo.Message, error) {
|
|
|
|
|
func (b *Bdiscord) webhookSend(msg *config.Message, channelID string) (string, error) {
|
|
|
|
|
var (
|
|
|
|
|
res *discordgo.Message
|
|
|
|
|
res2 *discordgo.Message
|
|
|
|
|
res string
|
|
|
|
|
err error
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
@ -61,48 +114,11 @@ func (b *Bdiscord) webhookSend(msg *config.Message, channelID string) (*discordg
|
|
|
|
|
|
|
|
|
|
// We can't send empty messages.
|
|
|
|
|
if msg.Text != "" {
|
|
|
|
|
res, err = b.transmitter.Send(
|
|
|
|
|
channelID,
|
|
|
|
|
&discordgo.WebhookParams{
|
|
|
|
|
Content: msg.Text,
|
|
|
|
|
Username: msg.Username,
|
|
|
|
|
AvatarURL: msg.Avatar,
|
|
|
|
|
AllowedMentions: b.getAllowedMentions(),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
b.Log.Errorf("Could not send text (%s) for message %#v: %s", msg.Text, msg, err)
|
|
|
|
|
}
|
|
|
|
|
res, err = b.webhookSendTextOnly(msg, channelID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if msg.Extra != nil {
|
|
|
|
|
for _, f := range msg.Extra["file"] {
|
|
|
|
|
fi := f.(config.FileInfo)
|
|
|
|
|
file := discordgo.File{
|
|
|
|
|
Name: fi.Name,
|
|
|
|
|
ContentType: "",
|
|
|
|
|
Reader: bytes.NewReader(*fi.Data),
|
|
|
|
|
}
|
|
|
|
|
content := fi.Comment
|
|
|
|
|
|
|
|
|
|
res2, err = b.transmitter.Send(
|
|
|
|
|
channelID,
|
|
|
|
|
&discordgo.WebhookParams{
|
|
|
|
|
Username: msg.Username,
|
|
|
|
|
AvatarURL: msg.Avatar,
|
|
|
|
|
Files: []*discordgo.File{&file},
|
|
|
|
|
Content: content,
|
|
|
|
|
AllowedMentions: b.getAllowedMentions(),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
b.Log.Errorf("Could not send file %#v for message %#v: %s", file, msg, err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if msg.Text == "" {
|
|
|
|
|
res = res2
|
|
|
|
|
if err == nil && msg.Extra != nil {
|
|
|
|
|
err = b.webhookSendFilesOnly(msg, channelID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res, err
|
|
|
|
@ -120,35 +136,44 @@ func (b *Bdiscord) handleEventWebhook(msg *config.Message, channelID string) (st
|
|
|
|
|
return "", nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
msg.Text = helper.ClipMessage(msg.Text, MessageLength, b.GetString("MessageClipped"))
|
|
|
|
|
msg.Text = b.replaceUserMentions(msg.Text)
|
|
|
|
|
// discord username must be [0..32] max
|
|
|
|
|
if len(msg.Username) > 32 {
|
|
|
|
|
msg.Username = msg.Username[0:32]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if msg.ID != "" {
|
|
|
|
|
// Exploit that a discord message ID is actually just a large number, and we encode a list of IDs by separating them with ";".
|
|
|
|
|
var msgIds = strings.Split(msg.ID, ";")
|
|
|
|
|
msgParts := helper.ClipOrSplitMessage(b.replaceUserMentions(msg.Text), MessageLength, b.GetString("MessageClipped"), len(msgIds))
|
|
|
|
|
for len(msgParts) < len(msgIds) {
|
|
|
|
|
msgParts = append(msgParts, "((obsoleted by edit))")
|
|
|
|
|
}
|
|
|
|
|
b.Log.Debugf("Editing webhook message")
|
|
|
|
|
err := b.transmitter.Edit(channelID, msg.ID, &discordgo.WebhookParams{
|
|
|
|
|
Content: msg.Text,
|
|
|
|
|
Username: msg.Username,
|
|
|
|
|
AllowedMentions: b.getAllowedMentions(),
|
|
|
|
|
})
|
|
|
|
|
if err == nil {
|
|
|
|
|
var edit_err error = nil
|
|
|
|
|
for i := range msgParts {
|
|
|
|
|
// In case of split-messages where some parts remain the same (i.e. only a typo-fix in a huge message), this causes some noop-updates.
|
|
|
|
|
// TODO: Optimize away noop-updates of un-edited messages
|
|
|
|
|
edit_err = b.transmitter.Edit(channelID, msgIds[i], &discordgo.WebhookParams{
|
|
|
|
|
Content: msgParts[i],
|
|
|
|
|
Username: msg.Username,
|
|
|
|
|
AllowedMentions: b.getAllowedMentions(),
|
|
|
|
|
})
|
|
|
|
|
if edit_err != nil {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if edit_err == nil {
|
|
|
|
|
return msg.ID, nil
|
|
|
|
|
}
|
|
|
|
|
b.Log.Errorf("Could not edit webhook message: %s", err)
|
|
|
|
|
b.Log.Errorf("Could not edit webhook message(s): %s; sending as new message(s) instead", edit_err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b.Log.Debugf("Processing webhook sending for message %#v", msg)
|
|
|
|
|
discordMsg, err := b.webhookSend(msg, channelID)
|
|
|
|
|
msg.Text = b.replaceUserMentions(msg.Text)
|
|
|
|
|
msgId, err := b.webhookSend(msg, channelID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
b.Log.Errorf("Could not broadcast via webhook for message %#v: %s", msg, err)
|
|
|
|
|
b.Log.Errorf("Could not broadcast via webhook for message %#v: %s", msgId, err)
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
if discordMsg == nil {
|
|
|
|
|
return "", nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return discordMsg.ID, nil
|
|
|
|
|
return msgId, nil
|
|
|
|
|
}
|
|
|
|
|