@ -237,6 +237,7 @@ 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 ) ;
@ -1960,6 +1961,29 @@ 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 ) {
@ -2100,8 +2124,13 @@ 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 : {
@ -2287,7 +2316,11 @@ 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 : {
@ -3935,7 +3968,11 @@ 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 ;
}
}
@ -4208,6 +4245,9 @@ 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_ ) ;
@ -8691,6 +8731,29 @@ 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_ ;
@ -11660,6 +11723,16 @@ 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 " ) ) ;
@ -11748,7 +11821,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 ! = " video" & &
if ( type ! = " animation " & & type ! = " photo " & & type ! = " live_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 " ) ;
}
}
@ -11780,8 +11853,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 ( 400 , PSLICE ( )
return td : : Status : : Error (
< < " Can't parse InputPollMedia: " < < r_input_message_content . error ( ) . message ( ) ) ;
400 , PSLICE ( ) < < " Failed to parse InputPollMedia: " < < r_input_message_content . error ( ) . message ( ) ) ;
}
}
return r_input_message_content . move_as_ok ( ) ;
return r_input_message_content . move_as_ok ( ) ;
}
}
@ -11842,6 +11915,13 @@ 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 " ) ) ;
@ -11986,7 +12066,8 @@ 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 ( const Query * query ) {
td : : Result < td : : vector < td_api : : object_ptr < td_api : : inputPollOption > > > Client : : get_input_poll_options (
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 ) ;
@ -12009,7 +12090,11 @@ 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 " ) ) ) ;
options . push_back ( make_object < td_api : : inputPollOption > ( std : : move ( option_text ) , nullptr ) ) ;
auto r_media = get_input_poll_media ( query , object . extract_field ( " media " ) , true ) ;
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 ;
}
}
@ -12905,6 +12990,25 @@ 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 ) {
@ -13062,6 +13166,7 @@ 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 " ) ) ;
@ -13087,7 +13192,8 @@ 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 ) , nullptr ) ;
poll_type = make_object < td_api : : inputPollTypeQuiz > ( std : : move ( correct_option_ids ) , std : : move ( explanation ) ,
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 {
@ -13104,8 +13210,9 @@ 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 ) , nullptr , is_anonymous ,
std : : move ( question ) , std : : move ( options ) , std : : move ( description ) , std : : move ( media ) , 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 ) ) ;