converter: handle link previews TG -> Matrix
Signed-off-by: Sumner Evans <sumner.evans@automattic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ package msgconv
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/gotd/td/tg"
|
||||
@@ -26,33 +27,105 @@ type ttlable interface {
|
||||
GetTTLSeconds() (value int, ok bool)
|
||||
}
|
||||
|
||||
func mediaRequiringUpload(media tg.MessageMediaClass) bool {
|
||||
allowed := []uint32{
|
||||
tg.MessageMediaPhotoTypeID,
|
||||
tg.MessageMediaGeoTypeID,
|
||||
tg.MessageMediaContactTypeID,
|
||||
tg.MessageMediaDocumentTypeID,
|
||||
tg.MessageMediaStoryTypeID,
|
||||
}
|
||||
return slices.Contains(allowed, media.TypeID())
|
||||
}
|
||||
|
||||
func (mc *MessageConverter) ToMatrix(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, msg *tg.Message) (*bridgev2.ConvertedMessage, error) {
|
||||
log := zerolog.Ctx(ctx).With().Str("conversion_direction", "to_matrix").Logger()
|
||||
ctx = log.WithContext(ctx)
|
||||
|
||||
cm := &bridgev2.ConvertedMessage{}
|
||||
if msg.Message != "" {
|
||||
if len(msg.Message) > 0 {
|
||||
var linkPreviews []*event.BeeperLinkPreview
|
||||
if media, ok := msg.GetMedia(); ok && media.TypeID() == tg.MessageMediaWebPageTypeID {
|
||||
preview, err := mc.webpageToBeeperLinkPreview(ctx, intent, media)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if preview != nil {
|
||||
linkPreviews = append(linkPreviews, preview)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO formatting
|
||||
cm.Parts = append(cm.Parts, &bridgev2.ConvertedMessagePart{
|
||||
ID: networkid.PartID("caption"),
|
||||
Type: event.EventMessage,
|
||||
Content: &event.MessageEventContent{MsgType: event.MsgText, Body: msg.Message},
|
||||
ID: networkid.PartID("caption"),
|
||||
Type: event.EventMessage,
|
||||
Content: &event.MessageEventContent{
|
||||
MsgType: event.MsgText,
|
||||
Body: msg.Message,
|
||||
BeeperLinkPreviews: linkPreviews,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if media, ok := msg.GetMedia(); ok {
|
||||
mediaParts, disappearingSetting, err := mc.convertMedia(ctx, portal, intent, msg.ID, media)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
switch {
|
||||
case mediaRequiringUpload(media):
|
||||
mediaParts, disappearingSetting, err := mc.convertMediaRequiringUpload(ctx, portal, intent, msg.ID, media)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if disappearingSetting != nil {
|
||||
cm.Disappear = *disappearingSetting
|
||||
}
|
||||
cm.Parts = append(cm.Parts, mediaParts)
|
||||
}
|
||||
if disappearingSetting != nil {
|
||||
cm.Disappear = *disappearingSetting
|
||||
}
|
||||
cm.Parts = append(cm.Parts, mediaParts)
|
||||
}
|
||||
return cm, nil
|
||||
}
|
||||
|
||||
func (mc *MessageConverter) convertMedia(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, msgID int, media tg.MessageMediaClass) (*bridgev2.ConvertedMessagePart, *database.DisappearingSetting, error) {
|
||||
func (mc *MessageConverter) webpageToBeeperLinkPreview(ctx context.Context, intent bridgev2.MatrixAPI, media tg.MessageMediaClass) (*event.BeeperLinkPreview, error) {
|
||||
webpage, ok := media.(*tg.MessageMediaWebPage).Webpage.(*tg.WebPage)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
preview := &event.BeeperLinkPreview{
|
||||
MatchedURL: webpage.URL,
|
||||
LinkPreview: event.LinkPreview{
|
||||
Title: webpage.Title,
|
||||
CanonicalURL: webpage.URL,
|
||||
Description: webpage.Description,
|
||||
},
|
||||
}
|
||||
|
||||
if pc, ok := webpage.GetPhoto(); ok && pc.TypeID() == tg.PhotoTypeID {
|
||||
photo := pc.(*tg.Photo)
|
||||
for _, s := range photo.GetSizes() {
|
||||
switch size := s.(type) {
|
||||
case *tg.PhotoCachedSize:
|
||||
preview.ImageWidth = size.GetW()
|
||||
preview.ImageHeight = size.GetH()
|
||||
case *tg.PhotoSizeProgressive:
|
||||
preview.ImageWidth = size.GetW()
|
||||
preview.ImageHeight = size.GetH()
|
||||
}
|
||||
}
|
||||
|
||||
data, mimeType, err := download.DownloadPhoto(ctx, mc.client.API(), photo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
preview.ImageSize = len(data)
|
||||
preview.ImageType = mimeType
|
||||
|
||||
preview.ImageURL, preview.ImageEncryption, err = intent.UploadMedia(ctx, "", data, "", mimeType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return preview, nil
|
||||
}
|
||||
|
||||
func (mc *MessageConverter) convertMediaRequiringUpload(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, msgID int, media tg.MessageMediaClass) (*bridgev2.ConvertedMessagePart, *database.DisappearingSetting, error) {
|
||||
var partID networkid.PartID
|
||||
var msgType event.MessageType
|
||||
var filename string
|
||||
@@ -97,7 +170,6 @@ func (mc *MessageConverter) convertMedia(ctx context.Context, portal *bridgev2.P
|
||||
// case *tg.MessageMediaGeo: // messageMediaGeo#56e0d474
|
||||
// case *tg.MessageMediaContact: // messageMediaContact#70322949
|
||||
// case *tg.MessageMediaUnsupported: // messageMediaUnsupported#9f84f49e
|
||||
// case *tg.MessageMediaWebPage: // messageMediaWebPage#ddf10c3b
|
||||
// case *tg.MessageMediaVenue: // messageMediaVenue#2ec0533f
|
||||
// case *tg.MessageMediaGame: // messageMediaGame#fdb19008
|
||||
// case *tg.MessageMediaInvoice: // messageMediaInvoice#f6a548d3
|
||||
@@ -146,7 +218,7 @@ func (mc *MessageConverter) convertMedia(ctx context.Context, portal *bridgev2.P
|
||||
filename = "image" + exmime.ExtensionFromMimetype(mimeType)
|
||||
}
|
||||
|
||||
data, mimeType, err = download.DownloadPhoto(ctx, mc.client.API(), media)
|
||||
data, mimeType, err = download.DownloadPhotoMedia(ctx, mc.client.API(), media)
|
||||
case *tg.MessageMediaDocument:
|
||||
document, ok := media.Document.(*tg.Document)
|
||||
if !ok {
|
||||
@@ -160,7 +232,6 @@ func (mc *MessageConverter) convertMedia(ctx context.Context, portal *bridgev2.P
|
||||
// case *tg.MessageMediaGeo: // messageMediaGeo#56e0d474
|
||||
// case *tg.MessageMediaContact: // messageMediaContact#70322949
|
||||
// case *tg.MessageMediaUnsupported: // messageMediaUnsupported#9f84f49e
|
||||
// case *tg.MessageMediaWebPage: // messageMediaWebPage#ddf10c3b
|
||||
// case *tg.MessageMediaVenue: // messageMediaVenue#2ec0533f
|
||||
// case *tg.MessageMediaGame: // messageMediaGame#fdb19008
|
||||
// case *tg.MessageMediaInvoice: // messageMediaInvoice#f6a548d3
|
||||
|
||||
Reference in New Issue
Block a user