diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index b723afaa..e75562cd 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -735,6 +735,9 @@ keyboardButtonTypeRequestPhoneNumber = KeyboardButtonType; //@description A button that sends the user's location when pressed; available only in private chats keyboardButtonTypeRequestLocation = KeyboardButtonType; +//@description A button that allows the user to create and send a poll when pressed; available only in private chats @force_regular If true, only regular polls should be allowed to create @force_quiz If true, only quiz mode polls should be allowed to create +keyboardButtonTypeRequestPoll force_regular:Bool force_quiz:Bool = KeyboardButtonType; + //@description Represents a single button in a bot keyboard @text Text of the button @type Type of the button keyboardButton text:string type:KeyboardButtonType = KeyboardButton; @@ -1562,7 +1565,7 @@ inputMessageGame bot_user_id:int32 game_short_name:string = InputMessageContent; //@payload The invoice payload @provider_token Payment provider token @provider_data JSON-encoded data about the invoice, which will be shared with the payment provider @start_parameter Unique invoice bot start_parameter for the generation of this invoice inputMessageInvoice invoice:invoice title:string description:string photo_url:string photo_size:int32 photo_width:int32 photo_height:int32 payload:bytes provider_token:string provider_data:string start_parameter:string = InputMessageContent; -//@description A message with a poll. Polls can't be sent to secret chats. Polls can be sent to private chats only by bots @question Poll question, 1-255 characters @options List of poll answer options, 2-10 strings 1-100 characters each +//@description A message with a poll. Polls can't be sent to secret chats. Polls can be sent to private chats if this is a private chat with self or with a bot only @question Poll question, 1-255 characters @options List of poll answer options, 2-10 strings 1-100 characters each //@is_anonymous True, if the poll voters are anonymous. Non-anonymous polls can't be sent or forwarded to channels @type Type of the poll inputMessagePoll question:string options:vector is_anonymous:Bool type:PollType = InputMessageContent; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 834e884c..93fb7bae 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/generate/scheme/telegram_api.tl b/td/generate/scheme/telegram_api.tl index c4e1a6e5..7ab7dd1c 100644 --- a/td/generate/scheme/telegram_api.tl +++ b/td/generate/scheme/telegram_api.tl @@ -534,6 +534,7 @@ keyboardButtonGame#50f41ccf text:string = KeyboardButton; keyboardButtonBuy#afd93fbb text:string = KeyboardButton; keyboardButtonUrlAuth#10b78d29 flags:# text:string fwd_text:flags.0?string url:string button_id:int = KeyboardButton; inputKeyboardButtonUrlAuth#d02e7fd4 flags:# request_write_access:flags.0?true text:string fwd_text:flags.1?string url:string bot:InputUser = KeyboardButton; +keyboardButtonRequestPoll#bbc7515d flags:# quiz:flags.0?Bool text:string = KeyboardButton; keyboardButtonRow#77608b83 buttons:Vector = KeyboardButtonRow; diff --git a/td/generate/scheme/telegram_api.tlo b/td/generate/scheme/telegram_api.tlo index fc67277c..c45d531d 100644 Binary files a/td/generate/scheme/telegram_api.tlo and b/td/generate/scheme/telegram_api.tlo differ diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 35e6a3a8..7754abf8 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -17785,8 +17785,9 @@ Status MessagesManager::can_send_message_content(DialogId dialog_id, const Messa auto content_type = content->get_type(); switch (dialog_type) { case DialogType::User: - if (content_type == MessageContentType::Poll && !is_forward && !td_->auth_manager_->is_bot() && !is_via_bot) { - return Status::Error(400, "Polls can't be sent to private chats"); + if (content_type == MessageContentType::Poll && !is_forward && !td_->auth_manager_->is_bot() && !is_via_bot && + !td_->contacts_manager_->is_user_bot(dialog_id.get_user_id()) && dialog_id != get_my_dialog_id()) { + return Status::Error(400, "Polls can't be sent to the private chat"); } break; case DialogType::Chat: diff --git a/td/telegram/ReplyMarkup.cpp b/td/telegram/ReplyMarkup.cpp index 3fddb1b8..65deae1a 100644 --- a/td/telegram/ReplyMarkup.cpp +++ b/td/telegram/ReplyMarkup.cpp @@ -41,6 +41,15 @@ static StringBuilder &operator<<(StringBuilder &string_builder, const KeyboardBu case KeyboardButton::Type::RequestLocation: string_builder << "RequestLocation"; break; + case KeyboardButton::Type::RequestPoll: + string_builder << "RequestPoll"; + break; + case KeyboardButton::Type::RequestPollQuiz: + string_builder << "RequestPollQuiz"; + break; + case KeyboardButton::Type::RequestPollRegular: + string_builder << "RequestPollRegular"; + break; default: UNREACHABLE(); } @@ -175,6 +184,20 @@ static KeyboardButton get_keyboard_button(tl_object_ptrtext_); break; } + case telegram_api::keyboardButtonRequestPoll::ID: { + auto keyboard_button = move_tl_object_as(keyboard_button_ptr); + if (keyboard_button->flags_ & telegram_api::keyboardButtonRequestPoll::QUIZ_MASK) { + if (keyboard_button->quiz_) { + button.type = KeyboardButton::Type::RequestPollQuiz; + } else { + button.type = KeyboardButton::Type::RequestPollRegular; + } + } else { + button.type = KeyboardButton::Type::RequestPoll; + } + button.text = std::move(keyboard_button->text_); + break; + } default: LOG(ERROR) << "Unsupported keyboard button: " << to_string(keyboard_button_ptr); } @@ -346,16 +369,33 @@ static Result get_keyboard_button(tl_object_ptr(button->type_.get()); + if (request_poll->force_quiz_ && request_poll->force_regular_) { + return Status::Error(400, "Can't force quiz mode and regular poll simultaneously"); + } + if (request_poll->force_quiz_) { + current_button.type = KeyboardButton::Type::RequestPollQuiz; + } else if (request_poll->force_regular_) { + current_button.type = KeyboardButton::Type::RequestPollRegular; + } else { + current_button.type = KeyboardButton::Type::RequestPoll; + } + break; + } default: UNREACHABLE(); } @@ -560,6 +600,12 @@ static tl_object_ptr get_keyboard_button(const Key return make_tl_object(keyboard_button.text); case KeyboardButton::Type::RequestLocation: return make_tl_object(keyboard_button.text); + case KeyboardButton::Type::RequestPoll: + return make_tl_object(0, false, keyboard_button.text); + case KeyboardButton::Type::RequestPollQuiz: + return make_tl_object(1, true, keyboard_button.text); + case KeyboardButton::Type::RequestPollRegular: + return make_tl_object(1, false, keyboard_button.text); default: UNREACHABLE(); return nullptr; @@ -674,6 +720,15 @@ static tl_object_ptr get_keyboard_button_object(const Ke case KeyboardButton::Type::RequestLocation: type = make_tl_object(); break; + case KeyboardButton::Type::RequestPoll: + type = make_tl_object(false, false); + break; + case KeyboardButton::Type::RequestPollQuiz: + type = make_tl_object(false, true); + break; + case KeyboardButton::Type::RequestPollRegular: + type = make_tl_object(true, false); + break; default: UNREACHABLE(); return nullptr; diff --git a/td/telegram/ReplyMarkup.h b/td/telegram/ReplyMarkup.h index 5f999aad..79e15f57 100644 --- a/td/telegram/ReplyMarkup.h +++ b/td/telegram/ReplyMarkup.h @@ -17,7 +17,14 @@ namespace td { struct KeyboardButton { // append only - enum class Type : int32 { Text, RequestPhoneNumber, RequestLocation }; + enum class Type : int32 { + Text, + RequestPhoneNumber, + RequestLocation, + RequestPoll, + RequestPollQuiz, + RequestPollRegular + }; Type type; string text; };