From a72494d7212bd5436a93f0e89a3fd0b328e28590 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 7 Jun 2018 21:42:17 +0300 Subject: [PATCH] Support Terms of Service. GitOrigin-RevId: 389c4ba590a4feb34ac6d801f9097291e87423d8 --- CMakeLists.txt | 2 + td/generate/scheme/td_api.tl | 38 +++++++++------- td/generate/scheme/td_api.tlo | Bin 125884 -> 126296 bytes td/telegram/AuthManager.cpp | 24 ++++++---- td/telegram/AuthManager.h | 12 +++-- td/telegram/AuthManager.hpp | 26 +++++++++++ td/telegram/MessagesManager.cpp | 2 - td/telegram/Td.cpp | 13 +++--- td/telegram/Td.h | 4 +- td/telegram/TermsOfService.cpp | 76 ++++++++++++++++++++++++++++++++ td/telegram/TermsOfService.h | 70 +++++++++++++++++++++++++++++ td/telegram/Version.h | 1 + td/telegram/cli.cpp | 4 +- 13 files changed, 234 insertions(+), 38 deletions(-) create mode 100644 td/telegram/TermsOfService.cpp create mode 100644 td/telegram/TermsOfService.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 71bea97e4..2f6e84f3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -409,6 +409,7 @@ set(TDLIB_SOURCE td/telegram/StorageManager.cpp td/telegram/Td.cpp td/telegram/TdDb.cpp + td/telegram/TermsOfService.cpp td/telegram/TopDialogManager.cpp td/telegram/UpdatesManager.cpp td/telegram/VideoNotesManager.cpp @@ -534,6 +535,7 @@ set(TDLIB_SOURCE td/telegram/TdCallback.h td/telegram/TdDb.h td/telegram/TdParameters.h + td/telegram/TermsOfService.h td/telegram/TopDialogManager.h td/telegram/UniqueId.h td/telegram/UpdatesManager.h diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 86d0904b1..0f5fa54ab 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -63,6 +63,20 @@ authenticationCodeInfo phone_number:string type:AuthenticationCodeType next_type emailAddressAuthenticationCodeInfo email_address_pattern:string length:int32 = EmailAddressAuthenticationCodeInfo; +//@description Represents a part of the text that needs to be formatted in some unusual way @offset Offset of the entity in UTF-16 code points @length Length of the entity, in UTF-16 code points @type Type of the entity +textEntity offset:int32 length:int32 type:TextEntityType = TextEntity; + +//@description Contains a list of text entities @entities List of text entities +textEntities entities:vector = TextEntities; + +//@description A text with some entities @text The text @entities Entities contained in the text +formattedText text:string entities:vector = FormattedText; + + +//@description Contains Telegram terms of service @text Text of the terms of service @min_user_age Mininum age of a user which can accept the terms; 0 if any @show_popup True, if a blocking popup with terms of services should be shown to the user +termsOfService text:formattedText min_user_age:int32 show_popup:Bool = TermsOfService; + + //@class AuthorizationState @description Represents the current authorization state of the client //@description TDLib needs TdlibParameters for initialization @@ -74,8 +88,8 @@ authorizationStateWaitEncryptionKey is_encrypted:Bool = AuthorizationState; //@description TDLib needs the user's phone number to authorize authorizationStateWaitPhoneNumber = AuthorizationState; -//@description TDLib needs the user's authentication code to finalize authorization @is_registered True, if the user is already registered @code_info Information about the authorization code that was sent -authorizationStateWaitCode is_registered:Bool code_info:authenticationCodeInfo = AuthorizationState; +//@description TDLib needs the user's authentication code to finalize authorization @is_registered True, if the user is already registered @terms_of_service Telegram terms of service, which should be accepted before user can continue registration; may be null @code_info Information about the authorization code that was sent +authorizationStateWaitCode is_registered:Bool terms_of_service:termsOfService code_info:authenticationCodeInfo = AuthorizationState; //@description The user has been authorized, but needs to enter a password to start using the application @password_hint Hint for the password; can be empty @has_recovery_email_address True if a recovery email address has been set up //@recovery_email_address_pattern Pattern of the email address to which the recovery email was sent; empty until a recovery email has been sent @@ -173,16 +187,6 @@ maskPointChin = MaskPoint; maskPosition point:MaskPoint x_shift:double y_shift:double scale:double = MaskPosition; -//@description Represents a part of the text that needs to be formatted in some unusual way @offset Offset of the entity in UTF-16 code points @length Length of the entity, in UTF-16 code points @type Type of the entity -textEntity offset:int32 length:int32 type:TextEntityType = TextEntity; - -//@description Contains a list of text entities @entities List of text entities -textEntities entities:vector = TextEntities; - -//@description A text with some entities @text The text @entities Entities contained in the text -formattedText text:string entities:vector = FormattedText; - - //@description Describes an animation file. The animation must be encoded in GIF or MPEG4 format @duration Duration of the animation, in seconds; as defined by the sender @width Width of the animation @height Height of the animation //@file_name Original name of the file; as defined by the sender @mime_type MIME type of the file, usually "image/gif" or "video/mp4" @thumbnail Animation thumbnail; may be null @animation File containing the animation animation duration:int32 width:int32 height:int32 file_name:string mime_type:string thumbnail:photoSize animation:file = Animation; @@ -2176,6 +2180,9 @@ updateSavedAnimations animation_ids:vector = Update; //@description The connection state has changed @state The new connection state updateConnectionState state:ConnectionState = Update; +//@description A new terms of service should be accepted by the user @terms_of_service_id Terms of service identifier @terms_of_service The new terms of service +updateTermsOfService terms_of_service_id:string terms_of_service:termsOfService = Update; + //@description A new incoming inline query; for bots only @id Unique query identifier @sender_user_id Identifier of the user who sent the query @user_location User location, provided by the client; may be null @query Text of the query @offset Offset of the first entry to return updateNewInlineQuery id:int64 sender_user_id:int32 user_location:location query:string offset:string = Update; @@ -3138,6 +3145,10 @@ setStickerPositionInSet sticker:InputFile position:int32 = Ok; removeStickerFromSet sticker:InputFile = Ok; +//@description Accepts Telegram terms of services @terms_of_service_id Terms of service identifier +acceptTermsOfService terms_of_service_id:string = Ok; + + //@description Sends a custom request; for bots only @method The method name @parameters JSON-serialized method parameters sendCustomRequest method:string parameters:string = CustomRequestResult; @@ -3155,9 +3166,6 @@ getCountryCode = Text; //@description Returns the default text for invitation messages to be used as a placeholder when the current user invites friends to Telegram getInviteText = Text; -//@description Returns the terms of service. Can be called before authorization @country_code A two-letter ISO 3166-1 alpha-2 country code of user's country -getTermsOfService country_code:string = Text; - //@description Returns information about a tg:// deep link. Use "tg://need_update_for_some_feature" or "tg:some_unsupported_feature" for testing. Returns a 404 error for unknown links. Can be called before authorization @link The link getDeepLinkInfo link:string = DeepLinkInfo; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index c01edc40c78b20c960eba055aae8035ce495ed4b..2753451856f3ed8f1eaf886df3b9632dfd5b8f5e 100644 GIT binary patch delta 2109 zcmaJ?UrbwN6z4!06~S~+wTvP)l5lA+>jhdUrF3PjrK4ST&1ytLY&$5najYE_|KUtc z-1MQ*W!LP(SQ8#*_CjK3XSxSWy2KeDiNTB+qNt6*gonK>;b9u@?RU>zAy%G#J?HoR z&hMP_@!hq%4VynVH2?m&*PQ-?s!L<$3oZ zRy}&@wiFXe-Ij6%LC@GIm}D#`tI^TfPtPTaVu|_qJCRg8aqe_VEdEj? zo^mHdC){Jq&uUVV?@(ekv_PH9Qj!s=FA)A_2B-l`4@W_)=NbhXBU8Nt-pEx? zE*shE$*uoM<_#wHfv!C9vU6qPHBw9{TJ=JDPSe~p7e5zT6k7^KUW*Fv+u9#*T!gziixSCz{|X& zm?)oM%=nWxqk~7THkDYJylVvuRk_T8fufrnHnXF|R(^zD;lk2$lo9Sjt{8WaVjpN} zVzUp;8wP+STt5V8BHdqcqL;kf53KUlE6 zJqwl<8)XS^#q${}wo|jmF-XFvh!68L{2xBEBrm?|W zR5@cqo~A{#QM>>)lAZ$| zV$ediM^Q-U1h&HZ3lF-5l@II5+fL}DezQ(=zUD;d_r*grYd8iuiZ+f_2mv{~0Vcua zmD_i@P$cX^kxv!0`V0Pt=*LhvFow==jp2<<-$fpG9C_j6kdzH5F_jyymCKD=)XV}$ zvTkrt@|KcNd%#CyK@XDC9=rzYO6;KrI9_@Y@U4;F?N{$OzSb_5KNS1FB_au5k6ID8 z|M_cA>%mt$6rT}t8*Kvz<8lGzHJ5+yd)v6@Wv@cg%#iQ|FeL2--__6XO6k2gp@0|G zX@iDwJmfOz2tOg-`s_Gdrb*5xFXoZrt``_#<>Pwt+c@}T)(Mp0#7kbTyLtj2P4$Fa zQ&|5*cU{y6d9Z$EuzuYBO(nMNhqGl~fe*mmle$vfKksQH)6>ypYTrx=zW`e8e@*e~ n>%bO#XW%1a)$dbbCj+h{h0Jwe9Xi~MG}y|i7S{iO-G+Yw#8|88 delta 1801 zcmZ`(Uu;WZ6z`d`Su7c;tSIT2xZAzkYVE9@cI*DAtJXhtk}; z(uz;F8(U5KZ~9@yc`$#yy~U9kgV8k^_qv{v3iGh}_p<#b`wpFsn>_3kRAtiZtxF(~ zd0}rXwQAz`&sK%B3;xlLa>hmjstkOimrV-B2DKbT@ovieOt# z;u5yBwvokZ1%d^T_AUnfbwcq*?$tSplk;^_andCgCo{vM^eZb@Ls_|5J0ad9 z0yaUT&}kIdTO!n;E+@hmMj;6t7>!EMgVBrx(sIqAooNYwBElA)tA`qvpDsg1Up)vI zCF|iXM(zf}(g}$0DdVrwKxLIH5Mg&7ZDzh}BAO-}iPKDMGHYW=NiPy|fP|`r*4`Lc zK_B%<3;MCGU`Ks=D-HFd6?_J7YIYG~T%LQ(<=Uvc`k+*rVDcKA$#D6x^q1m@VA7Y7Z)V(^l#QvMn z-a=gZf;!K2kH{xmKtHg@207P41tM-LP)L?j56t+A3US&bY|bO_m`87uCp_d+Kbpi9 z4?b`Qlsq@ZKig~{t8zEI&S9flags_ & SENT_CODE_FLAG_HAS_TIMEOUT) != 0 ? sent_code->timeout_ : 0); } -td_api::object_ptr SendCodeHelper::get_authorization_state_wait_code() const { - return make_tl_object(phone_registered_, get_authentication_code_info_object()); +td_api::object_ptr SendCodeHelper::get_authorization_state_wait_code( + const TermsOfService &terms_of_service) const { + return make_tl_object( + phone_registered_, terms_of_service.get_terms_of_service_object(), get_authentication_code_info_object()); } td_api::object_ptr SendCodeHelper::get_authentication_code_info_object() const { @@ -448,7 +450,7 @@ tl_object_ptr AuthManager::get_authorization_state_o case State::Ok: return make_tl_object(); case State::WaitCode: - return send_code_helper_.get_authorization_state_wait_code(); + return send_code_helper_.get_authorization_state_wait_code(terms_of_service_); case State::WaitPhoneNumber: return make_tl_object(); case State::WaitPassword: @@ -527,6 +529,7 @@ void AuthManager::set_phone_number(uint64 query_id, string phone_number, bool al send_code_helper_.send_code(phone_number, allow_flash_call, is_current_phone_number, api_id_, api_hash_); if (r_send_code.is_error()) { send_code_helper_ = SendCodeHelper(); + terms_of_service_ = TermsOfService(); r_send_code = send_code_helper_.send_code(phone_number, allow_flash_call, is_current_phone_number, api_id_, api_hash_); if (r_send_code.is_error()) { @@ -562,10 +565,6 @@ void AuthManager::check_code(uint64 query_id, string code, string first_name, st if (state_ != State::WaitCode) { return on_query_error(query_id, Status::Error(8, "checkAuthenticationCode unexpected")); } - first_name = clean_name(first_name, MAX_NAME_LENGTH); - if (!send_code_helper_.phone_registered() && first_name.empty()) { - return on_query_error(query_id, Status::Error(8, "First name can't be empty")); - } on_new_query(query_id); if (send_code_helper_.phone_registered() || first_name.empty()) { @@ -575,6 +574,11 @@ void AuthManager::check_code(uint64 query_id, string code, string first_name, st send_code_helper_.phone_code_hash().str(), code)), DcId::main(), NetQuery::Type::Common, NetQuery::AuthFlag::Off)); } else { + first_name = clean_name(first_name, MAX_NAME_LENGTH); + if (first_name.empty()) { + return on_query_error(Status::Error(8, "First name can't be empty")); + } + last_name = clean_name(last_name, MAX_NAME_LENGTH); start_net_query( NetQueryType::SignUp, @@ -710,6 +714,8 @@ void AuthManager::on_send_code_result(NetQueryPtr &result) { LOG(INFO) << "Receive " << to_string(sent_code); + terms_of_service_ = TermsOfService(std::move(sent_code->terms_of_service_)); + send_code_helper_.on_sent_code(std::move(sent_code)); update_state(State::WaitCode, true); @@ -864,6 +870,7 @@ void AuthManager::on_result(NetQueryPtr result) { if (query_id_ != 0) { if (state_ == State::WaitPhoneNumber) { send_code_helper_ = SendCodeHelper(); + terms_of_service_ = TermsOfService(); } on_query_error(std::move(result->error())); } @@ -951,6 +958,7 @@ bool AuthManager::load_state() { LOG(INFO) << "Load auth_state from db: " << tag("state", static_cast(db_state.state_)); if (db_state.state_ == State::WaitCode) { send_code_helper_ = std::move(db_state.send_code_helper_); + terms_of_service_ = std::move(db_state.terms_of_service_); } else if (db_state.state_ == State::WaitPassword) { wait_password_state_ = std::move(db_state.wait_password_state_); } else { @@ -970,7 +978,7 @@ void AuthManager::save_state() { DbState db_state; if (state_ == State::WaitCode) { - db_state = DbState::wait_code(api_id_, api_hash_, send_code_helper_); + db_state = DbState::wait_code(api_id_, api_hash_, send_code_helper_, terms_of_service_); } else if (state_ == State::WaitPassword) { db_state = DbState::wait_password(api_id_, api_hash_, wait_password_state_); } else { diff --git a/td/telegram/AuthManager.h b/td/telegram/AuthManager.h index 1cdc9fe97..033e25edb 100644 --- a/td/telegram/AuthManager.h +++ b/td/telegram/AuthManager.h @@ -8,6 +8,7 @@ #include "td/telegram/net/NetActor.h" #include "td/telegram/net/NetQuery.h" +#include "td/telegram/TermsOfService.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" @@ -22,7 +23,8 @@ namespace td { class SendCodeHelper { public: void on_sent_code(telegram_api::object_ptr sent_code); - td_api::object_ptr get_authorization_state_wait_code() const; + td_api::object_ptr get_authorization_state_wait_code( + const TermsOfService &terms_of_service) const; td_api::object_ptr get_authentication_code_info_object() const; Result resend_code(); @@ -209,16 +211,19 @@ class AuthManager : public NetActor { // WaitCode SendCodeHelper send_code_helper_; + TermsOfService terms_of_service_; - //WaitPassword + // WaitPassword WaitPasswordState wait_password_state_; - static DbState wait_code(int32 api_id, string api_hash, SendCodeHelper send_code_helper) { + static DbState wait_code(int32 api_id, string api_hash, SendCodeHelper send_code_helper, + TermsOfService terms_of_service) { DbState state; state.state_ = State::WaitCode; state.api_id_ = api_id; state.api_hash_ = api_hash; state.send_code_helper_ = std::move(send_code_helper); + state.terms_of_service_ = std::move(terms_of_service); state.state_timestamp_ = Timestamp::now(); return state; } @@ -251,6 +256,7 @@ class AuthManager : public NetActor { // State::WaitCode SendCodeHelper send_code_helper_; + TermsOfService terms_of_service_; // for bots string bot_token_; diff --git a/td/telegram/AuthManager.hpp b/td/telegram/AuthManager.hpp index 6d4424e17..7591723d2 100644 --- a/td/telegram/AuthManager.hpp +++ b/td/telegram/AuthManager.hpp @@ -11,6 +11,7 @@ #include "td/utils/tl_helpers.h" namespace td { + template void SendCodeHelper::AuthenticationCodeInfo::store(T &storer) const { using td::store; @@ -18,6 +19,7 @@ void SendCodeHelper::AuthenticationCodeInfo::store(T &storer) const { store(length, storer); store(pattern, storer); } + template void SendCodeHelper::AuthenticationCodeInfo::parse(T &parser) { using td::parse; @@ -47,6 +49,7 @@ void SendCodeHelper::parse(T &parser) { parse(next_code_info_, parser); parse(next_code_timestamp_, parser); } + template void AuthManager::WaitPasswordState::store(T &storer) const { using td::store; @@ -70,11 +73,19 @@ void AuthManager::WaitPasswordState::parse(T &parser) { template void AuthManager::DbState::store(T &storer) const { using td::store; + bool has_terms_of_service = !terms_of_service_.get_id().empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_terms_of_service); + END_STORE_FLAGS(); store(state_, storer); store(api_id_, storer); store(api_hash_, storer); store(state_timestamp_, storer); + if (has_terms_of_service) { + store(terms_of_service_, storer); + } + if (state_ == State::WaitCode) { store(send_code_helper_, storer); } else if (state_ == State::WaitPassword) { @@ -83,20 +94,35 @@ void AuthManager::DbState::store(T &storer) const { UNREACHABLE(); } } + template void AuthManager::DbState::parse(T &parser) { using td::parse; + bool has_terms_of_service = false; + if (parser.version() >= static_cast(Version::AddTermsOfService)) { + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_terms_of_service); + END_PARSE_FLAGS(); + } parse(state_, parser); parse(api_id_, parser); parse(api_hash_, parser); parse(state_timestamp_, parser); + if (has_terms_of_service) { + parse(terms_of_service_, parser); + } + if (state_ == State::WaitCode) { parse(send_code_helper_, parser); + if (parser.version() < static_cast(Version::AddTermsOfService)) { + parser.set_error("Have no terms of service"); + } } else if (state_ == State::WaitPassword) { parse(wait_password_state_, parser); } else { parser.set_error(PSTRING() << "Unexpected " << tag("state", static_cast(state_))); } } + } // namespace td diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index b08263780..ecfe3756a 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -23539,7 +23539,6 @@ bool MessagesManager::update_message_content(DialogId dialog_id, Message *old_me new_photo->photos.push_back(old_photo->photos.back()); if (need_merge_files) { - FileId old_file_id = old_photo->photos.back().file_id; FileView old_file_view = td_->file_manager_->get_file_view(old_file_id); FileId new_file_id = new_photo->photos[0].file_id; FileView new_file_view = td_->file_manager_->get_file_view(new_file_id); @@ -23808,7 +23807,6 @@ bool MessagesManager::update_message_content(DialogId dialog_id, Message *old_me } if (is_content_changed || need_update) { - auto old_file_id = get_message_content_file_id(old_content.get()); old_content = std::move(new_content); update_message_content_file_id_remote(old_content.get(), old_file_id); } else { diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 1d5edc6ef..190de0b59 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -3941,7 +3941,6 @@ bool Td::is_preauthentication_request(int32 id) { case td_api::addNetworkStatistics::ID: case td_api::resetNetworkStatistics::ID: case td_api::getCountryCode::ID: - case td_api::getTermsOfService::ID: case td_api::getDeepLinkInfo::ID: case td_api::addProxy::ID: case td_api::enableProxy::ID: @@ -6946,6 +6945,13 @@ void Td::on_request(uint64 id, td_api::removeRecentHashtag &request) { send_closure(hashtag_hints_, &HashtagHints::remove_hashtag, std::move(request.hashtag_), std::move(promise)); } +void Td::on_request(uint64 id, td_api::acceptTermsOfService &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.terms_of_service_id_); + CREATE_OK_REQUEST_PROMISE(promise); + accept_terms_of_service(this, std::move(request.terms_of_service_id_), std::move(promise)); +} + void Td::on_request(uint64 id, const td_api::getCountryCode &request) { CREATE_NO_ARGS_REQUEST(GetCountryCodeRequest); } @@ -6955,11 +6961,6 @@ void Td::on_request(uint64 id, const td_api::getInviteText &request) { CREATE_NO_ARGS_REQUEST(GetInviteTextRequest); } -void Td::on_request(uint64 id, td_api::getTermsOfService &request) { - CLEAN_INPUT_STRING(request.country_code_); - send_error_raw(id, 500, "Unsupported"); -} - void Td::on_request(uint64 id, td_api::getDeepLinkInfo &request) { CLEAN_INPUT_STRING(request.link_); CREATE_REQUEST_PROMISE(promise); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 3bf6dc350..5294b118f 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -807,12 +807,12 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, td_api::removeRecentHashtag &request); + void on_request(uint64 id, td_api::acceptTermsOfService &request); + void on_request(uint64 id, const td_api::getCountryCode &request); void on_request(uint64 id, const td_api::getInviteText &request); - void on_request(uint64 id, td_api::getTermsOfService &request); - void on_request(uint64 id, td_api::getDeepLinkInfo &request); void on_request(uint64 id, td_api::addProxy &request); diff --git a/td/telegram/TermsOfService.cpp b/td/telegram/TermsOfService.cpp new file mode 100644 index 000000000..df0022d30 --- /dev/null +++ b/td/telegram/TermsOfService.cpp @@ -0,0 +1,76 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/TermsOfService.h" + +#include "td/telegram/Global.h" +#include "td/telegram/misc.h" +#include "td/telegram/net/NetQueryCreator.h" +#include "td/telegram/Td.h" + +#include "td/utils/buffer.h" +#include "td/utils/logging.h" + +namespace td { + +class AcceptTermsOfServiceQuery : public Td::ResultHandler { + Promise promise_; + + public: + explicit AcceptTermsOfServiceQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(string terms_of_service_id) { + send_query(G()->net_query_creator().create(create_storer(telegram_api::help_acceptTermsOfService( + telegram_api::make_object(std::move(terms_of_service_id)))))); + } + + void on_result(uint64 id, BufferSlice packet) override { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(id, result_ptr.move_as_error()); + } + + auto result = result_ptr.ok(); + if (!result) { + LOG(ERROR) << "Failed to accept terms of service"; + } + promise_.set_value(Unit()); + } + + void on_error(uint64 id, Status status) override { + promise_.set_error(std::move(status)); + } +}; + +TermsOfService::TermsOfService(telegram_api::object_ptr terms) { + if (terms == nullptr) { + return; + } + + id_ = std::move(terms->id_->data_); + auto entities = get_message_entities(nullptr, std::move(terms->entities_), "TermsOfService"); + auto status = fix_formatted_text(terms->text_, entities, true, true, true, false); + if (status.is_error()) { + if (!clean_input_string(terms->text_)) { + terms->text_.clear(); + } + entities.clear(); + } + if (terms->text_.empty()) { + id_.clear(); + } + text_ = FormattedText{std::move(terms->text_), std::move(entities)}; + min_user_age_ = + ((terms->flags_ & telegram_api::help_termsOfService::MIN_AGE_CONFIRM_MASK) != 0 ? terms->min_age_confirm_ : 0); + show_popup_ = (terms->flags_ & telegram_api::help_termsOfService::POPUP_MASK) != 0; +} + +void accept_terms_of_service(Td *td, string &&terms_of_service_id, Promise &&promise) { + td->create_handler(std::move(promise))->send(std::move(terms_of_service_id)); +} + +} // namespace td \ No newline at end of file diff --git a/td/telegram/TermsOfService.h b/td/telegram/TermsOfService.h new file mode 100644 index 000000000..8d167ef29 --- /dev/null +++ b/td/telegram/TermsOfService.h @@ -0,0 +1,70 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/telegram/MessageEntity.h" +#include "td/telegram/MessageEntity.hpp" + +#include "td/actor/PromiseFuture.h" + +#include "td/utils/common.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +class Td; + +class TermsOfService { + string id_; + FormattedText text_; + int32 min_user_age_ = 0; + bool show_popup_ = true; + + public: + explicit TermsOfService(telegram_api::object_ptr terms = nullptr); + + Slice get_id() const { + return id_; + } + + td_api::object_ptr get_terms_of_service_object() const { + if (id_.empty()) { + return nullptr; + } + + return td_api::make_object(get_formatted_text_object(text_), min_user_age_, show_popup_); + } + + template + void store(T &storer) const { + using td::store; + BEGIN_STORE_FLAGS(); + STORE_FLAG(show_popup_); + END_STORE_FLAGS(); + store(id_, storer); + store(text_, storer); + store(min_user_age_, storer); + } + + template + void parse(T &parser) { + using td::parse; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(show_popup_); + END_PARSE_FLAGS(); + parse(id_, parser); + parse(text_, parser); + parse(min_user_age_, parser); + } +}; + +void accept_terms_of_service(Td *td, string &&terms_of_service_id, Promise &&promise); + +} // namespace td \ No newline at end of file diff --git a/td/telegram/Version.h b/td/telegram/Version.h index c5adf582a..437f939d3 100644 --- a/td/telegram/Version.h +++ b/td/telegram/Version.h @@ -24,6 +24,7 @@ enum class Version : int32 { AddMessageInvoiceProviderData, AddCaptionEntities, AddVenueType, + AddTermsOfService, Next }; diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 1fe376c6c..7b7a68818 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -1744,8 +1744,8 @@ class CliClient final : public Actor { send_request(make_tl_object()); } else if (op == "git") { send_request(make_tl_object()); - } else if (op == "gtos") { - send_request(make_tl_object(args)); + } else if (op == "atos") { + send_request(make_tl_object(args)); } else if (op == "gdli") { send_request(make_tl_object(args)); } else if (op == "tme") {