antonio-antuan / rust-tdlib

Rust client for TDlib
MIT License
57 stars 11 forks source link

How to get last 50 posts? #33

Closed makorne closed 1 year ago

makorne commented 1 year ago

Hi! Thank you for great crate!

But how to get last 50 posts? I tried like this:

 let history = client.get_chat_history( 
   GetChatHistory::builder()
     .chat_id(chat_id)
     .limit(50)
     .offset(-50)  // If set 50 - Error : Parameter offset must be non-positive
     .from_message_id(0)
     .build(), 
 )
 .await?;

But allways has got only 0 posts even in chats where thousands of posts ...

antonio-antuan commented 1 year ago

You can find details here: https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1get_chat_history.html
and here: https://github.com/tdlib/td/issues/236

tldr from tdlib docs:

The messages are returned in a reverse chronological order (i.e., in order of decreasing message_id). For optimal performance, the number of returned messages is chosen by TDLib. This is an offline request if only_local is true.

offset 0 limit 50 should help.

makorne commented 1 year ago

You can find details here: https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1get_chat_history.html and here: tdlib/td#236

tldr from tdlib docs:

The messages are returned in a reverse chronological order (i.e., in order of decreasing message_id). For optimal performance, the number of returned messages is chosen by TDLib. This is an offline request if only_local is true.

offset 0 limit 50 should help.

In this case mainly 1 post only:

LimitGotScreenshot_2023-05-28_20-02-55

I tried this and any combinations without success.

Even read tdlib source:

void MessagesManager::load_messages(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit,
                                    int left_tries, bool only_local, Promise<Unit> &&promise) {
  LOG(INFO) << "Load " << (only_local ? "local " : "") << "messages in " << dialog_id << " from " << from_message_id
            << " with offset = " << offset << " and limit = " << limit << ". " << left_tries << " tries left";
  CHECK(offset <= 0);
  CHECK(left_tries > 0);
  only_local |= dialog_id.get_type() == DialogType::SecretChat;
  if (!only_local) {
    Dialog *d = get_dialog(dialog_id);
    if (d != nullptr && d->have_full_history) {
      LOG(INFO) << "Have full history in " << dialog_id << ", so don't need to get chat history from server";
      only_local = true;
    }
  }
  bool from_database = (left_tries > 2 || only_local) && G()->parameters().use_message_db;
  // TODO do not send requests to database if (from_message_id < d->first_database_message_id ||
  // !d->first_database_message_id.is_valid()) && !d->have_full_history

  if (from_message_id == MessageId()) {
    get_history_from_the_end(dialog_id, from_database, only_local, std::move(promise));
    return;
  }
  if (offset >= -1) {
    // get history before some server or local message
    limit = min(max(limit + offset + 1, MAX_GET_HISTORY / 2), MAX_GET_HISTORY);
    offset = -1;
  } else {
    // get history around some server or local message
    int32 messages_to_load = max(MAX_GET_HISTORY, limit);
    int32 max_add = max(messages_to_load - limit - 2, 0);
    offset -= max_add;
    limit = MAX_GET_HISTORY;
  }
  get_history(dialog_id, from_message_id, offset, limit, from_database, only_local, std::move(promise));
}

I dont know why does not work.

antonio-antuan commented 1 year ago

yes. there is another explanation :)

https://github.com/tdlib/td/issues/740

antonio-antuan commented 1 year ago

you can use this as a reference (but it may be buggy, did'nt checked it properly and also haven't been using it for a long time).
it receives (or at least should receive) all messages until the specified date (timestamp) is reached.

https://github.com/antonio-antuan/feeder/blob/main/tg-collector/src/tg_client.rs#L583

antonio-antuan commented 1 year ago

@makorne how is it going? :) wanna close the issue.