package telegram import ( "context" "fmt" "github.com/TelegramExchange/tgex-parser/internal/domain" "github.com/gotd/td/tg" ) func (t *Telegram) GetChannelDiff(ctx context.Context, channel domain.Channel, limit int) (domain.ChannelDiff, error) { req := &tg.UpdatesGetChannelDifferenceRequest{ Channel: &tg.InputChannel{ ChannelID: channel.ChannelID(), AccessHash: channel.AccessHash, }, Filter: &tg.ChannelMessagesFilterEmpty{}, Pts: channel.Pts, Limit: limit, } rawDiff, err := t.API().UpdatesGetChannelDifference(ctx, req) if err != nil { return domain.ChannelDiff{}, fmt.Errorf("get difference: %w", err) } result := domain.ChannelDiff{} switch d := rawDiff.(type) { case *tg.UpdatesChannelDifferenceEmpty: result.NewPts = d.Pts case *tg.UpdatesChannelDifferenceTooLong: if dialog, ok := d.Dialog.(*tg.Dialog); ok { result.NewPts = dialog.Pts } result.NewPosts = extractPosts(channel, d.Messages) result.UpdatedChannel = extractChannelMeta(channel, d.Chats) case *tg.UpdatesChannelDifference: result.NewPts = d.Pts result.NewPosts = extractPosts(channel, d.NewMessages) result.DeletedPosts = extractDeletedPosts(channel, d.OtherUpdates) result.UpdatedChannel = extractChannelMeta(channel, d.Chats) default: return domain.ChannelDiff{}, fmt.Errorf("unexpected rawDiff type: %T", rawDiff) } return result, nil } func extractPosts(channel domain.Channel, msgs []tg.MessageClass) []domain.Post { posts := make([]domain.Post, 0, len(msgs)) for _, raw := range msgs { m, ok := raw.(*tg.Message) if !ok { continue } text := messageToHTML(m.Message, m.Entities) p := domain.NewPost(channel, m.ID, text, m.Views) posts = append(posts, p) } return posts } func extractDeletedPosts(channel domain.Channel, updates []tg.UpdateClass) []domain.Post { var deleted []domain.Post for _, upd := range updates { if u, ok := upd.(*tg.UpdateDeleteChannelMessages); ok { for _, msgID := range u.Messages { p := domain.NewPost(channel, msgID, "", 0) deleted = append(deleted, p) } } } return deleted } func extractChannelMeta(currentChannel domain.Channel, chats []tg.ChatClass) *domain.Channel { for _, chat := range chats { ch, ok := chat.(*tg.Channel) if !ok { continue } if ch.ID != currentChannel.ChannelID() { continue } username := "" if usernameVal, ok := ch.GetUsername(); ok { username = usernameVal } // Keep current access hash if new one is not provided or is zero accessHash := currentChannel.AccessHash if accessHashVal, ok := ch.GetAccessHash(); ok && accessHashVal != 0 { accessHash = accessHashVal } updated := domain.Channel{ ID: currentChannel.ID, TelegramID: domain.ChatIDFromChannelID(ch.ID), Username: username, Title: ch.Title, AccessHash: accessHash, Pts: currentChannel.Pts, } return &updated } return nil }