121 lines
2.9 KiB
Go
121 lines
2.9 KiB
Go
package telegram
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/TelegramExchange/tgex-backend/tg_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
|
|
}
|