Compare commits

..

No commits in common. '45446e175218efb68536d90689b35ace5b716881' and '25e4994382ef07c8d0d061b42e89a65fae9f595e' have entirely different histories.

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.10 FATAL_ERROR) cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(TelegramBotApi VERSION 10.0 LANGUAGES CXX) project(TelegramBotApi VERSION 9.6 LANGUAGES CXX)
add_subdirectory(td EXCLUDE_FROM_ALL) add_subdirectory(td EXCLUDE_FROM_ALL)

@ -237,7 +237,6 @@ bool Client::init_methods() {
methods_.emplace("sendaudio", &Client::process_send_audio_query); methods_.emplace("sendaudio", &Client::process_send_audio_query);
methods_.emplace("senddice", &Client::process_send_dice_query); methods_.emplace("senddice", &Client::process_send_dice_query);
methods_.emplace("senddocument", &Client::process_send_document_query); methods_.emplace("senddocument", &Client::process_send_document_query);
methods_.emplace("sendlivephoto", &Client::process_send_live_photo_query);
methods_.emplace("sendphoto", &Client::process_send_photo_query); methods_.emplace("sendphoto", &Client::process_send_photo_query);
methods_.emplace("sendsticker", &Client::process_send_sticker_query); methods_.emplace("sendsticker", &Client::process_send_sticker_query);
methods_.emplace("sendvideo", &Client::process_send_video_query); methods_.emplace("sendvideo", &Client::process_send_video_query);
@ -1961,29 +1960,6 @@ class Client::JsonPhoto final : public td::Jsonable {
const Client *client_; const Client *client_;
}; };
class Client::JsonLivePhoto final : public td::Jsonable {
public:
JsonLivePhoto(const td_api::photo *photo, const td_api::video *video, const Client *client)
: photo_(photo), video_(video), client_(client) {
}
void store(td::JsonValueScope *scope) const {
auto object = scope->enter_object();
object("photo", JsonPhoto(photo_, client_));
object("duration", video_->duration_);
object("width", video_->width_);
object("height", video_->height_);
if (!video_->mime_type_.empty()) {
object("mime_type", video_->mime_type_);
}
client_->json_store_file(object, video_->video_.get());
}
private:
const td_api::photo *photo_;
const td_api::video *video_;
const Client *client_;
};
class Client::JsonChatPhoto final : public td::Jsonable { class Client::JsonChatPhoto final : public td::Jsonable {
public: public:
JsonChatPhoto(const td_api::chatPhoto *photo, const Client *client) : photo_(photo), client_(client) { JsonChatPhoto(const td_api::chatPhoto *photo, const Client *client) : photo_(photo), client_(client) {
@ -2124,13 +2100,8 @@ class Client::JsonPaidMedia final : public td::Jsonable {
} }
case td_api::paidMediaPhoto::ID: { case td_api::paidMediaPhoto::ID: {
auto media = static_cast<const td_api::paidMediaPhoto *>(paid_media_); auto media = static_cast<const td_api::paidMediaPhoto *>(paid_media_);
if (media->video_ != nullptr) {
object("type", "live_photo");
object("live_photo", JsonLivePhoto(media->photo_.get(), media->video_.get(), client_));
} else {
object("type", "photo"); object("type", "photo");
object("photo", JsonPhoto(media->photo_.get(), client_)); object("photo", JsonPhoto(media->photo_.get(), client_));
}
break; break;
} }
case td_api::paidMediaVideo::ID: { case td_api::paidMediaVideo::ID: {
@ -2316,11 +2287,7 @@ class Client::JsonPollMedia final : public td::Jsonable {
} }
case td_api::messagePhoto::ID: { case td_api::messagePhoto::ID: {
auto content = static_cast<const td_api::messagePhoto *>(content_); auto content = static_cast<const td_api::messagePhoto *>(content_);
if (content->video_ != nullptr) {
object("live_photo", JsonLivePhoto(content->photo_.get(), content->video_.get(), client_));
} else {
object("photo", JsonPhoto(content->photo_.get(), client_)); object("photo", JsonPhoto(content->photo_.get(), client_));
}
break; break;
} }
case td_api::messageSticker::ID: { case td_api::messageSticker::ID: {
@ -3968,11 +3935,7 @@ class Client::JsonExternalReplyInfo final : public td::Jsonable {
case td_api::messagePhoto::ID: { case td_api::messagePhoto::ID: {
auto content = static_cast<const td_api::messagePhoto *>(reply_->content_.get()); auto content = static_cast<const td_api::messagePhoto *>(reply_->content_.get());
CHECK(content->photo_ != nullptr); CHECK(content->photo_ != nullptr);
if (content->video_ != nullptr) {
object("live_photo", JsonLivePhoto(content->photo_.get(), content->video_.get(), client_));
} else {
object("photo", JsonPhoto(content->photo_.get(), client_)); object("photo", JsonPhoto(content->photo_.get(), client_));
}
add_media_spoiler(object, content->has_spoiler_); add_media_spoiler(object, content->has_spoiler_);
break; break;
} }
@ -4245,9 +4208,6 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
case td_api::messagePhoto::ID: { case td_api::messagePhoto::ID: {
auto content = static_cast<const td_api::messagePhoto *>(message_->content.get()); auto content = static_cast<const td_api::messagePhoto *>(message_->content.get());
CHECK(content->photo_ != nullptr); CHECK(content->photo_ != nullptr);
if (content->video_ != nullptr) {
object("live_photo", JsonLivePhoto(content->photo_.get(), content->video_.get(), client_));
}
object("photo", JsonPhoto(content->photo_.get(), client_)); object("photo", JsonPhoto(content->photo_.get(), client_));
add_caption(object, content->caption_, content->show_caption_above_media_); add_caption(object, content->caption_, content->show_caption_above_media_);
add_media_spoiler(object, content->has_spoiler_); add_media_spoiler(object, content->has_spoiler_);
@ -8731,29 +8691,6 @@ void Client::on_update_authorization_state() {
td::make_unique<TdOnOkCallback>()); td::make_unique<TdOnOkCallback>());
} }
if (parameters_->td_proxy_.type != TdProxyType::None) {
const auto &p = parameters_->td_proxy_;
object_ptr<td_api::ProxyType> type;
switch (p.type) {
case TdProxyType::Socks5:
type = make_object<td_api::proxyTypeSocks5>(p.username, p.password);
break;
case TdProxyType::Http:
type = make_object<td_api::proxyTypeHttp>(p.username, p.password, p.http_only);
break;
case TdProxyType::Mtproto:
type = make_object<td_api::proxyTypeMtproto>(p.secret);
break;
default:
break;
}
if (type != nullptr) {
auto proxy = make_object<td_api::proxy>(p.server, p.port, std::move(type));
send_request(make_object<td_api::addProxy>(std::move(proxy), true, "telegram-bot-api --td-proxy"),
td::make_unique<TdOnOkCallback>());
}
}
auto request = make_object<td_api::setTdlibParameters>(); auto request = make_object<td_api::setTdlibParameters>();
request->use_test_dc_ = is_test_dc_; request->use_test_dc_ = is_test_dc_;
request->database_directory_ = dir_; request->database_directory_ = dir_;
@ -11723,16 +11660,6 @@ td::Result<td_api::object_ptr<td_api::InputMessageContent>> Client::get_input_me
return make_object<td_api::inputMessagePhoto>(std::move(input_file), nullptr, nullptr, td::vector<int32>(), 0, 0, return make_object<td_api::inputMessagePhoto>(std::move(input_file), nullptr, nullptr, td::vector<int32>(), 0, 0,
std::move(caption), show_caption_above_media, nullptr, has_spoiler); std::move(caption), show_caption_above_media, nullptr, has_spoiler);
} }
if (type == "live_photo") {
TRY_RESULT(photo, object.get_optional_string_field("photo"));
auto input_photo = get_input_file(query, td::Slice(), photo, false);
if (input_photo == nullptr) {
return td::Status::Error("photo not found");
}
return make_object<td_api::inputMessagePhoto>(std::move(input_photo), nullptr, std::move(input_file),
td::vector<int32>(), 0, 0, std::move(caption),
show_caption_above_media, nullptr, has_spoiler);
}
if (type == "video") { if (type == "video") {
TRY_RESULT(width, object.get_optional_int_field("width")); TRY_RESULT(width, object.get_optional_int_field("width"));
TRY_RESULT(height, object.get_optional_int_field("height")); TRY_RESULT(height, object.get_optional_int_field("height"));
@ -11821,7 +11748,7 @@ td::Result<td_api::object_ptr<td_api::InputMessageContent>> Client::get_input_po
TRY_RESULT(venue, get_venue(object)); TRY_RESULT(venue, get_venue(object));
return make_object<td_api::inputMessageVenue>(std::move(venue)); return make_object<td_api::inputMessageVenue>(std::move(venue));
} }
if (type != "animation" && type != "photo" && type != "live_photo" && type != "video" && if (type != "animation" && type != "photo" && type != "video" &&
(for_option ? type != "sticker" : type != "audio" && type != "document")) { (for_option ? type != "sticker" : type != "audio" && type != "document")) {
return td::Status::Error("invalid type specified"); return td::Status::Error("invalid type specified");
} }
@ -11853,8 +11780,8 @@ td::Result<td_api::object_ptr<td_api::InputMessageContent>> Client::get_input_po
auto r_input_message_content = get_input_poll_media(query, r_value.move_as_ok(), false); auto r_input_message_content = get_input_poll_media(query, r_value.move_as_ok(), false);
if (r_input_message_content.is_error()) { if (r_input_message_content.is_error()) {
return td::Status::Error( return td::Status::Error(400, PSLICE()
400, PSLICE() << "Failed to parse InputPollMedia: " << r_input_message_content.error().message()); << "Can't parse InputPollMedia: " << r_input_message_content.error().message());
} }
return r_input_message_content.move_as_ok(); return r_input_message_content.move_as_ok();
} }
@ -11915,13 +11842,6 @@ td::Result<td_api::object_ptr<td_api::inputPaidMedia>> Client::get_input_paid_me
TRY_RESULT(type, object.get_required_string_field("type")); TRY_RESULT(type, object.get_required_string_field("type"));
if (type == "photo") { if (type == "photo") {
media_type = make_object<td_api::inputPaidMediaTypePhoto>(nullptr); media_type = make_object<td_api::inputPaidMediaTypePhoto>(nullptr);
} else if (type == "live_photo") {
TRY_RESULT(photo, object.get_optional_string_field("photo"));
media_type = make_object<td_api::inputPaidMediaTypePhoto>(std::move(input_file));
input_file = get_input_file(query, "photo", photo, false);
if (input_file == nullptr) {
return td::Status::Error("photo not found");
}
} else if (type == "video") { } else if (type == "video") {
TRY_RESULT(duration, object.get_optional_int_field("duration")); TRY_RESULT(duration, object.get_optional_int_field("duration"));
TRY_RESULT(supports_streaming, object.get_optional_bool_field("supports_streaming")); TRY_RESULT(supports_streaming, object.get_optional_bool_field("supports_streaming"));
@ -12066,8 +11986,7 @@ td::Result<td_api::object_ptr<td_api::inputMessageInvoice>> Client::get_input_me
std::move(paid_media_caption)); std::move(paid_media_caption));
} }
td::Result<td::vector<td_api::object_ptr<td_api::inputPollOption>>> Client::get_input_poll_options( td::Result<td::vector<td_api::object_ptr<td_api::inputPollOption>>> Client::get_input_poll_options(const Query *query) {
const Query *query) const {
auto input_options = query->arg("options"); auto input_options = query->arg("options");
LOG(INFO) << "Parsing JSON object: " << input_options; LOG(INFO) << "Parsing JSON object: " << input_options;
auto r_value = json_decode(input_options); auto r_value = json_decode(input_options);
@ -12090,11 +12009,7 @@ td::Result<td::vector<td_api::object_ptr<td_api::inputPollOption>>> Client::get_
TRY_RESULT(parse_mode, object.get_optional_string_field("text_parse_mode")); TRY_RESULT(parse_mode, object.get_optional_string_field("text_parse_mode"));
TRY_RESULT(option_text, TRY_RESULT(option_text,
get_formatted_text(std::move(text), std::move(parse_mode), object.extract_field("text_entities"))); get_formatted_text(std::move(text), std::move(parse_mode), object.extract_field("text_entities")));
auto r_media = get_input_poll_media(query, object.extract_field("media"), true); options.push_back(make_object<td_api::inputPollOption>(std::move(option_text), nullptr));
if (r_media.is_error()) {
return td::Status::Error(400, PSLICE() << "Failed to parse poll option media: " << r_media.error().message());
}
options.push_back(make_object<td_api::inputPollOption>(std::move(option_text), r_media.move_as_ok()));
continue; continue;
} }
@ -12990,25 +12905,6 @@ td::Status Client::process_send_photo_query(PromisedQueryPtr &query) {
return td::Status::OK(); return td::Status::OK();
} }
td::Status Client::process_send_live_photo_query(PromisedQueryPtr &query) {
auto live_photo = get_input_file(query.get(), "live_photo");
if (live_photo == nullptr) {
return td::Status::Error(400, "There is no live photo in the request");
}
auto photo = get_input_file(query.get(), "photo");
if (photo == nullptr) {
return td::Status::Error(400, "There is no photo in the request");
}
TRY_RESULT(caption, get_caption(query.get()));
auto show_caption_above_media = to_bool(query->arg("show_caption_above_media"));
auto has_spoiler = to_bool(query->arg("has_spoiler"));
do_send_message(
make_object<td_api::inputMessagePhoto>(std::move(photo), nullptr, std::move(live_photo), td::vector<int32>(), 0,
0, std::move(caption), show_caption_above_media, nullptr, has_spoiler),
std::move(query));
return td::Status::OK();
}
td::Status Client::process_send_sticker_query(PromisedQueryPtr &query) { td::Status Client::process_send_sticker_query(PromisedQueryPtr &query) {
auto sticker = get_input_file(query.get(), "sticker"); auto sticker = get_input_file(query.get(), "sticker");
if (sticker == nullptr) { if (sticker == nullptr) {
@ -13166,7 +13062,6 @@ td::Status Client::process_send_poll_query(PromisedQueryPtr &query) {
TRY_RESULT(explanation, TRY_RESULT(explanation,
get_formatted_text(query->arg("explanation").str(), query->arg("explanation_parse_mode").str(), get_formatted_text(query->arg("explanation").str(), query->arg("explanation_parse_mode").str(),
get_input_entities(query.get(), "explanation_entities"))); get_input_entities(query.get(), "explanation_entities")));
TRY_RESULT(explanation_media, get_input_poll_media(query.get(), "explanation_media"));
td::vector<int32> correct_option_ids; td::vector<int32> correct_option_ids;
if (query->has_arg("correct_option_ids")) { if (query->has_arg("correct_option_ids")) {
auto r_value = json_decode(query->arg("correct_option_ids")); auto r_value = json_decode(query->arg("correct_option_ids"));
@ -13192,8 +13087,7 @@ td::Status Client::process_send_poll_query(PromisedQueryPtr &query) {
correct_option_ids.push_back(get_integer_arg(query.get(), "correct_option_id", -1)); correct_option_ids.push_back(get_integer_arg(query.get(), "correct_option_id", -1));
} }
poll_type = make_object<td_api::inputPollTypeQuiz>(std::move(correct_option_ids), std::move(explanation), poll_type = make_object<td_api::inputPollTypeQuiz>(std::move(correct_option_ids), std::move(explanation), nullptr);
std::move(explanation_media));
} else if (type.empty() || type == "regular") { } else if (type.empty() || type == "regular") {
poll_type = make_object<td_api::inputPollTypeRegular>(to_bool(query->arg("allow_adding_options"))); poll_type = make_object<td_api::inputPollTypeRegular>(to_bool(query->arg("allow_adding_options")));
} else { } else {
@ -13210,9 +13104,8 @@ td::Status Client::process_send_poll_query(PromisedQueryPtr &query) {
auto hide_results_until_closes = to_bool(query->arg("hide_results_until_closes")); auto hide_results_until_closes = to_bool(query->arg("hide_results_until_closes"));
auto members_only = to_bool(query->arg("members_only")); auto members_only = to_bool(query->arg("members_only"));
TRY_RESULT(country_codes, get_strings(query.get(), 12, "country_codes")); TRY_RESULT(country_codes, get_strings(query.get(), 12, "country_codes"));
TRY_RESULT(media, get_input_poll_media(query.get(), "media"));
do_send_message(make_object<td_api::inputMessagePoll>( do_send_message(make_object<td_api::inputMessagePoll>(
std::move(question), std::move(options), std::move(description), std::move(media), is_anonymous, std::move(question), std::move(options), std::move(description), nullptr, is_anonymous,
allows_multiple_answers, allows_revoting, members_only, std::move(country_codes), shuffle_options, allows_multiple_answers, allows_revoting, members_only, std::move(country_codes), shuffle_options,
hide_results_until_closes, std::move(poll_type), open_period, close_date, is_closed), hide_results_until_closes, std::move(poll_type), open_period, close_date, is_closed),
std::move(query)); std::move(query));

@ -117,7 +117,6 @@ class Client final : public WebhookActor::Callback {
class JsonDocument; class JsonDocument;
class JsonPhotoSize; class JsonPhotoSize;
class JsonPhoto; class JsonPhoto;
class JsonLivePhoto;
class JsonChatPhoto; class JsonChatPhoto;
class JsonThumbnail; class JsonThumbnail;
class JsonMaskPosition; class JsonMaskPosition;
@ -709,7 +708,7 @@ class Client final : public WebhookActor::Callback {
bool disable_notification, bool protect_content, bool allow_paid_broadcast, int64 effect_id, bool disable_notification, bool protect_content, bool allow_paid_broadcast, int64 effect_id,
object_ptr<td_api::inputSuggestedPostInfo> &&input_suggested_post_info); object_ptr<td_api::inputSuggestedPostInfo> &&input_suggested_post_info);
td::Result<td::vector<object_ptr<td_api::inputPollOption>>> get_input_poll_options(const Query *query) const; static td::Result<td::vector<object_ptr<td_api::inputPollOption>>> get_input_poll_options(const Query *query);
static td::Result<object_ptr<td_api::ReactionType>> get_reaction_type(td::JsonValue &&value); static td::Result<object_ptr<td_api::ReactionType>> get_reaction_type(td::JsonValue &&value);
@ -798,7 +797,6 @@ class Client final : public WebhookActor::Callback {
td::Status process_send_audio_query(PromisedQueryPtr &query); td::Status process_send_audio_query(PromisedQueryPtr &query);
td::Status process_send_dice_query(PromisedQueryPtr &query); td::Status process_send_dice_query(PromisedQueryPtr &query);
td::Status process_send_document_query(PromisedQueryPtr &query); td::Status process_send_document_query(PromisedQueryPtr &query);
td::Status process_send_live_photo_query(PromisedQueryPtr &query);
td::Status process_send_photo_query(PromisedQueryPtr &query); td::Status process_send_photo_query(PromisedQueryPtr &query);
td::Status process_send_sticker_query(PromisedQueryPtr &query); td::Status process_send_sticker_query(PromisedQueryPtr &query);
td::Status process_send_video_query(PromisedQueryPtr &query); td::Status process_send_video_query(PromisedQueryPtr &query);

@ -103,18 +103,6 @@ struct SharedData {
} }
}; };
enum class TdProxyType { None, Socks5, Http, Mtproto };
struct TdProxyParameters {
TdProxyType type = TdProxyType::None;
td::string server;
td::int32 port = 0;
td::string username;
td::string password;
td::string secret; // for Mtproto
bool http_only = false; // for Http: route only HTTP, not TCP-tunneled MTProto
};
struct ClientParameters { struct ClientParameters {
td::string working_directory_; td::string working_directory_;
bool allow_colon_in_filenames_ = true; bool allow_colon_in_filenames_ = true;
@ -129,8 +117,6 @@ struct ClientParameters {
td::int32 default_max_webhook_connections_ = 0; td::int32 default_max_webhook_connections_ = 0;
td::IPAddress webhook_proxy_ip_address_; td::IPAddress webhook_proxy_ip_address_;
TdProxyParameters td_proxy_;
double start_time_ = 0; double start_time_ = 0;
td::ActorId<td::GetHostByNameActor> get_host_by_name_actor_id_; td::ActorId<td::GetHostByNameActor> get_host_by_name_actor_id_;

@ -165,7 +165,7 @@ int main(int argc, char *argv[]) {
auto start_time = td::Time::now(); auto start_time = td::Time::now();
auto shared_data = std::make_shared<SharedData>(); auto shared_data = std::make_shared<SharedData>();
auto parameters = std::make_unique<ClientParameters>(); auto parameters = std::make_unique<ClientParameters>();
parameters->version_ = "10.0"; parameters->version_ = "9.6";
parameters->shared_data_ = shared_data; parameters->shared_data_ = shared_data;
parameters->start_time_ = start_time; parameters->start_time_ = start_time;
auto net_query_stats = td::create_net_query_stats(); auto net_query_stats = td::create_net_query_stats();
@ -298,64 +298,6 @@ int main(int argc, char *argv[]) {
} }
return parameters->webhook_proxy_ip_address_.init_host_port(address.str()); return parameters->webhook_proxy_ip_address_.init_host_port(address.str());
}); });
options.add_checked_option(
'\0', "td-proxy",
"proxy for connections to Telegram MTProto servers; supported schemes: "
"socks5://[user:pass@]host:port, socks5h://[user:pass@]host:port (same as socks5 — DNS is always remote), "
"http://[user:pass@]host:port (CONNECT-capable), mtproto://secret@host:port (secret in hex)",
[&](td::Slice url) {
TdProxyParameters &p = parameters->td_proxy_;
if (td::begins_with(url, "socks5h://")) {
p.type = TdProxyType::Socks5;
url.remove_prefix(10);
} else if (td::begins_with(url, "socks5://")) {
p.type = TdProxyType::Socks5;
url.remove_prefix(9);
} else if (td::begins_with(url, "http://")) {
p.type = TdProxyType::Http;
url.remove_prefix(7);
} else if (td::begins_with(url, "mtproto://")) {
p.type = TdProxyType::Mtproto;
url.remove_prefix(10);
} else {
return td::Status::Error("--td-proxy: unsupported scheme (use socks5://, socks5h://, http:// or mtproto://)");
}
auto at_pos = url.rfind('@');
td::Slice userinfo;
td::Slice hostport = url;
if (at_pos != td::Slice::npos) {
userinfo = url.substr(0, at_pos);
hostport = url.substr(at_pos + 1);
}
auto colon_pos = hostport.rfind(':');
if (colon_pos == td::Slice::npos) {
return td::Status::Error("--td-proxy: missing port (host:port)");
}
p.server = hostport.substr(0, colon_pos).str();
TRY_RESULT(port, td::to_integer_safe<td::int32>(hostport.substr(colon_pos + 1)));
if (port <= 0 || port > 65535) {
return td::Status::Error("--td-proxy: invalid port");
}
p.port = port;
if (p.server.empty()) {
return td::Status::Error("--td-proxy: empty host");
}
if (p.type == TdProxyType::Mtproto) {
if (userinfo.empty()) {
return td::Status::Error("--td-proxy: mtproto proxy requires a secret (mtproto://SECRET@host:port)");
}
p.secret = userinfo.str();
} else if (!userinfo.empty()) {
auto user_colon = userinfo.find(':');
if (user_colon == td::Slice::npos) {
p.username = userinfo.str();
} else {
p.username = userinfo.substr(0, user_colon).str();
p.password = userinfo.substr(user_colon + 1).str();
}
}
return td::Status::OK();
});
options.add_check([&] { options.add_check([&] {
if (parameters->api_id_ <= 0 || parameters->api_hash_.empty()) { if (parameters->api_id_ <= 0 || parameters->api_hash_.empty()) {
return td::Status::Error("You must provide valid api-id and api-hash obtained at https://my.telegram.org"); return td::Status::Error("You must provide valid api-id and api-hash obtained at https://my.telegram.org");

Loading…
Cancel
Save