pkg/download -> pkg/media
Signed-off-by: Sumner Evans <sumner.evans@automattic.com>
This commit is contained in:
@@ -17,8 +17,8 @@ import (
|
||||
"maunium.net/go/mautrix/bridgev2"
|
||||
"maunium.net/go/mautrix/bridgev2/networkid"
|
||||
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/download"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/ids"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/media"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/msgconv"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/util"
|
||||
)
|
||||
@@ -241,7 +241,7 @@ func (t *TelegramClient) GetChatInfo(ctx context.Context, portal *bridgev2.Porta
|
||||
avatar = &bridgev2.Avatar{
|
||||
ID: ids.MakeAvatarID(photo.ID),
|
||||
Get: func(ctx context.Context) (data []byte, err error) {
|
||||
data, _, _, _, err = download.DownloadPhoto(ctx, t.client.API(), photo)
|
||||
data, _, _, _, err = media.DownloadPhoto(ctx, t.client.API(), photo)
|
||||
return
|
||||
},
|
||||
}
|
||||
@@ -304,7 +304,7 @@ func (t *TelegramClient) getUserInfoFromTelegramUser(user *tg.User) (*bridgev2.U
|
||||
avatar = &bridgev2.Avatar{
|
||||
ID: ids.MakeAvatarID(photo.PhotoID),
|
||||
Get: func(ctx context.Context) (data []byte, err error) {
|
||||
data, _, err = download.DownloadPhotoFileLocation(ctx, t.client.API(), &tg.InputPeerPhotoFileLocation{
|
||||
data, _, err = media.DownloadFileLocation(ctx, t.client.API(), &tg.InputPeerPhotoFileLocation{
|
||||
Peer: &tg.InputPeerUser{UserID: user.ID},
|
||||
PhotoID: photo.PhotoID,
|
||||
Big: true,
|
||||
|
||||
@@ -12,8 +12,8 @@ import (
|
||||
"maunium.net/go/mautrix/bridgev2/networkid"
|
||||
"maunium.net/go/mautrix/mediaproxy"
|
||||
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/download"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/ids"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/media"
|
||||
)
|
||||
|
||||
var _ bridgev2.DirectMediableNetwork = (*TelegramConnector)(nil)
|
||||
@@ -63,14 +63,14 @@ func (tc *TelegramConnector) Download(ctx context.Context, mediaID networkid.Med
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var media tg.MessageMediaClass
|
||||
var msgMedia tg.MessageMediaClass
|
||||
if m, ok := messages.(getMessages); !ok {
|
||||
return nil, fmt.Errorf("unknown message type %T", messages)
|
||||
} else {
|
||||
var found bool
|
||||
for _, message := range m.GetMessages() {
|
||||
if msg, ok := message.(*tg.Message); ok && msg.ID == int(info.MessageID) {
|
||||
media = msg.Media
|
||||
msgMedia = msg.Media
|
||||
found = true
|
||||
break
|
||||
}
|
||||
@@ -82,18 +82,19 @@ func (tc *TelegramConnector) Download(ctx context.Context, mediaID networkid.Med
|
||||
|
||||
var data []byte
|
||||
var mimeType string
|
||||
switch media := media.(type) {
|
||||
switch msgMedia := msgMedia.(type) {
|
||||
case *tg.MessageMediaPhoto:
|
||||
data, _, _, mimeType, err = download.DownloadPhotoMedia(ctx, client.client.API(), media)
|
||||
data, _, _, mimeType, err = media.DownloadPhotoMedia(ctx, client.client.API(), msgMedia)
|
||||
case *tg.MessageMediaDocument:
|
||||
document, ok := media.Document.(*tg.Document)
|
||||
document, ok := msgMedia.Document.(*tg.Document)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unrecognized document type %T", media.Document)
|
||||
return nil, fmt.Errorf("unrecognized document type %T", msgMedia.Document)
|
||||
}
|
||||
|
||||
// Download the thumbnail for this media rather than the media itself.
|
||||
if info.Thumbnail {
|
||||
_, _, largestThumbnail := download.GetLargestPhotoSize(document.Thumbs)
|
||||
data, mimeType, err = download.DownloadPhotoFileLocation(ctx, client.client.API(), &tg.InputDocumentFileLocation{
|
||||
_, _, largestThumbnail := media.GetLargestPhotoSize(document.Thumbs)
|
||||
data, mimeType, err = media.DownloadFileLocation(ctx, client.client.API(), &tg.InputDocumentFileLocation{
|
||||
ID: document.GetID(),
|
||||
AccessHash: document.GetAccessHash(),
|
||||
FileReference: document.GetFileReference(),
|
||||
@@ -101,10 +102,10 @@ func (tc *TelegramConnector) Download(ctx context.Context, mediaID networkid.Med
|
||||
})
|
||||
} else {
|
||||
mimeType = document.GetMimeType()
|
||||
data, err = download.DownloadDocument(ctx, client.client.API(), document)
|
||||
data, err = media.DownloadDocument(ctx, client.client.API(), document)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unhandled media type %T", media)
|
||||
return nil, fmt.Errorf("unhandled media type %T", msgMedia)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package download
|
||||
package media
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
"github.com/gotd/td/telegram/downloader"
|
||||
@@ -9,12 +8,10 @@ import (
|
||||
)
|
||||
|
||||
func DownloadDocument(ctx context.Context, client downloader.Client, document *tg.Document) ([]byte, error) {
|
||||
file := tg.InputDocumentFileLocation{
|
||||
data, _, err := DownloadFileLocation(ctx, client, &tg.InputDocumentFileLocation{
|
||||
ID: document.GetID(),
|
||||
AccessHash: document.GetAccessHash(),
|
||||
FileReference: document.GetFileReference(),
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
_, err := downloader.NewDownloader().Download(client, &file).Stream(ctx, &buf)
|
||||
return buf.Bytes(), err
|
||||
})
|
||||
return data, err
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package media
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/gotd/td/telegram/downloader"
|
||||
"github.com/gotd/td/tg"
|
||||
)
|
||||
|
||||
func DownloadFileLocation(ctx context.Context, client downloader.Client, file tg.InputFileLocationClass) (data []byte, mimeType string, err error) {
|
||||
// TODO convert to streaming? stream to file?
|
||||
var buf bytes.Buffer
|
||||
storageFileTypeClass, err := downloader.NewDownloader().Download(client, file).Stream(ctx, &buf)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
switch storageFileTypeClass.(type) {
|
||||
case *tg.StorageFileJpeg:
|
||||
mimeType = "image/jpeg"
|
||||
case *tg.StorageFileGif:
|
||||
mimeType = "image/gif"
|
||||
case *tg.StorageFilePng:
|
||||
mimeType = "image/png"
|
||||
case *tg.StorageFilePdf:
|
||||
mimeType = "application/pdf"
|
||||
case *tg.StorageFileMp3:
|
||||
mimeType = "audio/mp3"
|
||||
case *tg.StorageFileMov:
|
||||
mimeType = "video/quicktime"
|
||||
case *tg.StorageFileMp4:
|
||||
mimeType = "video/mp4"
|
||||
case *tg.StorageFileWebp:
|
||||
mimeType = "image/webp"
|
||||
default:
|
||||
mimeType = http.DetectContentType(buf.Bytes())
|
||||
}
|
||||
return buf.Bytes(), mimeType, nil
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
package download
|
||||
package media
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gotd/td/telegram/downloader"
|
||||
"github.com/gotd/td/tg"
|
||||
@@ -48,54 +46,10 @@ func GetLargestPhotoSize(sizes []tg.PhotoSizeClass) (width, height int, largest
|
||||
return
|
||||
}
|
||||
|
||||
func GetLargestDimensions(sizes []tg.PhotoSizeClass) (width, height int) {
|
||||
for _, s := range sizes {
|
||||
switch size := s.(type) {
|
||||
case *tg.PhotoCachedSize:
|
||||
width = size.GetW()
|
||||
height = size.GetH()
|
||||
case *tg.PhotoSizeProgressive:
|
||||
width = size.GetW()
|
||||
height = size.GetH()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func DownloadPhotoFileLocation(ctx context.Context, client downloader.Client, file tg.InputFileLocationClass) (data []byte, mimeType string, err error) {
|
||||
// TODO convert to streaming?
|
||||
var buf bytes.Buffer
|
||||
storageFileTypeClass, err := downloader.NewDownloader().Download(client, file).Stream(ctx, &buf)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
switch storageFileTypeClass.(type) {
|
||||
case *tg.StorageFileJpeg:
|
||||
mimeType = "image/jpeg"
|
||||
case *tg.StorageFileGif:
|
||||
mimeType = "image/gif"
|
||||
case *tg.StorageFilePng:
|
||||
mimeType = "image/png"
|
||||
case *tg.StorageFilePdf:
|
||||
mimeType = "application/pdf"
|
||||
case *tg.StorageFileMp3:
|
||||
mimeType = "audio/mp3"
|
||||
case *tg.StorageFileMov:
|
||||
mimeType = "video/quicktime"
|
||||
case *tg.StorageFileMp4:
|
||||
mimeType = "video/mp4"
|
||||
case *tg.StorageFileWebp:
|
||||
mimeType = "image/webp"
|
||||
default:
|
||||
mimeType = http.DetectContentType(buf.Bytes())
|
||||
}
|
||||
return buf.Bytes(), mimeType, nil
|
||||
}
|
||||
|
||||
func DownloadPhoto(ctx context.Context, client downloader.Client, photo *tg.Photo) (data []byte, width, height int, mimeType string, err error) {
|
||||
var largest tg.PhotoSizeClass
|
||||
width, height, largest = GetLargestPhotoSize(photo.GetSizes())
|
||||
data, mimeType, err = DownloadPhotoFileLocation(ctx, client, &tg.InputPhotoFileLocation{
|
||||
data, mimeType, err = DownloadFileLocation(ctx, client, &tg.InputPhotoFileLocation{
|
||||
ID: photo.GetID(),
|
||||
AccessHash: photo.GetAccessHash(),
|
||||
FileReference: photo.GetFileReference(),
|
||||
@@ -105,13 +59,11 @@ func DownloadPhoto(ctx context.Context, client downloader.Client, photo *tg.Phot
|
||||
}
|
||||
|
||||
func DownloadPhotoMedia(ctx context.Context, client downloader.Client, media *tg.MessageMediaPhoto) (data []byte, width, height int, mimeType string, err error) {
|
||||
p, ok := media.GetPhoto()
|
||||
if !ok {
|
||||
if p, ok := media.GetPhoto(); !ok {
|
||||
return nil, 0, 0, "", fmt.Errorf("photo message sent without a photo")
|
||||
}
|
||||
photo, ok := p.(*tg.Photo)
|
||||
if !ok {
|
||||
} else if photo, ok := p.(*tg.Photo); !ok {
|
||||
return nil, 0, 0, "", fmt.Errorf("unrecognized photo type %T", p)
|
||||
} else {
|
||||
return DownloadPhoto(ctx, client, photo)
|
||||
}
|
||||
return DownloadPhoto(ctx, client, photo)
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package media
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gotd/td/telegram/downloader"
|
||||
"github.com/gotd/td/tg"
|
||||
"maunium.net/go/mautrix/bridgev2"
|
||||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
// LocationToID converts a Telegram [tg.Document],
|
||||
// [tg.InputDocumentFileLocation], [tg.InputPeerPhotoFileLocation],
|
||||
// [tg.InputFileLocation], or [tg.InputPhotoFileLocation] into a key for use in
|
||||
// the telegram_file table.
|
||||
func LocationToID(location any) (id string) {
|
||||
switch location := location.(type) {
|
||||
case *tg.Document:
|
||||
return fmt.Sprintf("%d", location.ID)
|
||||
case *tg.InputDocumentFileLocation:
|
||||
return fmt.Sprintf("%d-%s", location.ID, location.ThumbSize)
|
||||
case *tg.InputPhotoFileLocation:
|
||||
return fmt.Sprintf("%d-%s", location.ID, location.ThumbSize)
|
||||
case *tg.InputFileLocation:
|
||||
return fmt.Sprintf("%d-%d", location.VolumeID, location.LocalID)
|
||||
case *tg.InputPeerPhotoFileLocation:
|
||||
return fmt.Sprintf("%d", location.PhotoID)
|
||||
default:
|
||||
panic(fmt.Errorf("unknown location type %T", location))
|
||||
}
|
||||
}
|
||||
|
||||
func TransferToMatrix(ctx context.Context, roomID id.RoomID, client downloader.Client, intent bridgev2.MatrixAPI, file tg.InputFileLocationClass, filenameOpt ...string) (id.ContentURIString, *event.EncryptedFileInfo, error) {
|
||||
data, mimeType, err := DownloadFileLocation(ctx, client, file)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("downloading file failed: %w", err)
|
||||
}
|
||||
var filename string
|
||||
if len(filenameOpt) > 0 {
|
||||
filename = filenameOpt[0]
|
||||
}
|
||||
return intent.UploadMedia(ctx, roomID, data, filename, mimeType)
|
||||
}
|
||||
@@ -16,8 +16,8 @@ import (
|
||||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/download"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/ids"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/media"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/util"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/waveform"
|
||||
)
|
||||
@@ -119,8 +119,8 @@ func (mc *MessageConverter) ToMatrix(ctx context.Context, portal *bridgev2.Porta
|
||||
return cm, nil
|
||||
}
|
||||
|
||||
func (mc *MessageConverter) webpageToBeeperLinkPreview(ctx context.Context, intent bridgev2.MatrixAPI, media tg.MessageMediaClass) (preview *event.BeeperLinkPreview, err error) {
|
||||
webpage, ok := media.(*tg.MessageMediaWebPage).Webpage.(*tg.WebPage)
|
||||
func (mc *MessageConverter) webpageToBeeperLinkPreview(ctx context.Context, intent bridgev2.MatrixAPI, msgMedia tg.MessageMediaClass) (preview *event.BeeperLinkPreview, err error) {
|
||||
webpage, ok := msgMedia.(*tg.MessageMediaWebPage).Webpage.(*tg.WebPage)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -135,7 +135,7 @@ func (mc *MessageConverter) webpageToBeeperLinkPreview(ctx context.Context, inte
|
||||
|
||||
if pc, ok := webpage.GetPhoto(); ok && pc.TypeID() == tg.PhotoTypeID {
|
||||
var data []byte
|
||||
data, preview.ImageWidth, preview.ImageHeight, preview.ImageType, err = download.DownloadPhoto(ctx, mc.client.API(), pc.(*tg.Photo))
|
||||
data, preview.ImageWidth, preview.ImageHeight, preview.ImageType, err = media.DownloadPhoto(ctx, mc.client.API(), pc.(*tg.Photo))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -170,7 +170,7 @@ func (mc *MessageConverter) directMedia(ctx context.Context, portal *bridgev2.Po
|
||||
return portal.Bridge.Matrix.GenerateContentURI(ctx, mediaID)
|
||||
}
|
||||
|
||||
func (mc *MessageConverter) convertMediaRequiringUpload(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, msgID int, media tg.MessageMediaClass) (*bridgev2.ConvertedMessagePart, *database.DisappearingSetting, error) {
|
||||
func (mc *MessageConverter) convertMediaRequiringUpload(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, msgID int, msgMedia tg.MessageMediaClass) (*bridgev2.ConvertedMessagePart, *database.DisappearingSetting, error) {
|
||||
var partID networkid.PartID
|
||||
var msgType event.MessageType
|
||||
var filename string
|
||||
@@ -179,27 +179,27 @@ func (mc *MessageConverter) convertMediaRequiringUpload(ctx context.Context, por
|
||||
var info event.FileInfo
|
||||
|
||||
// Determine the filename and some other information
|
||||
switch media := media.(type) {
|
||||
switch msgMedia := msgMedia.(type) {
|
||||
case *tg.MessageMediaPhoto:
|
||||
partID = networkid.PartID("photo")
|
||||
msgType = event.MsgImage
|
||||
filename = "image"
|
||||
if photo, ok := media.Photo.(*tg.Photo); ok {
|
||||
info.Width, info.Height, _ = download.GetLargestPhotoSize(photo.GetSizes())
|
||||
if photo, ok := msgMedia.Photo.(*tg.Photo); ok {
|
||||
info.Width, info.Height, _ = media.GetLargestPhotoSize(photo.GetSizes())
|
||||
}
|
||||
case *tg.MessageMediaDocument:
|
||||
partID = networkid.PartID("document")
|
||||
msgType = event.MsgFile
|
||||
document, ok := media.Document.(*tg.Document)
|
||||
document, ok := msgMedia.Document.(*tg.Document)
|
||||
info.Size = int(document.Size)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("unrecognized document type %T", media.Document)
|
||||
return nil, nil, fmt.Errorf("unrecognized document type %T", msgMedia.Document)
|
||||
}
|
||||
|
||||
if thumbSizes, ok := document.GetThumbs(); ok {
|
||||
info.ThumbnailInfo = &event.FileInfo{}
|
||||
var largestThumbnail tg.PhotoSizeClass
|
||||
info.ThumbnailInfo.Width, info.ThumbnailInfo.Height, largestThumbnail = download.GetLargestPhotoSize(thumbSizes)
|
||||
info.ThumbnailInfo.Width, info.ThumbnailInfo.Height, largestThumbnail = media.GetLargestPhotoSize(thumbSizes)
|
||||
|
||||
var err error
|
||||
info.ThumbnailInfo.ThumbnailURL, err = mc.directMedia(ctx, portal, msgID, true)
|
||||
@@ -208,17 +208,12 @@ func (mc *MessageConverter) convertMediaRequiringUpload(ctx context.Context, por
|
||||
}
|
||||
|
||||
if info.ThumbnailInfo.ThumbnailURL == "" {
|
||||
data, mimeType, err := download.DownloadPhotoFileLocation(ctx, mc.client.API(), &tg.InputDocumentFileLocation{
|
||||
info.ThumbnailInfo.ThumbnailURL, info.ThumbnailInfo.ThumbnailFile, err = media.TransferToMatrix(ctx, portal.MXID, mc.client.API(), intent, &tg.InputDocumentFileLocation{
|
||||
ID: document.GetID(),
|
||||
AccessHash: document.GetAccessHash(),
|
||||
FileReference: document.GetFileReference(),
|
||||
ThumbSize: largestThumbnail.GetType(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("downloading thumbnail failed: %w", err)
|
||||
}
|
||||
|
||||
info.ThumbnailInfo.ThumbnailURL, info.ThumbnailInfo.ThumbnailFile, err = intent.UploadMedia(ctx, "", data, filename, mimeType)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -249,7 +244,7 @@ func (mc *MessageConverter) convertMediaRequiringUpload(ctx context.Context, por
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unhandled media type %T", media)
|
||||
return nil, nil, fmt.Errorf("unhandled media type %T", msgMedia)
|
||||
}
|
||||
|
||||
var encryptedFileInfo *event.EncryptedFileInfo
|
||||
@@ -263,31 +258,31 @@ func (mc *MessageConverter) convertMediaRequiringUpload(ctx context.Context, por
|
||||
var data []byte
|
||||
var mimeType string
|
||||
var err error
|
||||
switch media := media.(type) {
|
||||
switch msgMedia := msgMedia.(type) {
|
||||
case *tg.MessageMediaPhoto:
|
||||
if _, ok := media.GetTTLSeconds(); ok {
|
||||
if _, ok := msgMedia.GetTTLSeconds(); ok {
|
||||
filename = "disappearing_image" + exmime.ExtensionFromMimetype(mimeType)
|
||||
} else {
|
||||
filename = "image" + exmime.ExtensionFromMimetype(mimeType)
|
||||
}
|
||||
|
||||
data, _, _, mimeType, err = download.DownloadPhotoMedia(ctx, mc.client.API(), media)
|
||||
data, _, _, mimeType, err = media.DownloadPhotoMedia(ctx, mc.client.API(), msgMedia)
|
||||
case *tg.MessageMediaDocument:
|
||||
document, ok := media.Document.(*tg.Document)
|
||||
document, ok := msgMedia.Document.(*tg.Document)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("unrecognized document type %T", media.Document)
|
||||
return nil, nil, fmt.Errorf("unrecognized document type %T", msgMedia.Document)
|
||||
}
|
||||
|
||||
mimeType = document.GetMimeType()
|
||||
data, err = download.DownloadDocument(ctx, mc.client.API(), document)
|
||||
data, err = media.DownloadDocument(ctx, mc.client.API(), document)
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unhandled media type %T", media)
|
||||
return nil, nil, fmt.Errorf("unhandled media type %T", msgMedia)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
mxcURI, encryptedFileInfo, err = intent.UploadMedia(ctx, "", data, filename, mimeType)
|
||||
mxcURI, encryptedFileInfo, err = intent.UploadMedia(ctx, portal.MXID, data, filename, mimeType)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -297,7 +292,7 @@ func (mc *MessageConverter) convertMediaRequiringUpload(ctx context.Context, por
|
||||
|
||||
// Handle spoilers
|
||||
// See: https://github.com/matrix-org/matrix-spec-proposals/pull/3725
|
||||
if s, ok := media.(spoilable); ok && s.GetSpoiler() {
|
||||
if s, ok := msgMedia.(spoilable); ok && s.GetSpoiler() {
|
||||
extra["town.robin.msc3725.content_warning"] = map[string]any{
|
||||
"type": "town.robin.msc3725.spoiler",
|
||||
}
|
||||
@@ -306,7 +301,7 @@ func (mc *MessageConverter) convertMediaRequiringUpload(ctx context.Context, por
|
||||
|
||||
// Handle disappearing messages
|
||||
var disappearingSetting *database.DisappearingSetting
|
||||
if t, ok := media.(ttlable); ok {
|
||||
if t, ok := msgMedia.(ttlable); ok {
|
||||
if ttl, ok := t.GetTTLSeconds(); ok {
|
||||
disappearingSetting = &database.DisappearingSetting{
|
||||
Type: database.DisappearingTypeAfterSend,
|
||||
|
||||
Reference in New Issue
Block a user