diff --git a/go.mod b/go.mod index 005ffef9..26b9cf34 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 go.mau.fi/util v0.8.7-0.20250427215252-d2d18a7e463c + go.mau.fi/webp v0.2.0 go.mau.fi/zerozap v0.1.1 go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 diff --git a/go.sum b/go.sum index a7381142..08349910 100644 --- a/go.sum +++ b/go.sum @@ -78,6 +78,8 @@ github.com/yuin/goldmark v1.7.10 h1:S+LrtBjRmqMac2UdtB6yyCEJm+UILZ2fefI4p7o0QpI= github.com/yuin/goldmark v1.7.10/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= go.mau.fi/util v0.8.7-0.20250427215252-d2d18a7e463c h1:qfJyMZq1pPyuXKoVWwHs6OmR9CzO3pHFRPYT/QpaaaA= go.mau.fi/util v0.8.7-0.20250427215252-d2d18a7e463c/go.mod h1:uNB3UTXFbkpp7xL1M/WvQks90B/L4gvbLpbS0603KOE= +go.mau.fi/webp v0.2.0 h1:QVMenHw7JDb4vall5sV75JNBQj9Hw4u8AKbi1QetHvg= +go.mau.fi/webp v0.2.0/go.mod h1:VSg9MyODn12Mb5pyG0NIyNFhujrmoFSsZBs8syOZD1Q= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= go.mau.fi/zerozap v0.1.1 h1:mxE/dW4wtkqBYOXOEEzXldk5qKB+ahsZXjoTGnvEhZQ= diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index f024e06e..fb0817e6 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -115,6 +115,9 @@ var fileCaps = event.FileFeatureMap{ event.CapMsgSticker: { MimeTypes: map[string]event.CapabilitySupportLevel{ "image/webp": event.CapLevelFullySupported, + // These are converted to webp + "image/jpeg": event.CapLevelPartialSupport, + "image/png": event.CapLevelPartialSupport, // TODO //"video/lottie+json": event.CapLevelFullySupported, //"video/webm": event.CapLevelFullySupported, diff --git a/pkg/connector/matrix.go b/pkg/connector/matrix.go index 27853371..1800741a 100644 --- a/pkg/connector/matrix.go +++ b/pkg/connector/matrix.go @@ -38,6 +38,7 @@ import ( "github.com/rs/zerolog" "go.mau.fi/util/ffmpeg" "go.mau.fi/util/variationselector" + "go.mau.fi/webp" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" @@ -75,7 +76,23 @@ func (t *TelegramClient) transferMediaToTelegram(ctx context.Context, content *e filename := getMediaFilename(content) err := t.main.Bridge.Bot.DownloadMediaToFile(ctx, content.URL, content.File, false, func(f *os.File) (err error) { uploadFilename := f.Name() - if sticker && content.Info != nil && (content.Info.MimeType != "video/webm" && content.Info.MimeType != "application/x-tgsticker") { + if sticker && content.Info != nil && (content.Info.MimeType == "image/png" || content.Info.MimeType == "image/jpeg") { + tempFile, err := os.CreateTemp("", "telegram-sticker-*") + if err != nil { + return err + } + defer func() { + tempFile.Close() + os.Remove(tempFile.Name()) + }() + if image, _, err := image.Decode(f); err != nil { + return fmt.Errorf("failed to decode sticker image: %w", err) + } else if err := webp.Encode(tempFile, image, nil); err != nil { + return fmt.Errorf("failed to encode sticker webp image: %w", err) + } + uploadFilename = tempFile.Name() + content.Info.MimeType = "image/webp" + } else if sticker && content.Info != nil && (content.Info.MimeType != "video/webm" && content.Info.MimeType != "application/x-tgsticker") { uploadFilename, err = ffmpeg.ConvertPath(ctx, uploadFilename, ".webp", []string{}, []string{}, false) if err != nil { return fmt.Errorf("failed to convert sticker to webm: %+w", err)