directdownload: include receiver in media ID

Signed-off-by: Sumner Evans <sumner.evans@automattic.com>
This commit is contained in:
Sumner Evans
2024-08-07 11:18:59 -06:00
parent e0194f7621
commit 83695b4336
4 changed files with 33 additions and 27 deletions
+13 -6
View File
@@ -34,15 +34,22 @@ func (tc *TelegramConnector) Download(ctx context.Context, mediaID networkid.Med
ctx = log.WithContext(ctx) ctx = log.WithContext(ctx)
log.Info().Msg("handling direct download") log.Info().Msg("handling direct download")
// TODO fix this userLogin, err := tc.Bridge.GetExistingUserLoginByID(ctx, ids.MakeUserLoginID(info.ReceiverID))
logins, err := tc.Bridge.GetUserLoginsInPortal(ctx, info.PeerType.AsPortalKey(info.ChatID, ""))
if err != nil { if err != nil {
return nil, err if info.PeerType != ids.PeerTypeChannel {
} else if len(logins) == 0 { return nil, fmt.Errorf("failed to get user login: %w", err)
return nil, fmt.Errorf("no user logins in the portal (%s %d)", info.PeerType, info.ChatID) }
logins, err := tc.Bridge.GetUserLoginsInPortal(ctx, ids.PeerTypeChannel.AsPortalKey(info.ChatID, ""))
if err != nil {
return nil, err
} else if len(logins) == 0 {
return nil, fmt.Errorf("no user logins in the portal (%s %d)", ids.PeerTypeChannel, info.ChatID)
}
userLogin = logins[0]
} }
client := logins[0].Client.(*TelegramClient) client := userLogin.Client.(*TelegramClient)
var messages tg.MessagesMessagesClass var messages tg.MessagesMessagesClass
switch info.PeerType { switch info.PeerType {
case ids.PeerTypeUser, ids.PeerTypeChat: case ids.PeerTypeUser, ids.PeerTypeChat:
+16 -18
View File
@@ -13,20 +13,22 @@ import (
// The format of the media ID is as follows (each character represents a single // The format of the media ID is as follows (each character represents a single
// byte, |'s added for clarity): // byte, |'s added for clarity):
// //
// v|p|cccccccc|mmmmmmmm|T|MMMMMMMM // v|p|cccccccc|rrrrrrrr|mmmmmmmm|T|MMMMMMMM
// //
// v (int8) = binary encoding format version. Should be 0. // v (int8) = binary encoding format version. Should be 0.
// p (byte) = the peer type of the Telegram chat ID // p (byte) = the peer type of the Telegram chat ID
// cccccccc (int64) = the Telegram chat ID (big endian) // cccccccc (int64) = the Telegram chat ID (big endian)
// rrrrrrrr (int64) = the receiver ID (big endian)
// mmmmmmmm (int64) = the Telegram message ID (big endian) // mmmmmmmm (int64) = the Telegram message ID (big endian)
// T (byte) = 0 or 1 depending on whether it's a thumbnail (optional) // MMMMMMMM (int64) = the Telegram media ID (big endian)
// MMMMMMMM (int64) = the Telegram media ID (big endian) (optional) // T (byte) = 0 or 1 depending on whether it's a thumbnail
type DirectMediaInfo struct { type DirectMediaInfo struct {
PeerType PeerType PeerType PeerType
ChatID int64 ChatID int64
ReceiverID int64
MessageID int64 MessageID int64
Thumbnail bool
TelegramMediaID int64 TelegramMediaID int64
Thumbnail bool
} }
func (m DirectMediaInfo) AsMediaID() (networkid.MediaID, error) { func (m DirectMediaInfo) AsMediaID() (networkid.MediaID, error) {
@@ -34,14 +36,15 @@ func (m DirectMediaInfo) AsMediaID() (networkid.MediaID, error) {
0x00, // Version 0x00, // Version
m.PeerType.AsByte(), // Peer Type m.PeerType.AsByte(), // Peer Type
} }
mediaID = binary.BigEndian.AppendUint64(mediaID, uint64(m.ChatID)) // Telegram Chat ID mediaID = binary.BigEndian.AppendUint64(mediaID, uint64(m.ChatID)) // Telegram Chat ID
mediaID = binary.BigEndian.AppendUint64(mediaID, uint64(m.MessageID)) // Telegram Message ID mediaID = binary.BigEndian.AppendUint64(mediaID, uint64(m.ReceiverID)) // Telegram Chat ID
mediaID = binary.BigEndian.AppendUint64(mediaID, uint64(m.MessageID)) // Telegram Message ID
mediaID = binary.BigEndian.AppendUint64(mediaID, uint64(m.TelegramMediaID)) // Telegram Media ID
if m.Thumbnail { if m.Thumbnail {
mediaID = append(mediaID, 0x01) mediaID = append(mediaID, 0x01)
} else { } else {
mediaID = append(mediaID, 0x00) mediaID = append(mediaID, 0x00)
} }
mediaID = binary.BigEndian.AppendUint64(mediaID, uint64(m.TelegramMediaID)) // Telegram Message ID
return mediaID, nil return mediaID, nil
} }
@@ -54,24 +57,19 @@ func ParseDirectMediaInfo(mediaID networkid.MediaID) (info DirectMediaInfo, err
err = fmt.Errorf("invalid version %d", mediaID[0]) err = fmt.Errorf("invalid version %d", mediaID[0])
return return
} }
if len(mediaID) != 35 {
// For compatibility with old media IDs that don't have the thumbnail flag
// and the Telegram media ID, we allow media IDs with 18, 19, or 27 bytes.
if len(mediaID) != 18 && len(mediaID) != 19 && len(mediaID) != 27 {
err = fmt.Errorf("invalid media ID") err = fmt.Errorf("invalid media ID")
return return
} }
info.PeerType, err = PeerTypeFromByte(mediaID[1]) info.PeerType, err = PeerTypeFromByte(mediaID[1])
if err != nil { if err != nil {
return return
} }
info.ChatID = int64(binary.BigEndian.Uint64(mediaID[2:])) info.ChatID = int64(binary.BigEndian.Uint64(mediaID[2:]))
info.MessageID = int64(binary.BigEndian.Uint64(mediaID[10:])) info.ReceiverID = int64(binary.BigEndian.Uint64(mediaID[10:]))
if len(mediaID) >= 19 { info.MessageID = int64(binary.BigEndian.Uint64(mediaID[18:]))
info.Thumbnail = mediaID[18] == 1 info.TelegramMediaID = int64(binary.BigEndian.Uint64(mediaID[26:]))
} info.Thumbnail = mediaID[34] == 1
if len(mediaID) >= 20 {
info.TelegramMediaID = int64(binary.BigEndian.Uint64(mediaID[19:]))
}
return return
} }
+2 -1
View File
@@ -326,7 +326,7 @@ func (t *ReadyTransferer) Download(ctx context.Context) ([]byte, *event.FileInfo
} }
// DirectDownloadURL returns the direct download URL for the media. // DirectDownloadURL returns the direct download URL for the media.
func (t *ReadyTransferer) DirectDownloadURL(ctx context.Context, portal *bridgev2.Portal, msgID int, thumbnail bool, telegramMediaID int64) (id.ContentURIString, *event.FileInfo, error) { func (t *ReadyTransferer) DirectDownloadURL(ctx context.Context, loggedInUserID int64, portal *bridgev2.Portal, msgID int, thumbnail bool, telegramMediaID int64) (id.ContentURIString, *event.FileInfo, error) {
peerType, chatID, err := ids.ParsePortalID(portal.ID) peerType, chatID, err := ids.ParsePortalID(portal.ID)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
@@ -334,6 +334,7 @@ func (t *ReadyTransferer) DirectDownloadURL(ctx context.Context, portal *bridgev
mediaID, err := ids.DirectMediaInfo{ mediaID, err := ids.DirectMediaInfo{
PeerType: peerType, PeerType: peerType,
ChatID: chatID, ChatID: chatID,
ReceiverID: loggedInUserID,
MessageID: int64(msgID), MessageID: int64(msgID),
Thumbnail: thumbnail, Thumbnail: thumbnail,
TelegramMediaID: telegramMediaID, TelegramMediaID: telegramMediaID,
+2 -2
View File
@@ -331,7 +331,7 @@ func (c *TelegramClient) convertMediaRequiringUpload(ctx context.Context, portal
WithRoomID(portal.MXID). WithRoomID(portal.MXID).
WithDocument(document, true) WithDocument(document, true)
if c.main.useDirectMedia { if c.main.useDirectMedia {
thumbnailURL, thumbnailInfo, err = thumbnailTransferer.DirectDownloadURL(ctx, portal, msgID, true, document.ID) thumbnailURL, thumbnailInfo, err = thumbnailTransferer.DirectDownloadURL(ctx, c.telegramUserID, portal, msgID, true, document.ID)
if err != nil { if err != nil {
log.Err(err).Msg("error getting direct download URL for thumbnail") log.Err(err).Msg("error getting direct download URL for thumbnail")
} }
@@ -355,7 +355,7 @@ func (c *TelegramClient) convertMediaRequiringUpload(ctx context.Context, portal
var err error var err error
if c.main.useDirectMedia && (!isSticker || c.main.Config.AnimatedSticker.Target == "disable") { if c.main.useDirectMedia && (!isSticker || c.main.Config.AnimatedSticker.Target == "disable") {
content.URL, content.Info, err = mediaTransferer.DirectDownloadURL(ctx, portal, msgID, false, telegramMediaID) content.URL, content.Info, err = mediaTransferer.DirectDownloadURL(ctx, c.telegramUserID, portal, msgID, false, telegramMediaID)
if err != nil { if err != nil {
log.Err(err).Msg("error getting direct download URL for media") log.Err(err).Msg("error getting direct download URL for media")
} }