Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions app/dl/iter.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"text/template"
"time"

"github.com/fatih/color"
"github.com/go-faster/errors"
"github.com/gotd/td/telegram/peers"
"github.com/gotd/td/tg"
Expand Down Expand Up @@ -171,6 +172,31 @@ func (i *iter) process(ctx context.Context) (ret bool, skip bool) {
}
message, err := tutil.GetSingleMessage(ctx, i.pool.Default(ctx), peer, msg)
if err != nil {
// Check if message is an unsupported type (MessageService, MessageEmpty, etc.)
var unsupportedErr *tutil.UnsupportedMessageTypeError
if errors.As(err, &unsupportedErr) {
color.Yellow("Skipping system message: %d/%d (%s)",
unsupportedErr.PeerID, unsupportedErr.MessageID, unsupportedErr.MessageType)
logctx.From(ctx).Warn("Skipping system message",
zap.Int64("peer_id", unsupportedErr.PeerID),
zap.Int("message_id", unsupportedErr.MessageID),
zap.String("message_type", unsupportedErr.MessageType),
)
i.logicalPos++ // increment logical position to skip this message
return false, true
}
// Check if message is deleted
var deletedErr *tutil.DeletedMessageError
if errors.As(err, &deletedErr) {
color.Yellow("Skipping deleted message: %d/%d",
deletedErr.PeerID, deletedErr.MessageID)
logctx.From(ctx).Warn("Skipping deleted message",
zap.Int64("peer_id", deletedErr.PeerID),
zap.Int("message_id", deletedErr.MessageID),
)
i.logicalPos++ // increment logical position to skip this message
return false, true
}
i.err = errors.Wrap(err, "resolve message")
return false, false
}
Expand Down
32 changes: 30 additions & 2 deletions core/util/tutil/tutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,25 @@ func FileExists(msg tg.MessageClass) bool {
}
}

type DeletedMessageError struct {
PeerID int64
MessageID int
}

func (e *DeletedMessageError) Error() string {
return fmt.Sprintf("message %d/%d may be deleted", e.PeerID, e.MessageID)
}

type UnsupportedMessageTypeError struct {
PeerID int64
MessageID int
MessageType string
}

func (e *UnsupportedMessageTypeError) Error() string {
return fmt.Sprintf("message %d/%d has unsupported type: %s (system message, not downloadable)", e.PeerID, e.MessageID, e.MessageType)
}

func GetSingleMessage(ctx context.Context, c *tg.Client, peer tg.InputPeerClass, msg int) (*tg.Message, error) {
it := query.Messages(c).
GetHistory(peer).OffsetID(msg + 1).
Expand All @@ -182,12 +201,21 @@ func GetSingleMessage(ctx context.Context, c *tg.Client, peer tg.InputPeerClass,

m, ok := it.Value().Msg.(*tg.Message)
if !ok {
return nil, errors.Errorf("invalid message %d", msg)
// Message exists but is not a regular message (likely MessageService, MessageEmpty, etc.)
// These are system messages like "user joined", "message pinned", etc. and should be skipped
return nil, &UnsupportedMessageTypeError{
PeerID: GetInputPeerID(peer),
MessageID: msg,
MessageType: fmt.Sprintf("%T", it.Value().Msg),
}
}

// check if message is deleted
if m.GetID() != msg {
return nil, errors.Errorf("the message %d/%d may be deleted", GetInputPeerID(peer), msg)
return nil, &DeletedMessageError{
PeerID: GetInputPeerID(peer),
MessageID: msg,
}
}

return m, nil
Expand Down