Add updateAttachMenuBots.

This commit is contained in:
levlam 2022-03-25 16:00:06 +03:00
parent 234c7423bf
commit ec802b1b57
7 changed files with 263 additions and 8 deletions

View File

@ -2499,6 +2499,17 @@ diceStickersSlotMachine background:sticker lever:sticker left_reel:sticker cente
importedContacts user_ids:vector<int53> importer_count:vector<int32> = ImportedContacts;
//@description Represents a bot added to attach menu
//@bot_user_id User identifier of the bot added to attach menu
//@name Name for the bot in attach menu
//@default_icon Default attach menu icon for the bot in SVG format; may be null
//@ios_static_icon Attach menu icon for the bot in SVG format for the official iOS app; may be null
//@ios_animated_icon Attach menu icon for the bot in TGS format for the official iOS app; may be null
//@android_icon Attach menu icon for the bot in TGS format for the official Android app; may be null
//@macos_icon Attach menu icon for the bot in TGS format for the official native macOS app; may be null
attachMenuBot bot_user_id:int53 name:string default_icon:file ios_static_icon:file ios_animated_icon:file android_icon:file macos_icon:file = AttachMenuBot;
//@description Contains an HTTP URL @url The URL
httpUrl url:string = HttpUrl;
@ -4079,6 +4090,9 @@ updateTermsOfService terms_of_service_id:string terms_of_service:termsOfService
//@description The list of users nearby has changed. The update is guaranteed to be sent only 60 seconds after a successful searchChatsNearby request @users_nearby The new list of users nearby
updateUsersNearby users_nearby:vector<chatNearby> = Update;
//@description The list of bots added to attach menu has changed @bots The new list of bots added to attach menu
updateAttachMenuBots bots:vector<attachMenuBot> = Update;
//@description The list of supported reactions has changed @reactions The new list of supported reactions
updateReactions reactions:vector<reaction> = Update;

View File

@ -7,21 +7,221 @@
#include "td/telegram/AttachMenuManager.h"
#include "td/telegram/AuthManager.h"
#include "td/telegram/ContactsManager.h"
#include "td/telegram/Document.h"
#include "td/telegram/DocumentsManager.h"
#include "td/telegram/files/FileManager.h"
#include "td/telegram/Td.h"
#include "td/actor/PromiseFuture.h"
#include "td/utils/algorithm.h"
#include "td/utils/buffer.h"
#include "td/utils/misc.h"
namespace td {
class GetAttachMenuBotsQuery final : public Td::ResultHandler {
Promise<telegram_api::object_ptr<telegram_api::AttachMenuBots>> promise_;
public:
explicit GetAttachMenuBotsQuery(Promise<telegram_api::object_ptr<telegram_api::AttachMenuBots>> &&promise)
: promise_(std::move(promise)) {
}
void send(int64 hash) {
send_query(G()->net_query_creator().create(telegram_api::messages_getAttachMenuBots(hash)));
}
void on_result(BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::messages_getAttachMenuBots>(packet);
if (result_ptr.is_error()) {
return on_error(result_ptr.move_as_error());
}
auto ptr = result_ptr.move_as_ok();
LOG(INFO) << "Receive result for GetAttachMenuBotsQuery: " << to_string(ptr);
promise_.set_value(std::move(ptr));
}
void on_error(Status status) final {
promise_.set_error(std::move(status));
}
};
bool operator==(const AttachMenuManager::AttachMenuBot &lhs, const AttachMenuManager::AttachMenuBot &rhs) {
return lhs.user_id_ == rhs.user_id_ && lhs.name_ == rhs.name_ &&
lhs.default_icon_file_id_ == rhs.default_icon_file_id_ &&
lhs.ios_static_icon_file_id_ == rhs.ios_static_icon_file_id_ &&
lhs.ios_animated_icon_file_id_ == rhs.ios_animated_icon_file_id_ &&
lhs.android_icon_file_id_ == rhs.android_icon_file_id_ && lhs.macos_icon_file_id_ == rhs.macos_icon_file_id_;
}
bool operator!=(const AttachMenuManager::AttachMenuBot &lhs, const AttachMenuManager::AttachMenuBot &rhs) {
return !(lhs == rhs);
}
AttachMenuManager::AttachMenuManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
}
void AttachMenuManager::start_up() {
init();
}
void AttachMenuManager::init() {
if (!is_active()) {
return;
}
if (is_inited_) {
return;
}
is_inited_ = true;
reload_attach_menu_bots();
}
void AttachMenuManager::tear_down() {
parent_.reset();
}
void AttachMenuManager::get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const {
if (td_->auth_manager_->is_bot()) {
bool AttachMenuManager::is_active() const {
return td_->auth_manager_->is_authorized() && !td_->auth_manager_->is_bot();
}
void AttachMenuManager::reload_attach_menu_bots() {
if (!is_active()) {
return;
}
auto promise = PromiseCreator::lambda(
[actor_id = actor_id(this)](Result<telegram_api::object_ptr<telegram_api::AttachMenuBots>> &&result) {
send_closure(actor_id, &AttachMenuManager::on_reload_attach_menu_bots, std::move(result));
});
td_->create_handler<GetAttachMenuBotsQuery>(std::move(promise))->send(0);
}
void AttachMenuManager::on_reload_attach_menu_bots(
Result<telegram_api::object_ptr<telegram_api::AttachMenuBots>> &&result) {
if (!is_active()) {
return;
}
if (result.is_error()) {
// TODO retry after some time
return;
}
is_inited_ = true;
auto attach_menu_bots_ptr = result.move_as_ok();
auto constructor_id = attach_menu_bots_ptr->get_id();
if (constructor_id == telegram_api::attachMenuBotsNotModified::ID) {
return;
}
CHECK(constructor_id == telegram_api::attachMenuBots::ID);
auto attach_menu_bots = move_tl_object_as<telegram_api::attachMenuBots>(attach_menu_bots_ptr);
td_->contacts_manager_->on_get_users(std::move(attach_menu_bots->users_), "on_reload_attach_menu_bots");
auto new_hash = attach_menu_bots->hash_;
vector<AttachMenuBot> new_attach_menu_bots;
for (auto &bot : attach_menu_bots->bots_) {
UserId user_id(bot->bot_id_);
if (!td_->contacts_manager_->have_user(user_id)) {
LOG(ERROR) << "Have no information about " << user_id;
new_hash = 0;
continue;
}
AttachMenuBot attach_menu_bot;
attach_menu_bot.user_id_ = user_id;
attach_menu_bot.name_ = std::move(bot->short_name_);
for (auto &icon : bot->icons_) {
Slice name = icon->name_;
int32 document_id = icon->icon_->get_id();
if (document_id == telegram_api::documentEmpty::ID) {
LOG(ERROR) << "Have no icon for " << user_id << " with name " << name;
new_hash = 0;
continue;
}
CHECK(document_id == telegram_api::document::ID);
if (name != "default_static" && name != "ios_static" && name != "ios_animated" && name != "android_animated" &&
name != "macos_animated") {
LOG(ERROR) << "Have icon for " << user_id << " with name " << name;
continue;
}
auto expected_document_type = ends_with(name, "_static") ? Document::Type::General : Document::Type::Sticker;
auto parsed_document =
td_->documents_manager_->on_get_document(move_tl_object_as<telegram_api::document>(icon->icon_), DialogId());
if (parsed_document.type != expected_document_type) {
LOG(ERROR) << "Receive wrong attach menu bot icon for " << user_id;
continue;
}
switch (name[5]) {
case 'l':
attach_menu_bot.default_icon_file_id_ = parsed_document.file_id;
break;
case 't':
attach_menu_bot.ios_static_icon_file_id_ = parsed_document.file_id;
break;
case 'n':
attach_menu_bot.ios_animated_icon_file_id_ = parsed_document.file_id;
break;
case 'i':
attach_menu_bot.android_icon_file_id_ = parsed_document.file_id;
break;
case '_':
attach_menu_bot.macos_icon_file_id_ = parsed_document.file_id;
break;
default:
UNREACHABLE();
}
}
new_attach_menu_bots.push_back(std::move(attach_menu_bot));
}
bool need_update = new_attach_menu_bots != attach_menu_bots_;
if (need_update || hash_ != new_hash) {
hash_ = new_hash;
attach_menu_bots_ = std::move(new_attach_menu_bots);
if (need_update) {
send_update_attach_menu_bots();
}
}
}
td_api::object_ptr<td_api::updateAttachMenuBots> AttachMenuManager::get_update_attach_menu_bots_object() const {
CHECK(is_active());
auto bots = transform(attach_menu_bots_, [td = td_](const AttachMenuBot &bot) {
auto get_file = [td](FileId file_id) {
if (!file_id.is_valid()) {
return nullptr;
}
return td->file_manager_->get_file_object(file_id);
};
return td_api::make_object<td_api::attachMenuBot>(
td->contacts_manager_->get_user_id_object(bot.user_id_, "attachMenuBot"), bot.name_,
get_file(bot.default_icon_file_id_), get_file(bot.ios_static_icon_file_id_),
get_file(bot.ios_animated_icon_file_id_), get_file(bot.android_icon_file_id_),
get_file(bot.macos_icon_file_id_));
});
return td_api::make_object<td_api::updateAttachMenuBots>(std::move(bots));
}
void AttachMenuManager::send_update_attach_menu_bots() const {
send_closure(G()->td(), &Td::send_update, get_update_attach_menu_bots_object());
}
void AttachMenuManager::get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const {
if (!is_active()) {
return;
}
updates.push_back(get_update_attach_menu_bots_object());
}
} // namespace td

View File

@ -6,11 +6,15 @@
//
#pragma once
#include "td/telegram/files/FileId.h"
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
#include "td/telegram/UserId.h"
#include "td/actor/actor.h"
#include "td/utils/common.h"
#include "td/utils/Status.h"
namespace td {
@ -20,14 +24,45 @@ class AttachMenuManager final : public Actor {
public:
AttachMenuManager(Td *td, ActorShared<> parent);
void init();
void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const;
void reload_attach_menu_bots();
void on_reload_attach_menu_bots(Result<telegram_api::object_ptr<telegram_api::AttachMenuBots>> &&result);
private:
void start_up() final;
void tear_down() final;
bool is_active() const;
struct AttachMenuBot {
UserId user_id_;
string name_;
FileId default_icon_file_id_;
FileId ios_static_icon_file_id_;
FileId ios_animated_icon_file_id_;
FileId android_icon_file_id_;
FileId macos_icon_file_id_;
};
friend bool operator==(const AttachMenuBot &lhs, const AttachMenuBot &rhs);
friend bool operator!=(const AttachMenuBot &lhs, const AttachMenuBot &rhs);
td_api::object_ptr<td_api::updateAttachMenuBots> get_update_attach_menu_bots_object() const;
void send_update_attach_menu_bots() const;
Td *td_;
ActorShared<> parent_;
bool is_inited_ = false;
int64 hash_ = 0;
vector<AttachMenuBot> attach_menu_bots_;
};
} // namespace td

View File

@ -6,6 +6,7 @@
//
#include "td/telegram/AuthManager.h"
#include "td/telegram/AttachMenuManager.h"
#include "td/telegram/AuthManager.hpp"
#include "td/telegram/ConfigManager.h"
#include "td/telegram/ConfigShared.h"
@ -786,6 +787,7 @@ void AuthManager::on_get_authorization(tl_object_ptr<telegram_api::auth_Authoriz
if (auth->setup_password_required_ && auth->otherwise_relogin_days_ > 0) {
G()->shared_config().set_option_integer("otherwise_relogin_days", auth->otherwise_relogin_days_);
}
td_->attach_menu_manager_->init();
td_->messages_manager_->on_authorization_success();
td_->notification_manager_->init();
td_->stickers_manager_->init();

View File

@ -222,6 +222,8 @@ class ContactsManager final : public Actor {
void on_update_dialog_administrators(DialogId dialog_id, vector<DialogAdministrator> &&administrators,
bool have_access, bool from_database);
void reload_attach_menu_bots();
void speculative_add_channel_participants(ChannelId channel_id, const vector<UserId> &added_user_ids,
UserId inviter_user_id, int32 date, bool by_me);

View File

@ -7,6 +7,7 @@
#include "td/telegram/UpdatesManager.h"
#include "td/telegram/AnimationsManager.h"
#include "td/telegram/AttachMenuManager.h"
#include "td/telegram/AuthManager.h"
#include "td/telegram/CallbackQueriesManager.h"
#include "td/telegram/CallManager.h"
@ -2724,6 +2725,11 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateMessageReaction
std::move(promise));
}
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateAttachMenuBots> update, Promise<Unit> &&promise) {
td_->attach_menu_manager_->reload_attach_menu_bots();
promise.set_value(Unit());
}
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateFolderPeers> update, Promise<Unit> &&promise) {
for (auto &folder_peer : update->folder_peers_) {
DialogId dialog_id(folder_peer->peer_);
@ -3315,8 +3321,4 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateSavedRingtones>
// unsupported updates
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateAttachMenuBots> update, Promise<Unit> &&promise) {
promise.set_value(Unit());
}
} // namespace td

View File

@ -387,6 +387,8 @@ class UpdatesManager final : public Actor {
void on_update(tl_object_ptr<telegram_api::updateMessageReactions> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateAttachMenuBots> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateFolderPeers> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateUserTyping> update, Promise<Unit> &&promise);
@ -512,8 +514,6 @@ class UpdatesManager final : public Actor {
void on_update(tl_object_ptr<telegram_api::updateSavedRingtones> update, Promise<Unit> &&promise);
// unsupported updates
void on_update(tl_object_ptr<telegram_api::updateAttachMenuBots> update, Promise<Unit> &&promise);
};
} // namespace td