Api version 6.1

This commit is contained in:
rubenlagus 2022-06-18 00:40:30 +02:00 committed by Ruben Bermudez
parent 9c9bfd0950
commit 9a3e5b3943
18 changed files with 668 additions and 36 deletions

View File

@ -0,0 +1,181 @@
package org.telegram.telegrambots.meta.api.methods.invoices;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.base.Strings;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.Singular;
import lombok.ToString;
import org.telegram.telegrambots.meta.api.methods.BotApiMethod;
import org.telegram.telegrambots.meta.api.objects.ApiResponse;
import org.telegram.telegrambots.meta.api.objects.Message;
import org.telegram.telegrambots.meta.api.objects.payments.LabeledPrice;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiValidationException;
import java.io.IOException;
import java.util.List;
/**
* @author Ruben Bermudez
* @version 6.1
* Use this method to create a link for an invoice. On success, the created link is returned.
*/
@EqualsAndHashCode(callSuper = false)
@Getter
@Setter
@ToString
@RequiredArgsConstructor
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CreateInvoiceLink extends BotApiMethod<Message> {
public static final String PATH = "createInvoiceLink";
public static final String TITLE_FIELD = "title";
public static final String DESCRIPTION_FIELD = "description";
public static final String PAYLOAD_FIELD = "payload";
public static final String PROVIDER_TOKEN_FIELD = "provider_token";
public static final String CURRENCY_FIELD = "currency";
public static final String PRICES_FIELD = "prices";
public static final String MAXTIPAMOUNT_FIELD = "max_tip_amount";
public static final String SUGGESTEDTIPAMOUNTS_FIELD = "suggested_tip_amounts";
public static final String PROVIDER_DATA_FIELD = "provider_data";
public static final String PHOTO_URL_FIELD = "photo_url";
public static final String PHOTO_SIZE_FIELD = "photo_size";
public static final String PHOTO_WIDTH_FIELD = "photo_width";
public static final String PHOTO_HEIGHT_FIELD = "photo_height";
public static final String NEED_NAME_FIELD = "need_name";
public static final String NEED_PHONE_NUMBER_FIELD = "need_phone_number";
public static final String NEED_EMAIL_FIELD = "need_email";
public static final String NEED_SHIPPING_ADDRESS_FIELD = "need_shipping_address";
public static final String SEND_PHONE_NUMBER_TO_PROVIDER_FIELD = "send_phone_number_to_provider";
public static final String SEND_EMAIL_TO_PROVIDER_FIELD = "send_email_to_provider";
public static final String IS_FLEXIBLE_FIELD = "is_flexible";
@JsonProperty(TITLE_FIELD)
@NonNull
private String title; ///< Product name, 1-32 characters
@JsonProperty(DESCRIPTION_FIELD)
@NonNull
private String description; ///< Product description, 1-255 characters
@JsonProperty(PAYLOAD_FIELD)
@NonNull
private String payload; ///< Bot-defined invoice payload, 1-128 bytes. This will not be displayed to the user, use for your internal processes.
@JsonProperty(PROVIDER_TOKEN_FIELD)
@NonNull
private String providerToken; ///< Payment provider token, obtained via BotFather
@JsonProperty(CURRENCY_FIELD)
@NonNull
private String currency; ///< Three-letter ISO 4217 currency code, see more on currencies
@JsonProperty(PRICES_FIELD)
@NonNull
@Singular
private List<LabeledPrice> prices; ///< Price breakdown, a JSON-serialized list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.)
/**
* Optional
* URL of the product photo for the invoice.
* Can be a photo of the goods or a marketing image for a service.
*/
@JsonProperty(PHOTO_URL_FIELD)
private String photoUrl;
@JsonProperty(PHOTO_SIZE_FIELD)
private Integer photoSize; ///< Optional Photo size in bytes
@JsonProperty(PHOTO_WIDTH_FIELD)
private Integer photoWidth; ///< Optional Photo width
@JsonProperty(PHOTO_HEIGHT_FIELD)
private Integer photoHeight; ///< Optional Photo height
@JsonProperty(NEED_NAME_FIELD)
private Boolean needName; ///< Optional Pass True, if you require the user's full name to complete the order
@JsonProperty(NEED_PHONE_NUMBER_FIELD)
private Boolean needPhoneNumber; ///< Optional Pass True, if you require the user's phone number to complete the order
@JsonProperty(NEED_EMAIL_FIELD)
private Boolean needEmail; ///< Optional Pass True, if you require the user's email address to complete the order
@JsonProperty(NEED_SHIPPING_ADDRESS_FIELD)
private Boolean needShippingAddress; ///< Optional Pass True, if you require the user's shipping address to complete the order
@JsonProperty(IS_FLEXIBLE_FIELD)
private Boolean isFlexible; ///< Optional Pass True, if the final price depends on the shipping method
@JsonProperty(SEND_PHONE_NUMBER_TO_PROVIDER_FIELD)
private Boolean sendPhoneNumberToProvider; ///< Optional Pass True, if the user's phone number should be sent to the provider
@JsonProperty(SEND_EMAIL_TO_PROVIDER_FIELD)
private Boolean sendEmailToProvider; ///< Optional Pass True, if the user's email address should be sent to the provider
/**
* Optional
* JSON-serialized data about the invoice, which will be shared with the payment provider.
*
* @apiNote A detailed description of required fields should be provided by the payment provider.
*/
@JsonProperty(PROVIDER_DATA_FIELD)
private String providerData;
/**
* The maximum accepted amount for tips in the smallest units of the currency (integer, not float/double).
* For example, for a maximum tip of US$ 1.45 pass max_tip_amount = 145.
* Defaults to 0
*/
@JsonProperty(MAXTIPAMOUNT_FIELD)
private Integer maxTipAmount;
/**
* Optional A JSON-serialized array of suggested amounts of tips in the smallest units of the currency (integer, not float/double).
* At most 4 suggested tip amounts can be specified.
* The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount.
*/
@JsonProperty(SUGGESTEDTIPAMOUNTS_FIELD)
@Singular
private List<Integer> suggestedTipAmounts;
@Override
public String getMethod() {
return PATH;
}
@Override
public Message deserializeResponse(String answer) throws TelegramApiRequestException {
try {
ApiResponse<Message> result = OBJECT_MAPPER.readValue(answer,
new TypeReference<ApiResponse<Message>>(){});
if (result.getOk()) {
return result.getResult();
} else {
throw new TelegramApiRequestException("Error sending invoice", result);
}
} catch (IOException e) {
throw new TelegramApiRequestException("Unable to deserialize response", e);
}
}
@Override
public void validate() throws TelegramApiValidationException {
if (Strings.isNullOrEmpty(title) || title.length() > 32) {
throw new TelegramApiValidationException("Title parameter can't be empty or longer than 32 chars", this);
}
if (Strings.isNullOrEmpty(description) || description.length() > 255) {
throw new TelegramApiValidationException("Description parameter can't be empty or longer than 255 chars", this);
}
if (Strings.isNullOrEmpty(payload)) {
throw new TelegramApiValidationException("Payload parameter can't be empty", this);
}
if (Strings.isNullOrEmpty(providerToken)) {
throw new TelegramApiValidationException("ProviderToken parameter can't be empty", this);
}
if (Strings.isNullOrEmpty(currency)) {
throw new TelegramApiValidationException("Currency parameter can't be empty", this);
}
if (prices.isEmpty()) {
throw new TelegramApiValidationException("Prices parameter can't be empty", this);
} else {
for (LabeledPrice price : prices) {
price.validate();
}
}
if (suggestedTipAmounts != null && !suggestedTipAmounts.isEmpty() && suggestedTipAmounts.size() > 4) {
throw new TelegramApiValidationException("No more that 4 suggested tips allowed", this);
}
}
}

View File

@ -0,0 +1,237 @@
package org.telegram.telegrambots.meta.api.methods.invoices;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.base.Strings;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.Singular;
import lombok.ToString;
import lombok.experimental.Tolerate;
import org.telegram.telegrambots.meta.api.methods.BotApiMethod;
import org.telegram.telegrambots.meta.api.objects.ApiResponse;
import org.telegram.telegrambots.meta.api.objects.Message;
import org.telegram.telegrambots.meta.api.objects.payments.LabeledPrice;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiValidationException;
import java.io.IOException;
import java.util.List;
/**
* @author Ruben Bermudez
* @version 1.0
* Use this method to send an invoice. On success, the sent Message is returned.
*/
@EqualsAndHashCode(callSuper = false)
@Getter
@Setter
@ToString
@RequiredArgsConstructor
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class SendInvoice extends BotApiMethod<Message> {
public static final String PATH = "sendinvoice";
private static final String CHATID_FIELD = "chat_id";
private static final String TITLE_FIELD = "title";
private static final String DESCRIPTION_FIELD = "description";
private static final String PAYLOAD_FIELD = "payload";
private static final String PROVIDER_TOKEN_FIELD = "provider_token";
private static final String START_PARAMETER_FIELD = "start_parameter";
private static final String CURRENCY_FIELD = "currency";
private static final String PRICES_FIELD = "prices";
private static final String PHOTO_URL_FIELD = "photo_url";
private static final String PHOTO_SIZE_FIELD = "photo_size";
private static final String PHOTO_WIDTH_FIELD = "photo_width";
private static final String PHOTO_HEIGHT_FIELD = "photo_height";
private static final String NEED_NAME_FIELD = "need_name";
private static final String NEED_PHONE_NUMBER_FIELD = "need_phone_number";
private static final String NEED_EMAIL_FIELD = "need_email";
private static final String NEED_SHIPPING_ADDRESS_FIELD = "need_shipping_address";
private static final String SEND_PHONE_NUMBER_TO_PROVIDER_FIELD = "send_phone_number_to_provider";
private static final String SEND_EMAIL_TO_PROVIDER_FIELD = "send_email_to_provider";
private static final String IS_FLEXIBLE_FIELD = "is_flexible";
private static final String DISABLE_NOTIFICATION_FIELD = "disable_notification";
private static final String REPLY_TO_MESSAGE_ID_FIELD = "reply_to_message_id";
private static final String REPLY_MARKUP_FIELD = "reply_markup";
private static final String PROVIDER_DATA_FIELD = "provider_data";
private static final String ALLOWSENDINGWITHOUTREPLY_FIELD = "allow_sending_without_reply";
private static final String MAXTIPAMOUNT_FIELD = "max_tip_amount";
private static final String SUGGESTEDTIPAMOUNTS_FIELD = "suggested_tip_amounts";
private static final String PROTECTCONTENT_FIELD = "protect_content";
@JsonProperty(CHATID_FIELD)
@NonNull
private String chatId; ///< Unique identifier for the target chat or username of the target channel (in the format @channelusername)
@JsonProperty(TITLE_FIELD)
@NonNull
private String title; ///< Product name
@JsonProperty(DESCRIPTION_FIELD)
@NonNull
private String description; ///< Product description
@JsonProperty(PAYLOAD_FIELD)
@NonNull
private String payload; ///< Bot-defined invoice payload, 1-128 bytes. This will not be displayed to the user, use for your internal processes.
@JsonProperty(PROVIDER_TOKEN_FIELD)
@NonNull
private String providerToken; ///< Payments provider token, obtained via Botfather
/**
* Optional
* Unique deep-linking parameter. If left empty, forwarded copies of the sent message will have a Pay button,
* allowing multiple users to pay directly from the forwarded message, using the same invoice.
* If non-empty, forwarded copies of the sent message will have a URL button with a deep link to the bot (instead of a Pay button),
* with the value used as the start parameter
*/
@JsonProperty(START_PARAMETER_FIELD)
@NonNull
private String startParameter;
@JsonProperty(CURRENCY_FIELD)
@NonNull
private String currency; ///< 3-letter ISO 4217 currency code
@JsonProperty(PRICES_FIELD)
@NonNull
@Singular
private List<LabeledPrice> prices; ///< Price breakdown, a list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.)
/**
* Optional. URL of the product photo for the invoice. Can be a photo of the goods or a marketing image for a service.
* People like it better when they see what they are paying for
*/
@JsonProperty(PHOTO_URL_FIELD)
private String photoUrl;
@JsonProperty(PHOTO_SIZE_FIELD)
private Integer photoSize; ///< Optional. Photo size
@JsonProperty(PHOTO_WIDTH_FIELD)
private Integer photoWidth; ///< Optional. Photo width
@JsonProperty(PHOTO_HEIGHT_FIELD)
private Integer photoHeight; ///< Optional. Photo height
@JsonProperty(NEED_NAME_FIELD)
private Boolean needName; ///< Optional. Pass True, if you require the user's full name to complete the order
@JsonProperty(NEED_PHONE_NUMBER_FIELD)
private Boolean needPhoneNumber; ///< Optional. Pass True, if you require the user's phone number to complete the order
@JsonProperty(NEED_EMAIL_FIELD)
private Boolean needEmail; ///< Optional. Pass True, if you require the user's email to complete the order
@JsonProperty(NEED_SHIPPING_ADDRESS_FIELD)
private Boolean needShippingAddress; ///< Optional. Pass True, if you require the user's shipping address to complete the order
@JsonProperty(IS_FLEXIBLE_FIELD)
private Boolean isFlexible; ///< Optional. Pass True, if the final price depends on the shipping method
@JsonProperty(DISABLE_NOTIFICATION_FIELD)
private Boolean disableNotification; ///< Optional. Sends the message silently. Users will receive a notification with no sound.
@JsonProperty(REPLY_TO_MESSAGE_ID_FIELD)
private Integer replyToMessageId; ///< Optional. If the message is a reply, ID of the original message
@JsonProperty(SEND_PHONE_NUMBER_TO_PROVIDER_FIELD)
private Boolean sendPhoneNumberToProvider; ///< Optional. Pass True, if user's phone number should be sent to provider
@JsonProperty(SEND_EMAIL_TO_PROVIDER_FIELD)
private Boolean sendEmailToProvider; ///< Optional. Pass True, if user's email address should be sent to provider
/**
* Optional. A JSON-serialized object for an inline keyboard.
*
* @apiNote If empty, one 'Buy title' button will be shown. If not empty, the first button must be a Pay button.
*/
@JsonProperty(REPLY_MARKUP_FIELD)
private InlineKeyboardMarkup replyMarkup;
/**
* Optional JSON-encoded data about the invoice, which will be shared with the payment provider.
*
* @apiNote A detailed description of required fields should be provided by the payment provider.
*/
@JsonProperty(PROVIDER_DATA_FIELD)
private String providerData;
@JsonProperty(ALLOWSENDINGWITHOUTREPLY_FIELD)
private Boolean allowSendingWithoutReply; ///< Optional Pass True, if the message should be sent even if the specified replied-to message is not found
/**
* The maximum accepted amount for tips in the smallest units of the currency (integer, not float/double).
* For example, for a maximum tip of US$ 1.45 pass max_tip_amount = 145.
* Defaults to 0
*/
@JsonProperty(MAXTIPAMOUNT_FIELD)
private Integer maxTipAmount;
/**
* A JSON-serialized array of suggested amounts of tips in the smallest units of the currency (integer, not float/double).
* At most 4 suggested tip amounts can be specified.
* The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount.
*/
@JsonProperty(SUGGESTEDTIPAMOUNTS_FIELD)
@Singular
private List<Integer> suggestedTipAmounts;
@JsonProperty(PROTECTCONTENT_FIELD)
private Boolean protectContent; ///< Optional. Protects the contents of sent messages from forwarding and saving
@Tolerate
public void setChatId(@NonNull Long chatId) {
this.chatId = chatId.toString();
}
@Override
public String getMethod() {
return PATH;
}
@Override
public Message deserializeResponse(String answer) throws TelegramApiRequestException {
try {
ApiResponse<Message> result = OBJECT_MAPPER.readValue(answer,
new TypeReference<ApiResponse<Message>>(){});
if (result.getOk()) {
return result.getResult();
} else {
throw new TelegramApiRequestException("Error sending invoice", result);
}
} catch (IOException e) {
throw new TelegramApiRequestException("Unable to deserialize response", e);
}
}
@Override
public void validate() throws TelegramApiValidationException {
if (Strings.isNullOrEmpty(chatId)) {
throw new TelegramApiValidationException("ChatId parameter can't be empty", this);
}
if (Strings.isNullOrEmpty(title) || title.length() > 32) {
throw new TelegramApiValidationException("Title parameter can't be empty or longer than 32 chars", this);
}
if (Strings.isNullOrEmpty(description) || description.length() > 255) {
throw new TelegramApiValidationException("Description parameter can't be empty or longer than 255 chars", this);
}
if (Strings.isNullOrEmpty(payload)) {
throw new TelegramApiValidationException("Payload parameter can't be empty", this);
}
if (Strings.isNullOrEmpty(providerToken)) {
throw new TelegramApiValidationException("ProviderToken parameter can't be empty", this);
}
if (Strings.isNullOrEmpty(currency)) {
throw new TelegramApiValidationException("Currency parameter can't be empty", this);
}
if (prices.isEmpty()) {
throw new TelegramApiValidationException("Prices parameter can't be empty", this);
} else {
for (LabeledPrice price : prices) {
price.validate();
}
}
if (suggestedTipAmounts != null && !suggestedTipAmounts.isEmpty() && suggestedTipAmounts.size() > 4) {
throw new TelegramApiValidationException("No more that 4 suggested tips allowed", this);
}
if (replyMarkup != null) {
replyMarkup.validate();
}
}
public static class SendInvoiceBuilder {
@Tolerate
public SendInvoiceBuilder chatId(@NonNull Long chatId) {
this.chatId = chatId.toString();
return this;
}
}
}

View File

@ -24,6 +24,8 @@ import java.util.List;
* @author Ruben Bermudez
* @version 1.0
* Use this method to send an invoice. On success, the sent Message is returned.
*
* @deprecated Use {@link org.telegram.telegrambots.meta.api.methods.invoices.SendInvoice}
*/
@EqualsAndHashCode(callSuper = false)
@Getter
@ -33,6 +35,7 @@ import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Deprecated
public class SendInvoice extends BotApiMethodMessage {
public static final String PATH = "sendinvoice";

View File

@ -10,7 +10,6 @@ import lombok.Setter;
import lombok.ToString;
import org.telegram.telegrambots.meta.api.methods.botapimethods.BotApiMethodBoolean;
import org.telegram.telegrambots.meta.api.objects.InputFile;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiValidationException;
/**
@ -57,11 +56,6 @@ public class SetStickerSetThumb extends BotApiMethodBoolean {
return PATH;
}
@Override
public Boolean deserializeResponse(String answer) throws TelegramApiRequestException {
return deserializeResponse(answer, Boolean.class);
}
@Override
public void validate() throws TelegramApiValidationException {
if (name.isEmpty()) {

View File

@ -13,19 +13,20 @@ import lombok.Singular;
import lombok.ToString;
import org.telegram.telegrambots.meta.api.methods.botapimethods.BotApiMethodBoolean;
import org.telegram.telegrambots.meta.api.objects.InputFile;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiValidationException;
import java.util.List;
/**
* @author Ruben Bermudez
* @version 1.0
* Use this method to specify a url and receive incoming updates via an outgoing webhook.
* Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url,
* containing a JSON-serialized Update. In case of an unsuccessful request, we will give up after a
* reasonable amount of attempts.
* 20 of June of 2015
* @version 6.1
* Use this method to specify a URL and receive incoming updates via an outgoing webhook.
* Whenever there is an update for the bot, we will send an HTTPS POST request to the specified URL,
* containing a JSON-serialized Update. In case of an unsuccessful request,
* we will give up after a reasonable amount of attempts. Returns True on success.
*
* If you'd like to make sure that the webhook was set by you, you can specify secret data in the parameter secret_token.
* If specified, the request will contain a header X-Telegram-Bot-Api-Secret-Token with the secret token as content.
*/
@EqualsAndHashCode(callSuper = false)
@Getter
@ -44,6 +45,7 @@ public class SetWebhook extends BotApiMethodBoolean {
public static final String ALLOWEDUPDATES_FIELD = "allowed_updates";
public static final String IPADDRESS_FIELD = "ip_address";
public static final String DROPPENDINGUPDATES_FIELD = "drop_pending_updates";
public static final String SECRETTOKEN_FIELD = "secret_token";
@JsonProperty(URL_FIELD)
@NonNull
@ -73,17 +75,20 @@ public class SetWebhook extends BotApiMethodBoolean {
private String ipAddress;
@JsonProperty(DROPPENDINGUPDATES_FIELD)
private Boolean dropPendingUpdates;
/**
* Optional
* A secret token to be sent in a header X-Telegram-Bot-Api-Secret-Token in every webhook request, 1-256 characters.
* Only characters A-Z, a-z, 0-9, _ and - are allowed.
* The header is useful to ensure that the request comes from a webhook set by you.
*/
@JsonProperty(SECRETTOKEN_FIELD)
private String secretToken;
@Override
public String getMethod() {
return PATH;
}
@Override
public Boolean deserializeResponse(String answer) throws TelegramApiRequestException {
return deserializeResponse(answer, Boolean.class);
}
@Override
public void validate() throws TelegramApiValidationException {
if (url.isEmpty()) {
@ -94,5 +99,8 @@ public class SetWebhook extends BotApiMethodBoolean {
throw new TelegramApiValidationException("Certificate parameter must be a new file to upload", this);
}
}
if (secretToken != null && !secretToken.matches("[A-Za-z0-9_-]+")) {
throw new TelegramApiValidationException("SecretToken parameter must only contains A-Z, a-z, 0-9, _ and -", this);
}
}
}

View File

@ -44,8 +44,14 @@ public class Audio implements BotApiObject {
private Integer duration; ///< Integer Duration of the audio in seconds as defined by sender
@JsonProperty(MIMETYPE_FIELD)
private String mimeType; ///< Optional. MIME type of the file as defined by sender
/**
* Optional.
* File size in bytes.
* It can be bigger than 2^31 and some programming languages may have difficulty/silent defects in interpreting it.
* But it has at most 52 significant bits, so a signed 64-bit integer or double-precision float type are safe for storing this value.
*/
@JsonProperty(FILESIZE_FIELD)
private Integer fileSize; ///< Optional. File size
private Long fileSize;
@JsonProperty(TITLE_FIELD)
private String title; ///< Optional. Title of the audio as defined by sender or by audio tags
@JsonProperty(PERFORMER_FIELD)

View File

@ -14,7 +14,7 @@ import org.telegram.telegrambots.meta.api.interfaces.BotApiObject;
/**
* @author Ruben Bermudez
* @version 1.0
* @version 6.1
* This object represents a Telegram chat with an user or a group
*/
@SuppressWarnings("WeakerAccess")
@ -47,6 +47,8 @@ public class Chat implements BotApiObject {
private static final String MESSAGEAUTODELETETIME_FIELD = "message_auto_delete_time";
private static final String HASPRIVATEFORWARDS_FIELD = "has_private_forwards";
private static final String HASPROTECTEDCONTENT_FIELD = "has_protected_content";
private static final String JOINTOSENDMESSAGES_FIELD = "join_to_send_messages";
private static final String JOINBYREQUEST_FIELD = "join_by_request";
private static final String USERCHATTYPE = "private";
private static final String GROUPCHATTYPE = "group";
@ -126,6 +128,20 @@ public class Chat implements BotApiObject {
*/
@JsonProperty(HASPROTECTEDCONTENT_FIELD)
private Boolean HasProtectedContent;
/**
* Optional.
* True, if users need to join the supergroup before they can send messages.
* Returned only in getChat.
*/
@JsonProperty(JOINTOSENDMESSAGES_FIELD)
private Boolean joinToSendMessages;
/**
* Optional.
* True, if all users directly joining the supergroup need to be approved by supergroup administrators.
* Returned only in getChat.
*/
@JsonProperty(JOINBYREQUEST_FIELD)
private Boolean joinByRequest;
@JsonIgnore
public Boolean isGroupChat() {

View File

@ -44,6 +44,12 @@ public class Document implements BotApiObject {
private String fileName; ///< Optional. Original filename as defined by sender
@JsonProperty(MIMETYPE_FIELD)
private String mimeType; ///< Optional. Mime type of a file as defined by sender
/**
* Optional.
* File size in bytes.
* It can be bigger than 2^31 and some programming languages may have difficulty/silent defects in interpreting it.
* But it has at most 52 significant bits, so a signed 64-bit integer or double-precision float type are safe for storing this value.
*/
@JsonProperty(FILESIZE_FIELD)
private Integer fileSize; ///< Optional. File size
private Long fileSize;
}

View File

@ -37,8 +37,14 @@ public class File implements BotApiObject {
*/
@JsonProperty(FILEUNIQUEID_FIELD)
private String fileUniqueId;
/**
* Optional.
* File size in bytes.
* It can be bigger than 2^31 and some programming languages may have difficulty/silent defects in interpreting it.
* But it has at most 52 significant bits, so a signed 64-bit integer or double-precision float type are safe for storing this value.
*/
@JsonProperty(FILE_SIZE_FIELD)
private Integer fileSize; ///< Optional. File size, if known
private Long fileSize;
@JsonProperty(FILE_PATH_FIELD)
private String filePath; ///< Optional. File path. Use https://api.telegram.org/file/bot<token>/<file_path> to get the file.

View File

@ -13,7 +13,7 @@ import org.telegram.telegrambots.meta.api.interfaces.BotApiObject;
/**
* @author Ruben Bermudez
* @version 3.0
* @version 6.1
* This object represents a Telegram user or bot.
*/
@EqualsAndHashCode(callSuper = false)
@ -24,7 +24,6 @@ import org.telegram.telegrambots.meta.api.interfaces.BotApiObject;
@AllArgsConstructor
@RequiredArgsConstructor
public class User implements BotApiObject {
private static final String ID_FIELD = "id";
private static final String FIRSTNAME_FIELD = "first_name";
private static final String ISBOT_FIELD = "is_bot";
@ -34,6 +33,8 @@ public class User implements BotApiObject {
private static final String CANJOINGROUPS_FIELD = "can_join_groups";
private static final String CANREADALLGROUPMESSAGES_FIELD = "can_read_all_group_messages";
private static final String SUPPORTINLINEQUERIES_FIELD = "supports_inline_queries";
private static final String ISPREMIUM_FIELD = "is_premium";
private static final String ADDEDTOATTACHMENTMENU_FIELD = "added_to_attachment_menu";
/**
* Unique identifier for this user or bot.
@ -62,4 +63,8 @@ public class User implements BotApiObject {
private Boolean canReadAllGroupMessages; ///< Optional. True, if privacy mode is disabled for the bot. Returned only in getMe.
@JsonProperty(SUPPORTINLINEQUERIES_FIELD)
private Boolean supportInlineQueries; ///< Optional. True, if the bot supports inline queries. Returned only in getMe.
@JsonProperty(ISPREMIUM_FIELD)
private Boolean isPremium; ///< Optional. True, if this user is a Telegram Premium user
@JsonProperty(ADDEDTOATTACHMENTMENU_FIELD)
private Boolean addedToAttachmentMenu; ///< Optional. True, if this user added the bot to the attachment menu
}

View File

@ -50,8 +50,14 @@ public class Video implements BotApiObject {
private PhotoSize thumb; ///< Video thumbnail
@JsonProperty(MIMETYPE_FIELD)
private String mimeType; ///< Optional. Mime type of a file as defined by sender
/**
* Optional.
* File size in bytes.
* It can be bigger than 2^31 and some programming languages may have difficulty/silent defects in interpreting it.
* But it has at most 52 significant bits, so a signed 64-bit integer or double-precision float type are safe for storing this value.
*/
@JsonProperty(FILESIZE_FIELD)
private Integer fileSize; ///< Optional. File size
private Long fileSize;
@JsonProperty(FILENAME_FIELD)
private String fileName; ///< Optional. Original filename as defined by sender
}

View File

@ -39,6 +39,12 @@ public class Voice implements BotApiObject {
private Integer duration; ///< Integer Duration of the audio in seconds as defined by sender
@JsonProperty(MIMETYPE_FIELD)
private String mimeType; ///< Optional. MIME type of the file as defined by sender
/**
* Optional.
* File size in bytes.
* It can be bigger than 2^31 and some programming languages may have difficulty/silent defects in interpreting it.
* But it has at most 52 significant bits, so a signed 64-bit integer or double-precision float type are safe for storing this value.
*/
@JsonProperty(FILESIZE_FIELD)
private Integer fileSize; ///< Optional. File size
private Long fileSize;
}

View File

@ -76,6 +76,12 @@ public class Animation implements BotApiObject {
private String fileName; ///< Optional. Original animation filename as defined by sender
@JsonProperty(MIMETYPE_FIELD)
private String mimetype; ///< Optional. MIME type of the file as defined by sender
/**
* Optional.
* File size in bytes.
* It can be bigger than 2^31 and some programming languages may have difficulty/silent defects in interpreting it.
* But it has at most 52 significant bits, so a signed 64-bit integer or double-precision float type are safe for storing this value.
*/
@JsonProperty(FILESIZE_FIELD)
private Integer fileSize; ///< Optional. File size
private Long fileSize;
}

View File

@ -19,7 +19,7 @@ import org.telegram.telegrambots.meta.exceptions.TelegramApiValidationException;
/**
* @author Ruben Bermudez
* @version 1.0
* @version 6.1
* This object represents one button of an inline keyboard. You must use exactly one of the
* optional fields.
* @apiNote This will only work in Telegram versions released after 9 April, 2016. Older clients will
@ -94,7 +94,8 @@ public class InlineKeyboardButton implements Validable, BotApiObject {
@JsonProperty(PAY_FIELD)
private Boolean pay;
/**
* Optional. An HTTP URL used to automatically authorize the user.
* Optional.
* An HTTPS URL used to automatically authorize the user.
* Can be used as a replacement for the Telegram Login Widget.
*/
@JsonProperty(LOGIN_URL_FIELD)

View File

@ -8,11 +8,12 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.telegram.telegrambots.meta.api.interfaces.BotApiObject;
import org.telegram.telegrambots.meta.api.objects.File;
import org.telegram.telegrambots.meta.api.objects.PhotoSize;
/**
* @author Ruben Bermudez
* @version 1.0
* @version 6.1
* This object represents a sticker.
*/
@EqualsAndHashCode(callSuper = false)
@ -34,6 +35,7 @@ public class Sticker implements BotApiObject {
private static final String MASKPOSITON_FIELD = "mask_position";
private static final String ISANIMATED_FIELD = "is_animated";
private static final String ISVIDEO_FIELD = "is_video";
private static final String PREMIUMANIMATION_FIELD = "premium_animation";
@JsonProperty(FILEID_FIELD)
private String fileId; ///< Identifier for this file, which can be used to download or reuse the file
@ -61,4 +63,6 @@ public class Sticker implements BotApiObject {
private Boolean isAnimated; ///< True, if the sticker is animated
@JsonProperty(ISVIDEO_FIELD)
private Boolean isVideo; ///< True, if the sticker is a video sticker
@JsonProperty(PREMIUMANIMATION_FIELD)
private File premiumAnimation; ///< Optional. Premium animation for the sticker, if the sticker is premium
}

View File

@ -0,0 +1,128 @@
package org.telegram.telegrambots.meta.api.methods.invoices;
import org.junit.jupiter.api.Test;
import org.telegram.telegrambots.meta.api.objects.payments.LabeledPrice;
import org.telegram.telegrambots.meta.exceptions.TelegramApiValidationException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* @author Ruben Bermudez
* @version 5.2
*/
public class CreateInvoiceLinkTest {
@Test
public void validObjectMustNotThrow() {
CreateInvoiceLink createInvoiceLink = createSendInvoiceObject();
assertDoesNotThrow(createInvoiceLink::validate);
createInvoiceLink.setSuggestedTipAmounts(new ArrayList<>());
assertDoesNotThrow(createInvoiceLink::validate);
}
@Test
public void titleCantBeEmpty() {
CreateInvoiceLink createInvoiceLink = createSendInvoiceObject();
createInvoiceLink.setTitle("");
Throwable thrown = assertThrows(TelegramApiValidationException.class, createInvoiceLink::validate);
assertEquals("Title parameter can't be empty or longer than 32 chars", thrown.getMessage());
}
@Test
public void titleCantBeOver32Chars() {
CreateInvoiceLink createInvoiceLink = createSendInvoiceObject();
createInvoiceLink.setTitle("1234567890123456789012345678901234");
Throwable thrown = assertThrows(TelegramApiValidationException.class, createInvoiceLink::validate);
assertEquals("Title parameter can't be empty or longer than 32 chars", thrown.getMessage());
}
@Test
public void descriptionCantBeEmpty() {
CreateInvoiceLink createInvoiceLink = createSendInvoiceObject();
createInvoiceLink.setDescription("");
Throwable thrown = assertThrows(TelegramApiValidationException.class, createInvoiceLink::validate);
assertEquals("Description parameter can't be empty or longer than 255 chars", thrown.getMessage());
}
@Test
public void descriptionCantBeOver255() {
CreateInvoiceLink createInvoiceLink = createSendInvoiceObject();
createInvoiceLink.setDescription("1234567890123456789012345678901234567890123456789012345678901234567890" +
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" +
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345" +
"1234567890123456789012345678901234567890123456789012345678901234567890");
Throwable thrown = assertThrows(TelegramApiValidationException.class, createInvoiceLink::validate);
assertEquals("Description parameter can't be empty or longer than 255 chars", thrown.getMessage());
}
@Test
public void payloadCantBeEmpty() {
CreateInvoiceLink createInvoiceLink = createSendInvoiceObject();
createInvoiceLink.setPayload("");
Throwable thrown = assertThrows(TelegramApiValidationException.class, createInvoiceLink::validate);
assertEquals("Payload parameter can't be empty", thrown.getMessage());
}
@Test
public void providerTokenCantBeEmpty() {
CreateInvoiceLink createInvoiceLink = createSendInvoiceObject();
createInvoiceLink.setProviderToken("");
Throwable thrown = assertThrows(TelegramApiValidationException.class, createInvoiceLink::validate);
assertEquals("ProviderToken parameter can't be empty", thrown.getMessage());
}
@Test
public void currencyCantBeEmpty() {
CreateInvoiceLink createInvoiceLink = createSendInvoiceObject();
createInvoiceLink.setCurrency("");
Throwable thrown = assertThrows(TelegramApiValidationException.class, createInvoiceLink::validate);
assertEquals("Currency parameter can't be empty", thrown.getMessage());
}
@Test
public void pricesMustBeValidated() {
CreateInvoiceLink createInvoiceLink = createSendInvoiceObject();
createInvoiceLink.setPrices(Collections.singletonList(LabeledPrice.builder().label("").amount(1).build()));
Throwable thrown = assertThrows(TelegramApiValidationException.class, createInvoiceLink::validate);
assertEquals("Label parameter can't be empty", thrown.getMessage());
}
@Test
public void pricesCantBeEmpty() {
CreateInvoiceLink createInvoiceLink = createSendInvoiceObject();
createInvoiceLink.setPrices(new ArrayList<>());
Throwable thrown = assertThrows(TelegramApiValidationException.class, createInvoiceLink::validate);
assertEquals("Prices parameter can't be empty", thrown.getMessage());
createInvoiceLink.setPrices(Collections.singletonList(LabeledPrice.builder().label("").amount(1).build()));
thrown = assertThrows(TelegramApiValidationException.class, createInvoiceLink::validate);
assertEquals("Label parameter can't be empty", thrown.getMessage());
}
@Test
public void suggestedTipAmountsMustNotHaveMoreThan4Elements() {
CreateInvoiceLink createInvoiceLink = createSendInvoiceObject();
createInvoiceLink.setSuggestedTipAmounts(Arrays.asList(1,2,3,4,5));
Throwable thrown = assertThrows(TelegramApiValidationException.class, createInvoiceLink::validate);
assertEquals("No more that 4 suggested tips allowed", thrown.getMessage());
}
private CreateInvoiceLink createSendInvoiceObject() {
return CreateInvoiceLink.builder()
.title("Title")
.description("Description")
.payload("Payload")
.providerToken("ProviderToken")
.currency("Currency")
.price(LabeledPrice.builder().label("Label").amount(1).build())
.suggestedTipAmount(1)
.suggestedTipAmount(2)
.suggestedTipAmount(3)
.suggestedTipAmount(4)
.build();
}
}

View File

@ -1,4 +1,4 @@
package org.telegram.telegrambots.meta.api.methods.send;
package org.telegram.telegrambots.meta.api.methods.invoices;
import org.junit.jupiter.api.Test;
import org.telegram.telegrambots.meta.api.objects.payments.LabeledPrice;
@ -40,7 +40,15 @@ public class SendInvoiceTest {
SendInvoice sendInvoice = createSendInvoiceObject();
sendInvoice.setTitle("");
Throwable thrown = assertThrows(TelegramApiValidationException.class, sendInvoice::validate);
assertEquals("Title parameter can't be empty", thrown.getMessage());
assertEquals("Title parameter can't be empty or longer than 32 chars", thrown.getMessage());
}
@Test
public void titleCantBeOver32Chars() {
SendInvoice sendInvoice = createSendInvoiceObject();
sendInvoice.setTitle("1234567890123456789012345678901234");
Throwable thrown = assertThrows(TelegramApiValidationException.class, sendInvoice::validate);
assertEquals("Title parameter can't be empty or longer than 32 chars", thrown.getMessage());
}
@Test
@ -48,7 +56,18 @@ public class SendInvoiceTest {
SendInvoice sendInvoice = createSendInvoiceObject();
sendInvoice.setDescription("");
Throwable thrown = assertThrows(TelegramApiValidationException.class, sendInvoice::validate);
assertEquals("Description parameter can't be empty", thrown.getMessage());
assertEquals("Description parameter can't be empty or longer than 255 chars", thrown.getMessage());
}
@Test
public void descriptionCantBeOver255() {
SendInvoice sendInvoice = createSendInvoiceObject();
sendInvoice.setDescription("1234567890123456789012345678901234567890123456789012345678901234567890" +
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" +
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345" +
"1234567890123456789012345678901234567890123456789012345678901234567890");
Throwable thrown = assertThrows(TelegramApiValidationException.class, sendInvoice::validate);
assertEquals("Description parameter can't be empty or longer than 255 chars", thrown.getMessage());
}
@Test

View File

@ -489,7 +489,7 @@ class TestDeserialization {
assertEquals("AwADBAADbXXXXXXXXXXXGBdhD2l6_XX", document.getFileId());
assertEquals("Testfile.pdf", document.getFileName());
assertEquals("application/pdf", document.getMimeType());
assertEquals(Integer.valueOf(536392), document.getFileSize());
assertEquals(Long.valueOf(536392), document.getFileSize());
}
private void assertVoice(Voice voice) {
@ -497,7 +497,7 @@ class TestDeserialization {
assertEquals("AwADBAADbXXXXXXXXXXXGBdhD2l6_XX", voice.getFileId());
assertEquals(Integer.valueOf(5), voice.getDuration());
assertEquals("audio/ogg", voice.getMimeType());
assertEquals(Integer.valueOf(23000), voice.getFileSize());
assertEquals(Long.valueOf(23000), voice.getFileSize());
}
private void assertAudio(Audio audio) {
@ -505,7 +505,7 @@ class TestDeserialization {
assertEquals("AwADBAADbXXXXXXXXXXXGBdhD2l6_XX", audio.getFileId());
assertEquals(Integer.valueOf(243), audio.getDuration());
assertEquals("audio/mpeg", audio.getMimeType());
assertEquals(Integer.valueOf(3897500), audio.getFileSize());
assertEquals(Long.valueOf(3897500), audio.getFileSize());
assertEquals("Testmusicfile", audio.getTitle());
}