Add class InputInvoice.

This commit is contained in:
levlam 2021-03-31 01:20:40 +03:00
parent f1b949456b
commit b9bc86fb5a
4 changed files with 324 additions and 279 deletions

View File

@ -469,34 +469,10 @@ class MessageCall : public MessageContent {
class MessageInvoice : public MessageContent {
public:
string title;
string description;
Photo photo;
string start_parameter;
// InputMessageInvoice
Invoice invoice;
string payload;
string provider_token;
string provider_data;
// MessageInvoice
int64 total_amount = 0;
MessageId receipt_message_id;
InputInvoice input_invoice;
MessageInvoice() = default;
MessageInvoice(string &&title, string &&description, Photo &&photo, string &&start_parameter, int64 total_amount,
string &&currency, bool is_test, bool need_shipping_address, MessageId receipt_message_id)
: title(std::move(title))
, description(std::move(description))
, photo(std::move(photo))
, start_parameter(std::move(start_parameter))
, invoice(std::move(currency), is_test, need_shipping_address)
, payload()
, provider_token()
, provider_data()
, total_amount(total_amount)
, receipt_message_id(receipt_message_id) {
explicit MessageInvoice(InputInvoice &&input_invoice) : input_invoice(std::move(input_invoice)) {
}
MessageContentType get_type() const override {
@ -782,16 +758,7 @@ static void store(const MessageContent *content, StorerT &storer) {
}
case MessageContentType::Invoice: {
auto m = static_cast<const MessageInvoice *>(content);
store(m->title, storer);
store(m->description, storer);
store(m->photo, storer);
store(m->start_parameter, storer);
store(m->invoice, storer);
store(m->payload, storer);
store(m->provider_token, storer);
store(m->provider_data, storer);
store(m->total_amount, storer);
store(m->receipt_message_id, storer);
store(m->input_invoice, storer);
break;
}
case MessageContentType::LiveLocation: {
@ -1100,20 +1067,7 @@ static void parse(unique_ptr<MessageContent> &content, ParserT &parser) {
}
case MessageContentType::Invoice: {
auto m = make_unique<MessageInvoice>();
parse(m->title, parser);
parse(m->description, parser);
parse(m->photo, parser);
parse(m->start_parameter, parser);
parse(m->invoice, parser);
parse(m->payload, parser);
parse(m->provider_token, parser);
if (parser.version() >= static_cast<int32>(Version::AddMessageInvoiceProviderData)) {
parse(m->provider_data, parser);
} else {
m->provider_data.clear();
}
parse(m->total_amount, parser);
parse(m->receipt_message_id, parser);
parse(m->input_invoice, parser);
content = std::move(m);
break;
}
@ -1812,116 +1766,9 @@ static Result<InputMessageContent> create_input_message_content(
return Status::Error(400, "Invoices can be sent only by bots");
}
auto input_invoice = move_tl_object_as<td_api::inputMessageInvoice>(input_message_content);
if (!clean_input_string(input_invoice->title_)) {
return Status::Error(400, "Invoice title must be encoded in UTF-8");
}
if (!clean_input_string(input_invoice->description_)) {
return Status::Error(400, "Invoice description must be encoded in UTF-8");
}
if (!clean_input_string(input_invoice->photo_url_)) {
return Status::Error(400, "Invoice photo URL must be encoded in UTF-8");
}
if (!clean_input_string(input_invoice->start_parameter_)) {
return Status::Error(400, "Invoice bot start parameter must be encoded in UTF-8");
}
if (!clean_input_string(input_invoice->provider_token_)) {
return Status::Error(400, "Invoice provider token must be encoded in UTF-8");
}
if (!clean_input_string(input_invoice->provider_data_)) {
return Status::Error(400, "Invoice provider data must be encoded in UTF-8");
}
if (!clean_input_string(input_invoice->invoice_->currency_)) {
return Status::Error(400, "Invoice currency must be encoded in UTF-8");
}
auto message_invoice = make_unique<MessageInvoice>();
message_invoice->title = std::move(input_invoice->title_);
message_invoice->description = std::move(input_invoice->description_);
auto r_http_url = parse_url(input_invoice->photo_url_);
if (r_http_url.is_error()) {
if (!input_invoice->photo_url_.empty()) {
LOG(INFO) << "Can't register url " << input_invoice->photo_url_;
}
} else {
auto url = r_http_url.ok().get_url();
auto r_invoice_file_id = td->file_manager_->from_persistent_id(url, FileType::Temp);
if (r_invoice_file_id.is_error()) {
LOG(INFO) << "Can't register url " << url;
} else {
auto invoice_file_id = r_invoice_file_id.move_as_ok();
PhotoSize s;
s.type = 'n';
s.dimensions =
get_dimensions(input_invoice->photo_width_, input_invoice->photo_height_, "inputMessageInvoice");
s.size = input_invoice->photo_size_; // TODO use invoice_file_id size
s.file_id = invoice_file_id;
message_invoice->photo.id = 0;
message_invoice->photo.photos.push_back(s);
}
}
message_invoice->start_parameter = std::move(input_invoice->start_parameter_);
message_invoice->invoice.currency = std::move(input_invoice->invoice_->currency_);
message_invoice->invoice.price_parts.reserve(input_invoice->invoice_->price_parts_.size());
int64 total_amount = 0;
const int64 MAX_AMOUNT = 9999'9999'9999;
for (auto &price : input_invoice->invoice_->price_parts_) {
if (!clean_input_string(price->label_)) {
return Status::Error(400, "Invoice price label must be encoded in UTF-8");
}
message_invoice->invoice.price_parts.emplace_back(std::move(price->label_), price->amount_);
if (price->amount_ < -MAX_AMOUNT || price->amount_ > MAX_AMOUNT) {
return Status::Error(400, "Too big amount of the currency specified");
}
total_amount += price->amount_;
}
if (total_amount <= 0) {
return Status::Error(400, "Total price must be positive");
}
if (total_amount > MAX_AMOUNT) {
return Status::Error(400, "Total price is too big");
}
message_invoice->total_amount = total_amount;
if (input_invoice->invoice_->max_tip_amount_ < 0 || input_invoice->invoice_->max_tip_amount_ > MAX_AMOUNT) {
return Status::Error(400, "Invalid max tip amount of the currency specified");
}
for (auto tip_amount : input_invoice->invoice_->suggested_tip_amounts_) {
if (tip_amount < 0 || tip_amount > input_invoice->invoice_->max_tip_amount_) {
return Status::Error(400, "Invalid suggested tip amount of the currency specified");
}
}
message_invoice->invoice.max_tip_amount = input_invoice->invoice_->max_tip_amount_;
message_invoice->invoice.suggested_tip_amounts = std::move(input_invoice->invoice_->suggested_tip_amounts_);
message_invoice->invoice.is_test = input_invoice->invoice_->is_test_;
message_invoice->invoice.need_name = input_invoice->invoice_->need_name_;
message_invoice->invoice.need_phone_number = input_invoice->invoice_->need_phone_number_;
message_invoice->invoice.need_email_address = input_invoice->invoice_->need_email_address_;
message_invoice->invoice.need_shipping_address = input_invoice->invoice_->need_shipping_address_;
message_invoice->invoice.send_phone_number_to_provider = input_invoice->invoice_->send_phone_number_to_provider_;
message_invoice->invoice.send_email_address_to_provider =
input_invoice->invoice_->send_email_address_to_provider_;
message_invoice->invoice.is_flexible = input_invoice->invoice_->is_flexible_;
if (message_invoice->invoice.send_phone_number_to_provider) {
message_invoice->invoice.need_phone_number = true;
}
if (message_invoice->invoice.send_email_address_to_provider) {
message_invoice->invoice.need_email_address = true;
}
if (message_invoice->invoice.is_flexible) {
message_invoice->invoice.need_shipping_address = true;
}
message_invoice->payload = std::move(input_invoice->payload_);
message_invoice->provider_token = std::move(input_invoice->provider_token_);
message_invoice->provider_data = std::move(input_invoice->provider_data_);
content = std::move(message_invoice);
TRY_RESULT(input_invoice, process_input_message_invoice(
move_tl_object_as<td_api::inputMessageInvoice>(input_message_content), td));
content = make_unique<MessageInvoice>(std::move(input_invoice));
break;
}
case td_api::inputMessagePoll::ID: {
@ -2280,88 +2127,6 @@ SecretInputMedia get_secret_input_media(const MessageContent *content, Td *td,
return SecretInputMedia{};
}
static tl_object_ptr<telegram_api::invoice> get_input_invoice(const Invoice &invoice) {
int32 flags = 0;
if (invoice.is_test) {
flags |= telegram_api::invoice::TEST_MASK;
}
if (invoice.need_name) {
flags |= telegram_api::invoice::NAME_REQUESTED_MASK;
}
if (invoice.need_phone_number) {
flags |= telegram_api::invoice::PHONE_REQUESTED_MASK;
}
if (invoice.need_email_address) {
flags |= telegram_api::invoice::EMAIL_REQUESTED_MASK;
}
if (invoice.need_shipping_address) {
flags |= telegram_api::invoice::SHIPPING_ADDRESS_REQUESTED_MASK;
}
if (invoice.send_phone_number_to_provider) {
flags |= telegram_api::invoice::PHONE_TO_PROVIDER_MASK;
}
if (invoice.send_email_address_to_provider) {
flags |= telegram_api::invoice::EMAIL_TO_PROVIDER_MASK;
}
if (invoice.is_flexible) {
flags |= telegram_api::invoice::FLEXIBLE_MASK;
}
if (invoice.max_tip_amount != 0) {
flags |= telegram_api::invoice::MAX_TIP_AMOUNT_MASK;
}
auto prices = transform(invoice.price_parts, [](const LabeledPricePart &price) {
return telegram_api::make_object<telegram_api::labeledPrice>(price.label, price.amount);
});
return make_tl_object<telegram_api::invoice>(
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
false /*ignored*/, false /*ignored*/, false /*ignored*/, invoice.currency, std::move(prices),
invoice.max_tip_amount, vector<int64>(invoice.suggested_tip_amounts));
}
static tl_object_ptr<telegram_api::inputWebDocument> get_input_web_document(const FileManager *file_manager,
const Photo &photo) {
if (photo.is_empty()) {
return nullptr;
}
CHECK(photo.photos.size() == 1);
const PhotoSize &size = photo.photos[0];
CHECK(size.file_id.is_valid());
vector<tl_object_ptr<telegram_api::DocumentAttribute>> attributes;
if (size.dimensions.width != 0 && size.dimensions.height != 0) {
attributes.push_back(
make_tl_object<telegram_api::documentAttributeImageSize>(size.dimensions.width, size.dimensions.height));
}
auto file_view = file_manager->get_file_view(size.file_id);
CHECK(file_view.has_url());
auto file_name = get_url_file_name(file_view.url());
return make_tl_object<telegram_api::inputWebDocument>(
file_view.url(), size.size, MimeType::from_extension(PathView(file_name).extension(), "image/jpeg"),
std::move(attributes));
}
static tl_object_ptr<telegram_api::inputMediaInvoice> get_input_media_invoice(const FileManager *file_manager,
const MessageInvoice *message_invoice) {
CHECK(message_invoice != nullptr);
int32 flags = telegram_api::inputMediaInvoice::START_PARAM_MASK;
auto input_web_document = get_input_web_document(file_manager, message_invoice->photo);
if (input_web_document != nullptr) {
flags |= telegram_api::inputMediaInvoice::PHOTO_MASK;
}
return make_tl_object<telegram_api::inputMediaInvoice>(
flags, message_invoice->title, message_invoice->description, std::move(input_web_document),
get_input_invoice(message_invoice->invoice), BufferSlice(message_invoice->payload),
message_invoice->provider_token,
telegram_api::make_object<telegram_api::dataJSON>(
message_invoice->provider_data.empty() ? "null" : message_invoice->provider_data),
message_invoice->start_parameter);
}
static tl_object_ptr<telegram_api::InputMedia> get_input_media_impl(
const MessageContent *content, Td *td, tl_object_ptr<telegram_api::InputFile> input_file,
tl_object_ptr<telegram_api::InputFile> input_thumbnail, int32 ttl, const string &emoji) {
@ -2395,7 +2160,7 @@ static tl_object_ptr<telegram_api::InputMedia> get_input_media_impl(
}
case MessageContentType::Invoice: {
auto m = static_cast<const MessageInvoice *>(content);
return get_input_media_invoice(td->file_manager_.get(), m);
return get_input_media_invoice(m->input_invoice, td);
}
case MessageContentType::LiveLocation: {
auto m = static_cast<const MessageLiveLocation *>(content);
@ -3016,15 +2781,9 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo
case MessageContentType::Invoice: {
auto old_ = static_cast<const MessageInvoice *>(old_content);
auto new_ = static_cast<const MessageInvoice *>(new_content);
if (old_->title != new_->title || old_->description != new_->description || old_->photo != new_->photo ||
old_->start_parameter != new_->start_parameter || old_->invoice != new_->invoice ||
old_->total_amount != new_->total_amount || old_->receipt_message_id != new_->receipt_message_id) {
if (old_->input_invoice != new_->input_invoice) {
need_update = true;
}
if (old_->payload != new_->payload || old_->provider_token != new_->provider_token ||
old_->provider_data != new_->provider_data) {
is_content_changed = true;
}
break;
}
case MessageContentType::LiveLocation: {
@ -4158,26 +3917,9 @@ unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message,
return std::move(m);
}
case telegram_api::messageMediaInvoice::ID: {
auto message_invoice = move_tl_object_as<telegram_api::messageMediaInvoice>(media);
MessageId receipt_message_id;
if ((message_invoice->flags_ & telegram_api::messageMediaInvoice::RECEIPT_MSG_ID_MASK) != 0) {
receipt_message_id = MessageId(ServerMessageId(message_invoice->receipt_msg_id_));
if (!receipt_message_id.is_valid()) {
LOG(ERROR) << "Receive as receipt message " << receipt_message_id << " in " << owner_dialog_id;
receipt_message_id = MessageId();
}
}
bool need_shipping_address =
(message_invoice->flags_ & telegram_api::messageMediaInvoice::SHIPPING_ADDRESS_REQUESTED_MASK) != 0;
bool is_test = (message_invoice->flags_ & telegram_api::messageMediaInvoice::TEST_MASK) != 0;
case telegram_api::messageMediaInvoice::ID:
return td::make_unique<MessageInvoice>(
std::move(message_invoice->title_), std::move(message_invoice->description_),
get_web_document_photo(td->file_manager_.get(), std::move(message_invoice->photo_), owner_dialog_id),
std::move(message_invoice->start_param_), message_invoice->total_amount_,
std::move(message_invoice->currency_), is_test, need_shipping_address, receipt_message_id);
}
get_input_invoice(move_tl_object_as<telegram_api::messageMediaInvoice>(media), td, owner_dialog_id));
case telegram_api::messageMediaWebPage::ID: {
auto media_web_page = move_tl_object_as<telegram_api::messageMediaWebPage>(media);
auto web_page_id = td->web_pages_manager_->on_get_web_page(std::move(media_web_page->webpage_), owner_dialog_id);
@ -4710,10 +4452,7 @@ tl_object_ptr<td_api::MessageContent> get_message_content_object(const MessageCo
}
case MessageContentType::Invoice: {
const MessageInvoice *m = static_cast<const MessageInvoice *>(content);
return make_tl_object<td_api::messageInvoice>(
m->title, m->description, get_photo_object(td->file_manager_.get(), m->photo), m->invoice.currency,
m->total_amount, m->start_parameter, m->invoice.is_test, m->invoice.need_shipping_address,
m->receipt_message_id.get());
return get_message_invoice_object(m->input_invoice, td);
}
case MessageContentType::LiveLocation: {
const MessageLiveLocation *m = static_cast<const MessageLiveLocation *>(content);
@ -5109,7 +4848,7 @@ vector<FileId> get_message_content_file_ids(const MessageContent *content, const
case MessageContentType::Game:
return static_cast<const MessageGame *>(content)->game.get_file_ids(td);
case MessageContentType::Invoice:
return photo_get_file_ids(static_cast<const MessageInvoice *>(content)->photo);
return get_input_invoice_file_ids(static_cast<const MessageInvoice *>(content)->input_invoice);
case MessageContentType::ChatChangePhoto:
return photo_get_file_ids(static_cast<const MessageChatChangePhoto *>(content)->photo);
case MessageContentType::PassportDataReceived: {

View File

@ -7,21 +7,24 @@
#include "td/telegram/Payments.h"
#include "td/telegram/ContactsManager.h"
#include "td/telegram/files/FileManager.h"
#include "td/telegram/files/FileType.h"
#include "td/telegram/Global.h"
#include "td/telegram/MessagesManager.h"
#include "td/telegram/misc.h"
#include "td/telegram/PasswordManager.h"
#include "td/telegram/Td.h"
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
#include "td/telegram/UpdatesManager.h"
#include "td/utils/algorithm.h"
#include "td/utils/buffer.h"
#include "td/utils/common.h"
#include "td/utils/format.h"
#include "td/utils/HttpUrl.h"
#include "td/utils/JsonBuilder.h"
#include "td/utils/logging.h"
#include "td/utils/MimeType.h"
#include "td/utils/PathView.h"
#include "td/utils/Status.h"
namespace td {
@ -600,6 +603,245 @@ StringBuilder &operator<<(StringBuilder &string_builder, const Invoice &invoice)
<< invoice.max_tip_amount << "]";
}
bool operator==(const InputInvoice &lhs, const InputInvoice &rhs) {
return lhs.title == rhs.title && lhs.description == rhs.description && lhs.photo == rhs.photo &&
lhs.start_parameter == rhs.start_parameter && lhs.invoice == rhs.invoice &&
lhs.total_amount == rhs.total_amount && lhs.receipt_message_id == rhs.receipt_message_id &&
lhs.payload == rhs.payload && lhs.provider_token == rhs.provider_token &&
lhs.provider_data == rhs.provider_data;
}
bool operator!=(const InputInvoice &lhs, const InputInvoice &rhs) {
return !(lhs == rhs);
}
InputInvoice get_input_invoice(tl_object_ptr<telegram_api::messageMediaInvoice> &&message_invoice, Td *td,
DialogId owner_dialog_id) {
InputInvoice result;
result.title = std::move(message_invoice->title_);
result.description = std::move(message_invoice->description_);
result.photo = get_web_document_photo(td->file_manager_.get(), std::move(message_invoice->photo_), owner_dialog_id);
result.start_parameter = std::move(message_invoice->start_param_);
result.invoice.currency = std::move(message_invoice->currency_);
result.invoice.is_test = (message_invoice->flags_ & telegram_api::messageMediaInvoice::TEST_MASK) != 0;
result.invoice.need_shipping_address =
(message_invoice->flags_ & telegram_api::messageMediaInvoice::SHIPPING_ADDRESS_REQUESTED_MASK) != 0;
// result.payload = string();
// result.provider_token = string();
// result.provider_data = string();
result.total_amount = message_invoice->total_amount_;
if ((message_invoice->flags_ & telegram_api::messageMediaInvoice::RECEIPT_MSG_ID_MASK) != 0) {
result.receipt_message_id = MessageId(ServerMessageId(message_invoice->receipt_msg_id_));
if (!result.receipt_message_id.is_valid()) {
LOG(ERROR) << "Receive as receipt message " << result.receipt_message_id << " in " << owner_dialog_id;
result.receipt_message_id = MessageId();
}
}
return result;
}
Result<InputInvoice> process_input_message_invoice(td_api::object_ptr<td_api::inputMessageInvoice> &&input_invoice,
Td *td) {
if (!clean_input_string(input_invoice->title_)) {
return Status::Error(400, "Invoice title must be encoded in UTF-8");
}
if (!clean_input_string(input_invoice->description_)) {
return Status::Error(400, "Invoice description must be encoded in UTF-8");
}
if (!clean_input_string(input_invoice->photo_url_)) {
return Status::Error(400, "Invoice photo URL must be encoded in UTF-8");
}
if (!clean_input_string(input_invoice->start_parameter_)) {
return Status::Error(400, "Invoice bot start parameter must be encoded in UTF-8");
}
if (!clean_input_string(input_invoice->provider_token_)) {
return Status::Error(400, "Invoice provider token must be encoded in UTF-8");
}
if (!clean_input_string(input_invoice->provider_data_)) {
return Status::Error(400, "Invoice provider data must be encoded in UTF-8");
}
if (!clean_input_string(input_invoice->invoice_->currency_)) {
return Status::Error(400, "Invoice currency must be encoded in UTF-8");
}
InputInvoice result;
result.title = std::move(input_invoice->title_);
result.description = std::move(input_invoice->description_);
auto r_http_url = parse_url(input_invoice->photo_url_);
if (r_http_url.is_error()) {
if (!input_invoice->photo_url_.empty()) {
LOG(INFO) << "Can't register url " << input_invoice->photo_url_;
}
} else {
auto url = r_http_url.ok().get_url();
auto r_invoice_file_id = td->file_manager_->from_persistent_id(url, FileType::Temp);
if (r_invoice_file_id.is_error()) {
LOG(INFO) << "Can't register url " << url;
} else {
auto invoice_file_id = r_invoice_file_id.move_as_ok();
PhotoSize s;
s.type = 'n';
s.dimensions =
get_dimensions(input_invoice->photo_width_, input_invoice->photo_height_, "process_input_message_invoice");
s.size = input_invoice->photo_size_; // TODO use invoice_file_id size
s.file_id = invoice_file_id;
result.photo.id = 0;
result.photo.photos.push_back(s);
}
}
result.start_parameter = std::move(input_invoice->start_parameter_);
result.invoice.currency = std::move(input_invoice->invoice_->currency_);
result.invoice.price_parts.reserve(input_invoice->invoice_->price_parts_.size());
int64 total_amount = 0;
const int64 MAX_AMOUNT = 9999'9999'9999;
for (auto &price : input_invoice->invoice_->price_parts_) {
if (!clean_input_string(price->label_)) {
return Status::Error(400, "Invoice price label must be encoded in UTF-8");
}
result.invoice.price_parts.emplace_back(std::move(price->label_), price->amount_);
if (price->amount_ < -MAX_AMOUNT || price->amount_ > MAX_AMOUNT) {
return Status::Error(400, "Too big amount of the currency specified");
}
total_amount += price->amount_;
}
if (total_amount <= 0) {
return Status::Error(400, "Total price must be positive");
}
if (total_amount > MAX_AMOUNT) {
return Status::Error(400, "Total price is too big");
}
result.total_amount = total_amount;
if (input_invoice->invoice_->max_tip_amount_ < 0 || input_invoice->invoice_->max_tip_amount_ > MAX_AMOUNT) {
return Status::Error(400, "Invalid max tip amount of the currency specified");
}
for (auto tip_amount : input_invoice->invoice_->suggested_tip_amounts_) {
if (tip_amount < 0 || tip_amount > input_invoice->invoice_->max_tip_amount_) {
return Status::Error(400, "Invalid suggested tip amount of the currency specified");
}
}
result.invoice.max_tip_amount = input_invoice->invoice_->max_tip_amount_;
result.invoice.suggested_tip_amounts = std::move(input_invoice->invoice_->suggested_tip_amounts_);
result.invoice.is_test = input_invoice->invoice_->is_test_;
result.invoice.need_name = input_invoice->invoice_->need_name_;
result.invoice.need_phone_number = input_invoice->invoice_->need_phone_number_;
result.invoice.need_email_address = input_invoice->invoice_->need_email_address_;
result.invoice.need_shipping_address = input_invoice->invoice_->need_shipping_address_;
result.invoice.send_phone_number_to_provider = input_invoice->invoice_->send_phone_number_to_provider_;
result.invoice.send_email_address_to_provider = input_invoice->invoice_->send_email_address_to_provider_;
result.invoice.is_flexible = input_invoice->invoice_->is_flexible_;
if (result.invoice.send_phone_number_to_provider) {
result.invoice.need_phone_number = true;
}
if (result.invoice.send_email_address_to_provider) {
result.invoice.need_email_address = true;
}
if (result.invoice.is_flexible) {
result.invoice.need_shipping_address = true;
}
result.payload = std::move(input_invoice->payload_);
result.provider_token = std::move(input_invoice->provider_token_);
result.provider_data = std::move(input_invoice->provider_data_);
return result;
}
tl_object_ptr<td_api::messageInvoice> get_message_invoice_object(const InputInvoice &input_invoice, Td *td) {
return make_tl_object<td_api::messageInvoice>(
input_invoice.title, input_invoice.description, get_photo_object(td->file_manager_.get(), input_invoice.photo),
input_invoice.invoice.currency, input_invoice.total_amount, input_invoice.start_parameter,
input_invoice.invoice.is_test, input_invoice.invoice.need_shipping_address,
input_invoice.receipt_message_id.get());
}
static tl_object_ptr<telegram_api::invoice> get_input_invoice(const Invoice &invoice) {
int32 flags = 0;
if (invoice.is_test) {
flags |= telegram_api::invoice::TEST_MASK;
}
if (invoice.need_name) {
flags |= telegram_api::invoice::NAME_REQUESTED_MASK;
}
if (invoice.need_phone_number) {
flags |= telegram_api::invoice::PHONE_REQUESTED_MASK;
}
if (invoice.need_email_address) {
flags |= telegram_api::invoice::EMAIL_REQUESTED_MASK;
}
if (invoice.need_shipping_address) {
flags |= telegram_api::invoice::SHIPPING_ADDRESS_REQUESTED_MASK;
}
if (invoice.send_phone_number_to_provider) {
flags |= telegram_api::invoice::PHONE_TO_PROVIDER_MASK;
}
if (invoice.send_email_address_to_provider) {
flags |= telegram_api::invoice::EMAIL_TO_PROVIDER_MASK;
}
if (invoice.is_flexible) {
flags |= telegram_api::invoice::FLEXIBLE_MASK;
}
if (invoice.max_tip_amount != 0) {
flags |= telegram_api::invoice::MAX_TIP_AMOUNT_MASK;
}
auto prices = transform(invoice.price_parts, [](const LabeledPricePart &price) {
return telegram_api::make_object<telegram_api::labeledPrice>(price.label, price.amount);
});
return make_tl_object<telegram_api::invoice>(
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
false /*ignored*/, false /*ignored*/, false /*ignored*/, invoice.currency, std::move(prices),
invoice.max_tip_amount, vector<int64>(invoice.suggested_tip_amounts));
}
static tl_object_ptr<telegram_api::inputWebDocument> get_input_web_document(const FileManager *file_manager,
const Photo &photo) {
if (photo.is_empty()) {
return nullptr;
}
CHECK(photo.photos.size() == 1);
const PhotoSize &size = photo.photos[0];
CHECK(size.file_id.is_valid());
vector<tl_object_ptr<telegram_api::DocumentAttribute>> attributes;
if (size.dimensions.width != 0 && size.dimensions.height != 0) {
attributes.push_back(
make_tl_object<telegram_api::documentAttributeImageSize>(size.dimensions.width, size.dimensions.height));
}
auto file_view = file_manager->get_file_view(size.file_id);
CHECK(file_view.has_url());
auto file_name = get_url_file_name(file_view.url());
return make_tl_object<telegram_api::inputWebDocument>(
file_view.url(), size.size, MimeType::from_extension(PathView(file_name).extension(), "image/jpeg"),
std::move(attributes));
}
tl_object_ptr<telegram_api::inputMediaInvoice> get_input_media_invoice(const InputInvoice &input_invoice, Td *td) {
int32 flags = telegram_api::inputMediaInvoice::START_PARAM_MASK;
auto input_web_document = get_input_web_document(td->file_manager_.get(), input_invoice.photo);
if (input_web_document != nullptr) {
flags |= telegram_api::inputMediaInvoice::PHOTO_MASK;
}
return make_tl_object<telegram_api::inputMediaInvoice>(
flags, input_invoice.title, input_invoice.description, std::move(input_web_document),
get_input_invoice(input_invoice.invoice), BufferSlice(input_invoice.payload), input_invoice.provider_token,
telegram_api::make_object<telegram_api::dataJSON>(
input_invoice.provider_data.empty() ? "null" : input_invoice.provider_data),
input_invoice.start_parameter);
}
vector<FileId> get_input_invoice_file_ids(const InputInvoice &input_invoice) {
return photo_get_file_ids(input_invoice.photo);
}
bool operator==(const Address &lhs, const Address &rhs) {
return lhs.country_code == rhs.country_code && lhs.state == rhs.state && lhs.city == rhs.city &&
lhs.street_line1 == rhs.street_line1 && lhs.street_line2 == rhs.street_line2 &&

View File

@ -9,19 +9,21 @@
#include "td/actor/PromiseFuture.h"
#include "td/telegram/DialogId.h"
#include "td/telegram/MessageId.h"
#include "td/telegram/Photo.h"
#include "td/telegram/ServerMessageId.h"
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
#include "td/utils/common.h"
#include "td/utils/Slice.h"
#include "td/utils/Status.h"
#include "td/utils/StringBuilder.h"
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
namespace td {
class Td;
struct LabeledPricePart {
string label;
int64 amount = 0;
@ -51,6 +53,20 @@ struct Invoice {
}
};
struct InputInvoice {
string title;
string description;
Photo photo;
string start_parameter;
Invoice invoice;
string payload;
string provider_token;
string provider_data;
int64 total_amount = 0;
MessageId receipt_message_id;
};
struct Address {
string country_code;
string state;
@ -102,6 +118,21 @@ bool operator!=(const Invoice &lhs, const Invoice &rhs);
StringBuilder &operator<<(StringBuilder &string_builder, const Invoice &invoice);
bool operator==(const InputInvoice &lhs, const InputInvoice &rhs);
bool operator!=(const InputInvoice &lhs, const InputInvoice &rhs);
InputInvoice get_input_invoice(tl_object_ptr<telegram_api::messageMediaInvoice> &&message_invoice, Td *td,
DialogId owner_dialog_id);
Result<InputInvoice> process_input_message_invoice(td_api::object_ptr<td_api::inputMessageInvoice> &&input_invoice,
Td *td);
tl_object_ptr<td_api::messageInvoice> get_message_invoice_object(const InputInvoice &input_invoice, Td *td);
tl_object_ptr<telegram_api::inputMediaInvoice> get_input_media_invoice(const InputInvoice &input_invoice, Td *td);
vector<FileId> get_input_invoice_file_ids(const InputInvoice &input_invoice);
bool operator==(const Address &lhs, const Address &rhs);
bool operator!=(const Address &lhs, const Address &rhs);

View File

@ -9,6 +9,7 @@
#include "td/telegram/Payments.h"
#include "td/telegram/Photo.hpp"
#include "td/telegram/Version.h"
#include "td/utils/tl_helpers.h"
@ -70,6 +71,38 @@ void parse(Invoice &invoice, ParserT &parser) {
}
}
template <class StorerT>
void store(const InputInvoice &input_invoice, StorerT &storer) {
store(input_invoice.title, storer);
store(input_invoice.description, storer);
store(input_invoice.photo, storer);
store(input_invoice.start_parameter, storer);
store(input_invoice.invoice, storer);
store(input_invoice.payload, storer);
store(input_invoice.provider_token, storer);
store(input_invoice.provider_data, storer);
store(input_invoice.total_amount, storer);
store(input_invoice.receipt_message_id, storer);
}
template <class ParserT>
void parse(InputInvoice &input_invoice, ParserT &parser) {
parse(input_invoice.title, parser);
parse(input_invoice.description, parser);
parse(input_invoice.photo, parser);
parse(input_invoice.start_parameter, parser);
parse(input_invoice.invoice, parser);
parse(input_invoice.payload, parser);
parse(input_invoice.provider_token, parser);
if (parser.version() >= static_cast<int32>(Version::AddMessageInvoiceProviderData)) {
parse(input_invoice.provider_data, parser);
} else {
input_invoice.provider_data.clear();
}
parse(input_invoice.total_amount, parser);
parse(input_invoice.receipt_message_id, parser);
}
template <class StorerT>
void store(const Address &address, StorerT &storer) {
store(address.country_code, storer);