From d2a06ebbbe5ec101fbb73fa9b645d70aab41b6b2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 28 Apr 2026 16:09:13 +0300 Subject: [PATCH] capabilities: mark lottie and webm as allowed sticker formats --- pkg/connector/capabilities.go | 6 +++--- pkg/connector/handlematrix.go | 10 +++++++++- pkg/connector/media/sticker.go | 24 ++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index b306f504..c27a223c 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -145,9 +145,9 @@ var fileCaps = event.FileFeatureMap{ // These are converted to webp "image/jpeg": event.CapLevelPartialSupport, "image/png": event.CapLevelPartialSupport, - // TODO - //"video/lottie+json": event.CapLevelFullySupported, - //"video/webm": event.CapLevelFullySupported, + // These will only go through if they're from an imported Telegram pack + "video/lottie+json": event.CapLevelPartialSupport, + "video/webm": event.CapLevelPartialSupport, }, }, event.CapMsgVoice: { diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 62e3f4fe..1a013347 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -54,6 +54,7 @@ import ( "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" + "go.mau.fi/mautrix-telegram/pkg/connector/media" "go.mau.fi/mautrix-telegram/pkg/gotd/telegram/message" "go.mau.fi/mautrix-telegram/pkg/gotd/telegram/uploader" "go.mau.fi/mautrix-telegram/pkg/gotd/tg" @@ -275,10 +276,17 @@ func (tc *TelegramClient) transferMediaToTelegram(ctx context.Context, content * } else if sticker && (info.MimeType != "video/webm" && 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) + return fmt.Errorf("failed to convert sticker to webm: %w", err) } defer os.Remove(uploadFilename) info.MimeType = "image/webp" + } else if sticker && info.MimeType == "video/lottie+json" { + uploadFilename, err = media.CompressGZip(f) + if err != nil { + return fmt.Errorf("failed to compress lottie sticker: %w", err) + } + defer os.Remove(uploadFilename) + info.MimeType = "application/x-tgsticker" } else if cfg, _, err := image.DecodeConfig(f); err != nil { forceDocument = true } else if fileInfo, err := f.Stat(); err != nil { diff --git a/pkg/connector/media/sticker.go b/pkg/connector/media/sticker.go index 160df901..e5f4c521 100644 --- a/pkg/connector/media/sticker.go +++ b/pkg/connector/media/sticker.go @@ -110,6 +110,30 @@ func (c *AnimatedStickerConfig) convertWebm(ctx context.Context, src *os.File) * } } +func CompressGZip(src *os.File) (replPath string, err error) { + tempFile, err := os.CreateTemp("", "telegram-sticker-gzip-*.tgs") + if err != nil { + return "", fmt.Errorf("failed to create temp file: %w", err) + } + writer := gzip.NewWriter(tempFile) + defer func() { + _ = tempFile.Close() + _ = writer.Close() + if replPath == "" { + _ = os.Remove(tempFile.Name()) + } + }() + _, err = io.Copy(writer, src) + if err != nil { + return "", fmt.Errorf("failed to compress lottie gzip: %w", err) + } + err = writer.Close() + if err != nil { + return "", fmt.Errorf("failed to close gzip writer: %w", err) + } + return tempFile.Name(), nil +} + func extractGZip(src *os.File) (*ConvertedSticker, error) { reader, err := gzip.NewReader(src) if err != nil {