From fc712656faf6c5e304e915f4ac86ba8331c177fc Mon Sep 17 00:00:00 2001 From: Rubenlagus Date: Mon, 27 Mar 2017 00:49:08 +0200 Subject: [PATCH] Payments API --- README.md | 6 +- TelegramBots.wiki/Changelog.md | 10 +- TelegramBots.wiki/Getting-Started.md | 4 +- TelegramBots.wiki/How-To-Update.md | 5 +- pom.xml | 4 +- telegrambots-meta/pom.xml | 13 +- .../api/methods/AnswerPreCheckoutQuery.java | 125 ++++++ .../api/methods/AnswerShippingQuery.java | 146 +++++++ .../api/methods/send/SendAudio.java | 6 +- .../api/methods/send/SendContact.java | 6 +- .../api/methods/send/SendDocument.java | 6 +- .../api/methods/send/SendGame.java | 6 +- .../api/methods/send/SendInvoice.java | 388 ++++++++++++++++++ .../api/methods/send/SendLocation.java | 6 +- .../api/methods/send/SendMessage.java | 6 +- .../api/methods/send/SendPhoto.java | 6 +- .../api/methods/send/SendSticker.java | 6 +- .../api/methods/send/SendVenue.java | 6 +- .../api/methods/send/SendVideo.java | 6 +- .../api/methods/send/SendVoice.java | 6 +- .../telegrambots/api/objects/Message.java | 39 +- .../telegrambots/api/objects/Update.java | 34 +- .../result/InlineQueryResultGame.java | 10 +- .../result/InlineQueryResultGif.java | 16 +- .../result/InlineQueryResultMpeg4Gif.java | 16 +- .../api/objects/payments/Invoice.java | 77 ++++ .../api/objects/payments/LabeledPrice.java | 79 ++++ .../api/objects/payments/OrderInfo.java | 56 +++ .../objects/payments/PreCheckoutQuery.java | 85 ++++ .../api/objects/payments/ShippingAddress.java | 72 ++++ .../api/objects/payments/ShippingOption.java | 100 +++++ .../api/objects/payments/ShippingQuery.java | 57 +++ .../objects/payments/SuccessfulPayment.java | 84 ++++ .../replykeyboard/ReplyKeyboardMarkup.java | 12 +- .../buttons/InlineKeyboardButton.java | 23 +- .../telegram/telegrambots/bots/AbsSender.java | 88 ++-- telegrambots/pom.xml | 15 +- .../telegrambots/bots/DefaultAbsSender.java | 9 + .../test/BotApiMethodHelperFactory.java | 25 +- .../telegrambots/test/TestRestApi.java | 17 + 40 files changed, 1547 insertions(+), 134 deletions(-) create mode 100644 telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/AnswerPreCheckoutQuery.java create mode 100644 telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/AnswerShippingQuery.java create mode 100644 telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendInvoice.java create mode 100644 telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/Invoice.java create mode 100644 telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/LabeledPrice.java create mode 100644 telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/OrderInfo.java create mode 100644 telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/PreCheckoutQuery.java create mode 100644 telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/ShippingAddress.java create mode 100644 telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/ShippingOption.java create mode 100644 telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/ShippingQuery.java create mode 100644 telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/SuccessfulPayment.java diff --git a/README.md b/README.md index 2301f786..acc96d74 100644 --- a/README.md +++ b/README.md @@ -27,12 +27,12 @@ Just import add the library to your project with one of these options: org.telegram telegrambots - 2.4.4.5 + 2.4.4.6 ``` - 2. Using Jitpack from [here](https://jitpack.io/#rubenlagus/TelegramBots/2.4.4.5) - 3. Download the jar(including all dependencies) from [here](https://github.com/rubenlagus/TelegramBots/releases/tag/2.4.4.5) + 2. Using Jitpack from [here](https://jitpack.io/#rubenlagus/TelegramBots/2.4.4.6) + 3. Download the jar(including all dependencies) from [here](https://github.com/rubenlagus/TelegramBots/releases/tag/2.4.4.6) In order to use Long Polling mode, just create your own bot extending `org.telegram.telegrambots.bots.TelegramLongPollingBot`. diff --git a/TelegramBots.wiki/Changelog.md b/TelegramBots.wiki/Changelog.md index 36a150a3..fe8b58c9 100644 --- a/TelegramBots.wiki/Changelog.md +++ b/TelegramBots.wiki/Changelog.md @@ -42,4 +42,12 @@ 3. Added new How to send photos by file_id to FAQ. 4. Added reference to new gitbook about this library. 5. Added custom ExponentialBackOff waiting time when having network problems in long-polling mode. (Custom implementation is allowed via BotOptions) -6. Bug fixing: #184, #183 \ No newline at end of file +6. Bug fixing: #184, #183 + +### 2.4.4.6 ### +1. New field `gif_duration` and `mpeg4_duration` in `InlineQueryResultGif` and `InlineQueryResultMpeg4Gif`. +2. Field `new_chat_member` was replaced by `new_chat_members` in `Message` object. +3. Some methods gets now constructors with mandatory parameters to simplify their creation (including preconditions). +4. New Payments API methods + +**[[How to update to version 2.4.4.6|How-To-Update#2.4.4.6]]** \ No newline at end of file diff --git a/TelegramBots.wiki/Getting-Started.md b/TelegramBots.wiki/Getting-Started.md index 1b264f32..4fc69a5d 100644 --- a/TelegramBots.wiki/Getting-Started.md +++ b/TelegramBots.wiki/Getting-Started.md @@ -11,13 +11,13 @@ First you need ot get the library and add it to your project. There are few poss org.telegram telegrambots - 2.4.4.5 + 2.4.4.6 ``` * With **Gradle**: ```groovy - compile group: 'org.telegram', name: 'telegrambots', version: '2.4.4.5' + compile group: 'org.telegram', name: 'telegrambots', version: '2.4.4.6' ``` 2. Don't like **Maven Central Repository**? It can also be taken from [Jitpack](https://jitpack.io/#rubenlagus/TelegramBots). diff --git a/TelegramBots.wiki/How-To-Update.md b/TelegramBots.wiki/How-To-Update.md index e0a82b2c..676615ec 100644 --- a/TelegramBots.wiki/How-To-Update.md +++ b/TelegramBots.wiki/How-To-Update.md @@ -20,4 +20,7 @@ ### To version 2.4.4.4 ### 1. All calls to `editMessageText`, `editMessageCaption` or `editMessageReplyMarkup` in `AbsSender` return value is changed to `Serializable` -2. In `editMessageTextAsync`, `editMessageCaptionAsync` or `editMessageReplyMarkupAsync` in `AbsSender`, second parameter should become `SentCallback` due to new return type. \ No newline at end of file +2. In `editMessageTextAsync`, `editMessageCaptionAsync` or `editMessageReplyMarkupAsync` in `AbsSender`, second parameter should become `SentCallback` due to new return type. + +### To version 2.4.4.6 ### +1. In `Message` object, field `new_chat_member` was replaced by `new_chat_members` that is now an array of users. \ No newline at end of file diff --git a/pom.xml b/pom.xml index f464327f..230f29eb 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ org.telegram Bots pom - 2.4.4.5 + 2.4.4.6 telegrambots @@ -24,6 +24,6 @@ true - 2.4.4.5 + 2.4.4.6 \ No newline at end of file diff --git a/telegrambots-meta/pom.xml b/telegrambots-meta/pom.xml index 1c630ae2..f7ab4329 100644 --- a/telegrambots-meta/pom.xml +++ b/telegrambots-meta/pom.xml @@ -5,7 +5,7 @@ 4.0.0 org.telegram telegrambots-meta - 2.4.4.5 + 2.4.4.6 jar Telegram Bots Meta @@ -228,6 +228,17 @@ + + org.apache.maven.plugins + maven-dependency-plugin + 2.4 + + + copy + package + + + diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/AnswerPreCheckoutQuery.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/AnswerPreCheckoutQuery.java new file mode 100644 index 00000000..b2c9199c --- /dev/null +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/AnswerPreCheckoutQuery.java @@ -0,0 +1,125 @@ +package org.telegram.telegrambots.api.methods; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.type.TypeReference; +import org.telegram.telegrambots.api.objects.replykeyboard.ApiResponse; +import org.telegram.telegrambots.exceptions.TelegramApiRequestException; +import org.telegram.telegrambots.exceptions.TelegramApiValidationException; + +import java.io.IOException; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * @author Ruben Bermudez + * @version 1.0 + * + * Once the user has confirmed their payment and shipping details, the Bot API sends the final confirmation + * in the form of an Update with the field pre_checkout_query. Use this method to respond to such pre-checkout queries. + * + * On success, True is returned + * + * @apiNote The Bot API must receive an answer within 10 seconds after the pre-checkout query was sent. + */ +public class AnswerPreCheckoutQuery extends BotApiMethod { + public static final String PATH = "answerPreCheckoutQuery"; + + private static final String PRE_CHECKOUT_QUERY_ID_FIELD = "pre_checkout_query_id"; + private static final String OK_FIELD = "ok"; + private static final String ERROR_MESSAGE_FIELD = "error_message"; + + @JsonProperty(PRE_CHECKOUT_QUERY_ID_FIELD) + private String preCheckoutQueryId; ///< Unique identifier for the query to be answered + @JsonProperty(OK_FIELD) + private Boolean ok; ///< Specify True if everything is alright (goods are available, etc.) and the bot is ready to proceed with the order. Use False if there are any problems. + @JsonProperty(ERROR_MESSAGE_FIELD) + private String errorMessage; ///< Optional. Required if ok is False. Error message in human readable form that explains the reason for failure to proceed with the checkout + + /** + * Creates an empty answer pre-checkout query + */ + public AnswerPreCheckoutQuery() { + super(); + } + + /** + * Creates an answer pre-checkout query with mandatory parameters + * @param preCheckoutQueryId Unique identifier for the query to be answered + * @param ok Specify True if delivery to the specified address is possible and False if there are any problems + */ + public AnswerPreCheckoutQuery(String preCheckoutQueryId, Boolean ok) { + this.preCheckoutQueryId = checkNotNull(preCheckoutQueryId); + this.ok = checkNotNull(ok); + } + + public String getPreCheckoutQueryId() { + return preCheckoutQueryId; + } + + public AnswerPreCheckoutQuery setPreCheckoutQueryId(String preCheckoutQueryId) { + this.preCheckoutQueryId = checkNotNull(preCheckoutQueryId); + return this; + } + + public Boolean getOk() { + return ok; + } + + public AnswerPreCheckoutQuery setOk(Boolean ok) { + this.ok = checkNotNull(ok); + return this; + } + + public String getErrorMessage() { + return errorMessage; + } + + public AnswerPreCheckoutQuery setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + return this; + } + + @Override + public void validate() throws TelegramApiValidationException { + if (preCheckoutQueryId == null || preCheckoutQueryId.isEmpty()) { + throw new TelegramApiValidationException("PreCheckoutQueryId can't be empty", this); + } + if (ok == null) { + throw new TelegramApiValidationException("Ok can't be null", this); + } + if (!ok) { + if (errorMessage == null || errorMessage.isEmpty()) { + throw new TelegramApiValidationException("ErrorMessage can't be empty if not ok", this); + } + } + } + + @Override + public String getMethod() { + return PATH; + } + + @Override + public Boolean deserializeResponse(String answer) throws TelegramApiRequestException { + try { + ApiResponse result = OBJECT_MAPPER.readValue(answer, + new TypeReference>(){}); + if (result.getOk()) { + return result.getResult(); + } else { + throw new TelegramApiRequestException("Error answering pre-checkout query", result); + } + } catch (IOException e) { + throw new TelegramApiRequestException("Unable to deserialize response", e); + } + } + + @Override + public String toString() { + return "AnswerPreCheckoutQuery{" + + "preCheckoutQueryId='" + preCheckoutQueryId + '\'' + + ", ok=" + ok + + ", errorMessage='" + errorMessage + '\'' + + '}'; + } +} diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/AnswerShippingQuery.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/AnswerShippingQuery.java new file mode 100644 index 00000000..63424aa2 --- /dev/null +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/AnswerShippingQuery.java @@ -0,0 +1,146 @@ +package org.telegram.telegrambots.api.methods; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.type.TypeReference; +import org.telegram.telegrambots.api.objects.payments.ShippingOption; +import org.telegram.telegrambots.api.objects.replykeyboard.ApiResponse; +import org.telegram.telegrambots.exceptions.TelegramApiRequestException; +import org.telegram.telegrambots.exceptions.TelegramApiValidationException; + +import java.io.IOException; +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * @author Ruben Bermudez + * @version 1.0 + * + * If you sent an invoice requesting a shipping address and the parameter flexible was specified, + * the Bot API will send an Update with a shipping_query field to the bot. + * Use this method to reply to shipping queries. + * + * On success, True is returned + */ +public class AnswerShippingQuery extends BotApiMethod { + public static final String PATH = "answerShippingQuery"; + + private static final String SHIPPING_QUERY_ID_FIELD = "shipping_query_id"; + private static final String OK_FIELD = "ok"; + private static final String SHIPPING_OPTIONS_FIELD = "shipping_options"; + private static final String ERROR_MESSAGE_FIELD = "error_message"; + + @JsonProperty(SHIPPING_QUERY_ID_FIELD) + private String shippingQueryId; ///< Unique identifier for the query to be answered + @JsonProperty(OK_FIELD) + private Boolean ok; ///< Specify True if delivery to the specified address is possible and False if there are any problems + @JsonProperty(SHIPPING_OPTIONS_FIELD) + private List shippingOptions; ///< Optional. Required if ok is True. A JSON-serialized array of available shipping options. + @JsonProperty(ERROR_MESSAGE_FIELD) + private String errorMessage; ///< Optional. Required if ok is False. Error message in human readable form that explains why it is impossible to complete the order (e.g. "Sorry, delivery to your desired address is unavailable'). + + /** + * Creates an empty answer shipping query + */ + public AnswerShippingQuery() { + super(); + } + + /** + * Creates an answer shipping query with mandatory parameters + * @param shippingQueryId Unique identifier for the query to be answered + * @param ok Specify True if delivery to the specified address is possible and False if there are any problems + */ + public AnswerShippingQuery(String shippingQueryId, Boolean ok) { + this.shippingQueryId = checkNotNull(shippingQueryId); + this.ok = checkNotNull(ok); + } + + public String getShippingQueryId() { + return shippingQueryId; + } + + public AnswerShippingQuery setShippingQueryId(String shippingQueryId) { + this.shippingQueryId = checkNotNull(shippingQueryId); + return this; + } + + public Boolean getOk() { + return ok; + } + + public AnswerShippingQuery setOk(Boolean ok) { + this.ok = checkNotNull(ok); + return this; + } + + public List getShippingOptions() { + return shippingOptions; + } + + public AnswerShippingQuery setShippingOptions(List shippingOptions) { + this.shippingOptions = shippingOptions; + return this; + } + + public String getErrorMessage() { + return errorMessage; + } + + public AnswerShippingQuery setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + return this; + } + + @Override + public void validate() throws TelegramApiValidationException { + if (shippingQueryId == null || shippingQueryId.isEmpty()) { + throw new TelegramApiValidationException("ShippingQueryId can't be empty", this); + } + if (ok == null) { + throw new TelegramApiValidationException("Ok can't be null", this); + } + if (ok) { + if (shippingOptions == null || shippingOptions.isEmpty()) { + throw new TelegramApiValidationException("ShippingOptions array can't be empty if ok", this); + } + for (ShippingOption shippingOption : shippingOptions) { + shippingOption.validate(); + } + } else { + if (errorMessage == null || errorMessage.isEmpty()) { + throw new TelegramApiValidationException("ErrorMessage can't be empty if not ok", this); + } + } + } + + @Override + public String getMethod() { + return PATH; + } + + @Override + public Boolean deserializeResponse(String answer) throws TelegramApiRequestException { + try { + ApiResponse result = OBJECT_MAPPER.readValue(answer, + new TypeReference>(){}); + if (result.getOk()) { + return result.getResult(); + } else { + throw new TelegramApiRequestException("Error answering shipping query", result); + } + } catch (IOException e) { + throw new TelegramApiRequestException("Unable to deserialize response", e); + } + } + + @Override + public String toString() { + return "AnswerShippingQuery{" + + "shippingQueryId='" + shippingQueryId + '\'' + + ", ok=" + ok + + ", shippingOptions=" + shippingOptions + + ", errorMessage='" + errorMessage + '\'' + + '}'; + } +} diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendAudio.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendAudio.java index 0bd726cd..6f053266 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendAudio.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendAudio.java @@ -41,11 +41,7 @@ public class SendAudio extends PartialBotApiMethod { private String chatId; ///< Unique identifier for the chat to send the message to (or Username fro channels) private String audio; ///< Audio file to send. file_id as String to resend an audio that is already on the Telegram servers or Url to upload it private Integer replyToMessageId; ///< Optional. If the message is a reply, ID of the original message - /** - * Optional. Sends the message silently. iOS users will not receive a notification, Android - * users will receive a notification with no sound. Other apps coming soon - */ - private Boolean disableNotification; + private Boolean disableNotification; ///< Optional. Sends the message silently. Users will receive a notification with no sound. private ReplyKeyboard replyMarkup; ///< Optional. JSON-serialized object for a custom reply keyboard private String performer; ///< Optional. Performer of sent audio private String title; ///< Optional. Title of sent audio diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendContact.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendContact.java index 1e0765fc..13982534 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendContact.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendContact.java @@ -39,12 +39,8 @@ public class SendContact extends BotApiMethod { private String firstName; ///< User's first name @JsonProperty(LAST_NAME_FIELD) private String lastName; ///< Optional. User's last name - /** - * Optional. Sends the message silently. iOS users will not receive a notification, Android - * users will receive a notification with no sound. Other apps coming soon - */ @JsonProperty(DISABLENOTIFICATION_FIELD) - private Boolean disableNotification; + private Boolean disableNotification; ///< Optional. Sends the message silently. Users will receive a notification with no sound. @JsonProperty(REPLYTOMESSAGEID_FIELD) private Integer replyToMessageId; ///< Optional. If the message is a reply, ID of the original message @JsonProperty(REPLYMARKUP_FIELD) diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendDocument.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendDocument.java index 82ccf0ee..c9bdc664 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendDocument.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendDocument.java @@ -32,11 +32,7 @@ public class SendDocument extends PartialBotApiMethod { private String chatId; ///< Unique identifier for the chat to send the message to or Username for the channel to send the message to private String document; ///< File file to send. file_id as String to resend a file that is already on the Telegram servers or Url to upload it private String caption; ///< Optional. Document caption (may also be used when resending documents by file_id), 0-200 characters - /** - * Optional. Sends the message silently. iOS users will not receive a notification, Android - * users will receive a notification with no sound. Other apps coming soon - */ - private Boolean disableNotification; + private Boolean disableNotification; ///< Optional. Sends the message silently. Users will receive a notification with no sound. private Integer replyToMessageId; ///< Optional. If the message is a reply, ID of the original message private ReplyKeyboard replyMarkup; ///< Optional. JSON-serialized object for a custom reply keyboard diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendGame.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendGame.java index 54bb240d..c9c94efc 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendGame.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendGame.java @@ -49,12 +49,8 @@ public class SendGame extends BotApiMethod { private String chatId; ///< Unique identifier for the chat to send the message to (Or username for channels) @JsonProperty(GAMESHORTNAME_FIELD) private String gameShortName; ///< Short name of the game - /** - * Optional. Sends the message silently. iOS users will not receive a notification, Android - * users will receive a notification with no sound. Other apps coming soon - */ @JsonProperty(DISABLENOTIFICATION_FIELD) - private Boolean disableNotification; + private Boolean disableNotification; ///< Optional. Sends the message silently. Users will receive a notification with no sound. @JsonProperty(REPLYTOMESSAGEID_FIELD) private Integer replyToMessageId; ///< Optional. If the message is a reply, ID of the original message @JsonProperty(REPLYMARKUP_FIELD) diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendInvoice.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendInvoice.java new file mode 100644 index 00000000..7330d60f --- /dev/null +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendInvoice.java @@ -0,0 +1,388 @@ +package org.telegram.telegrambots.api.methods.send; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.type.TypeReference; +import org.telegram.telegrambots.api.methods.BotApiMethod; +import org.telegram.telegrambots.api.objects.Message; +import org.telegram.telegrambots.api.objects.payments.LabeledPrice; +import org.telegram.telegrambots.api.objects.replykeyboard.ApiResponse; +import org.telegram.telegrambots.api.objects.replykeyboard.InlineKeyboardMarkup; +import org.telegram.telegrambots.exceptions.TelegramApiRequestException; +import org.telegram.telegrambots.exceptions.TelegramApiValidationException; + +import java.io.IOException; +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * @author Ruben Bermudez + * @version 1.0 + * Use this method to send an invoice. On success, the sent Message is returned. + */ +public class SendInvoice extends BotApiMethod { + 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 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\t"; + + @JsonProperty(CHATID_FIELD) + private Integer chatId; ///< Unique identifier for the target private chat + @JsonProperty(TITLE_FIELD) + private String title; ///< Product name + @JsonProperty(DESCRIPTION_FIELD) + private String description; ///< Product description + @JsonProperty(PAYLOAD_FIELD) + 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) + private String providerToken; ///< Payments provider token, obtained via Botfather + @JsonProperty(START_PARAMETER_FIELD) + private String startParameter; ///< Unique deep-linking parameter that can be used to generate this invoice when used as a start parameter. + @JsonProperty(CURRENCY_FIELD) + private String currency; ///< 3-letter ISO 4217 currency code + @JsonProperty(PRICES_FIELD) + private List prices; ///< Price breakdown, a list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.) + @JsonProperty(PHOTO_URL_FIELD) + /** + * 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 + */ + 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(REPLY_MARKUP_FIELD) + /** + * Optional. A JSON-serialized object for an inline keyboard. + * + * @note If empty, one 'Buy title' button will be shown. If not empty, the first button must be a Pay button. + */ + private InlineKeyboardMarkup replyMarkup; + + + /** + * Build an empty SendInvoice object + */ + public SendInvoice() { + super(); + } + + /** + * Build a SendInvoice object with empty parameters + * @param chatId Unique identifier for the target private chat + * @param title Product name + * @param description Product description + * @param payload Bot defined invoice payload, 1-128 bytes. + * @param providerToken Payments provider token + * @param startParameter Unique deep-linking parameter. + * @param currency 3-letter ISO 4217 currency code + * @param prices Price breakdown, a list of components + */ + public SendInvoice(Integer chatId, String title, String description, String payload, String providerToken, + String startParameter, String currency, List prices) { + this.chatId = checkNotNull(chatId); + this.title = checkNotNull(title); + this.description = checkNotNull(description); + this.payload = checkNotNull(payload); + this.providerToken = checkNotNull(providerToken); + this.startParameter = checkNotNull(startParameter); + this.currency = checkNotNull(currency); + this.prices = checkNotNull(prices); + } + + public Integer getChatId() { + return chatId; + } + + public SendInvoice setChatId(Integer chatId) { + this.chatId = checkNotNull(chatId); + return this; + } + + public String getTitle() { + return title; + } + + public SendInvoice setTitle(String title) { + this.title = checkNotNull(title); + return this; + } + + public String getDescription() { + return description; + } + + public SendInvoice setDescription(String description) { + this.description = checkNotNull(description); + return this; + } + + public String getPayload() { + return payload; + } + + public SendInvoice setPayload(String payload) { + this.payload = checkNotNull(payload); + return this; + } + + public String getProviderToken() { + return providerToken; + } + + public SendInvoice setProviderToken(String providerToken) { + this.providerToken = checkNotNull(providerToken); + return this; + } + + public String getStartParameter() { + return startParameter; + } + + public SendInvoice setStartParameter(String startParameter) { + this.startParameter = checkNotNull(startParameter); + return this; + } + + public String getCurrency() { + return currency; + } + + public SendInvoice setCurrency(String currency) { + this.currency = checkNotNull(currency); + return this; + } + + public List getPrices() { + return prices; + } + + public SendInvoice setPrices(List prices) { + this.prices = checkNotNull(prices); + return this; + } + + public String getPhotoUrl() { + return photoUrl; + } + + public SendInvoice setPhotoUrl(String photoUrl) { + this.photoUrl = photoUrl; + return this; + } + + public Integer getPhotoSize() { + return photoSize; + } + + public SendInvoice setPhotoSize(Integer photoSize) { + this.photoSize = photoSize; + return this; + } + + public Integer getPhotoWidth() { + return photoWidth; + } + + public SendInvoice setPhotoWidth(Integer photoWidth) { + this.photoWidth = photoWidth; + return this; + } + + public Integer getPhotoHeight() { + return photoHeight; + } + + public SendInvoice setPhotoHeight(Integer photoHeight) { + this.photoHeight = photoHeight; + return this; + } + + public Boolean getNeedName() { + return needName; + } + + public SendInvoice setNeedName(Boolean needName) { + this.needName = needName; + return this; + } + + public Boolean getNeedPhoneNumber() { + return needPhoneNumber; + } + + public SendInvoice setNeedPhoneNumber(Boolean needPhoneNumber) { + this.needPhoneNumber = needPhoneNumber; + return this; + } + + public Boolean getNeedEmail() { + return needEmail; + } + + public SendInvoice setNeedEmail(Boolean needEmail) { + this.needEmail = needEmail; + return this; + } + + public Boolean getNeedShippingAddress() { + return needShippingAddress; + } + + public SendInvoice setNeedShippingAddress(Boolean needShippingAddress) { + this.needShippingAddress = needShippingAddress; + return this; + } + + public Boolean getFlexible() { + return isFlexible; + } + + public SendInvoice setFlexible(Boolean flexible) { + isFlexible = flexible; + return this; + } + + public Boolean getDisableNotification() { + return disableNotification; + } + + public SendInvoice setDisableNotification(Boolean disableNotification) { + this.disableNotification = disableNotification; + return this; + } + + public Integer getReplyToMessageId() { + return replyToMessageId; + } + + public SendInvoice setReplyToMessageId(Integer replyToMessageId) { + this.replyToMessageId = replyToMessageId; + return this; + } + + public InlineKeyboardMarkup getReplyMarkup() { + return replyMarkup; + } + + public SendInvoice setReplyMarkup(InlineKeyboardMarkup replyMarkup) { + this.replyMarkup = replyMarkup; + return this; + } + + @Override + public String getMethod() { + return PATH; + } + + @Override + public Message deserializeResponse(String answer) throws TelegramApiRequestException { + try { + ApiResponse result = OBJECT_MAPPER.readValue(answer, + new TypeReference>(){}); + 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 (chatId == null) { + throw new TelegramApiValidationException("ChatId parameter can't be empty", this); + } + if (title == null || title.isEmpty()) { + throw new TelegramApiValidationException("Title parameter can't be empty", this); + } + if (description == null || description.isEmpty()) { + throw new TelegramApiValidationException("Description parameter can't be empty", this); + } + if (payload == null || payload.isEmpty()) { + throw new TelegramApiValidationException("Payload parameter can't be empty", this); + } + if (providerToken == null || providerToken.isEmpty()) { + throw new TelegramApiValidationException("ProviderToken parameter can't be empty", this); + } + if (startParameter == null || startParameter.isEmpty()) { + throw new TelegramApiValidationException("StartParameter parameter can't be empty", this); + } + if (currency == null || currency.isEmpty()) { + throw new TelegramApiValidationException("Currency parameter can't be empty", this); + } + if (prices == null || prices.isEmpty()) { + throw new TelegramApiValidationException("Prices parameter can't be empty", this); + } else { + for (LabeledPrice price : prices) { + price.validate(); + } + } + if (replyMarkup != null) { + replyMarkup.validate(); + } + } + + @Override + public String toString() { + return "SendInvoice{" + + "chatId='" + chatId + '\'' + + ", title='" + title + '\'' + + ", description='" + description + '\'' + + ", payload='" + payload + '\'' + + ", providerToken='" + providerToken + '\'' + + ", startParameter='" + startParameter + '\'' + + ", currency='" + currency + '\'' + + ", prices=" + prices + + ", photoUrl='" + photoUrl + '\'' + + ", photoSize=" + photoSize + + ", photoWidth=" + photoWidth + + ", photoHeight=" + photoHeight + + ", needName=" + needName + + ", needPhoneNumber=" + needPhoneNumber + + ", needEmail=" + needEmail + + ", needShippingAddress=" + needShippingAddress + + ", isFlexible=" + isFlexible + + ", disableNotification=" + disableNotification + + ", replyToMessageId=" + replyToMessageId + + ", replyMarkup=" + replyMarkup + + '}'; + } +} diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendLocation.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendLocation.java index e36a2927..74f58ced 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendLocation.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendLocation.java @@ -35,12 +35,8 @@ public class SendLocation extends BotApiMethod { private Float latitude; ///< Latitude of location @JsonProperty(LONGITUDE_FIELD) private Float longitude; ///< Longitude of location - /** - * Optional. Sends the message silently. iOS users will not receive a notification, Android - * users will receive a notification with no sound. Other apps coming soon - */ @JsonProperty(DISABLENOTIFICATION_FIELD) - private Boolean disableNotification; + private Boolean disableNotification; ///< Optional. Sends the message silently. Users will receive a notification with no sound. @JsonProperty(REPLYTOMESSAGEID_FIELD) private Integer replyToMessageId; ///< Optional. If the message is a reply, ID of the original message @JsonProperty(REPLYMARKUP_FIELD) diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendMessage.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendMessage.java index 42db3e56..ad877042 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendMessage.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendMessage.java @@ -39,12 +39,8 @@ public class SendMessage extends BotApiMethod { private String parseMode; ///< Optional. Send Markdown, if you want Telegram apps to show bold, italic and URL text in your bot's message. @JsonProperty(DISABLEWEBPAGEPREVIEW_FIELD) private Boolean disableWebPagePreview; ///< Optional. Disables link previews for links in this message - /** - * Optional. Sends the message silently. iOS users will not receive a notification, Android - * users will receive a notification with no sound. Other apps coming soon - */ @JsonProperty(DISABLENOTIFICATION_FIELD) - private Boolean disableNotification; + private Boolean disableNotification; ///< Optional. Sends the message silently. Users will receive a notification with no sound. @JsonProperty(REPLYTOMESSAGEID_FIELD) private Integer replyToMessageId; ///< Optional. If the message is a reply, ID of the original message @JsonProperty(REPLYMARKUP_FIELD) diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendPhoto.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendPhoto.java index 66999b2c..c956b665 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendPhoto.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendPhoto.java @@ -32,11 +32,7 @@ public class SendPhoto extends PartialBotApiMethod { private String chatId; ///< Unique identifier for the chat to send the message to (Or username for channels) private String photo; ///< Photo to send. file_id as String to resend a photo that is already on the Telegram servers or URL to upload it private String caption; ///< Optional Photo caption (may also be used when resending photos by file_id). - /** - * Optional. Sends the message silently. iOS users will not receive a notification, Android - * users will receive a notification with no sound. Other apps coming soon - */ - private Boolean disableNotification; + private Boolean disableNotification; ///< Optional. Sends the message silently. Users will receive a notification with no sound. private Integer replyToMessageId; ///< Optional. If the message is a reply, ID of the original message private ReplyKeyboard replyMarkup; ///< Optional. JSON-serialized object for a custom reply keyboard diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendSticker.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendSticker.java index 3bb9d4e9..cd08c537 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendSticker.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendSticker.java @@ -30,11 +30,7 @@ public class SendSticker extends PartialBotApiMethod { public static final String REPLYMARKUP_FIELD = "reply_markup"; private String chatId; ///< Unique identifier for the chat to send the message to (Or username for channels) private String sticker; ///< Sticker file to send. file_id as String to resend a sticker that is already on the Telegram servers or URL to upload it - /** - * Optional. Sends the message silently. iOS users will not receive a notification, Android - * users will receive a notification with no sound. Other apps coming soon - */ - private Boolean disableNotification; + private Boolean disableNotification; ///< Optional. Sends the message silently. Users will receive a notification with no sound. private Integer replyToMessageId; ///< Optional. If the message is a reply, ID of the original message private ReplyKeyboard replyMarkup; ///< Optional. JSON-serialized object for a custom reply keyboard diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendVenue.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendVenue.java index 3ca54999..591c1a21 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendVenue.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendVenue.java @@ -41,12 +41,8 @@ public class SendVenue extends BotApiMethod { private Float longitude; ///< Longitude of venue location @JsonProperty(TITLE_FIELD) private String title; ///< Title of the venue - /** - * Optional. Sends the message silently. iOS users will not receive a notification, Android - * users will receive a notification with no sound. Other apps coming soon - */ @JsonProperty(DISABLENOTIFICATION_FIELD) - private Boolean disableNotification; + private Boolean disableNotification; ///< Optional. Sends the message silently. Users will receive a notification with no sound. @JsonProperty(ADDRESS_FIELD) private String address; ///< Address of the venue @JsonProperty(FOURSQUARE_ID_FIELD) diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendVideo.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendVideo.java index 1424ef16..f999e221 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendVideo.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendVideo.java @@ -39,11 +39,7 @@ public class SendVideo extends PartialBotApiMethod { private String caption; ///< OptionaL. Video caption (may also be used when resending videos by file_id). private Integer width; ///< Optional. Video width private Integer height; ///< OptionaL. Video height - /** - * Optional. Sends the message silently. iOS users will not receive a notification, Android - * users will receive a notification with no sound. Other apps coming soon - */ - private Boolean disableNotification; + private Boolean disableNotification; ///< Optional. Sends the message silently. Users will receive a notification with no sound. private Integer replyToMessageId; ///< Optional. If the message is a reply, ID of the original message private ReplyKeyboard replyMarkup; ///< Optional. JSON-serialized object for a custom reply keyboard diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendVoice.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendVoice.java index d350594a..ca5bd11e 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendVoice.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/methods/send/SendVoice.java @@ -35,11 +35,7 @@ public class SendVoice extends PartialBotApiMethod { private String chatId; ///< Unique identifier for the chat sent message to (Or username for channels) private String voice; ///< Audio file to send. You can either pass a file_id as String to resend an audio that is already on the Telegram servers, or upload a new audio file using multipart/form-data. - /** - * Optional. Sends the message silently. iOS users will not receive a notification, Android - * users will receive a notification with no sound. Other apps coming soon - */ - private Boolean disableNotification; + private Boolean disableNotification; ///< Optional. Sends the message silently. Users will receive a notification with no sound. private Integer replyToMessageId; ///< Optional. If the message is a reply, ID of the original message private ReplyKeyboard replyMarkup; ///< Optional. JSON-serialized object for a custom reply keyboard private Integer duration; ///< Optional. Duration of sent audio in seconds diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/Message.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/Message.java index 1c90f1c4..133d70e9 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/Message.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/Message.java @@ -1,9 +1,10 @@ package org.telegram.telegrambots.api.objects; import com.fasterxml.jackson.annotation.JsonProperty; - import org.telegram.telegrambots.api.interfaces.BotApiObject; import org.telegram.telegrambots.api.objects.games.Game; +import org.telegram.telegrambots.api.objects.payments.Invoice; +import org.telegram.telegrambots.api.objects.payments.SuccessfulPayment; import java.util.List; @@ -32,7 +33,7 @@ public class Message implements BotApiObject { private static final String LOCATION_FIELD = "location"; private static final String VENUE_FIELD = "venue"; private static final String PINNED_MESSAGE_FIELD = "pinned_message"; - private static final String NEWCHATMEMBER_FIELD = "new_chat_member"; + private static final String NEWCHATMEMBERS_FIELD = "new_chat_members"; private static final String LEFTCHATMEMBER_FIELD = "left_chat_member"; private static final String NEWCHATTITLE_FIELD = "new_chat_title"; private static final String NEWCHATPHOTO_FIELD = "new_chat_photo"; @@ -48,6 +49,8 @@ public class Message implements BotApiObject { private static final String EDITDATE_FIELD = "edit_date"; private static final String GAME_FIELD = "game"; private static final String FORWARDFROMMESSAGEID_FIELD = "forward_from_message_id"; + private static final String INVOICE_FIELD = "invoice"; + private static final String SUCCESSFUL_PAYMENT_FIELD = "successful_payment"; @JsonProperty(MESSAGEID_FIELD) private Integer messageId; ///< Integer Unique message identifier @@ -89,8 +92,8 @@ public class Message implements BotApiObject { private Venue venue; ///< Optional. Message is a venue, information about the venue @JsonProperty(PINNED_MESSAGE_FIELD) private Message pinnedMessage; ///< Optional. Specified message was pinned. Note that the Message object in this field will not contain further reply_to_message fields even if it is itself a reply. - @JsonProperty(NEWCHATMEMBER_FIELD) - private User newChatMember; ///< Optional. A new member was added to the group, information about them (this member may be bot itself) + @JsonProperty(NEWCHATMEMBERS_FIELD) + private List newChatMembers; ///< Optional. New members were added to the group or supergroup, information about them (there are may be the bot itself among them) @JsonProperty(LEFTCHATMEMBER_FIELD) private User leftChatMember; ///< Optional. A member was removed from the group, information about them (this member may be bot itself) @JsonProperty(NEWCHATTITLE_FIELD) @@ -149,6 +152,10 @@ public class Message implements BotApiObject { private Game game; ///< Optional. Message is a game, information about the game @JsonProperty(FORWARDFROMMESSAGEID_FIELD) private Integer forwardFromMessageId; ///< Optional. For forwarded channel posts, identifier of the original message in the channel + @JsonProperty(INVOICE_FIELD) + private Invoice invoice; ///< Optional. Message is an invoice for a payment, information about the invoice. + @JsonProperty(SUCCESSFUL_PAYMENT_FIELD) + private SuccessfulPayment successfulPayment; ///< Optional. Message is a service message about a successful payment, information about the payment. public Message() { super(); @@ -223,8 +230,8 @@ public class Message implements BotApiObject { return pinnedMessage; } - public User getNewChatMember() { - return newChatMember; + public List getNewChatMembers() { + return newChatMembers; } public User getLeftChatMember() { @@ -351,6 +358,22 @@ public class Message implements BotApiObject { return photo != null && !photo.isEmpty(); } + public boolean hasInvoice() { + return invoice != null; + } + + public boolean hasSuccessfulPayment() { + return successfulPayment != null; + } + + public Invoice getInvoice() { + return invoice; + } + + public SuccessfulPayment getSuccessfulPayment() { + return successfulPayment; + } + @Override public String toString() { return "Message{" + @@ -372,7 +395,7 @@ public class Message implements BotApiObject { ", location=" + location + ", venue=" + venue + ", pinnedMessage=" + pinnedMessage + - ", newChatMember=" + newChatMember + + ", newChatMembers=" + newChatMembers + ", leftChatMember=" + leftChatMember + ", newChatTitle='" + newChatTitle + '\'' + ", newChatPhoto=" + newChatPhoto + @@ -388,6 +411,8 @@ public class Message implements BotApiObject { ", editDate=" + editDate + ", game=" + game + ", forwardFromMessageId=" + forwardFromMessageId + + ", invoice=" + invoice + + ", successfulPayment=" + successfulPayment + '}'; } } diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/Update.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/Update.java index 003caac5..d540bf8b 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/Update.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/Update.java @@ -5,13 +5,16 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.telegram.telegrambots.api.interfaces.BotApiObject; import org.telegram.telegrambots.api.objects.inlinequery.ChosenInlineQuery; import org.telegram.telegrambots.api.objects.inlinequery.InlineQuery; +import org.telegram.telegrambots.api.objects.payments.PreCheckoutQuery; +import org.telegram.telegrambots.api.objects.payments.ShippingQuery; /** * @author Ruben Bermudez * @version 1.0 - * @brief This object represents an incoming update. - * Only one of the optional parameters can be present in any given update. - * @date 20 of June of 2015 + * + * This object represents an incoming update. + * + * @apiNote Only one of the optional parameters can be present in any given update. */ public class Update implements BotApiObject { private static final String UPDATEID_FIELD = "update_id"; @@ -22,6 +25,8 @@ public class Update implements BotApiObject { private static final String EDITEDMESSAGE_FIELD = "edited_message"; private static final String CHANNELPOST_FIELD = "channel_post"; private static final String EDITEDCHANNELPOST_FIELD = "edited_channel_post"; + private static final String SHIPPING_QUERY_FIELD = "shipping_query"; + private static final String PRE_CHECKOUT_QUERY_FIELD = "pre_checkout_query"; @JsonProperty(UPDATEID_FIELD) private Integer updateId; @@ -39,7 +44,10 @@ public class Update implements BotApiObject { private Message channelPost; ///< Optional. New incoming channel post of any kind — text, photo, sticker, etc. @JsonProperty(EDITEDCHANNELPOST_FIELD) private Message editedChannelPost; ///< Optional. New version of a channel post that is known to the bot and was edited - + @JsonProperty(SHIPPING_QUERY_FIELD) + private ShippingQuery shippingQuery; ///< Optional. New incoming shipping query. Only for invoices with flexible price + @JsonProperty(PRE_CHECKOUT_QUERY_FIELD) + private PreCheckoutQuery preCheckoutQuery; ///< Optional. New incoming pre-checkout query. Contains full information about checkout public Update() { super(); @@ -77,6 +85,14 @@ public class Update implements BotApiObject { return editedChannelPost; } + public ShippingQuery getShippingQuery() { + return shippingQuery; + } + + public PreCheckoutQuery getPreCheckoutQuery() { + return preCheckoutQuery; + } + public boolean hasMessage() { return message != null; } @@ -105,6 +121,14 @@ public class Update implements BotApiObject { return editedChannelPost != null; } + public boolean hasShippingQuery() { + return shippingQuery != null; + } + + public boolean hasPreCheckoutQuery() { + return preCheckoutQuery != null; + } + @Override public String toString() { return "Update{" + @@ -116,6 +140,8 @@ public class Update implements BotApiObject { ", editedMessage=" + editedMessage + ", channelPost=" + channelPost + ", editedChannelPost=" + editedChannelPost + + ", shippingQuery=" + shippingQuery + + ", preCheckoutQuery=" + preCheckoutQuery + '}'; } } diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/inlinequery/result/InlineQueryResultGame.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/inlinequery/result/InlineQueryResultGame.java index 04832e8f..bd854e90 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/inlinequery/result/InlineQueryResultGame.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/inlinequery/result/InlineQueryResultGame.java @@ -25,9 +25,10 @@ import org.telegram.telegrambots.exceptions.TelegramApiValidationException; /** * @author Ruben Bermudez * @version 1.0 - * @brief Represents a Game - * @note This will only work in Telegram versions released after 1 October, 2016. Older clients will ignore them. - * @date 27 of September 2016 + * + * Represents a Game + * + * @apiNote This will only work in Telegram versions released after 1 October, 2016. Older clients will ignore them. */ public class InlineQueryResultGame implements InlineQueryResult { @@ -95,7 +96,8 @@ public class InlineQueryResultGame implements InlineQueryResult { @Override public String toString() { return "InlineQueryResultGame{" + - "id='" + id + '\'' + + "type='" + type + '\'' + + ", id='" + id + '\'' + ", gameShortName='" + gameShortName + '\'' + ", replyMarkup=" + replyMarkup + '}'; diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/inlinequery/result/InlineQueryResultGif.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/inlinequery/result/InlineQueryResultGif.java index 617a2ccc..5904adc1 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/inlinequery/result/InlineQueryResultGif.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/inlinequery/result/InlineQueryResultGif.java @@ -26,6 +26,7 @@ public class InlineQueryResultGif implements InlineQueryResult { private static final String CAPTION_FIELD = "caption"; private static final String INPUTMESSAGECONTENT_FIELD = "input_message_content"; private static final String REPLY_MARKUP_FIELD = "reply_markup"; + private static final String GIF_DURATION_FIELD = "gif_duration"; @JsonProperty(TYPE_FIELD) private final String type = "gif"; ///< Type of the result, must be "gif" @@ -47,6 +48,8 @@ public class InlineQueryResultGif implements InlineQueryResult { private InputMessageContent inputMessageContent; ///< Optional. Content of the message to be sent instead of the GIF animation @JsonProperty(REPLY_MARKUP_FIELD) private InlineKeyboardMarkup replyMarkup; ///< Optional. Inline keyboard attached to the message + @JsonProperty(GIF_DURATION_FIELD) + private Integer gifDuration; ///< Optional. Duration of the GIF public InlineQueryResultGif() { super(); @@ -137,6 +140,14 @@ public class InlineQueryResultGif implements InlineQueryResult { return this; } + public Integer getGifDuration() { + return gifDuration; + } + + public void setGifDuration(Integer gifDuration) { + this.gifDuration = gifDuration; + } + @Override public void validate() throws TelegramApiValidationException { if (id == null || id.isEmpty()) { @@ -164,8 +175,9 @@ public class InlineQueryResultGif implements InlineQueryResult { ", thumbUrl='" + thumbUrl + '\'' + ", title='" + title + '\'' + ", caption='" + caption + '\'' + - ", inputMessageContent='" + inputMessageContent + '\'' + - ", replyMarkup='" + replyMarkup + '\'' + + ", inputMessageContent=" + inputMessageContent + + ", replyMarkup=" + replyMarkup + + ", gifDuration=" + gifDuration + '}'; } } diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/inlinequery/result/InlineQueryResultMpeg4Gif.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/inlinequery/result/InlineQueryResultMpeg4Gif.java index 6ee2afce..015094f7 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/inlinequery/result/InlineQueryResultMpeg4Gif.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/inlinequery/result/InlineQueryResultMpeg4Gif.java @@ -26,6 +26,7 @@ public class InlineQueryResultMpeg4Gif implements InlineQueryResult { private static final String CAPTION_FIELD = "caption"; private static final String INPUTMESSAGECONTENT_FIELD = "input_message_content"; private static final String REPLY_MARKUP_FIELD = "reply_markup"; + private static final String MPEG4_DURATION_FIELD = "mpeg4_duration"; @JsonProperty(TYPE_FIELD) private final String type = "mpeg4_gif"; ///< Type of the result, must be "mpeg4_gif" @@ -47,6 +48,8 @@ public class InlineQueryResultMpeg4Gif implements InlineQueryResult { private InputMessageContent inputMessageContent; ///< Optional. Content of the message to be sent instead of the photo @JsonProperty(REPLY_MARKUP_FIELD) private InlineKeyboardMarkup replyMarkup; ///< Optional. Inline keyboard attached to the message + @JsonProperty(MPEG4_DURATION_FIELD) + private Integer mpeg4Duration; ///< Optional. Video duration public InlineQueryResultMpeg4Gif() { super(); @@ -137,6 +140,14 @@ public class InlineQueryResultMpeg4Gif implements InlineQueryResult { return this; } + public Integer getMpeg4Duration() { + return mpeg4Duration; + } + + public void setMpeg4Duration(Integer mpeg4Duration) { + this.mpeg4Duration = mpeg4Duration; + } + @Override public void validate() throws TelegramApiValidationException { if (id == null || id.isEmpty()) { @@ -164,8 +175,9 @@ public class InlineQueryResultMpeg4Gif implements InlineQueryResult { ", thumbUrl='" + thumbUrl + '\'' + ", title='" + title + '\'' + ", caption='" + caption + '\'' + - ", inputMessageContent='" + inputMessageContent + '\'' + - ", replyMarkup='" + replyMarkup + '\'' + + ", inputMessageContent=" + inputMessageContent + + ", replyMarkup=" + replyMarkup + + ", mpeg4Duration=" + mpeg4Duration + '}'; } } diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/Invoice.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/Invoice.java new file mode 100644 index 00000000..86c1077c --- /dev/null +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/Invoice.java @@ -0,0 +1,77 @@ +package org.telegram.telegrambots.api.objects.payments; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.telegram.telegrambots.api.interfaces.BotApiObject; +import org.telegram.telegrambots.api.objects.PhotoSize; + +/** + * @author Ruben Bermudez + * @version 1.0 + * + * This object contains basic information about an invoice. + */ +public class Invoice implements BotApiObject { + private static final String TITLE_FIELD = "title"; + private static final String DESCRIPTION_FIELD = "description"; + private static final String START_PARAMETER_FIELD = "start_parameter"; + private static final String CURRENCY_FIELD = "currency"; + private static final String TOTAL_AMOUNT_FIELD = "total_amount"; + private static final String PHOTO_FIELD = "photo"; + + @JsonProperty(TITLE_FIELD) + private String title; ///< Product name + @JsonProperty(DESCRIPTION_FIELD) + private String description; ///< Product description + @JsonProperty(START_PARAMETER_FIELD) + private String startParameter; ///< Unique bot deep-linking parameter for generation of this invoice + @JsonProperty(CURRENCY_FIELD) + private String currency; ///< Three-letter ISO 4217 currency code + @JsonProperty(TOTAL_AMOUNT_FIELD) + /** + * Total price in the smallest units of the currency (integer, not float/double). + * For example, for a price of US$ 1.45 pass amount = 145. + */ + private Integer totalAmount; ///< Goods total price in minimal quantity of the currency + @JsonProperty(PHOTO_FIELD) + private PhotoSize photo; ///< Optional. Goods photo + + public Invoice() { + super(); + } + + public String getTitle() { + return title; + } + + public String getDescription() { + return description; + } + + public String getStartParameter() { + return startParameter; + } + + public String getCurrency() { + return currency; + } + + public Integer getTotalAmount() { + return totalAmount; + } + + public PhotoSize getPhoto() { + return photo; + } + + @Override + public String toString() { + return "Invoice{" + + "title='" + title + '\'' + + ", description='" + description + '\'' + + ", startParameter='" + startParameter + '\'' + + ", currency='" + currency + '\'' + + ", totalAmount=" + totalAmount + + ", photo=" + photo + + '}'; + } +} diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/LabeledPrice.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/LabeledPrice.java new file mode 100644 index 00000000..42603e47 --- /dev/null +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/LabeledPrice.java @@ -0,0 +1,79 @@ +package org.telegram.telegrambots.api.objects.payments; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.telegram.telegrambots.api.interfaces.InputBotApiObject; +import org.telegram.telegrambots.api.interfaces.Validable; +import org.telegram.telegrambots.exceptions.TelegramApiValidationException; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * @author Ruben Bermudez + * @version 1.0 + * This object represents a portion of goods price. + */ +public class LabeledPrice implements InputBotApiObject, Validable { + private static final String LABEL_FIELD = "label"; + private static final String AMOUNT_FIELD = "amount"; + + @JsonProperty(LABEL_FIELD) + private String label; ///< Portion label + @JsonProperty(AMOUNT_FIELD) + /** + * Price of the product in the smallest units of the currency (integer, not float/double). + * For example, for a price of US$ 1.45 pass amount = 145. + */ + private Integer amount; + + /** + * Builds an empty LabeledPrice + */ + public LabeledPrice() { + super(); + } + + /** + * Builds a LabeledPrice with mandatory parameters + * @param label Portion label + * @param amount Currency amount in minimal quantity of the currency + */ + public LabeledPrice(String label, Integer amount) { + super(); + this.label = checkNotNull(label); + this.amount = checkNotNull(amount); + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = checkNotNull(label); + } + + public Integer getAmount() { + return amount; + } + + public void setAmount(Integer amount) { + this.amount = checkNotNull(amount); + } + + @Override + public void validate() throws TelegramApiValidationException { + if (label == null || label.isEmpty()) { + throw new TelegramApiValidationException("Label parameter can't be empty", this); + } + if (amount == null) { + throw new TelegramApiValidationException("Amount parameter can't be empty", this); + } + } + + @Override + public String toString() { + return "LabeledPrice{" + + "label='" + label + '\'' + + ", amount=" + amount + + '}'; + } +} diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/OrderInfo.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/OrderInfo.java new file mode 100644 index 00000000..30062eeb --- /dev/null +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/OrderInfo.java @@ -0,0 +1,56 @@ +package org.telegram.telegrambots.api.objects.payments; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.telegram.telegrambots.api.interfaces.BotApiObject; + +/** + * @author Ruben Bermudez + * @version 1.0 + * + * This object represents information about an order. + */ +public class OrderInfo implements BotApiObject { + private static final String NAME_FIELD = "name"; + private static final String PHONE_NUMBER_FIELD = "phone_number"; + private static final String EMAIL_FIELD = "email"; + private static final String SHIPPING_ADDRESS_FIELD = "shipping_address"; + + @JsonProperty(NAME_FIELD) + private String name; ///< Optional. User name + @JsonProperty(PHONE_NUMBER_FIELD) + private String phoneNumber; ///< Optional. User's phone number + @JsonProperty(EMAIL_FIELD) + private String email; ///< Optional. User email + @JsonProperty(SHIPPING_ADDRESS_FIELD) + private ShippingAddress shippingAddress; ///< Optional. First line for the address + + public OrderInfo() { + super(); + } + + public String getName() { + return name; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public String getEmail() { + return email; + } + + public ShippingAddress getShippingAddress() { + return shippingAddress; + } + + @Override + public String toString() { + return "OrderInfo{" + + "name='" + name + '\'' + + ", phoneNumber='" + phoneNumber + '\'' + + ", email='" + email + '\'' + + ", shippingAddress=" + shippingAddress + + '}'; + } +} diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/PreCheckoutQuery.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/PreCheckoutQuery.java new file mode 100644 index 00000000..13ac2f69 --- /dev/null +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/PreCheckoutQuery.java @@ -0,0 +1,85 @@ +package org.telegram.telegrambots.api.objects.payments; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.telegram.telegrambots.api.interfaces.BotApiObject; +import org.telegram.telegrambots.api.objects.User; + +/** + * @author Ruben Bermudez + * @version 1.0 + * + * This object contains information about incoming pre-checkout query. + */ +public class PreCheckoutQuery implements BotApiObject { + private static final String ID_FIELD = "id"; + private static final String FROM_FIELD = "from"; + private static final String CURRENCY_FIELD = "currency"; + private static final String TOTAL_AMOUNT_FIELD = "total_amount"; + private static final String INVOICE_PAYLOAD_FIELD = "invoice_payload"; + private static final String SHIPPING_OPTION_ID_FIELD = "shipping_option_id"; + private static final String ORDER_INFO_FIELD = "order_info"; + + @JsonProperty(ID_FIELD) + private String id; ///< Unique query identifier + @JsonProperty(FROM_FIELD) + private User from; ///< User who sent the query + @JsonProperty(CURRENCY_FIELD) + private String currency; ///< Three-letter ISO 4217 currency code + @JsonProperty(TOTAL_AMOUNT_FIELD) + /** + * Total price in the smallest units of the currency (integer, not float/double). + * For example, for a price of US$ 1.45 pass amount = 145. + */ + private Integer totalAmount; + @JsonProperty(INVOICE_PAYLOAD_FIELD) + private String invoicePayload; ///< Bot specified invoice payload + @JsonProperty(SHIPPING_OPTION_ID_FIELD) + private String shippingOptionId; ///< Optional. Identifier of a chosen by user shipping option + @JsonProperty(ORDER_INFO_FIELD) + private OrderInfo orderInfo; ///< Optional. Order info provided by the user + + public PreCheckoutQuery() { + super(); + } + + public String getId() { + return id; + } + + public User getFrom() { + return from; + } + + public String getCurrency() { + return currency; + } + + public Integer getTotalAmount() { + return totalAmount; + } + + public String getInvoicePayload() { + return invoicePayload; + } + + public String getShippingOptionId() { + return shippingOptionId; + } + + public OrderInfo getOrderInfo() { + return orderInfo; + } + + @Override + public String toString() { + return "PreCheckoutQuery{" + + "id='" + id + '\'' + + ", from=" + from + + ", currency='" + currency + '\'' + + ", totalAmount=" + totalAmount + + ", invoicePayload='" + invoicePayload + '\'' + + ", shippingOptionId='" + shippingOptionId + '\'' + + ", orderInfo=" + orderInfo + + '}'; + } +} diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/ShippingAddress.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/ShippingAddress.java new file mode 100644 index 00000000..afdd6b90 --- /dev/null +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/ShippingAddress.java @@ -0,0 +1,72 @@ +package org.telegram.telegrambots.api.objects.payments; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.telegram.telegrambots.api.interfaces.BotApiObject; + +/** + * @author Ruben Bermudez + * @version 1.0 + * + * 2-letter ISO 3166-1 alpha-2 country code + */ +public class ShippingAddress implements BotApiObject { + private static final String COUNTRY_CODE_FIELD = "country_code"; + private static final String STATE_FIELD = "state"; + private static final String CITY_FIELD = "city"; + private static final String STREET_LINE1_FIELD = "street_line1"; + private static final String STREET_LINE2_FIELD = "street_line2"; + private static final String POST_CODE_FIELD = "post_code"; + + @JsonProperty(COUNTRY_CODE_FIELD) + private String countryCode; ///< Two-letter ISO 3166-1 alpha-2 country code + @JsonProperty(STATE_FIELD) + private String state; ///< State, if applicable + @JsonProperty(CITY_FIELD) + private String city; ///< City + @JsonProperty(STREET_LINE1_FIELD) + private String streetLine1; ///< First line for the address + @JsonProperty(STREET_LINE2_FIELD) + private String streetLine2; ///< Second line for the address + @JsonProperty(POST_CODE_FIELD) + private String postCode; ///< Address post code + + public ShippingAddress() { + super(); + } + + public String getCountryCode() { + return countryCode; + } + + public String getState() { + return state; + } + + public String getCity() { + return city; + } + + public String getStreetLine1() { + return streetLine1; + } + + public String getStreetLine2() { + return streetLine2; + } + + public String getPostCode() { + return postCode; + } + + @Override + public String toString() { + return "ShippingAddress{" + + "countryCode='" + countryCode + '\'' + + ", state='" + state + '\'' + + ", city='" + city + '\'' + + ", streetLine1='" + streetLine1 + '\'' + + ", streetLine2='" + streetLine2 + '\'' + + ", postCode='" + postCode + '\'' + + '}'; + } +} diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/ShippingOption.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/ShippingOption.java new file mode 100644 index 00000000..f24ce208 --- /dev/null +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/ShippingOption.java @@ -0,0 +1,100 @@ +package org.telegram.telegrambots.api.objects.payments; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.telegram.telegrambots.api.interfaces.InputBotApiObject; +import org.telegram.telegrambots.api.interfaces.Validable; +import org.telegram.telegrambots.exceptions.TelegramApiValidationException; + +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * @author Ruben Bermudez + * @version 1.0 + * + * This object represents one shipping option. + */ +public class ShippingOption implements InputBotApiObject, Validable { + private static final String ID_FIELD = "id"; + private static final String TITLE_FIELD = "title"; + private static final String PRICES_FIELD = "prices"; + + @JsonProperty(ID_FIELD) + private String id; ///< Shipping option identifier + @JsonProperty(TITLE_FIELD) + private String title; ///< Option title + @JsonProperty(PRICES_FIELD) + private List prices; ///< List of price portions + + /** + * Creates an empty shipping option + */ + public ShippingOption() { + super(); + } + + /** + * Creates a shipping option with mandatory fields + * @param id Shipping option identifier + * @param title Option title + * @param prices List of price portions + */ + public ShippingOption(String id, String title, List prices) { + this.id = checkNotNull(id); + this.title = checkNotNull(title); + this.prices = checkNotNull(prices); + } + + public String getId() { + return id; + } + + public ShippingOption setId(String id) { + this.id = checkNotNull(id); + return this; + } + + public String getTitle() { + return title; + } + + public ShippingOption setTitle(String title) { + this.title = checkNotNull(title); + return this; + } + + public List getPrices() { + return prices; + } + + public ShippingOption setPrices(List prices) { + this.prices = checkNotNull(prices); + return this; + } + + @Override + public void validate() throws TelegramApiValidationException { + if (id == null || id.isEmpty()) { + throw new TelegramApiValidationException("Id parameter can't be empty", this); + } + if (title == null || title.isEmpty()) { + throw new TelegramApiValidationException("Title parameter can't be empty", this); + } + if (prices == null || prices.isEmpty()) { + throw new TelegramApiValidationException("Prices parameter can't be empty", this); + } + for (LabeledPrice price : prices) { + price.validate(); + } + } + + @Override + public String toString() { + return "ShippingOption{" + + "id='" + id + '\'' + + ", title='" + title + '\'' + + ", prices=" + prices + + '}'; + } +} diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/ShippingQuery.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/ShippingQuery.java new file mode 100644 index 00000000..637fe58b --- /dev/null +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/ShippingQuery.java @@ -0,0 +1,57 @@ +package org.telegram.telegrambots.api.objects.payments; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.telegram.telegrambots.api.interfaces.BotApiObject; +import org.telegram.telegrambots.api.objects.User; + +/** + * @author Ruben Bermudez + * @version 1.0 + * + * This object contains information about incoming shipping query. + */ +public class ShippingQuery implements BotApiObject { + private static final String ID_FIELD = "id"; + private static final String FROM_FIELD = "from"; + private static final String INVOICE_PAYLOAD_FIELD = "invoice_payload"; + private static final String SHIPPING_ADDRESS_FIELD = "shipping_address"; + + @JsonProperty(ID_FIELD) + private String id; ///< Unique query identifier + @JsonProperty(FROM_FIELD) + private User from; ///< User who sent the query + @JsonProperty(INVOICE_PAYLOAD_FIELD) + private String invoicePayload; ///< Bot specified invoice payload + @JsonProperty(SHIPPING_ADDRESS_FIELD) + private ShippingAddress shippingAddress; ///< User specified shipping address + + public ShippingQuery() { + super(); + } + + public String getId() { + return id; + } + + public User getFrom() { + return from; + } + + public String getInvoicePayload() { + return invoicePayload; + } + + public ShippingAddress getShippingAddress() { + return shippingAddress; + } + + @Override + public String toString() { + return "ShippingQuery{" + + "id='" + id + '\'' + + ", from=" + from + + ", invoicePayload='" + invoicePayload + '\'' + + ", shippingAddress=" + shippingAddress + + '}'; + } +} diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/SuccessfulPayment.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/SuccessfulPayment.java new file mode 100644 index 00000000..c8478b01 --- /dev/null +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/payments/SuccessfulPayment.java @@ -0,0 +1,84 @@ +package org.telegram.telegrambots.api.objects.payments; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.telegram.telegrambots.api.interfaces.BotApiObject; + +/** + * @author Ruben Bermudez + * @version 1.0 + * + * This object contains basic information about a successful payment. + */ +public class SuccessfulPayment implements BotApiObject { + private static final String CURRENCY_FIELD = "currency"; + private static final String TOTAL_AMOUNT_FIELD = "total_amount"; + private static final String INVOICE_PAYLOAD_FIELD = "invoice_payload"; + private static final String SHIPPING_OPTION_ID_FIELD = "shipping_option_id"; + private static final String ORDER_INFO_FIELD = "order_info"; + private static final String TELEGRAM_PAYMENT_CHARGE_ID_FIELD = "telegram_payment_charge_id"; + private static final String PROVIDER_PAYMENT_CHARGE_ID_FIELD = "provider_payment_charge_id"; + + @JsonProperty(CURRENCY_FIELD) + private String currency; ///< Three-letter ISO 4217 currency code + @JsonProperty(TOTAL_AMOUNT_FIELD) + /** + * Total price in the smallest units of the currency (integer, not float/double). + * For example, for a price of US$ 1.45 pass amount = 145. + */ + private Integer totalAmount; + @JsonProperty(INVOICE_PAYLOAD_FIELD) + private String invoicePayload; ///< Bot specified invoice payload + @JsonProperty(SHIPPING_OPTION_ID_FIELD) + private String shippingOptionId; ///< Optional. Identifier of a chosen by user shipping option + @JsonProperty(ORDER_INFO_FIELD) + private OrderInfo orderInfo; ///< Optional. Order info provided by the user + @JsonProperty(TELEGRAM_PAYMENT_CHARGE_ID_FIELD) + private String telegramPaymentChargeId; ///< Telegram payment identifier + @JsonProperty(PROVIDER_PAYMENT_CHARGE_ID_FIELD) + private String providerPaymentChargeId; ///< Provider payment identifier + + public SuccessfulPayment() { + super(); + } + + public String getCurrency() { + return currency; + } + + public Integer getTotalAmount() { + return totalAmount; + } + + public String getInvoicePayload() { + return invoicePayload; + } + + public String getShippingOptionId() { + return shippingOptionId; + } + + public OrderInfo getOrderInfo() { + return orderInfo; + } + + public String getTelegramPaymentChargeId() { + return telegramPaymentChargeId; + } + + public String getProviderPaymentChargeId() { + return providerPaymentChargeId; + } + + @Override + public String toString() { + return "SuccessfulPayment{" + + "currency='" + currency + '\'' + + ", totalAmount=" + totalAmount + + ", invoicePayload='" + invoicePayload + '\'' + + ", shippingOptionId='" + shippingOptionId + '\'' + + ", orderInfo=" + orderInfo + + ", telegramPaymentChargeId='" + telegramPaymentChargeId + '\'' + + ", providerPaymentChargeId='" + providerPaymentChargeId + '\'' + + '}'; + } +} diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/replykeyboard/ReplyKeyboardMarkup.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/replykeyboard/ReplyKeyboardMarkup.java index 7484323a..6486eb88 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/replykeyboard/ReplyKeyboardMarkup.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/replykeyboard/ReplyKeyboardMarkup.java @@ -26,7 +26,7 @@ public class ReplyKeyboardMarkup implements ReplyKeyboard { @JsonProperty(RESIZEKEYBOARD_FIELD) private Boolean resizeKeyboard; ///< Optional. Requests clients to resize the keyboard vertically for optimal fit (e.g., make the keyboard smaller if there are just two rows of buttons). Defaults to false. @JsonProperty(ONETIMEKEYBOARD_FIELD) - private Boolean oneTimeKeyboad; ///< Optional. Requests clients to hide the keyboard as soon as it's been used. Defaults to false. + private Boolean oneTimeKeyboard; ///< Optional. Requests clients to hide the keyboard as soon as it's been used. Defaults to false. /** * Optional. Use this parameter if you want to show the keyboard to specific users only. * Targets: @@ -59,12 +59,12 @@ public class ReplyKeyboardMarkup implements ReplyKeyboard { return this; } - public Boolean getOneTimeKeyboad() { - return oneTimeKeyboad; + public Boolean getOneTimeKeyboard() { + return oneTimeKeyboard; } - public ReplyKeyboardMarkup setOneTimeKeyboad(Boolean oneTimeKeyboad) { - this.oneTimeKeyboad = oneTimeKeyboad; + public ReplyKeyboardMarkup setOneTimeKeyboard(Boolean oneTimeKeyboard) { + this.oneTimeKeyboard = oneTimeKeyboard; return this; } @@ -92,7 +92,7 @@ public class ReplyKeyboardMarkup implements ReplyKeyboard { return "ReplyKeyboardMarkup{" + "keyboard=" + keyboard + ", resizeKeyboard=" + resizeKeyboard + - ", oneTimeKeyboad=" + oneTimeKeyboad + + ", oneTimeKeyboard=" + oneTimeKeyboard + ", selective=" + selective + '}'; } diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/replykeyboard/buttons/InlineKeyboardButton.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/replykeyboard/buttons/InlineKeyboardButton.java index 093b7449..e378c717 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/replykeyboard/buttons/InlineKeyboardButton.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/api/objects/replykeyboard/buttons/InlineKeyboardButton.java @@ -14,7 +14,6 @@ import org.telegram.telegrambots.exceptions.TelegramApiValidationException; * optional fields. * @note This will only work in Telegram versions released after 9 April, 2016. Older clients will * display unsupported message. - * @date 10 of April of 2016 */ public class InlineKeyboardButton implements InputBotApiObject, Validable { @@ -24,6 +23,7 @@ public class InlineKeyboardButton implements InputBotApiObject, Validable { private static final String CALLBACK_GAME_FIELD = "callback_game"; private static final String SWITCH_INLINE_QUERY_FIELD = "switch_inline_query"; private static final String SWITCH_INLINE_QUERY_CURRENT_CHAT_FIELD = "switch_inline_query_current_chat"; + private static final String BUY_FIELD = "buy"; @JsonProperty(TEXT_FIELD) private String text; ///< Label text on the button @@ -43,7 +43,8 @@ public class InlineKeyboardButton implements InputBotApiObject, Validable { * If set, pressing the button will prompt the user to select one of their chats, * open that chat and insert the bot‘s username and the specified inline query in the input field. * Can be empty, in which case just the bot’s username will be inserted. - * @note: This offers an easy way for users to start using your bot in inline mode when + * + * @note This offers an easy way for users to start using your bot in inline mode when * they are currently in a private chat with it. * Especially useful when combined with switch_pm… actions – in this case the user will * be automatically returned to the chat they switched from, skipping the chat selection screen. @@ -58,6 +59,14 @@ public class InlineKeyboardButton implements InputBotApiObject, Validable { @JsonProperty(SWITCH_INLINE_QUERY_CURRENT_CHAT_FIELD) private String switchInlineQueryCurrentChat; + /** + * Optional. Specify True, to send a Buy button. + * + * @note This type of button must always be the first button in the first row. + */ + @JsonProperty(BUY_FIELD) + private Boolean buy; + public InlineKeyboardButton() { super(); } @@ -116,6 +125,15 @@ public class InlineKeyboardButton implements InputBotApiObject, Validable { return this; } + public Boolean getBuy() { + return buy; + } + + public InlineKeyboardButton setBuy(Boolean buy) { + this.buy = buy; + return this; + } + @Override public void validate() throws TelegramApiValidationException { if (text == null || text.isEmpty()) { @@ -132,6 +150,7 @@ public class InlineKeyboardButton implements InputBotApiObject, Validable { ", callbackGame=" + callbackGame + ", switchInlineQuery='" + switchInlineQuery + '\'' + ", switchInlineQueryCurrentChat='" + switchInlineQueryCurrentChat + '\'' + + ", buy=" + buy + '}'; } } diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/bots/AbsSender.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/bots/AbsSender.java index 51e194ec..5941ab00 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/bots/AbsSender.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/bots/AbsSender.java @@ -1,45 +1,16 @@ package org.telegram.telegrambots.bots; -import org.telegram.telegrambots.api.methods.AnswerCallbackQuery; -import org.telegram.telegrambots.api.methods.AnswerInlineQuery; -import org.telegram.telegrambots.api.methods.BotApiMethod; -import org.telegram.telegrambots.api.methods.ForwardMessage; -import org.telegram.telegrambots.api.methods.GetFile; -import org.telegram.telegrambots.api.methods.GetMe; -import org.telegram.telegrambots.api.methods.GetUserProfilePhotos; +import org.telegram.telegrambots.api.methods.*; import org.telegram.telegrambots.api.methods.games.GetGameHighScores; import org.telegram.telegrambots.api.methods.games.SetGameScore; -import org.telegram.telegrambots.api.methods.groupadministration.GetChat; -import org.telegram.telegrambots.api.methods.groupadministration.GetChatAdministrators; -import org.telegram.telegrambots.api.methods.groupadministration.GetChatMember; -import org.telegram.telegrambots.api.methods.groupadministration.GetChatMemberCount; -import org.telegram.telegrambots.api.methods.groupadministration.KickChatMember; -import org.telegram.telegrambots.api.methods.groupadministration.LeaveChat; -import org.telegram.telegrambots.api.methods.groupadministration.UnbanChatMember; -import org.telegram.telegrambots.api.methods.send.SendAudio; -import org.telegram.telegrambots.api.methods.send.SendChatAction; -import org.telegram.telegrambots.api.methods.send.SendContact; -import org.telegram.telegrambots.api.methods.send.SendDocument; -import org.telegram.telegrambots.api.methods.send.SendGame; -import org.telegram.telegrambots.api.methods.send.SendLocation; -import org.telegram.telegrambots.api.methods.send.SendMessage; -import org.telegram.telegrambots.api.methods.send.SendPhoto; -import org.telegram.telegrambots.api.methods.send.SendSticker; -import org.telegram.telegrambots.api.methods.send.SendVenue; -import org.telegram.telegrambots.api.methods.send.SendVideo; -import org.telegram.telegrambots.api.methods.send.SendVoice; +import org.telegram.telegrambots.api.methods.groupadministration.*; +import org.telegram.telegrambots.api.methods.send.*; import org.telegram.telegrambots.api.methods.updates.DeleteWebhook; import org.telegram.telegrambots.api.methods.updates.GetWebhookInfo; import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageCaption; import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageReplyMarkup; import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageText; -import org.telegram.telegrambots.api.objects.Chat; -import org.telegram.telegrambots.api.objects.ChatMember; -import org.telegram.telegrambots.api.objects.File; -import org.telegram.telegrambots.api.objects.Message; -import org.telegram.telegrambots.api.objects.User; -import org.telegram.telegrambots.api.objects.UserProfilePhotos; -import org.telegram.telegrambots.api.objects.WebhookInfo; +import org.telegram.telegrambots.api.objects.*; import org.telegram.telegrambots.api.objects.games.GameHighScore; import org.telegram.telegrambots.exceptions.TelegramApiException; import org.telegram.telegrambots.updateshandlers.SentCallback; @@ -249,6 +220,27 @@ public abstract class AbsSender { return sendApiMethod(deleteWebhook); } + public final Message sendInvoice(SendInvoice sendInvoice) throws TelegramApiException { + if(sendInvoice == null){ + throw new TelegramApiException("Parameter sendInvoice can not be null"); + } + return sendApiMethod(sendInvoice); + } + + public final Boolean answerShippingQuery(AnswerShippingQuery answerShippingQuery) throws TelegramApiException { + if(answerShippingQuery == null){ + throw new TelegramApiException("Parameter answerShippingQuery can not be null"); + } + return sendApiMethod(answerShippingQuery); + } + + public final Boolean answerPreCheckoutQuery(AnswerPreCheckoutQuery answerPreCheckoutQuery) throws TelegramApiException { + if(answerPreCheckoutQuery == null){ + throw new TelegramApiException("Parameter answerPreCheckoutQuery can not be null"); + } + return sendApiMethod(answerPreCheckoutQuery); + } + // Send Requests Async public final void sendMessageAsync(SendMessage sendMessage, SentCallback sentCallback) throws TelegramApiException { @@ -530,6 +522,36 @@ public abstract class AbsSender { sendApiMethodAsync(deleteWebhook, sentCallback); } + public final void sendInvoice(SendInvoice sendInvoice, SentCallback sentCallback) throws TelegramApiException { + if (sendInvoice == null) { + throw new TelegramApiException("Parameter sendInvoice can not be null"); + } + if (sentCallback == null) { + throw new TelegramApiException("Parameter sentCallback can not be null"); + } + sendApiMethodAsync(sendInvoice, sentCallback); + } + + public final void answerShippingQuery(AnswerShippingQuery answerShippingQuery, SentCallback sentCallback) throws TelegramApiException { + if (answerShippingQuery == null) { + throw new TelegramApiException("Parameter answerShippingQuery can not be null"); + } + if (sentCallback == null) { + throw new TelegramApiException("Parameter sentCallback can not be null"); + } + sendApiMethodAsync(answerShippingQuery, sentCallback); + } + + public final void answerPreCheckoutQuery(AnswerPreCheckoutQuery answerPreCheckoutQuery, SentCallback sentCallback) throws TelegramApiException { + if (answerPreCheckoutQuery == null) { + throw new TelegramApiException("Parameter answerPreCheckoutQuery can not be null"); + } + if (sentCallback == null) { + throw new TelegramApiException("Parameter sentCallback can not be null"); + } + sendApiMethodAsync(answerPreCheckoutQuery, sentCallback); + } + // Specific Send Requests public abstract Message sendDocument(SendDocument sendDocument) throws TelegramApiException; diff --git a/telegrambots/pom.xml b/telegrambots/pom.xml index e16d2933..4dcf1087 100644 --- a/telegrambots/pom.xml +++ b/telegrambots/pom.xml @@ -5,7 +5,7 @@ 4.0.0 org.telegram telegrambots - 2.4.4.5 + 2.4.4.6 jar Telegram Bots @@ -66,7 +66,7 @@ 2.8.7 2.8.0 2.5 - 2.4.4.5 + 2.4.4.6 @@ -305,6 +305,17 @@ + + org.apache.maven.plugins + maven-dependency-plugin + 2.4 + + + copy + package + + + diff --git a/telegrambots/src/main/java/org/telegram/telegrambots/bots/DefaultAbsSender.java b/telegrambots/src/main/java/org/telegram/telegrambots/bots/DefaultAbsSender.java index 4537a1df..8bee1f72 100644 --- a/telegrambots/src/main/java/org/telegram/telegrambots/bots/DefaultAbsSender.java +++ b/telegrambots/src/main/java/org/telegram/telegrambots/bots/DefaultAbsSender.java @@ -45,6 +45,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import static org.telegram.telegrambots.Constants.SOCKET_TIMEOUT; + /** * @author Ruben Bermudez * @version 1.0 @@ -72,6 +74,13 @@ public abstract class DefaultAbsSender extends AbsSender { .build(); requestConfig = options.getRequestConfig(); + + if (requestConfig == null) { + requestConfig = RequestConfig.copy(RequestConfig.custom().build()) + .setSocketTimeout(SOCKET_TIMEOUT) + .setConnectTimeout(SOCKET_TIMEOUT) + .setConnectionRequestTimeout(SOCKET_TIMEOUT).build(); + } } /** diff --git a/telegrambots/src/test/java/org/telegram/telegrambots/test/BotApiMethodHelperFactory.java b/telegrambots/src/test/java/org/telegram/telegrambots/test/BotApiMethodHelperFactory.java index 71121580..c35e85db 100644 --- a/telegrambots/src/test/java/org/telegram/telegrambots/test/BotApiMethodHelperFactory.java +++ b/telegrambots/src/test/java/org/telegram/telegrambots/test/BotApiMethodHelperFactory.java @@ -18,12 +18,7 @@ import org.telegram.telegrambots.api.methods.groupadministration.GetChatMemberCo import org.telegram.telegrambots.api.methods.groupadministration.KickChatMember; import org.telegram.telegrambots.api.methods.groupadministration.LeaveChat; import org.telegram.telegrambots.api.methods.groupadministration.UnbanChatMember; -import org.telegram.telegrambots.api.methods.send.SendChatAction; -import org.telegram.telegrambots.api.methods.send.SendContact; -import org.telegram.telegrambots.api.methods.send.SendGame; -import org.telegram.telegrambots.api.methods.send.SendLocation; -import org.telegram.telegrambots.api.methods.send.SendMessage; -import org.telegram.telegrambots.api.methods.send.SendVenue; +import org.telegram.telegrambots.api.methods.send.*; import org.telegram.telegrambots.api.methods.updates.GetWebhookInfo; import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageCaption; import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageReplyMarkup; @@ -33,6 +28,7 @@ import org.telegram.telegrambots.api.objects.inlinequery.inputmessagecontent.Inp import org.telegram.telegrambots.api.objects.inlinequery.result.InlineQueryResult; import org.telegram.telegrambots.api.objects.inlinequery.result.InlineQueryResultArticle; import org.telegram.telegrambots.api.objects.inlinequery.result.InlineQueryResultPhoto; +import org.telegram.telegrambots.api.objects.payments.LabeledPrice; import org.telegram.telegrambots.api.objects.replykeyboard.ForceReplyKeyboard; import org.telegram.telegrambots.api.objects.replykeyboard.InlineKeyboardMarkup; import org.telegram.telegrambots.api.objects.replykeyboard.ReplyKeyboard; @@ -191,7 +187,7 @@ public final class BotApiMethodHelperFactory { private static ReplyKeyboard getKeyboardMarkup() { ReplyKeyboardMarkup keyboardMarkup = new ReplyKeyboardMarkup(); keyboardMarkup.setResizeKeyboard(true); - keyboardMarkup.setOneTimeKeyboad(true); + keyboardMarkup.setOneTimeKeyboard(true); keyboardMarkup.setSelective(true); List keyboard = new ArrayList<>(); KeyboardRow row = new KeyboardRow(); @@ -289,4 +285,19 @@ public final class BotApiMethodHelperFactory { .setChatId("12345") .setUserId(98765); } + + public static BotApiMethod getSendInvoice() { + List prices = new ArrayList<>(); + prices.add(new LabeledPrice("LABEL", 1000)); + + return new SendInvoice() + .setChatId(12345) + .setTitle("Random title") + .setDescription("Random description") + .setPayload("Random Payload") + .setProviderToken("Random provider token") + .setStartParameter("STARTPARAM") + .setCurrency("EUR") + .setPrices(prices); + } } diff --git a/telegrambots/src/test/java/org/telegram/telegrambots/test/TestRestApi.java b/telegrambots/src/test/java/org/telegram/telegrambots/test/TestRestApi.java index 5f05b206..d0b13f34 100644 --- a/telegrambots/src/test/java/org/telegram/telegrambots/test/TestRestApi.java +++ b/telegrambots/src/test/java/org/telegram/telegrambots/test/TestRestApi.java @@ -392,6 +392,23 @@ public class TestRestApi extends JerseyTest { assertEquals("{\"chat_id\":\"12345\",\"user_id\":98765,\"method\":\"unbanchatmember\"}", map(result)); } + @Test + public void TestSendInvoice() { + webhookBot.setReturnValue(BotApiMethodHelperFactory.getSendInvoice()); + + Entity entity = Entity.json(getUpdate()); + BotApiMethod result = + target("callback/testbot") + .request(MediaType.APPLICATION_JSON) + .post(entity, SendInvoice.class); + + assertEquals("{\"chat_id\":12345,\"title\":\"Random title\",\"description\":\"Random description\"" + + ",\"payload\":\"Random Payload\",\"provider_token\":\"Random provider token\",\"start_parameter\":" + + "\"STARTPARAM\",\"currency\":\"EUR\",\"prices\":[{\"@class\":" + + "\"org.telegram.telegrambots.api.objects.payments.LabeledPrice\",\"label\":\"LABEL\"," + + "\"amount\":1000}],\"method\":\"sendinvoice\"}", map(result)); + } + private Update getUpdate() { ObjectMapper mapper = new ObjectMapper(); try {