Add InlineQueriesManager::answer_inline_query function.

This commit is contained in:
levlam 2022-03-24 11:31:33 +03:00
parent 62b99ba52a
commit 461b740987
2 changed files with 416 additions and 404 deletions

View File

@ -363,10 +363,9 @@ UserId InlineQueriesManager::get_inline_bot_user_id(int64 query_id) const {
return it->second;
}
void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_personal,
vector<tl_object_ptr<td_api::InputInlineQueryResult>> &&input_results,
int32 cache_time, const string &next_offset,
const string &switch_pm_text, const string &switch_pm_parameter,
void InlineQueriesManager::answer_inline_query(
int64 inline_query_id, bool is_personal, vector<td_api::object_ptr<td_api::InputInlineQueryResult>> &&input_results,
int32 cache_time, const string &next_offset, const string &switch_pm_text, const string &switch_pm_parameter,
Promise<Unit> &&promise) const {
if (!td_->auth_manager_->is_bot()) {
return promise.set_error(Status::Error(400, "Method can be used by bots only"));
@ -389,8 +388,20 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
bool is_gallery = false;
bool force_vertical = false;
for (auto &input_result : input_results) {
if (input_result == nullptr) {
return promise.set_error(Status::Error(400, "Inline query result must be non-empty"));
TRY_RESULT_PROMISE(promise, result,
get_input_bot_inline_result(std::move(input_result), &is_gallery, &force_vertical));
results.push_back(std::move(result));
}
td_->create_handler<SetInlineBotResultsQuery>(std::move(promise))
->send(inline_query_id, is_gallery && !force_vertical, is_personal, std::move(results), cache_time, next_offset,
switch_pm_text, switch_pm_parameter);
}
Result<tl_object_ptr<telegram_api::InputBotInlineResult>> InlineQueriesManager::get_input_bot_inline_result(
td_api::object_ptr<td_api::InputInlineQueryResult> &&result, bool *is_gallery, bool *force_vertical) const {
if (result == nullptr) {
return Status::Error(400, "Inline query result must be non-empty");
}
string id;
@ -410,9 +421,9 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
FileType file_type = FileType::Temp;
Result<tl_object_ptr<telegram_api::InputBotInlineMessage>> r_inline_message = Status::Error(500, "Uninited");
switch (input_result->get_id()) {
switch (result->get_id()) {
case td_api::inputInlineQueryResultAnimation::ID: {
auto animation = move_tl_object_as<td_api::inputInlineQueryResultAnimation>(input_result);
auto animation = move_tl_object_as<td_api::inputInlineQueryResultAnimation>(result);
type = "gif";
id = std::move(animation->id_);
title = std::move(animation->title_);
@ -423,12 +434,14 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
content_url = std::move(animation->video_url_);
content_type = std::move(animation->video_mime_type_);
if (content_type != "image/gif" && content_type != "video/mp4") {
return promise.set_error(Status::Error(400, "Wrong animation MIME type specified"));
return Status::Error(400, "Wrong animation MIME type specified");
}
duration = animation->video_duration_;
width = animation->video_width_;
height = animation->video_height_;
is_gallery = true;
if (is_gallery != nullptr) {
*is_gallery = true;
}
file_type = FileType::Animation;
r_inline_message = get_inline_message(std::move(animation->input_message_content_),
@ -436,7 +449,7 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
break;
}
case td_api::inputInlineQueryResultArticle::ID: {
auto article = move_tl_object_as<td_api::inputInlineQueryResultArticle>(input_result);
auto article = move_tl_object_as<td_api::inputInlineQueryResultArticle>(result);
type = "article";
id = std::move(article->id_);
if (!article->url_.empty()) {
@ -453,14 +466,16 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
thumbnail_width = article->thumbnail_width_;
thumbnail_height = article->thumbnail_height_;
}
force_vertical = true;
if (force_vertical != nullptr) {
*force_vertical = true;
}
r_inline_message =
get_inline_message(std::move(article->input_message_content_), std::move(article->reply_markup_), -1);
break;
}
case td_api::inputInlineQueryResultAudio::ID: {
auto audio = move_tl_object_as<td_api::inputInlineQueryResultAudio>(input_result);
auto audio = move_tl_object_as<td_api::inputInlineQueryResultAudio>(result);
type = "audio";
id = std::move(audio->id_);
title = std::move(audio->title_);
@ -468,7 +483,9 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
content_url = std::move(audio->audio_url_);
content_type = "audio/mpeg";
duration = audio->audio_duration_;
force_vertical = true;
if (force_vertical != nullptr) {
*force_vertical = true;
}
file_type = FileType::Audio;
r_inline_message = get_inline_message(std::move(audio->input_message_content_), std::move(audio->reply_markup_),
@ -476,9 +493,9 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
break;
}
case td_api::inputInlineQueryResultContact::ID: {
auto contact = move_tl_object_as<td_api::inputInlineQueryResultContact>(input_result);
auto contact = move_tl_object_as<td_api::inputInlineQueryResultContact>(result);
if (contact->contact_ == nullptr) {
return promise.set_error(Status::Error(400, "Contact must be non-empty"));
return Status::Error(400, "Contact must be non-empty");
}
type = "contact";
id = std::move(contact->id_);
@ -486,10 +503,10 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
string first_name = trim(contact->contact_->first_name_);
string last_name = trim(contact->contact_->last_name_);
if (phone_number.empty()) {
return promise.set_error(Status::Error(400, "Field \"phone_number\" must contain a valid phone number"));
return Status::Error(400, "Field \"phone_number\" must contain a valid phone number");
}
if (first_name.empty()) {
return promise.set_error(Status::Error(400, "Field \"first_name\" must be non-empty"));
return Status::Error(400, "Field \"first_name\" must be non-empty");
}
if (last_name.empty()) {
title = std::move(first_name);
@ -502,14 +519,16 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
thumbnail_width = contact->thumbnail_width_;
thumbnail_height = contact->thumbnail_height_;
}
force_vertical = true;
if (force_vertical != nullptr) {
*force_vertical = true;
}
r_inline_message =
get_inline_message(std::move(contact->input_message_content_), std::move(contact->reply_markup_), -1);
break;
}
case td_api::inputInlineQueryResultDocument::ID: {
auto document = move_tl_object_as<td_api::inputInlineQueryResultDocument>(input_result);
auto document = move_tl_object_as<td_api::inputInlineQueryResultDocument>(result);
type = "file";
id = std::move(document->id_);
title = std::move(document->title_);
@ -526,7 +545,7 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
} else if (begins_with(content_type, "application/zip")) {
content_type = "application/zip";
} else {
return promise.set_error(Status::Error(400, "Unallowed document MIME type"));
return Status::Error(400, "Unallowed document MIME type");
}
}
@ -536,10 +555,10 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
break;
}
case td_api::inputInlineQueryResultGame::ID: {
auto game = move_tl_object_as<td_api::inputInlineQueryResultGame>(input_result);
auto game = move_tl_object_as<td_api::inputInlineQueryResultGame>(result);
auto r_reply_markup = get_reply_markup(std::move(game->reply_markup_), true, true, false, true);
if (r_reply_markup.is_error()) {
return promise.set_error(r_reply_markup.move_as_error());
return r_reply_markup.move_as_error();
}
auto input_reply_markup = get_input_reply_markup(r_reply_markup.ok());
@ -547,16 +566,14 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
if (input_reply_markup != nullptr) {
flags |= telegram_api::inputBotInlineMessageGame::REPLY_MARKUP_MASK;
}
auto result = make_tl_object<telegram_api::inputBotInlineResultGame>(
return make_tl_object<telegram_api::inputBotInlineResultGame>(
game->id_, game->game_short_name_,
make_tl_object<telegram_api::inputBotInlineMessageGame>(flags, std::move(input_reply_markup)));
results.push_back(std::move(result));
continue;
}
case td_api::inputInlineQueryResultLocation::ID: {
auto location = move_tl_object_as<td_api::inputInlineQueryResultLocation>(input_result);
auto location = move_tl_object_as<td_api::inputInlineQueryResultLocation>(result);
if (location->location_ == nullptr) {
return promise.set_error(Status::Error(400, "Location must be non-empty"));
return Status::Error(400, "Location must be non-empty");
}
type = "geo";
id = std::move(location->id_);
@ -574,7 +591,7 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
break;
}
case td_api::inputInlineQueryResultPhoto::ID: {
auto photo = move_tl_object_as<td_api::inputInlineQueryResultPhoto>(input_result);
auto photo = move_tl_object_as<td_api::inputInlineQueryResultPhoto>(result);
type = "photo";
id = std::move(photo->id_);
title = std::move(photo->title_);
@ -584,7 +601,9 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
content_type = "image/jpeg";
width = photo->photo_width_;
height = photo->photo_height_;
is_gallery = true;
if (is_gallery != nullptr) {
*is_gallery = true;
}
file_type = FileType::Photo;
r_inline_message = get_inline_message(std::move(photo->input_message_content_), std::move(photo->reply_markup_),
@ -592,19 +611,19 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
break;
}
case td_api::inputInlineQueryResultSticker::ID: {
auto sticker = move_tl_object_as<td_api::inputInlineQueryResultSticker>(input_result);
auto sticker = move_tl_object_as<td_api::inputInlineQueryResultSticker>(result);
type = "sticker";
id = std::move(sticker->id_);
thumbnail_url = std::move(sticker->thumbnail_url_);
content_url = std::move(sticker->sticker_url_);
content_type =
"image/webp"; // or "application/x-tgsticker"/"video/webm"; not used for previously uploaded files
content_type = "image/webp"; // or "application/x-tgsticker"/"video/webm"; not used for previously uploaded files
width = sticker->sticker_width_;
height = sticker->sticker_height_;
is_gallery = true;
if (is_gallery != nullptr) {
*is_gallery = true;
}
if (content_url.find('.') != string::npos) {
return promise.set_error(Status::Error(400, "Wrong sticker_file_id specified"));
return Status::Error(400, "Wrong sticker_file_id specified");
}
file_type = FileType::Sticker;
@ -613,9 +632,9 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
break;
}
case td_api::inputInlineQueryResultVenue::ID: {
auto venue = move_tl_object_as<td_api::inputInlineQueryResultVenue>(input_result);
auto venue = move_tl_object_as<td_api::inputInlineQueryResultVenue>(result);
if (venue->venue_ == nullptr) {
return promise.set_error(Status::Error(400, "Venue must be non-empty"));
return Status::Error(400, "Venue must be non-empty");
}
type = "venue";
id = std::move(venue->id_);
@ -632,7 +651,7 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
break;
}
case td_api::inputInlineQueryResultVideo::ID: {
auto video = move_tl_object_as<td_api::inputInlineQueryResultVideo>(input_result);
auto video = move_tl_object_as<td_api::inputInlineQueryResultVideo>(result);
type = "video";
id = std::move(video->id_);
title = std::move(video->title_);
@ -650,7 +669,7 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
} else if (begins_with(content_type, "text/html")) {
content_type = "text/html";
} else {
return promise.set_error(Status::Error(400, "Unallowed video MIME type"));
return Status::Error(400, "Unallowed video MIME type");
}
}
@ -660,14 +679,16 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
break;
}
case td_api::inputInlineQueryResultVoiceNote::ID: {
auto voice_note = move_tl_object_as<td_api::inputInlineQueryResultVoiceNote>(input_result);
auto voice_note = move_tl_object_as<td_api::inputInlineQueryResultVoiceNote>(result);
type = "voice";
id = std::move(voice_note->id_);
title = std::move(voice_note->title_);
content_url = std::move(voice_note->voice_note_url_);
content_type = "audio/ogg";
duration = voice_note->voice_note_duration_;
force_vertical = true;
if (force_vertical != nullptr) {
*force_vertical = true;
}
file_type = FileType::VoiceNote;
r_inline_message = get_inline_message(std::move(voice_note->input_message_content_),
@ -679,11 +700,11 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
break;
}
if (r_inline_message.is_error()) {
return promise.set_error(r_inline_message.move_as_error());
return r_inline_message.move_as_error();
}
auto inline_message = r_inline_message.move_as_ok();
if (inline_message->get_id() == telegram_api::inputBotInlineMessageMediaAuto::ID && file_type == FileType::Temp) {
return promise.set_error(Status::Error(400, "Sent message content must be explicitly specified"));
return Status::Error(400, "Sent message content must be explicitly specified");
}
if (duration < 0) {
@ -694,13 +715,13 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
if (!title.empty()) {
flags |= telegram_api::inputBotInlineResult::TITLE_MASK;
if (!clean_input_string(title)) {
return promise.set_error(Status::Error(400, "Strings must be encoded in UTF-8"));
return Status::Error(400, "Strings must be encoded in UTF-8");
}
}
if (!description.empty()) {
flags |= telegram_api::inputBotInlineResult::DESCRIPTION_MASK;
if (!clean_input_string(description)) {
return promise.set_error(Status::Error(400, "Strings must be encoded in UTF-8"));
return Status::Error(400, "Strings must be encoded in UTF-8");
}
}
@ -708,60 +729,54 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
auto r_file_id = td_->file_manager_->get_input_file_id(
file_type, make_tl_object<td_api::inputFileRemote>(content_url), DialogId(), false, false);
if (r_file_id.is_error()) {
return promise.set_error(Status::Error(400, r_file_id.error().message()));
return Status::Error(400, r_file_id.error().message());
}
auto file_id = r_file_id.ok();
FileView file_view = td_->file_manager_->get_file_view(file_id);
CHECK(file_view.has_remote_location());
if (file_view.is_encrypted()) {
return promise.set_error(Status::Error(400, "Can't send encrypted file"));
return Status::Error(400, "Can't send encrypted file");
}
if (file_view.main_remote_location().is_web()) {
return promise.set_error(Status::Error(400, "Can't send web file"));
return Status::Error(400, "Can't send web file");
}
if (file_type == FileType::Photo) {
auto result = make_tl_object<telegram_api::inputBotInlineResultPhoto>(
return make_tl_object<telegram_api::inputBotInlineResultPhoto>(
id, type, file_view.main_remote_location().as_input_photo(), std::move(inline_message));
results.push_back(std::move(result));
continue;
}
auto result = make_tl_object<telegram_api::inputBotInlineResultDocument>(
return make_tl_object<telegram_api::inputBotInlineResultDocument>(
flags, id, type, title, description, file_view.main_remote_location().as_input_document(),
std::move(inline_message));
results.push_back(std::move(result));
continue;
}
if (!url.empty()) {
flags |= telegram_api::inputBotInlineResult::URL_MASK;
if (!clean_input_string(url)) {
return promise.set_error(Status::Error(400, "Strings must be encoded in UTF-8"));
return Status::Error(400, "Strings must be encoded in UTF-8");
}
}
tl_object_ptr<telegram_api::inputWebDocument> thumbnail;
if (!thumbnail_url.empty()) {
flags |= telegram_api::inputBotInlineResult::THUMB_MASK;
if (!clean_input_string(thumbnail_url)) {
return promise.set_error(Status::Error(400, "Strings must be encoded in UTF-8"));
return Status::Error(400, "Strings must be encoded in UTF-8");
}
vector<tl_object_ptr<telegram_api::DocumentAttribute>> attributes;
if (thumbnail_width > 0 && thumbnail_height > 0) {
attributes.push_back(
make_tl_object<telegram_api::documentAttributeImageSize>(thumbnail_width, thumbnail_height));
attributes.push_back(make_tl_object<telegram_api::documentAttributeImageSize>(thumbnail_width, thumbnail_height));
}
thumbnail =
make_tl_object<telegram_api::inputWebDocument>(thumbnail_url, 0, thumbnail_type, std::move(attributes));
thumbnail = make_tl_object<telegram_api::inputWebDocument>(thumbnail_url, 0, thumbnail_type, std::move(attributes));
}
tl_object_ptr<telegram_api::inputWebDocument> content;
if (!content_url.empty() || !content_type.empty()) {
flags |= telegram_api::inputBotInlineResult::CONTENT_MASK;
if (!clean_input_string(content_url)) {
return promise.set_error(Status::Error(400, "Strings must be encoded in UTF-8"));
return Status::Error(400, "Strings must be encoded in UTF-8");
}
if (!clean_input_string(content_type)) {
return promise.set_error(Status::Error(400, "Strings must be encoded in UTF-8"));
return Status::Error(400, "Strings must be encoded in UTF-8");
}
vector<tl_object_ptr<telegram_api::DocumentAttribute>> attributes;
@ -785,14 +800,8 @@ void InlineQueriesManager::answer_inline_query(int64 inline_query_id, bool is_pe
content = make_tl_object<telegram_api::inputWebDocument>(content_url, 0, content_type, std::move(attributes));
}
auto result = make_tl_object<telegram_api::inputBotInlineResult>(
return make_tl_object<telegram_api::inputBotInlineResult>(
flags, id, type, title, description, url, std::move(thumbnail), std::move(content), std::move(inline_message));
results.push_back(std::move(result));
}
td_->create_handler<SetInlineBotResultsQuery>(std::move(promise))
->send(inline_query_id, is_gallery && !force_vertical, is_personal, std::move(results), cache_time, next_offset,
switch_pm_text, switch_pm_parameter);
}
uint64 InlineQueriesManager::send_inline_query(UserId bot_user_id, DialogId dialog_id, Location user_location,

View File

@ -41,7 +41,7 @@ class InlineQueriesManager final : public Actor {
void after_get_difference();
void answer_inline_query(int64 inline_query_id, bool is_personal,
vector<tl_object_ptr<td_api::InputInlineQueryResult>> &&input_results, int32 cache_time,
vector<td_api::object_ptr<td_api::InputInlineQueryResult>> &&input_results, int32 cache_time,
const string &next_offset, const string &switch_pm_text, const string &switch_pm_parameter,
Promise<Unit> &&promise) const;
@ -85,6 +85,9 @@ class InlineQueriesManager final : public Actor {
static constexpr int32 BOT_INLINE_MEDIA_RESULT_FLAG_HAS_TITLE = 1 << 2;
static constexpr int32 BOT_INLINE_MEDIA_RESULT_FLAG_HAS_DESCRIPTION = 1 << 3;
Result<tl_object_ptr<telegram_api::InputBotInlineResult>> get_input_bot_inline_result(
td_api::object_ptr<td_api::InputInlineQueryResult> &&result, bool *is_gallery, bool *force_vertical) const;
Result<tl_object_ptr<telegram_api::InputBotInlineMessage>> get_inline_message(
tl_object_ptr<td_api::InputMessageContent> &&input_message_content,
tl_object_ptr<td_api::ReplyMarkup> &&reply_markup_ptr,