diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 10b8a3ae8..121ede948 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1557,6 +1557,27 @@ sponsoredMessage message_id:int53 is_recommended:Bool can_be_reported:Bool conte //@description Contains a list of sponsored messages @messages List of sponsored messages @messages_between The minimum number of messages between shown sponsored messages, or 0 if only one sponsored message must be shown after all ordinary messages sponsoredMessages messages:vector messages_between:int32 = SponsoredMessages; +//@description Describes an option to report a sponsored message @id Unique identifier of the option @text Text of the option +reportChatSponsoredMessageOption id:bytes text:string = ReportChatSponsoredMessageOption; + + +//@class ReportChatSponsoredMessageResult @description Describes result of sponsored message report + +//@description The message was reported successfully +reportChatSponsoredMessageResultOk = ReportChatSponsoredMessageResult; + +//@description The sponsored message is too old or not found +reportChatSponsoredMessageResultFailed = ReportChatSponsoredMessageResult; + +//@description The user must choose an option to report the message and repeat request with the chosen option @title Title for the option choice @options List of available options +reportChatSponsoredMessageResultOptionRequired title:string options:vector = ReportChatSponsoredMessageResult; + +//@description Sponsored messages were hidden for the user in all chats +reportChatSponsoredMessageResultAdsHidden = ReportChatSponsoredMessageResult; + +//@description The user asked to hide sponsored messages, but Telegram Premium is required for this +reportChatSponsoredMessageResultPremiumRequired = ReportChatSponsoredMessageResult; + //@description Describes a file added to file download list //@file_id File identifier @@ -7685,6 +7706,12 @@ getChatSponsoredMessages chat_id:int53 = SponsoredMessages; //@message_id Identifier of the sponsored message clickChatSponsoredMessage chat_id:int53 message_id:int53 = Ok; +//@description Reports a sponsored message to to Telegram moderators +//@chat_id Chat identifier of the sponsored message +//@message_id Identifier of the sponsored message +//@option_id Option identifier chosen by the user; leave empty for the initial request +reportChatSponsoredMessage chat_id:int53 message_id:int53 option_id:bytes = ReportChatSponsoredMessageResult; + //@description Removes an active notification from notification list. Needs to be called only if the notification is removed by the current user @notification_group_id Identifier of notification group to which the notification belongs @notification_id Identifier of removed notification removeNotification notification_group_id:int32 notification_id:int32 = Ok; diff --git a/td/telegram/SponsoredMessageManager.cpp b/td/telegram/SponsoredMessageManager.cpp index e09f857f4..6b91d5ced 100644 --- a/td/telegram/SponsoredMessageManager.cpp +++ b/td/telegram/SponsoredMessageManager.cpp @@ -126,6 +126,69 @@ class ClickSponsoredMessageQuery final : public Td::ResultHandler { } }; +class ReportSponsoredMessageQuery final : public Td::ResultHandler { + Promise> promise_; + ChannelId channel_id_; + + public: + explicit ReportSponsoredMessageQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id, const string &message_id, const string &option_id) { + channel_id_ = channel_id; + auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); + if (input_channel == nullptr) { + return promise_.set_value(td_api::make_object()); + } + send_query(G()->net_query_creator().create(telegram_api::channels_reportSponsoredMessage( + std::move(input_channel), BufferSlice(message_id), BufferSlice(option_id)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for ReportSponsoredMessageQuery: " << to_string(ptr); + switch (ptr->get_id()) { + case telegram_api::channels_sponsoredMessageReportResultReported::ID: + return promise_.set_value(td_api::make_object()); + case telegram_api::channels_sponsoredMessageReportResultAdsHidden::ID: + return promise_.set_value(td_api::make_object()); + case telegram_api::channels_sponsoredMessageReportResultChooseOption::ID: { + auto options = + telegram_api::move_object_as(ptr); + if (options->options_.empty()) { + return promise_.set_value(td_api::make_object()); + } + vector> report_options; + for (auto &option : options->options_) { + report_options.push_back(td_api::make_object( + option->option_.as_slice().str(), option->text_)); + } + return promise_.set_value(td_api::make_object( + options->title_, std::move(report_options))); + } + default: + UNREACHABLE(); + } + } + + void on_error(Status status) final { + if (status.message() == "AD_EXPIRED") { + return promise_.set_value(td_api::make_object()); + } + if (status.message() == "PREMIUM_ACCOUNT_REQUIRED") { + return promise_.set_value(td_api::make_object()); + } + td_->contacts_manager_->on_get_channel_error(channel_id_, status, "ReportSponsoredMessageQuery"); + promise_.set_error(std::move(status)); + } +}; + struct SponsoredMessageManager::SponsoredMessage { int64 local_id = 0; bool is_recommended = false; @@ -515,4 +578,23 @@ void SponsoredMessageManager::click_sponsored_message(DialogId dialog_id, Messag ->send(dialog_id.get_channel_id(), random_id_it->second.random_id_); } +void SponsoredMessageManager::report_sponsored_message( + DialogId dialog_id, MessageId sponsored_message_id, const string &option_id, + Promise> &&promise) { + if (!dialog_id.is_valid() || !sponsored_message_id.is_valid_sponsored()) { + return promise.set_error(Status::Error(400, "Invalid message specified")); + } + auto it = dialog_sponsored_messages_.find(dialog_id); + if (it == dialog_sponsored_messages_.end()) { + return promise.set_value(td_api::make_object()); + } + auto random_id_it = it->second->message_infos.find(sponsored_message_id.get()); + if (random_id_it == it->second->message_infos.end()) { + return promise.set_value(td_api::make_object()); + } + + td_->create_handler(std::move(promise)) + ->send(dialog_id.get_channel_id(), random_id_it->second.random_id_, option_id); +} + } // namespace td diff --git a/td/telegram/SponsoredMessageManager.h b/td/telegram/SponsoredMessageManager.h index 41dce961e..b28157d24 100644 --- a/td/telegram/SponsoredMessageManager.h +++ b/td/telegram/SponsoredMessageManager.h @@ -39,6 +39,9 @@ class SponsoredMessageManager final : public Actor { void click_sponsored_message(DialogId dialog_id, MessageId sponsored_message_id, Promise &&promise); + void report_sponsored_message(DialogId dialog_id, MessageId sponsored_message_id, const string &option_id, + Promise> &&promise); + private: struct SponsoredMessage; struct SponsoredMessageInfo; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index b7dc91c67..74d05e44c 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -4774,6 +4774,13 @@ void Td::on_request(uint64 id, const td_api::clickChatSponsoredMessage &request) std::move(promise)); } +void Td::on_request(uint64 id, const td_api::reportChatSponsoredMessage &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + sponsored_message_manager_->report_sponsored_message(DialogId(request.chat_id_), MessageId(request.message_id_), + request.option_id_, std::move(promise)); +} + void Td::on_request(uint64 id, const td_api::getMessageThread &request) { CHECK_IS_USER(); CREATE_REQUEST(GetMessageThreadRequest, request.chat_id_, request.message_id_); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 025399934..4173eb206 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -636,6 +636,8 @@ class Td final : public Actor { void on_request(uint64 id, const td_api::clickChatSponsoredMessage &request); + void on_request(uint64 id, const td_api::reportChatSponsoredMessage &request); + void on_request(uint64 id, const td_api::getMessageLink &request); void on_request(uint64 id, const td_api::getMessageEmbeddingCode &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 070dd1e93..0c5de6ae6 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3728,6 +3728,12 @@ class CliClient final : public Actor { MessageId message_id; get_args(args, chat_id, message_id); send_request(td_api::make_object(chat_id, message_id)); + } else if (op == "rcspm") { + ChatId chat_id; + MessageId message_id; + string option_id; + get_args(args, chat_id, message_id, option_id); + send_request(td_api::make_object(chat_id, message_id, option_id)); } else if (op == "gmlink") { ChatId chat_id; MessageId message_id;