diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 163ebf6a..8bc76f28 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2157,7 +2157,7 @@ searchChatRecentLocationMessages chat_id:int53 limit:int32 = Messages; getActiveLiveLocationMessages = Messages; //@description Returns the last message sent in a chat no later than the specified date @chat_id Chat identifier @date Point in time (Unix timestamp) relative to which to search for messages -getChatMessageByDate chat_id:int53 date:int32 = Messages; +getChatMessageByDate chat_id:int53 date:int32 = Message; //@description Returns a public HTTPS link to a message. Available only for messages in public supergroups and channels @@ -2419,7 +2419,7 @@ checkChatInviteLink invite_link:string = ChatInviteLinkInfo; //@description Uses an invite link to add the current user to the chat if possible. The new member will not be added until the chat state has been synchronized with the server //@invite_link Invite link to import; should begin with "https://t.me/joinchat/", "https://telegram.me/joinchat/", or "https://telegram.dog/joinchat/" -joinChatByInviteLink invite_link:string = Ok; +joinChatByInviteLink invite_link:string = Chat; //@description Creates a new call @user_id Identifier of the user to be called @protocol Description of the call protocols supported by the client diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 9e5ca37b..338ce534 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 631c2474..0e5ac429 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -1403,13 +1403,16 @@ class CheckDialogInviteLinkQuery : public Td::ResultHandler { }; class ImportDialogInviteLinkQuery : public Td::ResultHandler { - Promise promise_; + Promise promise_; + + string invite_link_; public: - explicit ImportDialogInviteLinkQuery(Promise &&promise) : promise_(std::move(promise)) { + explicit ImportDialogInviteLinkQuery(Promise &&promise) : promise_(std::move(promise)) { } void send(const string &invite_link) { + invite_link_ = invite_link; send_query(G()->net_query_creator().create(create_storer( telegram_api::messages_importChatInvite(ContactsManager::get_dialog_invite_link_hash(invite_link).str())))); } @@ -1423,11 +1426,19 @@ class ImportDialogInviteLinkQuery : public Td::ResultHandler { auto ptr = result_ptr.move_as_ok(); LOG(INFO) << "Receive result for importChatInvite: " << to_string(ptr); + auto dialog_ids = td->updates_manager_->get_chats(ptr.get()); + if (dialog_ids.size() != 1u) { + LOG(ERROR) << "Receive wrong result for ImportDialogInviteLinkQuery: " << to_string(ptr); + return on_error(id, Status::Error(500, "Internal Server Error")); + } + td->updates_manager_->on_get_updates(std::move(ptr)); - promise_.set_value(Unit()); + td->contacts_manager_->invalidate_invite_link(invite_link_); + promise_.set_value(std::move(dialog_ids[0])); } void on_error(uint64 id, Status status) override { + td->contacts_manager_->invalidate_invite_link(invite_link_); promise_.set_error(std::move(status)); } }; @@ -4199,7 +4210,7 @@ void ContactsManager::check_dialog_invite_link(const string &invite_link, Promis td_->create_handler(std::move(promise))->send(invite_link); } -void ContactsManager::import_dialog_invite_link(const string &invite_link, Promise &&promise) { +void ContactsManager::import_dialog_invite_link(const string &invite_link, Promise &&promise) { if (!is_valid_invite_link(invite_link)) { return promise.set_error(Status::Error(3, "Wrong invite link")); } @@ -7109,6 +7120,10 @@ bool ContactsManager::update_invite_link(string &invite_link, return false; } +void ContactsManager::invalidate_invite_link(const string &invite_link) { + invite_link_infos_.erase(invite_link); +} + void ContactsManager::repair_chat_participants(ChatId chat_id) { send_get_chat_full_query(chat_id, Auto()); } diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 97a2f098..49045729 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -57,6 +57,10 @@ class ContactsManager : public Actor { public: ContactsManager(Td *td, ActorShared<> parent); + static UserId get_user_id(const tl_object_ptr &user); + static ChatId get_chat_id(const tl_object_ptr &chat); + static ChannelId get_channel_id(const tl_object_ptr &chat); + tl_object_ptr get_input_user(UserId user_id) const; bool have_input_user(UserId user_id) const; @@ -185,6 +189,8 @@ class ContactsManager : public Actor { void on_get_dialog_invite_link_info(const string &invite_link, tl_object_ptr &&chat_invite_ptr); + void invalidate_invite_link(const string &invite_link); + void on_get_created_public_channels(vector> &&chats); void on_get_user_full_success(UserId user_id); @@ -300,7 +306,7 @@ class ContactsManager : public Actor { void check_dialog_invite_link(const string &invite_link, Promise &&promise) const; - void import_dialog_invite_link(const string &invite_link, Promise &&promise); + void import_dialog_invite_link(const string &invite_link, Promise &&promise); string get_chat_invite_link(ChatId chat_id) const; @@ -733,10 +739,6 @@ class ContactsManager : public Actor { static const CSlice INVITE_LINK_URLS[3]; - static UserId get_user_id(const tl_object_ptr &user); - static ChatId get_chat_id(const tl_object_ptr &chat); - static ChannelId get_channel_id(const tl_object_ptr &chat); - static bool have_input_peer_user(const User *user, AccessRights access_rights); static bool have_input_peer_chat(const Chat *chat, AccessRights access_rights); static bool have_input_peer_channel(const Channel *c, AccessRights access_rights); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 54fafb36..e574c414 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -2096,16 +2096,32 @@ class CheckChatInviteLinkRequest : public RequestActor<> { } }; -class JoinChatByInviteLinkRequest : public RequestOnceActor { +class JoinChatByInviteLinkRequest : public RequestActor { string invite_link_; - void do_run(Promise &&promise) override { + DialogId dialog_id_; + + void do_run(Promise &&promise) override { + if (get_tries() < 2) { + promise.set_value(std::move(dialog_id_)); + return; + } td->contacts_manager_->import_dialog_invite_link(invite_link_, std::move(promise)); } + void do_set_result(DialogId &&result) override { + dialog_id_ = result; + } + + void do_send_result() override { + CHECK(dialog_id_.is_valid()); + td->messages_manager_->force_create_dialog(dialog_id_, "join chat by invite link"); + send_result(td->messages_manager_->get_chat_object(dialog_id_)); + } + public: JoinChatByInviteLinkRequest(ActorShared td, uint64 request_id, string invite_link) - : RequestOnceActor(std::move(td), request_id), invite_link_(std::move(invite_link)) { + : RequestActor(std::move(td), request_id), invite_link_(std::move(invite_link)) { } }; diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 148d0a04..21ddeae0 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -837,6 +837,52 @@ vector *> UpdatesManager::get_new_mes return messages; } +vector UpdatesManager::get_chats(const telegram_api::Updates *updates_ptr) { + const vector> *chats = nullptr; + switch (updates_ptr->get_id()) { + case telegram_api::updatesTooLong::ID: + case telegram_api::updateShortMessage::ID: + case telegram_api::updateShortChatMessage::ID: + case telegram_api::updateShort::ID: + case telegram_api::updateShortSentMessage::ID: + LOG(ERROR) << "Receive " << oneline(to_string(*updates_ptr)) << " instead of updates"; + break; + case telegram_api::updatesCombined::ID: { + chats = &static_cast(updates_ptr)->chats_; + break; + } + case telegram_api::updates::ID: { + chats = &static_cast(updates_ptr)->chats_; + break; + } + default: + UNREACHABLE(); + } + + if (chats == nullptr) { + return {}; + } + + vector dialog_ids; + dialog_ids.reserve(chats->size()); + for (const auto &chat : *chats) { + auto chat_id = ContactsManager::get_chat_id(chat); + if (chat_id.is_valid()) { + dialog_ids.push_back(DialogId(chat_id)); + continue; + } + + auto channel_id = ContactsManager::get_channel_id(chat); + if (channel_id.is_valid()) { + dialog_ids.push_back(DialogId(channel_id)); + continue; + } + + LOG(ERROR) << "Can't find id of " << oneline(to_string(chat)); + } + return dialog_ids; +} + void UpdatesManager::init_state() { if (!td_->auth_manager_->is_authorized()) { return; diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index 699da903..bf4e83b9 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -6,6 +6,7 @@ // #pragma once +#include "td/telegram/DialogId.h" #include "td/telegram/PtsManager.h" #include "td/telegram/td_api.h" @@ -36,6 +37,8 @@ class UpdatesManager : public Actor { vector *> get_new_messages(const telegram_api::Updates *updates_ptr); + vector get_chats(const telegram_api::Updates *updates_ptr); + void get_difference(const char *source); void schedule_get_difference(const char *source);