42wim / matterbridge

bridge between mattermost, IRC, gitter, xmpp, slack, discord, telegram, rocketchat, twitch, ssh-chat, zulip, whatsapp, keybase, matrix, microsoft teams, nextcloud, mumble, vk and more with REST API (mattermost not required!)
Apache License 2.0
6.56k stars 617 forks source link

[Zulip->Discord] Failed because of invalid avatar url #1214

Closed imolein closed 4 years ago

imolein commented 4 years ago

First, thanks for the Zulip fix in the last release! :)

Describe the bug I tested the latest release of matterbridge today, but got an error, when sending a message from Zulip to Discord. (see debug log below) Sending messages from Discord to Zulip works fine.

To Reproduce

Expected behavior The message is sent to discord.

Screenshots/debug logs

[0012] DEBUG zulip:        [handleQueue:bridge/zulip/zulip.go:127] receiving error: <nil>
[0012] DEBUG zulip:        [handleQueue:bridge/zulip/zulip.go:133] == Receiving gozulipbot.EventMessage{AvatarURL:"/user_avatars/2/f25df852e3ed925881cc11014faf67597a805c39.png?x=x&version=3", Client:"ZulipElectron", Content:"blubb", ContentType:"text/x-markdown", DisplayRecipient:gozulipbot.DisplayRecipient{Users:[]gozulipbot.User(nil), Topic:"XXXXX"}, GravatarHash:"", ID:26603, RecipientID:17, SenderDomain:"", SenderEmail:"xxxxx", SenderFullName:"Sebastian", SenderID:9, SenderShortName:"", Subject:"DiscordBridge", SubjectLinks:[]interface {}(nil), StreamID:5, Timestamp:1598434960, Type:"stream", Queue:(*gozulipbot.Queue)(0xc000864e10)}
[0012] DEBUG zulip:        [handleQueue:bridge/zulip/zulip.go:146] <= Sending message from Sebastian on zulip.xxxxx to gateway
[0012] DEBUG zulip:        [handleQueue:bridge/zulip/zulip.go:147] <= Message is config.Message{Text:"blubb", Channel:"XXXXX/topic:DiscordBridge", Username:"Sebastian", UserID:"9", Avatar:"/user_avatars/2/f25df852e3ed925881cc11014faf67597a805c39.png?x=x&version=3", Account:"zulip.xxxxx", Event:"", Protocol:"", Gateway:"", ParentID:"", Timestamp:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}, ID:"", Extra:map[string][]interface {}(nil)}
[0012] DEBUG gateway:      [SendMessage:gateway/gateway.go:421] => Sending config.Message{Text:"blubb", Channel:"XXXXX/topic:DiscordBridge", Username:"Sebastian", UserID:"9", Avatar:"/user_avatars/2/f25df852e3ed925881cc11014faf67597a805c39.png?x=x&version=3", Account:"zulip.xxxxx", Event:"", Protocol:"zulip", Gateway:"zulipdiscord", ParentID:"", Timestamp:time.Time{wall:0xbfc9a9840642f919, ext:12686312130, loc:(*time.Location)(0x318f8a0)}, ID:"", Extra:map[string][]interface {}(nil)} from zulip.xxxxx (XXXXX/topic:DiscordBridge) to discord.xxxxx (ID:XXXXX)
[0012] DEBUG discord:      [Send:bridge/discord/discord.go:192] => Receiving config.Message{Text:"blubb", Channel:"ID:XXXXX", Username:"Sebastian ", UserID:"9", Avatar:"/user_avatars/2/f25df852e3ed925881cc11014faf67597a805c39.png?x=x&version=3", Account:"zulip.xxxxx", Event:"", Protocol:"zulip", Gateway:"zulipdiscord", ParentID:"", Timestamp:time.Time{wall:0xbfc9a9840642f919, ext:12686312130, loc:(*time.Location)(0x318f8a0)}, ID:"", Extra:map[string][]interface {}(nil)}
[0012] DEBUG discord:      [Send:bridge/discord/discord.go:246] Broadcasting using Webhook
[0012] DEBUG discord:      [Send:bridge/discord/discord.go:273] Processing webhook sending for message config.Message{Text:"blubb", Channel:"ID:XXXXX", Username:"Sebastian ", UserID:"9", Avatar:"/user_avatars/2/f25df852e3ed925881cc11014faf67597a805c39.png?x=x&version=3", Account:"zulip.xxxxx", Event:"", Protocol:"zulip", Gateway:"zulipdiscord", ParentID:"", Timestamp:time.Time{wall:0xbfc9a9840642f919, ext:12686312130, loc:(*time.Location)(0x318f8a0)}, ID:"", Extra:map[string][]interface {}(nil)}
[0012] ERROR discord:      [webhookSend:bridge/discord/discord.go:429] Could not send text (blubb) for message &config.Message{Text:"blubb", Channel:"ID:XXXXX", Username:"Sebastian ", UserID:"9", Avatar:"/user_avatars/2/f25df852e3ed925881cc11014faf67597a805c39.png?x=x&version=3", Account:"zulip.xxxxx", Event:"", Protocol:"zulip", Gateway:"zulipdiscord", ParentID:"", Timestamp:time.Time{wall:0xbfc9a9840642f919, ext:12686312130, loc:(*time.Location)(0x318f8a0)}, ID:"", Extra:map[string][]interface {}(nil)}: HTTP 400 Bad Request, {"avatar_url": ["Not a well formed URL."]}
[0012] ERROR discord:      [Send:bridge/discord/discord.go:276] Could not broadcast via webook for message (*discordgo.Message)(nil): HTTP 400 Bad Request, {"avatar_url": ["Not a well formed URL."]}
[0012] ERROR gateway:      [handleMessage:gateway/handlers.go:228] SendMessage failed: HTTP 400 Bad Request, {"avatar_url": ["Not a well formed URL."]}

Environment (please complete the following information):

Additional context

[discord]
    [discord.xxxxx]
    Token=""      # removed
    Server=""     # removed
    RemoteNickFormat="{NICK} "
    ShowEmbeds=true
    EditSuffix=" (edited)"

[zulip]
    [zulip.xxxxx]
    Token=""      # removed
    Login=""      # removed
    Server=""     # removed
    RemoteNickFormat="[{PROTOCOL}] <{NICK}> "

[[gateway]]
name="zulipdiscord"
enable=true

    [[gateway.inout]]
    account="discord.xxxxx"
    channel=""    # removed

    [gateway.inout.options]
    WebhookURL="" # removed

        [[gateway.inout]]
    account="zulip.xxxxx"
    channel=""    # removed
imolein commented 4 years ago

After a quick look on the code and without knowing golang, I changed one line, which fixed it for me:

diff --git a/bridge/zulip/zulip.go b/bridge/zulip/zulip.go
index 9fcc54af..50d5f54d 100644
--- a/bridge/zulip/zulip.go
+++ b/bridge/zulip/zulip.go
@@ -141,7 +141,7 @@ func (b *Bzulip) handleQueue() error {
                                Channel:  b.getChannel(m.StreamID) + "/topic:" + m.Subject,
                                Account:  b.Account,
                                UserID:   strconv.Itoa(m.SenderID),
-                               Avatar:   m.AvatarURL,
+                               Avatar:   b.GetString("server") + m.AvatarURL,
                        }
                        b.Log.Debugf("<= Sending message from %s on %s to gateway", rmsg.Username, b.Account)
                        b.Log.Debugf("<= Message is %#v", rmsg)

But I don't know whether this is the correct place to do this or not. :)

42wim commented 4 years ago

Seems like they did some changes with the avatar_url and do not include the full URI anymore.; Is this an upload avatar image?

imolein commented 4 years ago

Yes, the path in AvatarURL is the avatar image. If I concat the server with the AvatarURL, the avatar is loaded.

42wim commented 4 years ago

Strange I've tested this on the zulipchat servers and it show a correct AvatarURL: Avatar:"https://zulip-avatars.s3.amazonaws.com/4757/55047f83ee6e4f876c806cf576d5e94bfd4ab787?x=x&version=2"

I'll have to do a check if the URL begins with http or not

imolein commented 4 years ago

Strange I've tested this on the zulipchat servers and it show a correct AvatarURL

I guess it's the only the path if the avatar is stored on the same domain as the server runs and the whole URL if a different storage backend, like s3, is used.

Neverless, thanks for the fix :)