Add BotMenuButton.

This commit is contained in:
levlam 2022-04-06 20:24:54 +03:00
parent 2a0ff37f76
commit 62612b9668
8 changed files with 191 additions and 5 deletions

View File

@ -286,6 +286,8 @@ set(TDLIB_SOURCE
td/telegram/BackgroundType.cpp
td/telegram/BotCommand.cpp
td/telegram/BotCommandScope.cpp
td/telegram/BotMenuButton.cpp
td/telegram/BotMenuButton.h
td/telegram/CallActor.cpp
td/telegram/CallDiscardReason.cpp
td/telegram/CallManager.cpp

View File

@ -385,6 +385,9 @@ botCommand command:string description:string = BotCommand;
//@description Contains a list of bot commands @bot_user_id Bot's user identifier @commands List of bot commands
botCommands bot_user_id:int53 commands:vector<botCommand> = BotCommands;
//@description Describes a button to be shown instead of bot commands menu button @text Text of the button @url URL to be passed to openWebApp
botMenuButton text:string url:string = BotMenuButton;
//@description Represents a location to which a chat is connected @location The location @address Location address; 1-64 characters, as defined by the chat owner
chatLocation location:location address:string = ChatLocation;
@ -472,10 +475,11 @@ user id:int53 first_name:string last_name:string username:string phone_number:st
//@description Contains information about a bot
//@share_text The text that is shown on the bot's profile page and is sent together with the link when users share the bot
//@param_description The text shown in the chat with the bot if the chat is empty
//@menu_button Information about a button to show instead of the bot commands menu button; may be null if ordinary bot commands menu must be shown
//@commands List of the bot commands
//@default_group_administrator_rights Default administrator rights for adding the bot to basic group and supergroup chats; may be null
//@default_channel_administrator_rights Default administrator rights for adding the bot to channels; may be null
botInfo share_text:string description:string commands:vector<botCommand> default_group_administrator_rights:chatAdministratorRights default_channel_administrator_rights:chatAdministratorRights = BotInfo;
botInfo share_text:string description:string menu_button:botMenuButton commands:vector<botCommand> default_group_administrator_rights:chatAdministratorRights default_channel_administrator_rights:chatAdministratorRights = BotInfo;
//@description Contains full information about a user
//@photo User profile photo; may be null
@ -4885,11 +4889,11 @@ getWebAppUrl bot_user_id:int53 url:string theme:themeParameters = HttpUrl;
//@bot_user_id Identifier of the target bot @button_text Text of the keyboardButtonTypeWebApp button, which opened the web app @data Received data
sendWebAppData bot_user_id:int53 button_text:string data:string = Ok;
//@description Informs TDLib that a web app is being opened from attach menu, bot menu, an internalLinkTypeAttachMenuBot link, or an inlineKeyboardButtonTypeWebApp button.
//@description Informs TDLib that a web app is being opened from attach menu, a botMenuButton button, an internalLinkTypeAttachMenuBot link, or an inlineKeyboardButtonTypeWebApp button.
//-For each bot, a confirmation alert about data sent to the bot must be shown once
//@chat_id Identifier of the chat in which the web app is opened. Web apps can be opened only in private chats for now
//@bot_user_id Identifier of the bot, providing the web app
//@url The URL from the inlineKeyboardButtonTypeWebApp button or the internalLinkTypeAttachMenuBot link, or an empty string otherwise
//@url The URL from an inlineKeyboardButtonTypeWebApp button, a botMenuButton button, or an internalLinkTypeAttachMenuBot link, or an empty string otherwise
//@from_bot_menu Pass true if the web app is opened from bot menu
//@theme Preferred web app theme; pass null to use the default theme
//@reply_to_message_id Identifier of the replied message for the message sent by the web app; 0 if none

View File

@ -0,0 +1,48 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
//
// 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/BotMenuButton.h"
namespace td {
unique_ptr<BotMenuButton> BotMenuButton::get_bot_menu_button(
telegram_api::object_ptr<telegram_api::BotMenuButton> &&bot_menu_button) {
CHECK(bot_menu_button != nullptr);
switch (bot_menu_button->get_id()) {
case telegram_api::botMenuButtonCommands::ID:
return nullptr;
case telegram_api::botMenuButtonDefault::ID:
return td::make_unique<BotMenuButton>(string(), "default");
case telegram_api::botMenuButton::ID: {
auto button = telegram_api::move_object_as<telegram_api::botMenuButton>(bot_menu_button);
if (button->text_.empty()) {
LOG(ERROR) << "Receive bot menu button with empty text: " << to_string(button);
return nullptr;
}
return td::make_unique<BotMenuButton>(std::move(button->text_), std::move(button->url_));
}
default:
UNREACHABLE();
return nullptr;
}
}
td_api::object_ptr<td_api::botMenuButton> BotMenuButton::get_bot_menu_button_object() const {
return td_api::make_object<td_api::botMenuButton>(text_, url_);
}
bool operator==(const BotMenuButton &lhs, const BotMenuButton &rhs) {
return lhs.text_ == rhs.text_ && lhs.url_ == rhs.url_;
}
bool operator==(const unique_ptr<BotMenuButton> &lhs, const unique_ptr<BotMenuButton> &rhs) {
if (lhs == nullptr) {
return rhs == nullptr;
}
return rhs != nullptr && *lhs == *rhs;
}
} // namespace td

View File

@ -0,0 +1,77 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
//
// 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/utils/common.h"
#include "td/utils/tl_helpers.h"
namespace td {
class Td;
class BotMenuButton {
string text_;
string url_;
friend bool operator==(const BotMenuButton &lhs, const BotMenuButton &rhs);
public:
BotMenuButton() = default;
BotMenuButton(string &&text, string &&url) : text_(std::move(text)), url_(std::move(url)) {
}
static unique_ptr<BotMenuButton> get_bot_menu_button(
telegram_api::object_ptr<telegram_api::BotMenuButton> &&bot_menu_button);
td_api::object_ptr<td_api::botMenuButton> get_bot_menu_button_object() const;
template <class StorerT>
void store(StorerT &storer) const {
bool has_text = !text_.empty();
bool has_url = !url_.empty();
BEGIN_STORE_FLAGS();
STORE_FLAG(has_text);
STORE_FLAG(has_url);
END_STORE_FLAGS();
if (has_text) {
td::store(text_, storer);
}
if (has_url) {
td::store(url_, storer);
}
}
template <class ParserT>
void parse(ParserT &parser) {
bool has_text;
bool has_url;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(has_text);
PARSE_FLAG(has_url);
END_PARSE_FLAGS();
if (has_text) {
td::parse(text_, parser);
}
if (has_url) {
td::parse(url_, parser);
}
}
};
bool operator==(const BotMenuButton &lhs, const BotMenuButton &rhs);
bool operator==(const unique_ptr<BotMenuButton> &lhs, const unique_ptr<BotMenuButton> &rhs);
inline bool operator!=(const unique_ptr<BotMenuButton> &lhs, const unique_ptr<BotMenuButton> &rhs) {
return !(lhs == rhs);
}
} // namespace td

View File

@ -7,6 +7,7 @@
#include "td/telegram/ContactsManager.h"
#include "td/telegram/AuthManager.h"
#include "td/telegram/BotMenuButton.h"
#include "td/telegram/ChannelParticipantFilter.h"
#include "td/telegram/ConfigShared.h"
#include "td/telegram/Dependencies.h"
@ -3700,6 +3701,7 @@ void ContactsManager::UserFull::store(StorerT &storer) const {
bool has_private_forward_name = !private_forward_name.empty();
bool has_group_administrator_rights = group_administrator_rights != AdministratorRights();
bool has_broadcast_administrator_rights = broadcast_administrator_rights != AdministratorRights();
bool has_menu_button = menu_button != nullptr;
BEGIN_STORE_FLAGS();
STORE_FLAG(has_about);
STORE_FLAG(is_blocked);
@ -3714,6 +3716,7 @@ void ContactsManager::UserFull::store(StorerT &storer) const {
STORE_FLAG(has_private_forward_name);
STORE_FLAG(has_group_administrator_rights);
STORE_FLAG(has_broadcast_administrator_rights);
STORE_FLAG(has_menu_button);
END_STORE_FLAGS();
if (has_about) {
store(about, storer);
@ -3738,6 +3741,9 @@ void ContactsManager::UserFull::store(StorerT &storer) const {
if (has_broadcast_administrator_rights) {
store(broadcast_administrator_rights, storer);
}
if (has_menu_button) {
store(menu_button, storer);
}
}
template <class ParserT>
@ -3750,6 +3756,7 @@ void ContactsManager::UserFull::parse(ParserT &parser) {
bool has_private_forward_name;
bool has_group_administrator_rights;
bool has_broadcast_administrator_rights;
bool has_menu_button;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(has_about);
PARSE_FLAG(is_blocked);
@ -3764,6 +3771,7 @@ void ContactsManager::UserFull::parse(ParserT &parser) {
PARSE_FLAG(has_private_forward_name);
PARSE_FLAG(has_group_administrator_rights);
PARSE_FLAG(has_broadcast_administrator_rights);
PARSE_FLAG(has_menu_button);
END_PARSE_FLAGS();
if (has_about) {
parse(about, parser);
@ -3788,6 +3796,9 @@ void ContactsManager::UserFull::parse(ParserT &parser) {
if (has_broadcast_administrator_rights) {
parse(broadcast_administrator_rights, parser);
}
if (has_menu_button) {
parse(menu_button, parser);
}
}
template <class StorerT>
@ -6180,6 +6191,26 @@ void ContactsManager::on_update_bot_commands(DialogId dialog_id, UserId bot_user
}
}
void ContactsManager::on_update_bot_menu_button(UserId bot_user_id,
tl_object_ptr<telegram_api::BotMenuButton> &&bot_menu_button) {
if (!bot_user_id.is_valid()) {
LOG(ERROR) << "Receive updateBotCOmmands about invalid " << bot_user_id;
return;
}
if (!have_user(bot_user_id) || !is_user_bot(bot_user_id)) {
return;
}
if (td_->auth_manager_->is_bot()) {
return;
}
auto user_full = get_user_full(bot_user_id);
if (user_full != nullptr) {
on_update_user_full_menu_button(user_full, bot_user_id, std::move(bot_menu_button));
update_user_full(user_full, bot_user_id, "on_update_bot_menu_button");
}
}
FileId ContactsManager::get_profile_photo_file_id(int64 photo_id) const {
auto it = my_photo_file_id_.find(photo_id);
if (it == my_photo_file_id_.end()) {
@ -10549,6 +10580,7 @@ void ContactsManager::on_get_user_full(tl_object_ptr<telegram_api::userFull> &&u
description = std::move(user->bot_info_->description_);
on_update_user_full_commands(user_full, user_id, std::move(user->bot_info_->commands_));
on_update_user_full_menu_button(user_full, user_id, std::move(user->bot_info_->menu_button_));
}
if (user_full->description != description) {
user_full->description = std::move(description);
@ -11531,6 +11563,17 @@ void ContactsManager::on_update_user_full_commands(UserFull *user_full, UserId u
}
}
void ContactsManager::on_update_user_full_menu_button(UserFull *user_full, UserId user_id,
tl_object_ptr<telegram_api::BotMenuButton> &&bot_menu_button) {
CHECK(user_full != nullptr);
CHECK(bot_menu_button != nullptr);
auto new_button = BotMenuButton::get_bot_menu_button(std::move(bot_menu_button));
if (user_full->menu_button != new_button) {
user_full->menu_button = std::move(new_button);
user_full->is_changed = true;
}
}
void ContactsManager::on_update_user_need_phone_number_privacy_exception(UserId user_id,
bool need_phone_number_privacy_exception) {
LOG(INFO) << "Receive " << need_phone_number_privacy_exception << " need phone number privacy exception with "
@ -11781,6 +11824,7 @@ void ContactsManager::drop_user_full(UserId user_id) {
user_full->need_phone_number_privacy_exception = false;
user_full->about = string();
user_full->description = string();
user_full->menu_button = nullptr;
user_full->commands.clear();
user_full->common_chat_count = 0;
user_full->private_forward_name.clear();
@ -16311,10 +16355,14 @@ tl_object_ptr<td_api::userFullInfo> ContactsManager::get_user_full_info_object(U
td_api::object_ptr<td_api::botInfo> bot_info;
bool is_bot = is_user_bot(user_id);
if (is_bot) {
td_api::object_ptr<td_api::botMenuButton> menu_button;
if (user_full->menu_button != nullptr) {
menu_button = user_full->menu_button->get_bot_menu_button_object();
}
auto commands =
transform(user_full->commands, [](const auto &command) { return command.get_bot_command_object(); });
bot_info = td_api::make_object<td_api::botInfo>(
user_full->about, user_full->description, std::move(commands),
user_full->about, user_full->description, std::move(menu_button), std::move(commands),
user_full->group_administrator_rights == AdministratorRights()
? nullptr
: user_full->group_administrator_rights.get_chat_administrator_rights_object(),

View File

@ -57,6 +57,8 @@ namespace td {
struct BinlogEvent;
class BotMenuButton;
class ChannelParticipantFilter;
struct MinChannel;
@ -219,6 +221,8 @@ class ContactsManager final : public Actor {
void on_update_bot_commands(DialogId dialog_id, UserId bot_user_id,
vector<tl_object_ptr<telegram_api::botCommand>> &&bot_commands);
void on_update_bot_menu_button(UserId bot_user_id, tl_object_ptr<telegram_api::BotMenuButton> &&bot_menu_button);
void on_update_dialog_administrators(DialogId dialog_id, vector<DialogAdministrator> &&administrators,
bool have_access, bool from_database);
@ -701,6 +705,7 @@ class ContactsManager final : public Actor {
string description;
string private_forward_name;
unique_ptr<BotMenuButton> menu_button;
vector<BotCommand> commands;
AdministratorRights group_administrator_rights;
AdministratorRights broadcast_administrator_rights;
@ -1235,6 +1240,8 @@ class ContactsManager final : public Actor {
static void on_update_user_full_common_chat_count(UserFull *user_full, UserId user_id, int32 common_chat_count);
static void on_update_user_full_commands(UserFull *user_full, UserId user_id,
vector<tl_object_ptr<telegram_api::botCommand>> &&bot_commands);
static void on_update_user_full_menu_button(UserFull *user_full, UserId user_id,
tl_object_ptr<telegram_api::BotMenuButton> &&bot_menu_button);
void on_update_user_full_need_phone_number_privacy_exception(UserFull *user_full, UserId user_id,
bool need_phone_number_privacy_exception) const;

View File

@ -16,7 +16,6 @@ namespace td {
template <class StorerT>
void store(KeyboardButton button, StorerT &storer) {
bool has_url = !button.url.empty();
;
BEGIN_STORE_FLAGS();
STORE_FLAG(has_url);
END_STORE_FLAGS();

View File

@ -2955,6 +2955,7 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateBotCommands> up
}
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateBotMenuButton> update, Promise<Unit> &&promise) {
td_->contacts_manager_->on_update_bot_menu_button(UserId(update->bot_id_), std::move(update->button_));
promise.set_value(Unit());
}