Add td_api::openWebView.

This commit is contained in:
levlam 2022-03-31 15:05:08 +03:00
parent ad7e0e2118
commit df24a2ec90
8 changed files with 169 additions and 3 deletions

View File

@ -1201,6 +1201,10 @@ loginUrlInfoOpen url:string skip_confirm:Bool = LoginUrlInfo;
loginUrlInfoRequestConfirmation url:string domain:string bot_user_id:int53 request_write_access:Bool = LoginUrlInfo; loginUrlInfoRequestConfirmation url:string domain:string bot_user_id:int53 request_write_access:Bool = LoginUrlInfo;
//@description Contains information about URL to be opened in web view @query_id Unique identifier for the web view opening query @url The URL to open in web view
webViewInfo query_id:int64 url:string = WebViewInfo;
//@description Contains information about a message thread //@description Contains information about a message thread
//@chat_id Identifier of the chat to which the message thread belongs //@chat_id Identifier of the chat to which the message thread belongs
//@message_thread_id Message thread identifier, unique within the chat //@message_thread_id Message thread identifier, unique within the chat
@ -4865,6 +4869,15 @@ getWebViewUrl bot_user_id:int53 url:string theme:themeParameters = HttpUrl;
//@bot_user_id Identifier of the target bot @button_text Text of the keyboardButtonTypeWebView button, which opened the web view @data Received data //@bot_user_id Identifier of the target bot @button_text Text of the keyboardButtonTypeWebView button, which opened the web view @data Received data
sendWebViewData bot_user_id:int53 button_text:string data:string = Ok; sendWebViewData bot_user_id:int53 button_text:string data:string = Ok;
//@description Informs TDLib that a web view is being opened from attach menu, bot menu, internalLinkTypeAttachMenuBot links, or an inlineKeyboardButtonTypeWebView button
//@chat_id Identifier of the chat in which web view is opened. Web view can be opened only in private chats for now
//@bot_user_id Identifier of the target bot, providing web view
//@url The URL from the inlineKeyboardButtonTypeWebView button or the internalLinkTypeAttachMenuBot link, or an empty string otherwise
//@from_bot_menu Pass true if the web view is opened from bot menu
//@theme Preferred web view theme; pass null to use the default theme
//@reply_to_message_id Identifier of the message to reply to by web view-generated message or 0
openWebView chat_id:int53 bot_user_id:int53 url:string from_bot_menu:Bool theme:themeParameters reply_to_message_id:int53 = WebViewInfo;
//@description Sets the result of interaction with web view and sends corresponding message on behalf of the user to the chat from which the query originated; for bots only //@description Sets the result of interaction with web view and sends corresponding message on behalf of the user to the chat from which the query originated; for bots only
//@web_view_query_id Identifier of the web view query //@web_view_query_id Identifier of the web view query
//@result The result of the query //@result The result of the query

View File

@ -6,6 +6,7 @@
// //
#include "td/telegram/AttachMenuManager.h" #include "td/telegram/AttachMenuManager.h"
#include "td/telegram/AccessRights.h"
#include "td/telegram/AuthManager.h" #include "td/telegram/AuthManager.h"
#include "td/telegram/ContactsManager.h" #include "td/telegram/ContactsManager.h"
#include "td/telegram/Dependencies.h" #include "td/telegram/Dependencies.h"
@ -14,8 +15,10 @@
#include "td/telegram/files/FileId.hpp" #include "td/telegram/files/FileId.hpp"
#include "td/telegram/files/FileManager.h" #include "td/telegram/files/FileManager.h"
#include "td/telegram/logevent/LogEvent.h" #include "td/telegram/logevent/LogEvent.h"
#include "td/telegram/MessagesManager.h"
#include "td/telegram/Td.h" #include "td/telegram/Td.h"
#include "td/telegram/TdDb.h" #include "td/telegram/TdDb.h"
#include "td/telegram/ThemeManager.h"
#include "td/utils/algorithm.h" #include "td/utils/algorithm.h"
#include "td/utils/buffer.h" #include "td/utils/buffer.h"
@ -25,6 +28,80 @@
namespace td { namespace td {
class RequestWebViewQuery final : public Td::ResultHandler {
Promise<td_api::object_ptr<td_api::webViewInfo>> promise_;
DialogId dialog_id_;
bool from_attach_menu_ = false;
public:
explicit RequestWebViewQuery(Promise<td_api::object_ptr<td_api::webViewInfo>> &&promise)
: promise_(std::move(promise)) {
}
void send(DialogId dialog_id, tl_object_ptr<telegram_api::InputUser> &&input_user, string &&url, bool from_bot_menu,
td_api::object_ptr<td_api::themeParameters> &&theme, MessageId reply_to_message_id, bool silent) {
dialog_id_ = dialog_id;
int32 flags = 0;
auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write);
CHECK(input_peer != nullptr);
string start_parameter;
if (begins_with(url, "start://")) {
start_parameter = url.substr(8);
url = string();
flags |= telegram_api::messages_requestWebView::START_PARAM_MASK;
} else if (!url.empty()) {
flags |= telegram_api::messages_requestWebView::URL_MASK;
} else if (from_bot_menu) {
flags |= telegram_api::messages_requestWebView::FROM_BOT_MENU_MASK;
} else {
from_attach_menu_ = true;
}
tl_object_ptr<telegram_api::dataJSON> theme_parameters;
if (theme != nullptr) {
theme_parameters = make_tl_object<telegram_api::dataJSON>(string());
theme_parameters->data_ = ThemeManager::get_theme_parameters_json_string(theme, false);
flags |= telegram_api::messages_requestWebView::THEME_PARAMS_MASK;
}
if (reply_to_message_id.is_valid()) {
flags |= telegram_api::messages_requestWebView::REPLY_TO_MSG_ID_MASK;
}
if (silent) {
flags |= telegram_api::messages_requestWebView::SILENT_MASK;
}
send_query(G()->net_query_creator().create(telegram_api::messages_requestWebView(
flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), std::move(input_user), url, start_parameter,
std::move(theme_parameters), reply_to_message_id.get_server_message_id().get())));
}
void on_result(BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::messages_requestWebView>(packet);
if (result_ptr.is_error()) {
return on_error(result_ptr.move_as_error());
}
auto ptr = result_ptr.move_as_ok();
promise_.set_value(td_api::make_object<td_api::webViewInfo>(ptr->query_id_, ptr->url_));
}
void on_error(Status status) final {
if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "RequestWebViewQuery")) {
if (from_attach_menu_) {
td_->attach_menu_manager_->reload_attach_menu_bots(Promise<Unit>());
}
}
promise_.set_error(std::move(status));
}
};
class GetAttachMenuBotsQuery final : public Td::ResultHandler { class GetAttachMenuBotsQuery final : public Td::ResultHandler {
Promise<telegram_api::object_ptr<telegram_api::AttachMenuBots>> promise_; Promise<telegram_api::object_ptr<telegram_api::AttachMenuBots>> promise_;
@ -315,6 +392,50 @@ bool AttachMenuManager::is_active() const {
return !G()->close_flag() && td_->auth_manager_->is_authorized() && !td_->auth_manager_->is_bot(); return !G()->close_flag() && td_->auth_manager_->is_authorized() && !td_->auth_manager_->is_bot();
} }
void AttachMenuManager::request_web_view(DialogId dialog_id, UserId bot_user_id, MessageId reply_to_message_id,
string &&url, bool from_bot_menu,
td_api::object_ptr<td_api::themeParameters> &&theme,
Promise<td_api::object_ptr<td_api::webViewInfo>> &&promise) {
TRY_STATUS_PROMISE(promise, td_->contacts_manager_->get_bot_data(bot_user_id));
TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(bot_user_id));
if (!td_->messages_manager_->have_dialog_force(dialog_id, "request_web_view")) {
return promise.set_error(Status::Error(400, "Chat not found"));
}
switch (dialog_id.get_type()) {
case DialogType::User:
// ok
break;
case DialogType::Chat:
case DialogType::Channel:
case DialogType::SecretChat:
return promise.set_error(Status::Error(400, "Web apps can be opened only in private chats"));
case DialogType::None:
default:
UNREACHABLE();
}
if (from_bot_menu && !url.empty()) {
return promise.set_error(Status::Error(400, "URL can't be specified when web app is opened from bot menu"));
}
if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Write)) {
return promise.set_error(Status::Error(400, "Have no write access to the chat"));
}
if (!reply_to_message_id.is_valid() || !reply_to_message_id.is_server() ||
!td_->messages_manager_->have_message_force({dialog_id, reply_to_message_id}, "request_web_view")) {
reply_to_message_id = MessageId();
}
bool silent = td_->messages_manager_->get_dialog_silent_send_message(dialog_id);
td_->create_handler<RequestWebViewQuery>(std::move(promise))
->send(dialog_id, std::move(input_user), std::move(url), from_bot_menu, std::move(theme), reply_to_message_id,
silent);
}
Result<AttachMenuManager::AttachMenuBot> AttachMenuManager::get_attach_menu_bot( Result<AttachMenuManager::AttachMenuBot> AttachMenuManager::get_attach_menu_bot(
tl_object_ptr<telegram_api::attachMenuBot> &&bot) const { tl_object_ptr<telegram_api::attachMenuBot> &&bot) const {
UserId user_id(bot->bot_id_); UserId user_id(bot->bot_id_);

View File

@ -6,7 +6,9 @@
// //
#pragma once #pragma once
#include "td/telegram/DialogId.h"
#include "td/telegram/files/FileId.h" #include "td/telegram/files/FileId.h"
#include "td/telegram/MessageId.h"
#include "td/telegram/td_api.h" #include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h" #include "td/telegram/telegram_api.h"
#include "td/telegram/UserId.h" #include "td/telegram/UserId.h"
@ -27,6 +29,10 @@ class AttachMenuManager final : public Actor {
void init(); void init();
void request_web_view(DialogId dialog_id, UserId bot_user_id, MessageId reply_to_message_id, string &&url,
bool from_bot_menu, td_api::object_ptr<td_api::themeParameters> &&theme,
Promise<td_api::object_ptr<td_api::webViewInfo>> &&promise);
void reload_attach_menu_bots(Promise<Unit> &&promise); void reload_attach_menu_bots(Promise<Unit> &&promise);
void get_attach_menu_bot(UserId user_id, Promise<td_api::object_ptr<td_api::attachMenuBot>> &&promise); void get_attach_menu_bot(UserId user_id, Promise<td_api::object_ptr<td_api::attachMenuBot>> &&promise);

View File

@ -25019,6 +25019,12 @@ bool MessagesManager::is_anonymous_administrator(DialogId dialog_id, string *aut
return true; return true;
} }
bool MessagesManager::get_dialog_silent_send_message(DialogId dialog_id) const {
auto *d = get_dialog(dialog_id);
CHECK(d != nullptr);
return d->notification_settings.silent_send_message;
}
int64 MessagesManager::generate_new_random_id() { int64 MessagesManager::generate_new_random_id() {
int64 random_id; int64 random_id;
do { do {
@ -26529,9 +26535,7 @@ void MessagesManager::on_yet_unsent_media_queue_updated(DialogId dialog_id) {
Result<MessageId> MessagesManager::send_bot_start_message(UserId bot_user_id, DialogId dialog_id, Result<MessageId> MessagesManager::send_bot_start_message(UserId bot_user_id, DialogId dialog_id,
const string &parameter) { const string &parameter) {
LOG(INFO) << "Begin to send bot start message to " << dialog_id; LOG(INFO) << "Begin to send bot start message to " << dialog_id;
if (td_->auth_manager_->is_bot()) { CHECK(!td_->auth_manager_->is_bot());
return Status::Error(400, "Bot can't send start message to another bot");
}
TRY_RESULT(bot_data, td_->contacts_manager_->get_bot_data(bot_user_id)); TRY_RESULT(bot_data, td_->contacts_manager_->get_bot_data(bot_user_id));

View File

@ -421,6 +421,8 @@ class MessagesManager final : public Actor {
void set_dialog_default_send_message_as_dialog_id(DialogId dialog_id, DialogId message_sender_dialog_id, void set_dialog_default_send_message_as_dialog_id(DialogId dialog_id, DialogId message_sender_dialog_id,
Promise<Unit> &&promise); Promise<Unit> &&promise);
bool get_dialog_silent_send_message(DialogId dialog_id) const;
Result<td_api::object_ptr<td_api::message>> send_message( Result<td_api::object_ptr<td_api::message>> send_message(
DialogId dialog_id, MessageId top_thread_message_id, MessageId reply_to_message_id, DialogId dialog_id, MessageId top_thread_message_id, MessageId reply_to_message_id,
tl_object_ptr<td_api::messageSendOptions> &&options, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, tl_object_ptr<td_api::messageSendOptions> &&options, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,

View File

@ -7360,6 +7360,15 @@ void Td::on_request(uint64 id, td_api::sendWebViewData &request) {
std::move(request.data_), std::move(promise)); std::move(request.data_), std::move(promise));
} }
void Td::on_request(uint64 id, td_api::openWebView &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.url_);
CREATE_REQUEST_PROMISE();
attach_menu_manager_->request_web_view(DialogId(request.chat_id_), UserId(request.bot_user_id_),
MessageId(request.reply_to_message_id_), std::move(request.url_),
request.from_bot_menu_, std::move(request.theme_), std::move(promise));
}
void Td::on_request(uint64 id, td_api::answerWebViewQuery &request) { void Td::on_request(uint64 id, td_api::answerWebViewQuery &request) {
CHECK_IS_BOT(); CHECK_IS_BOT();
CLEAN_INPUT_STRING(request.web_view_query_id_); CLEAN_INPUT_STRING(request.web_view_query_id_);

View File

@ -1159,6 +1159,8 @@ class Td final : public Actor {
void on_request(uint64 id, td_api::sendWebViewData &request); void on_request(uint64 id, td_api::sendWebViewData &request);
void on_request(uint64 id, td_api::openWebView &request);
void on_request(uint64 id, td_api::answerWebViewQuery &request); void on_request(uint64 id, td_api::answerWebViewQuery &request);
void on_request(uint64 id, td_api::getCallbackQueryAnswer &request); void on_request(uint64 id, td_api::getCallbackQueryAnswer &request);

View File

@ -3439,6 +3439,15 @@ class CliClient final : public Actor {
string data; string data;
get_args(args, user_id, button_text, data); get_args(args, user_id, button_text, data);
send_request(td_api::make_object<td_api::sendWebViewData>(user_id, button_text, data)); send_request(td_api::make_object<td_api::sendWebViewData>(user_id, button_text, data));
} else if (op == "owv") {
ChatId chat_id;
UserId bot_user_id;
string url;
bool from_bot_menu;
MessageId reply_to_message_id;
get_args(args, chat_id, bot_user_id, url, from_bot_menu, reply_to_message_id);
send_request(td_api::make_object<td_api::openWebView>(chat_id, bot_user_id, url, from_bot_menu,
get_theme_parameters(), reply_to_message_id));
} else if (op == "sca") { } else if (op == "sca") {
ChatId chat_id; ChatId chat_id;
string message_thread_id; string message_thread_id;