Add td_api::addBotMediaPreview.
This commit is contained in:
parent
c53bbeaf95
commit
80b71e4410
@ -10620,10 +10620,16 @@ allowBotToSendMessages bot_user_id:int53 = Ok;
|
||||
sendWebAppCustomRequest bot_user_id:int53 method:string parameters:string = CustomRequestResult;
|
||||
|
||||
|
||||
//@description Returns the list of media previews of a bot
|
||||
//@bot_user_id Identifier of the target bot
|
||||
//@description Returns the list of media previews of a bot @bot_user_id Identifier of the target bot
|
||||
getBotMediaPreviews bot_user_id:int53 = BotMediaPreviews;
|
||||
|
||||
//@description Adds a new media preview to the beginning of the list of bot's media previews. Returns the added preview. The total number of previews must not exceed getOption("bot_media_preview_count_max") for the given language
|
||||
//@bot_user_id Identifier of the target bot
|
||||
//@language_code A two-letter ISO 639-1 language code for which preview is added. If empty, then the preview will be shown to all users for whose languages there are no dedicated previews.
|
||||
//-If non-empty, then there must be an official language pack with the same name as returned by getLocalizationTargetInfo
|
||||
//@content Content of the added preview
|
||||
addBotMediaPreview bot_user_id:int53 language_code:string content:InputStoryContent = StoryContent;
|
||||
|
||||
|
||||
//@description Sets the name of a bot. Can be called only if userTypeBot.can_be_edited == true
|
||||
//@bot_user_id Identifier of the target bot
|
||||
|
@ -121,7 +121,7 @@ class GetPreviewMediasQuery final : public Td::ResultHandler {
|
||||
for (auto &media_ptr : ptr) {
|
||||
auto content = get_story_content(td_, std::move(media_ptr->media_), DialogId(bot_user_id_));
|
||||
if (content == nullptr) {
|
||||
LOG(ERROR) << "Receive invalid preview media for " << bot_user_id_;
|
||||
LOG(ERROR) << "Receive invalid media preview for " << bot_user_id_;
|
||||
} else {
|
||||
append(file_ids, get_story_content_file_ids(td_, content.get()));
|
||||
contents.push_back(get_story_content_object(td_, content.get()));
|
||||
@ -141,6 +141,71 @@ class GetPreviewMediasQuery final : public Td::ResultHandler {
|
||||
}
|
||||
};
|
||||
|
||||
class BotInfoManager::AddPreviewMediaQuery final : public Td::ResultHandler {
|
||||
FileId file_id_;
|
||||
unique_ptr<PendingBotMediaPreview> pending_preview_;
|
||||
|
||||
public:
|
||||
void send(telegram_api::object_ptr<telegram_api::InputUser> input_user,
|
||||
unique_ptr<PendingBotMediaPreview> pending_preview, FileId file_id,
|
||||
telegram_api::object_ptr<telegram_api::InputFile> input_file) {
|
||||
file_id_ = file_id;
|
||||
pending_preview_ = std::move(pending_preview);
|
||||
CHECK(pending_preview_ != nullptr);
|
||||
|
||||
const StoryContent *content = pending_preview_->content_.get();
|
||||
CHECK(input_file != nullptr);
|
||||
auto input_media = get_story_content_input_media(td_, content, std::move(input_file));
|
||||
CHECK(input_media != nullptr);
|
||||
send_query(G()->net_query_creator().create(
|
||||
telegram_api::bots_addPreviewMedia(std::move(input_user), pending_preview_->language_code_,
|
||||
std::move(input_media)),
|
||||
{{pending_preview_->bot_user_id_}}));
|
||||
}
|
||||
|
||||
void on_result(BufferSlice packet) final {
|
||||
auto result_ptr = fetch_result<telegram_api::bots_addPreviewMedia>(packet);
|
||||
if (result_ptr.is_error()) {
|
||||
return on_error(result_ptr.move_as_error());
|
||||
}
|
||||
|
||||
if (file_id_.is_valid()) {
|
||||
td_->file_manager_->delete_partial_remote_location(file_id_);
|
||||
}
|
||||
|
||||
auto ptr = result_ptr.move_as_ok();
|
||||
LOG(INFO) << "Receive result for AddPreviewMediaQuery: " << to_string(ptr);
|
||||
auto bot_user_id = pending_preview_->bot_user_id_;
|
||||
auto content = get_story_content(td_, std::move(ptr->media_), DialogId(bot_user_id));
|
||||
if (content == nullptr) {
|
||||
LOG(ERROR) << "Receive invalid media preview";
|
||||
return pending_preview_->promise_.set_error(Status::Error(500, "Receive invalid preview"));
|
||||
}
|
||||
auto file_ids = get_story_content_file_ids(td_, content.get());
|
||||
if (!file_ids.empty()) {
|
||||
auto file_source_id = td_->bot_info_manager_->get_bot_media_preview_file_source_id(bot_user_id);
|
||||
for (auto file_id : file_ids) {
|
||||
td_->file_manager_->add_file_source(file_id, file_source_id);
|
||||
}
|
||||
}
|
||||
pending_preview_->promise_.set_value(get_story_content_object(td_, content.get()));
|
||||
}
|
||||
|
||||
void on_error(Status status) final {
|
||||
LOG(INFO) << "Receive error for AddPreviewMediaQuery: " << status;
|
||||
auto bad_parts = FileManager::get_missing_file_parts(status);
|
||||
if (!bad_parts.empty()) {
|
||||
td_->bot_info_manager_->on_add_bot_media_preview_file_parts_missing(std::move(pending_preview_),
|
||||
std::move(bad_parts));
|
||||
return;
|
||||
}
|
||||
if (file_id_.is_valid()) {
|
||||
td_->file_manager_->delete_partial_remote_location(file_id_);
|
||||
}
|
||||
pending_preview_->promise_.set_error(std::move(status));
|
||||
}
|
||||
};
|
||||
|
||||
class CanBotSendMessageQuery final : public Td::ResultHandler {
|
||||
Promise<Unit> promise_;
|
||||
|
||||
@ -347,7 +412,31 @@ class GetBotInfoQuery final : public Td::ResultHandler {
|
||||
}
|
||||
};
|
||||
|
||||
class BotInfoManager::UploadMediaCallback final : public FileManager::UploadCallback {
|
||||
public:
|
||||
void on_upload_ok(FileId file_id, telegram_api::object_ptr<telegram_api::InputFile> input_file) final {
|
||||
send_closure_later(G()->bot_info_manager(), &BotInfoManager::on_upload_bot_media_preview, file_id,
|
||||
std::move(input_file));
|
||||
}
|
||||
void on_upload_encrypted_ok(FileId file_id,
|
||||
telegram_api::object_ptr<telegram_api::InputEncryptedFile> input_file) final {
|
||||
UNREACHABLE();
|
||||
}
|
||||
void on_upload_secure_ok(FileId file_id, telegram_api::object_ptr<telegram_api::InputSecureFile> input_file) final {
|
||||
UNREACHABLE();
|
||||
}
|
||||
void on_upload_error(FileId file_id, Status error) final {
|
||||
send_closure_later(G()->bot_info_manager(), &BotInfoManager::on_upload_bot_media_preview_error, file_id,
|
||||
std::move(error));
|
||||
}
|
||||
};
|
||||
|
||||
BotInfoManager::BotInfoManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
|
||||
upload_media_callback_ = std::make_shared<UploadMediaCallback>();
|
||||
}
|
||||
|
||||
BotInfoManager::~BotInfoManager() {
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), bot_media_preview_file_source_ids_);
|
||||
}
|
||||
|
||||
void BotInfoManager::tear_down() {
|
||||
@ -483,6 +572,104 @@ void BotInfoManager::reload_bot_media_previews(UserId bot_user_id, Promise<Unit>
|
||||
}));
|
||||
}
|
||||
|
||||
void BotInfoManager::add_bot_media_preview(UserId bot_user_id, const string &language_code,
|
||||
td_api::object_ptr<td_api::InputStoryContent> &&input_content,
|
||||
Promise<td_api::object_ptr<td_api::StoryContent>> &&promise) {
|
||||
TRY_RESULT_PROMISE(promise, input_user, get_media_preview_bot_input_user(bot_user_id, true));
|
||||
TRY_STATUS_PROMISE(promise, validate_bot_language_code(language_code));
|
||||
TRY_RESULT_PROMISE(promise, content, get_input_story_content(td_, std::move(input_content), DialogId(bot_user_id)));
|
||||
auto pending_preview = make_unique<PendingBotMediaPreview>();
|
||||
pending_preview->bot_user_id_ = bot_user_id;
|
||||
pending_preview->language_code_ = language_code;
|
||||
pending_preview->content_ = dup_story_content(td_, content.get());
|
||||
pending_preview->upload_order_ = bot_media_preview_upload_order_;
|
||||
pending_preview->promise_ = std::move(promise);
|
||||
|
||||
do_add_bot_media_preview(std::move(pending_preview), {});
|
||||
}
|
||||
|
||||
void BotInfoManager::do_add_bot_media_preview(unique_ptr<PendingBotMediaPreview> &&pending_preview,
|
||||
vector<int> bad_parts) {
|
||||
auto content = pending_preview->content_.get();
|
||||
auto upload_order = pending_preview->upload_order_;
|
||||
|
||||
FileId file_id = get_story_content_any_file_id(td_, content);
|
||||
CHECK(file_id.is_valid());
|
||||
|
||||
LOG(INFO) << "Ask to upload file " << file_id << " with bad parts " << bad_parts;
|
||||
bool is_inserted = being_uploaded_files_.emplace(file_id, std::move(pending_preview)).second;
|
||||
CHECK(is_inserted);
|
||||
// need to call resume_upload synchronously to make upload process consistent with being_uploaded_files_
|
||||
// and to send is_uploading_active == true in response
|
||||
td_->file_manager_->resume_upload(file_id, std::move(bad_parts), upload_media_callback_, 1, upload_order);
|
||||
}
|
||||
|
||||
void BotInfoManager::on_add_bot_media_preview_file_parts_missing(unique_ptr<PendingBotMediaPreview> &&pending_preview,
|
||||
vector<int> &&bad_parts) {
|
||||
do_add_bot_media_preview(std::move(pending_preview), std::move(bad_parts));
|
||||
}
|
||||
|
||||
void BotInfoManager::on_upload_bot_media_preview(FileId file_id,
|
||||
telegram_api::object_ptr<telegram_api::InputFile> input_file) {
|
||||
if (G()->close_flag()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(INFO) << "File " << file_id << " has been uploaded";
|
||||
|
||||
auto it = being_uploaded_files_.find(file_id);
|
||||
if (it == being_uploaded_files_.end()) {
|
||||
// callback may be called just before the file upload was canceled
|
||||
return;
|
||||
}
|
||||
|
||||
auto pending_preview = std::move(it->second);
|
||||
|
||||
being_uploaded_files_.erase(it);
|
||||
|
||||
FileView file_view = td_->file_manager_->get_file_view(file_id);
|
||||
CHECK(!file_view.is_encrypted());
|
||||
if (input_file == nullptr && file_view.has_remote_location()) {
|
||||
if (file_view.main_remote_location().is_web()) {
|
||||
return pending_preview->promise_.set_error(Status::Error(400, "Can't use web photo as a preview"));
|
||||
}
|
||||
if (pending_preview->was_reuploaded_) {
|
||||
return pending_preview->promise_.set_error(Status::Error(500, "Failed to reupload preview"));
|
||||
}
|
||||
pending_preview->was_reuploaded_ = true;
|
||||
|
||||
// delete file reference and forcely reupload the file
|
||||
td_->file_manager_->delete_file_reference(file_id, file_view.main_remote_location().get_file_reference());
|
||||
return do_add_bot_media_preview(std::move(pending_preview), {-1});
|
||||
}
|
||||
CHECK(input_file != nullptr);
|
||||
TRY_RESULT_PROMISE(pending_preview->promise_, input_user,
|
||||
get_media_preview_bot_input_user(pending_preview->bot_user_id_, true));
|
||||
|
||||
td_->create_handler<AddPreviewMediaQuery>()->send(std::move(input_user), std::move(pending_preview), file_id,
|
||||
std::move(input_file));
|
||||
}
|
||||
|
||||
void BotInfoManager::on_upload_bot_media_preview_error(FileId file_id, Status status) {
|
||||
if (G()->close_flag()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(INFO) << "File " << file_id << " has upload error " << status;
|
||||
|
||||
auto it = being_uploaded_files_.find(file_id);
|
||||
if (it == being_uploaded_files_.end()) {
|
||||
// callback may be called just before the file upload was canceled
|
||||
return;
|
||||
}
|
||||
|
||||
auto pending_preview = std::move(it->second);
|
||||
|
||||
being_uploaded_files_.erase(it);
|
||||
|
||||
pending_preview->promise_.set_error(std::move(status));
|
||||
}
|
||||
|
||||
void BotInfoManager::add_pending_set_query(UserId bot_user_id, const string &language_code, int type,
|
||||
const string &value, Promise<Unit> &&promise) {
|
||||
pending_set_bot_info_queries_.emplace_back(bot_user_id, language_code, type, value, std::move(promise));
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "td/telegram/DialogParticipant.h"
|
||||
#include "td/telegram/files/FileId.h"
|
||||
#include "td/telegram/files/FileSourceId.h"
|
||||
#include "td/telegram/UserId.h"
|
||||
|
||||
@ -15,14 +16,22 @@
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/FlatHashMap.h"
|
||||
#include "td/utils/Promise.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
class StoryContent;
|
||||
|
||||
class Td;
|
||||
|
||||
class BotInfoManager final : public Actor {
|
||||
public:
|
||||
BotInfoManager(Td *td, ActorShared<> parent);
|
||||
BotInfoManager(const BotInfoManager &) = delete;
|
||||
BotInfoManager &operator=(const BotInfoManager &) = delete;
|
||||
BotInfoManager(BotInfoManager &&) = delete;
|
||||
BotInfoManager &operator=(BotInfoManager &&) = delete;
|
||||
~BotInfoManager() final;
|
||||
|
||||
void set_default_group_administrator_rights(AdministratorRights administrator_rights, Promise<Unit> &&promise);
|
||||
|
||||
@ -38,6 +47,10 @@ class BotInfoManager final : public Actor {
|
||||
|
||||
void reload_bot_media_previews(UserId bot_user_id, Promise<Unit> &&promise);
|
||||
|
||||
void add_bot_media_preview(UserId bot_user_id, const string &language_code,
|
||||
td_api::object_ptr<td_api::InputStoryContent> &&input_content,
|
||||
Promise<td_api::object_ptr<td_api::StoryContent>> &&promise);
|
||||
|
||||
void set_bot_name(UserId bot_user_id, const string &language_code, const string &name, Promise<Unit> &&promise);
|
||||
|
||||
void get_bot_name(UserId bot_user_id, const string &language_code, Promise<string> &&promise);
|
||||
@ -55,6 +68,19 @@ class BotInfoManager final : public Actor {
|
||||
private:
|
||||
static constexpr double MAX_QUERY_DELAY = 0.01;
|
||||
|
||||
class UploadMediaCallback;
|
||||
|
||||
class AddPreviewMediaQuery;
|
||||
|
||||
struct PendingBotMediaPreview {
|
||||
UserId bot_user_id_;
|
||||
string language_code_;
|
||||
unique_ptr<StoryContent> content_;
|
||||
uint32 upload_order_ = 0;
|
||||
bool was_reuploaded_ = false;
|
||||
Promise<td_api::object_ptr<td_api::StoryContent>> promise_;
|
||||
};
|
||||
|
||||
struct PendingSetBotInfoQuery {
|
||||
UserId bot_user_id_;
|
||||
string language_code_;
|
||||
@ -92,6 +118,15 @@ class BotInfoManager final : public Actor {
|
||||
Result<telegram_api::object_ptr<telegram_api::InputUser>> get_media_preview_bot_input_user(
|
||||
UserId user_id, bool can_be_edited = false);
|
||||
|
||||
void do_add_bot_media_preview(unique_ptr<PendingBotMediaPreview> &&pending_preview, vector<int> bad_parts);
|
||||
|
||||
void on_add_bot_media_preview_file_parts_missing(unique_ptr<PendingBotMediaPreview> &&pending_preview,
|
||||
vector<int> &&bad_parts);
|
||||
|
||||
void on_upload_bot_media_preview(FileId file_id, telegram_api::object_ptr<telegram_api::InputFile> input_file);
|
||||
|
||||
void on_upload_bot_media_preview_error(FileId file_id, Status status);
|
||||
|
||||
void add_pending_set_query(UserId bot_user_id, const string &language_code, int type, const string &value,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
@ -103,6 +138,12 @@ class BotInfoManager final : public Actor {
|
||||
|
||||
FlatHashMap<UserId, FileSourceId, UserIdHash> bot_media_preview_file_source_ids_;
|
||||
|
||||
FlatHashMap<FileId, unique_ptr<PendingBotMediaPreview>, FileIdHash> being_uploaded_files_;
|
||||
|
||||
std::shared_ptr<UploadMediaCallback> upload_media_callback_;
|
||||
|
||||
uint32 bot_media_preview_upload_order_ = 0;
|
||||
|
||||
Td *td_;
|
||||
ActorShared<> parent_;
|
||||
};
|
||||
|
@ -7901,6 +7901,12 @@ void Td::on_request(uint64 id, const td_api::getBotMediaPreviews &request) {
|
||||
bot_info_manager_->get_bot_media_previews(UserId(request.bot_user_id_), std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::addBotMediaPreview &request) {
|
||||
CREATE_REQUEST_PROMISE();
|
||||
bot_info_manager_->add_bot_media_preview(UserId(request.bot_user_id_), request.language_code_,
|
||||
std::move(request.content_), std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::setBotName &request) {
|
||||
CLEAN_INPUT_STRING(request.name_);
|
||||
CREATE_OK_REQUEST_PROMISE();
|
||||
|
@ -1459,6 +1459,8 @@ class Td final : public Actor {
|
||||
|
||||
void on_request(uint64 id, const td_api::getBotMediaPreviews &request);
|
||||
|
||||
void on_request(uint64 id, td_api::addBotMediaPreview &request);
|
||||
|
||||
void on_request(uint64 id, td_api::setBotName &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::getBotName &request);
|
||||
|
@ -6562,6 +6562,22 @@ class CliClient final : public Actor {
|
||||
UserId bot_user_id;
|
||||
get_args(args, bot_user_id);
|
||||
send_request(td_api::make_object<td_api::getBotMediaPreviews>(bot_user_id));
|
||||
} else if (op == "abmpp") {
|
||||
UserId bot_user_id;
|
||||
string language_code;
|
||||
string photo;
|
||||
get_args(args, bot_user_id, language_code, photo);
|
||||
send_request(td_api::make_object<td_api::addBotMediaPreview>(
|
||||
bot_user_id, language_code,
|
||||
td_api::make_object<td_api::inputStoryContentPhoto>(as_input_file(photo), Auto())));
|
||||
} else if (op == "abmpv") {
|
||||
UserId bot_user_id;
|
||||
string language_code;
|
||||
string video;
|
||||
get_args(args, bot_user_id, language_code, video);
|
||||
send_request(td_api::make_object<td_api::addBotMediaPreview>(
|
||||
bot_user_id, language_code,
|
||||
td_api::make_object<td_api::inputStoryContentVideo>(as_input_file(video), Auto(), 0.0, 1.5, true)));
|
||||
} else if (op == "gbi") {
|
||||
UserId bot_user_id;
|
||||
string language_code;
|
||||
|
Loading…
Reference in New Issue
Block a user