├── .gitignore ├── LICENSE ├── README.md ├── pom.xml └── src └── main └── java └── se └── anyro └── tgbotapi ├── HttpResponseException.java ├── TgBotApi.java ├── types ├── Chat.java ├── ChatAction.java ├── ChatMember.java ├── ChatPhoto.java ├── Contact.java ├── Location.java ├── Message.java ├── MessageEntity.java ├── ParseMode.java ├── ResponseParameters.java ├── Update.java ├── User.java ├── Venue.java ├── WebhookInfo.java ├── file │ ├── Animation.java │ ├── Audio.java │ ├── Document.java │ ├── File.java │ ├── InputMedia.java │ ├── InputMediaAnimation.java │ ├── InputMediaAudio.java │ ├── InputMediaDocument.java │ ├── InputMediaPhoto.java │ ├── InputMediaVideo.java │ ├── PhotoSize.java │ ├── UserProfilePhotos.java │ ├── Video.java │ ├── VideoNote.java │ └── Voice.java ├── games │ ├── Animation.java │ ├── CallbackGame.java │ ├── Game.java │ └── GameHighScore.java ├── inline │ ├── CallbackQuery.java │ ├── ChosenInlineResult.java │ ├── InlineQuery.java │ ├── InlineQueryResult.java │ ├── InlineQueryResultArticle.java │ ├── InlineQueryResultAudio.java │ ├── InlineQueryResultCachedAudio.java │ ├── InlineQueryResultCachedDocument.java │ ├── InlineQueryResultCachedGif.java │ ├── InlineQueryResultCachedMpeg4Gif.java │ ├── InlineQueryResultCachedPhoto.java │ ├── InlineQueryResultCachedSticker.java │ ├── InlineQueryResultCachedVideo.java │ ├── InlineQueryResultCachedVoice.java │ ├── InlineQueryResultContact.java │ ├── InlineQueryResultDocument.java │ ├── InlineQueryResultGame.java │ ├── InlineQueryResultGif.java │ ├── InlineQueryResultLocation.java │ ├── InlineQueryResultMpeg4Gif.java │ ├── InlineQueryResultPhoto.java │ ├── InlineQueryResultVenue.java │ ├── InlineQueryResultVideo.java │ ├── InlineQueryResultVoice.java │ ├── InputContactMessageContent.java │ ├── InputLocationMessageContent.java │ ├── InputMessageContent.java │ ├── InputTextMessageContent.java │ └── InputVenueMessageContent.java ├── passport │ ├── EncryptedCredentials.java │ ├── EncryptedPassportElement.java │ ├── PassportData.java │ ├── PassportElementError.java │ ├── PassportElementErrorDataField.java │ ├── PassportElementErrorFile.java │ ├── PassportElementErrorFiles.java │ ├── PassportElementErrorFrontSide.java │ ├── PassportElementErrorReverseSide.java │ ├── PassportElementErrorSelfie.java │ ├── PassportElementErrorTranslationFile.java │ ├── PassportElementErrorTranslationFiles.java │ ├── PassportElementErrorUnspecified.java │ └── PassportFile.java ├── payments │ ├── Invoice.java │ ├── LabeledPrice.java │ ├── OrderInfo.java │ ├── PreCheckoutQuery.java │ ├── ShippingAddress.java │ ├── ShippingOption.java │ ├── ShippingQuery.java │ └── SuccessfulPayment.java ├── poll │ ├── Poll.java │ ├── PollAnswer.java │ └── PollOption.java ├── reply_markup │ ├── ForceReply.java │ ├── InlineKeyboardButton.java │ ├── InlineKeyboardMarkup.java │ ├── KeyboardButton.java │ ├── ReplyKeyboardMarkup.java │ ├── ReplyKeyboardRemove.java │ └── ReplyMarkup.java └── stickers │ ├── MaskPosition.java │ ├── Sticker.java │ └── StickerSet.java └── utils ├── FileSender.java └── Markdown.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Java 2 | *.class 3 | 4 | # Eclipse stuff 5 | bin/ 6 | .project 7 | .classpath 8 | .settings/ 9 | *.launch 10 | 11 | # Maven 12 | target/ 13 | 14 | # Mac stuff 15 | *.DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | TgBotApi 2 | ======== 3 | 4 | This Java library implements all the methods and types in [Telegram's Bot API](https://core.telegram.org/bots) including the new features in 4.1. [Telegram](https://telegram.org/) is an instant messenger for various platforms. 5 | 6 | If you find a bug or know some way to improve the library please report it to me as [an issue](https://github.com/nadam/tg-bot-api/issues) or [in private](https://telegram.me/nadam). Just don't ask me to add boiler plate stuff like getters and setters. There are lots of other Java libraries if you prefer that. 7 | 8 | Technical scope and limitations 9 | ------------------------------- 10 | - Uses GET methods with URL query string where possible (all methods except when sending files as multipart/form-data) 11 | - Supports getUpdates(), but I've only tested it with [webhook](https://core.telegram.org/bots/api#setwebhook) so far 12 | - [Making requests when getting updates](https://core.telegram.org/bots/api#making-requests-when-getting-updates) is not supported 13 | 14 | Features 15 | -------- 16 | - Full implementation of the API and hopefully quickly updated when new features are released 17 | - Javadoc links to corresponding official documentation 18 | - All types implemented as simple POJO classes with constructors and helper methods where necessary 19 | - All methods implemented as Java methods with various parameter options 20 | - A setSilent() method for bots who want to use disable_notification instead of having to set it each time you send a message 21 | - Helper methods to make life easier, for instance `TgBotApi.sendReply()`, `TgBotApi.downloadFile()` and `TgBotApi.debug()` 22 | - Enums and constants for common values 23 | 24 | Including in your project 25 | ------------------------- 26 | ### Gradle 27 | ``` 28 | repositories { 29 | maven { url 'https://jitpack.io' } 30 | } 31 | 32 | ``` 33 | ``` 34 | dependencies { 35 | implementation 'com.github.nadam:tg-bot-api:2.0.0' 36 | } 37 | ``` 38 | 39 | #### Dependencies 40 | The project depends on [GSON](https://github.com/google/gson) 2.8.2. I have currently only used it together with [Google App Engine](https://cloud.google.com/appengine/) (which includes GSON), but it should be possible to use it with any platform. 41 | 42 | #### Binary 43 | Latest binaries available in the [Releases section](https://github.com/nadam/tg-bot-api/releases). 44 | 45 | #### Building from source code 46 | A pom.xml for Maven is included in the project. For other options just make sure you include GSON 2.8.2 or later. 47 | 48 | Using the library 49 | ----------------- 50 | #### Telegram Bot API 51 | If you are new to bots or bot development for Telegram check out the following links: 52 | - [Introduction to bots](https://core.telegram.org/bots) 53 | - [Telegram Bot API documentation](https://core.telegram.org/bots/api) 54 | - [Bots FAQ](https://core.telegram.org/bots/faq) 55 | 56 | #### Preparation 57 | 1. Setup your bot using [@BotFather](https://telegram.me/botfather) as described in the links above to get your bot username and token 58 | 2. Use [@userinfobot](https://telegram.me/userinfobot) or similar to get your user id 59 | 60 | #### Sample code for Google App Engine using webhooks 61 | 1. For Google App Engine or similar, extend HttpServlet and implement the doPost() method. 62 | 2. Optionally implement the ErrorListener interface. 63 | 3. Create the `TgBotApi` object using your token and user id (it's good practice to put these values as constants in a separate file). 64 | 4. Parse the requests using `TgBotApi.parseFromWebhook()` to get the `Update` object 65 | 5. Optionally send a reply using `TgBotApi.sendMessage()` or `TgBotApi.sendReply()` 66 | 67 | ```java 68 | public class ExampleServlet extends HttpServlet implements ErrorListener { 69 | 70 | private TgBotApi api; 71 | 72 | public ExampleServlet() { 73 | super(); 74 | api = new TgBotApi(TOKEN, OWNER, this); 75 | } 76 | 77 | @Override 78 | public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { 79 | 80 | resp.setStatus(200); 81 | 82 | String messageText; 83 | long chatId = 0; 84 | 85 | try { 86 | Update update = api.parseFromWebhook(req.getReader()); 87 | 88 | // Do something interesting, 89 | // extract the chatId from the update object and 90 | // decide an appropriate messageText to send as reply. 91 | 92 | } catch (Exception e) { 93 | api.debug(e); 94 | return; 95 | } 96 | 97 | api.sendMessage(chatId, messageText); 98 | } 99 | 100 | @Override 101 | public void onError(int errorCode, String description) { 102 | api.debug(new Exception("ErrorCode " + errorCode + ", " + description)); 103 | } 104 | } 105 | ``` 106 | 107 | The code for other platforms will look quite similar. 108 | 109 | More information 110 | ---------------- 111 | #### Bots using TgBotApi 112 | - [TgBotApi Example](https://github.com/nadam/tg-bot-api-example) [@TgBotApiExampleBot](https://telegram.me/TgBotApiExampleBot) 113 | - [Userinfobot](https://github.com/nadam/userinfobot) [@userinfobot](https://telegram.me/userinfobot) 114 | - Groupinfobot [@groupinfobot](https://telegram.me/groupinfobot) 115 | - [Chat Bridge Bot](https://github.com/nadam/chatbridgebot) - [@chatbridgebot](https://telegram.me/chatbridgebot) 116 | - [Json Dump Bot](https://github.com/nadam/jsondumpbot) - [@JsonDumpBot](https://telegram.me/JsonDumpBot) 117 | - Jackpot Bot - [@jackpot_bot](https://telegram.me/jackpot_bot) 118 | 119 | #### Advanced Java for Telegram 120 | If you think the Bot API is too limiting you can use the Telegram API instead which is what ordinary Telegram clients use. You use it with an ordinary Telegram account or with a Bot account (using auth.importBotAuthorization). 121 | 122 | - [Deepthought by Ruben Bermudez](https://github.com/rubenlagus/Deepthought) 123 | - [Official outdated documentation](https://core.telegram.org/#telegram-api) 124 | 125 | #### Other stuff 126 | - [Google App Engine tutorial for Java](https://cloud.google.com/appengine/docs/java/gettingstarted/creating-guestbook) 127 | 128 | License 129 | ---------------- 130 | [Apache License 2.0](LICENSE) -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | jar 6 | 2.0.2-SNAPSHOT 7 | 8 | se.anyro.tgbotapi 9 | tg-bot-api 10 | 11 | 12 | 2.8.2 13 | UTF-8 14 | 15 | 16 | 17 | 3.1.0 18 | 19 | 20 | 21 | 22 | com.google.code.gson 23 | gson 24 | ${gson.version} 25 | compile 26 | 27 | 28 | 29 | 30 | 31 | ${project.build.directory}/${project.build.finalName}/WEB-INF/classes 32 | 33 | 34 | org.codehaus.mojo 35 | versions-maven-plugin 36 | 2.1 37 | 38 | 39 | compile 40 | 41 | display-dependency-updates 42 | display-plugin-updates 43 | 44 | 45 | 46 | 47 | 48 | org.apache.maven.plugins 49 | 3.1 50 | maven-compiler-plugin 51 | 52 | 1.7 53 | 1.7 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.eclipse.m2e 62 | lifecycle-mapping 63 | 1.0.0 64 | 65 | 66 | 67 | 68 | 69 | 70 | org.codehaus.mojo 71 | 72 | 73 | versions-maven-plugin 74 | 75 | 76 | [2.1,) 77 | 78 | 79 | 80 | display-dependency-updates 81 | 82 | 83 | display-plugin-updates 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/HttpResponseException.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi; 2 | 3 | import java.io.IOException; 4 | 5 | import se.anyro.tgbotapi.types.ResponseParameters; 6 | 7 | @SuppressWarnings("serial") 8 | public class HttpResponseException extends IOException { 9 | 10 | private int errorCode; 11 | 12 | private ResponseParameters parameters; 13 | 14 | public HttpResponseException(int errorCode, String description, ResponseParameters parameters) { 15 | super(description); 16 | this.errorCode = errorCode; 17 | this.parameters = parameters; 18 | } 19 | 20 | public int getErrorCode() { 21 | return errorCode; 22 | } 23 | 24 | public ResponseParameters getParameters() { 25 | return parameters; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/Chat.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types; 2 | 3 | /** 4 | * @see Chat 5 | */ 6 | public class Chat { 7 | public long id; 8 | public String type; 9 | public String title; 10 | public String username; 11 | public String first_name; 12 | public String last_name; 13 | public boolean all_members_are_administrators; 14 | public ChatPhoto photo; 15 | public String description; 16 | public String invite_link; 17 | public Message pinned_message; 18 | public String sticker_set_name; 19 | public boolean can_set_sticker_set; 20 | 21 | public enum Type { 22 | PRIVATE, GROUP, SUPERGROUP, CHANNEL 23 | } 24 | 25 | /** 26 | * Get the type field as an enum value. 27 | */ 28 | public Type getType() { 29 | try { 30 | return Type.valueOf(type.toUpperCase()); 31 | } catch (Exception e) { 32 | return null; 33 | } 34 | } 35 | 36 | public boolean isPrivate() { 37 | return Type.PRIVATE.toString().equals(type.toUpperCase()); 38 | } 39 | 40 | public boolean isGroupOrSupergroup() { 41 | Type type = getType(); 42 | return type == Type.GROUP || type == Type.SUPERGROUP; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | StringBuilder builder = new StringBuilder(); 48 | builder.append(type).append(' '); 49 | builder.append(title); 50 | if (first_name != null) { 51 | builder.append(' ').append(first_name); 52 | } 53 | if (last_name != null) { 54 | builder.append(' ').append(last_name); 55 | } 56 | if (username != null) { 57 | builder.append(" @").append(username); 58 | } 59 | return builder.toString(); 60 | } 61 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/ChatAction.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types; 2 | 3 | /** 4 | * @see ChatAction 5 | */ 6 | public enum ChatAction { 7 | 8 | TYPING("typing"), 9 | UPLOAD_PHOTO("upload_photo"), 10 | RECORD_VIDEO("record_video"), 11 | UPLOAD_VIDEO("upload_video"), 12 | RECORD_AUDIO("record_audio"), 13 | UPLOAD_AUDIO("upload_audio"), 14 | UPLOAD_DOCUMENT("upload_document"), 15 | FIND_LOCATION("find_location"), 16 | RECORD_VIDEO_NOTE("record_video_note"), 17 | UPLOAD_VIDEO_NOTE("upload_video_note"); 18 | 19 | public final String VALUE; 20 | 21 | private ChatAction(String value) { 22 | VALUE = value; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/ChatMember.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types; 2 | 3 | /** 4 | * @see Official documentation of ChatMember 5 | */ 6 | public class ChatMember { 7 | public User user; 8 | public String status; 9 | 10 | public int until_date; // Restricted and kicked only 11 | 12 | // Administrators only 13 | public boolean can_be_edited; 14 | public boolean can_change_info; 15 | public boolean can_post_messages; 16 | public boolean can_edit_messages; 17 | public boolean can_delete_messages; 18 | public boolean can_invite_users; 19 | public boolean can_restrict_members; 20 | public boolean can_pin_messages; 21 | public boolean can_promote_members; 22 | 23 | // Restricted only 24 | public boolean can_send_messages; 25 | public boolean can_send_media_messages; 26 | public boolean can_send_other_messages; 27 | public boolean can_add_web_page_previews; 28 | 29 | public enum Status { 30 | CREATOR, ADMINISTRATOR, MEMBER, RESTRICTED, LEFT, KICKED 31 | } 32 | 33 | /** 34 | * Get the status field as an enum value. 35 | */ 36 | public Status getStatus() { 37 | try { 38 | return Status.valueOf(status.toUpperCase()); 39 | } catch (Exception e) { 40 | return null; 41 | } 42 | } 43 | 44 | public boolean isOwner() { 45 | return getStatus() == Status.CREATOR; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/ChatPhoto.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types; 2 | 3 | /** 4 | * @see Chat 5 | */ 6 | public class ChatPhoto { 7 | public String small_file_id; 8 | public String big_file_id; 9 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/Contact.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types; 2 | 3 | /** 4 | * @see Contact 5 | */ 6 | public class Contact { 7 | public String phone_number; 8 | public String first_name; 9 | public String last_name; 10 | public long user_id; 11 | public String vcard; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/Location.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types; 2 | 3 | /** 4 | * @see Location 5 | */ 6 | public class Location { 7 | public float latitude; 8 | public float longitude; 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/Message.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types; 2 | 3 | import se.anyro.tgbotapi.types.file.Audio; 4 | import se.anyro.tgbotapi.types.file.Document; 5 | import se.anyro.tgbotapi.types.file.PhotoSize; 6 | import se.anyro.tgbotapi.types.file.Video; 7 | import se.anyro.tgbotapi.types.file.VideoNote; 8 | import se.anyro.tgbotapi.types.file.Voice; 9 | import se.anyro.tgbotapi.types.games.Animation; 10 | import se.anyro.tgbotapi.types.games.Game; 11 | import se.anyro.tgbotapi.types.passport.PassportData; 12 | import se.anyro.tgbotapi.types.payments.Invoice; 13 | import se.anyro.tgbotapi.types.payments.SuccessfulPayment; 14 | import se.anyro.tgbotapi.types.stickers.Sticker; 15 | 16 | /** 17 | * @see Message 18 | */ 19 | public class Message { 20 | public int message_id; 21 | public User from; 22 | public int date; 23 | public Chat chat; 24 | public User forward_from; 25 | public Chat forward_from_chat; // Only for channels 26 | public int forward_from_message_id; 27 | public String forward_signature; 28 | public String forward_sender_name; 29 | public int forward_date; 30 | public Message reply_to_message; 31 | public int edit_date; 32 | public String author_signature; 33 | public String text; 34 | public MessageEntity[] entities; 35 | public MessageEntity[] caption_entities; 36 | public Audio audio; 37 | public Document document; 38 | public Animation animation; 39 | public Game game; 40 | public PhotoSize[] photo; 41 | public Sticker sticker; 42 | public Video video; 43 | public Voice voice; 44 | public VideoNote video_note; 45 | public String caption; 46 | public Contact contact; 47 | public Location location; 48 | public Venue venue; 49 | public User[] new_chat_members; 50 | public User left_chat_member; 51 | public String new_chat_title; 52 | public PhotoSize[] new_chat_photo; 53 | public boolean delete_chat_photo; 54 | public boolean group_chat_created; 55 | public boolean supergroup_chat_created; 56 | public boolean channel_chat_created; 57 | public long migrate_to_chat_id; 58 | public long migrate_from_chat_id; 59 | public Message pinned_message; 60 | public Invoice invoice; 61 | public SuccessfulPayment successful_payment; 62 | public String connected_website; 63 | public PassportData passport_data; 64 | 65 | private static final String VIDEO_MP4 = "video/mp4"; 66 | 67 | /** 68 | * Returns text or caption depending on what is set or an empty string if none is available. 69 | */ 70 | public String getSafeTextOrCaption() { 71 | if (text != null) { 72 | return text; 73 | } else if (caption != null) { 74 | return caption; 75 | } else { 76 | return ""; 77 | } 78 | } 79 | 80 | public boolean isGif() { 81 | return document != null && VIDEO_MP4.equals(document.mime_type); 82 | } 83 | 84 | public boolean isReply() { 85 | return reply_to_message != null; 86 | } 87 | 88 | public boolean isForwardedFromChannel() { 89 | return forward_from_chat != null; 90 | } 91 | 92 | public boolean isForwardedFrom(long channel) { 93 | return forward_from_chat != null && forward_from_chat.id == channel; 94 | } 95 | 96 | /** 97 | * Did the user forward a message that isn't his/her own message? 98 | */ 99 | public boolean isForwardedFromOther() { 100 | if (forward_date == 0) { 101 | return false; // Not forwarded 102 | } 103 | if (forward_from == null || from == null) { 104 | return true; 105 | } 106 | return from.id != forward_from.id; 107 | } 108 | 109 | /** 110 | * Returns true if the message is just a notification such as a new group name or a member leaving a group. 111 | */ 112 | public boolean isNotification() { 113 | return new_chat_members != null || left_chat_member != null || new_chat_title != null || new_chat_photo != null 114 | || delete_chat_photo || group_chat_created || supergroup_chat_created || channel_chat_created 115 | || migrate_to_chat_id > 0 || migrate_from_chat_id > 0 || pinned_message != null; 116 | } 117 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/MessageEntity.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types; 2 | 3 | /** 4 | * @see Official documentation of MessageEntity 5 | */ 6 | public class MessageEntity { 7 | public String type; 8 | public int offset; 9 | public int length; 10 | public String url; 11 | public User user; 12 | 13 | public enum Type { 14 | MENTION, HASHTAG, CASHTAG, BOT_COMMAND, URL, EMAIL, PHONE_NUMBER, BOLD, ITALIC, CODE, PRE, TEXT_LINK, TEXT_MENTION 15 | } 16 | 17 | /** 18 | * Get the type field as an enum value. 19 | */ 20 | public Type getType() { 21 | return Type.valueOf(type.toUpperCase()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/ParseMode.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types; 2 | 3 | /** 4 | * The Bot API supports basic formatting for messages. You can use bold and italic text, as well as inline links and 5 | * pre-formatted code in your bots' messages. Telegram clients will render them accordingly. You can use either 6 | * markdown-style or HTML-style formatting. 7 | * 8 | * @see Formatting options 9 | */ 10 | public enum ParseMode { 11 | 12 | MARKDOWN("Markdown"), 13 | HTML("HTML"); 14 | 15 | public final String VALUE; 16 | 17 | private ParseMode(String value) { 18 | VALUE = value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/ResponseParameters.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types; 2 | 3 | /** 4 | * @see ResponseParameters 5 | */ 6 | public class ResponseParameters { 7 | public long migrate_to_chat_id; 8 | public int retry_after; 9 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/Update.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types; 2 | 3 | import se.anyro.tgbotapi.types.inline.CallbackQuery; 4 | import se.anyro.tgbotapi.types.inline.ChosenInlineResult; 5 | import se.anyro.tgbotapi.types.inline.InlineQuery; 6 | import se.anyro.tgbotapi.types.payments.PreCheckoutQuery; 7 | import se.anyro.tgbotapi.types.payments.ShippingQuery; 8 | import se.anyro.tgbotapi.types.poll.Poll; 9 | import se.anyro.tgbotapi.types.poll.PollAnswer; 10 | 11 | /** 12 | * @see Update 13 | */ 14 | public class Update { 15 | public int update_id; 16 | public Message message; 17 | public Message edited_message; 18 | public Message channel_post; 19 | public Message edited_channel_post; 20 | public InlineQuery inline_query; 21 | public ChosenInlineResult chosen_inline_result; 22 | public CallbackQuery callback_query; 23 | public ShippingQuery shipping_query; 24 | public PreCheckoutQuery pre_checkout_query; 25 | public Poll poll; 26 | public PollAnswer poll_answer; 27 | 28 | public enum Type { 29 | MESSAGE, EDITED_MESSAGE, CHANNEL_POST, EDITED_CHANNEL_POST, INLINE_QUERY, CHOSEN_INLINE_RESULT, CALLBACK_QUERY, SHIPPING_QUERY, PRE_CHECKOUT_QUERY, POLL, POLL_ANSWER, UNKNOWN 30 | } 31 | 32 | public boolean isMessage() { 33 | return message != null; 34 | } 35 | 36 | public boolean isEditedMessage() { 37 | return edited_message != null; 38 | } 39 | 40 | public boolean isChannelPost() { 41 | return channel_post != null; 42 | } 43 | 44 | public boolean isEditedChannelPost() { 45 | return edited_channel_post != null; 46 | } 47 | 48 | public boolean isInlineQuery() { 49 | return inline_query != null; 50 | } 51 | 52 | public boolean isChosenInlineResult() { 53 | return chosen_inline_result != null; 54 | } 55 | 56 | public boolean isCallbackQuery() { 57 | return callback_query != null; 58 | } 59 | 60 | public boolean isShippingQuery() { 61 | return shipping_query != null; 62 | } 63 | 64 | public boolean isPreCheckoutQuery() { 65 | return pre_checkout_query != null; 66 | } 67 | 68 | public boolean isPoll() { 69 | return poll != null; 70 | } 71 | 72 | public boolean isPollAnswer() { 73 | return poll_answer != null; 74 | } 75 | 76 | public Type getType() { 77 | if (isMessage()) { 78 | return Type.MESSAGE; 79 | } else if (isEditedMessage()) { 80 | return Type.EDITED_MESSAGE; 81 | } else if (isChannelPost()) { 82 | return Type.CHANNEL_POST; 83 | } else if (isEditedChannelPost()) { 84 | return Type.EDITED_CHANNEL_POST; 85 | } else if (isInlineQuery()) { 86 | return Type.INLINE_QUERY; 87 | } else if (isChosenInlineResult()) { 88 | return Type.CHOSEN_INLINE_RESULT; 89 | } else if (isCallbackQuery()) { 90 | return Type.CALLBACK_QUERY; 91 | } else if (isShippingQuery()) { 92 | return Type.SHIPPING_QUERY; 93 | } else if (isPreCheckoutQuery()) { 94 | return Type.PRE_CHECKOUT_QUERY; 95 | } else if (isPoll()) { 96 | return Type.POLL; 97 | } else if (isPollAnswer()) { 98 | return Type.POLL_ANSWER; 99 | } 100 | return Type.UNKNOWN; 101 | } 102 | 103 | /** 104 | * Returns the user who sent the message. Might return null for messages in channels or new types of updates. 105 | */ 106 | public User fromUser() { 107 | Type type = getType(); 108 | if (type == null) { 109 | return null; 110 | } 111 | switch (type) { 112 | case MESSAGE: 113 | return message.from; 114 | case EDITED_MESSAGE: 115 | return edited_message.from; 116 | case CHANNEL_POST: 117 | return channel_post.from; 118 | case EDITED_CHANNEL_POST: 119 | return edited_channel_post.from; 120 | case INLINE_QUERY: 121 | return inline_query.from; 122 | case CHOSEN_INLINE_RESULT: 123 | return chosen_inline_result.from; 124 | case CALLBACK_QUERY: 125 | return callback_query.from; 126 | case SHIPPING_QUERY: 127 | return shipping_query.from; 128 | case PRE_CHECKOUT_QUERY: 129 | return pre_checkout_query.from; 130 | case POLL: 131 | return null; 132 | case POLL_ANSWER: 133 | return poll_answer.user; 134 | default: 135 | return null; 136 | } 137 | } 138 | 139 | /** 140 | * Returns the id of the user who sent the message. Might return 0 for messages in channels or new types of updates. 141 | */ 142 | public long fromUserId() { 143 | User from = fromUser(); 144 | if (from != null) { 145 | return from.id; 146 | } 147 | return 0; 148 | } 149 | 150 | public Chat chat() { 151 | Type type = getType(); 152 | if (type == null) { 153 | return null; 154 | } 155 | switch (type) { 156 | case MESSAGE: 157 | return message.chat; 158 | case EDITED_MESSAGE: 159 | return edited_message.chat; 160 | case CHANNEL_POST: 161 | return channel_post.chat; 162 | case EDITED_CHANNEL_POST: 163 | return edited_channel_post.chat; 164 | case CALLBACK_QUERY: 165 | if (callback_query.message != null) { 166 | return callback_query.message.chat; 167 | } 168 | case INLINE_QUERY: 169 | case CHOSEN_INLINE_RESULT: 170 | case SHIPPING_QUERY: 171 | case PRE_CHECKOUT_QUERY: 172 | default: 173 | return null; 174 | } 175 | } 176 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/User.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types; 2 | 3 | /** 4 | * @see User 5 | */ 6 | public class User { 7 | public long id; 8 | public boolean is_bot; 9 | public String first_name; 10 | public String last_name; 11 | public String username; 12 | public String language_code; 13 | 14 | public String getUrl() { 15 | return "tg://user?id=" + id; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | StringBuilder builder = new StringBuilder(); 21 | builder.append(id).append(' '); 22 | builder.append(first_name); 23 | if (last_name != null) { 24 | builder.append(' ').append(last_name); 25 | } 26 | if (username != null) { 27 | builder.append(" @").append(username); 28 | } 29 | return builder.toString(); 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/Venue.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types; 2 | 3 | /** 4 | * @see Official documentation of Venue 5 | */ 6 | public class Venue { 7 | Location location; 8 | String title; 9 | String address; 10 | String foursquare_id; 11 | String foursquare_type; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/WebhookInfo.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types; 2 | 3 | /** 4 | * @see WebhookInfo 5 | */ 6 | public class WebhookInfo { 7 | public String url; 8 | public boolean has_custom_certificate; 9 | public int pending_update_count; 10 | public int last_error_date; 11 | public String last_error_message; 12 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/Animation.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | /** 4 | * @see Animation 5 | */ 6 | public class Animation { 7 | public String file_id; 8 | public int width; 9 | public int height; 10 | public int duration; 11 | public PhotoSize thumb; 12 | public String file_name; 13 | public String mime_type; 14 | public int file_size; 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/Audio.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | /** 4 | * @see Audio 5 | */ 6 | public class Audio { 7 | public String file_id; 8 | public int duration; 9 | public String performer; 10 | public String title; 11 | public String mime_type; 12 | public int file_size; 13 | public PhotoSize thumb; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/Document.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | /** 4 | * @see Document 5 | */ 6 | public class Document { 7 | public String file_id; 8 | public PhotoSize thumb; 9 | public String file_name; 10 | public String mime_type; 11 | public int file_size; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/File.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | /** 4 | * Represents a file ready to be downloaded. 5 | * 6 | * @see File 7 | */ 8 | public class File { 9 | public String file_id; 10 | public int file_size; 11 | public String file_path; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/InputMedia.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | import java.io.InputStream; 4 | 5 | import se.anyro.tgbotapi.types.ParseMode; 6 | 7 | /** 8 | * Base class of the InputMedia classes. 9 | * 10 | * @see Official documentation of InputMedia 11 | */ 12 | public abstract class InputMedia { 13 | 14 | public String media; 15 | public String thumb; 16 | public String caption; 17 | public String parse_mode; 18 | 19 | // Not part of JSON serialization 20 | public transient String filename; 21 | public transient InputStream mediaStream; 22 | public transient InputStream thumbStream; 23 | 24 | public InputMedia() { 25 | } 26 | 27 | protected InputMedia(String media) { 28 | this.media = media; 29 | } 30 | 31 | protected InputMedia(InputStream mediaStream, String filename) { 32 | this.media = "attach://" + filename; 33 | this.filename = filename; 34 | this.mediaStream = mediaStream; 35 | } 36 | 37 | public InputMedia(InputStream mediaStream, String filename, InputStream thumbStream) { 38 | this(mediaStream, filename); 39 | this.thumb = "attach://" + getThumbFilename(); 40 | this.thumbStream = thumbStream; 41 | } 42 | 43 | public void setParseMode(ParseMode parseMode) { 44 | this.parse_mode = parseMode.VALUE; 45 | } 46 | 47 | public String getThumbFilename() { 48 | return "thumb_" + filename; 49 | } 50 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/InputMediaAnimation.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | import java.io.InputStream; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InputMediaAnimation 8 | */ 9 | public class InputMediaAnimation extends InputMedia { 10 | 11 | public String type = "animation"; 12 | public Integer width; 13 | public Integer height; 14 | public Integer duration; 15 | public Boolean supports_streaming; 16 | 17 | public InputMediaAnimation() { 18 | } 19 | 20 | public InputMediaAnimation(String media) { 21 | super(media); 22 | } 23 | 24 | public InputMediaAnimation(String type, InputStream mediaStream, String filename) { 25 | super(mediaStream, filename); 26 | } 27 | 28 | public InputMediaAnimation(String type, InputStream mediaStream, String filename, InputStream thumbStream) { 29 | super(mediaStream, filename, thumbStream); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/InputMediaAudio.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | import java.io.InputStream; 4 | 5 | /** 6 | * @see Official documentation of InputMediaAudio 7 | */ 8 | public class InputMediaAudio extends InputMedia { 9 | 10 | public String type = "audio"; 11 | public Integer duration; 12 | public String performer; 13 | public String title; 14 | public Boolean supports_streaming; 15 | 16 | public InputMediaAudio() { 17 | } 18 | 19 | public InputMediaAudio(String media) { 20 | super(media); 21 | } 22 | 23 | public InputMediaAudio(String type, InputStream mediaStream, String filename) { 24 | super(mediaStream, filename); 25 | } 26 | 27 | public InputMediaAudio(String type, InputStream mediaStream, String filename, InputStream thumbStream) { 28 | super(mediaStream, filename, thumbStream); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/InputMediaDocument.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | import java.io.InputStream; 4 | 5 | /** 6 | * @see Official documentation of InputMediaPhoto 7 | */ 8 | public class InputMediaDocument extends InputMedia { 9 | 10 | public String type = "document"; 11 | 12 | public InputMediaDocument() { 13 | } 14 | 15 | public InputMediaDocument(String media) { 16 | super(media); 17 | } 18 | 19 | public InputMediaDocument(String type, InputStream mediaStream, String filename) { 20 | super(mediaStream, filename); 21 | } 22 | 23 | public InputMediaDocument(String type, InputStream mediaStream, String filename, InputStream thumbStream) { 24 | super(mediaStream, filename, thumbStream); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/InputMediaPhoto.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | import java.io.InputStream; 4 | 5 | /** 6 | * @see Official documentation of InputMediaPhoto 7 | */ 8 | public class InputMediaPhoto extends InputMedia { 9 | 10 | public String type = "photo"; 11 | 12 | public InputMediaPhoto() { 13 | } 14 | 15 | public InputMediaPhoto(String media) { 16 | super(media); 17 | } 18 | 19 | public InputMediaPhoto(String type, InputStream mediaStream, String filename) { 20 | super(mediaStream, filename); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/InputMediaVideo.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | import java.io.InputStream; 4 | 5 | /** 6 | * @see Official documentation of InputMediaVideo 7 | */ 8 | public class InputMediaVideo extends InputMedia { 9 | 10 | public String type = "video"; 11 | public Integer width; 12 | public Integer height; 13 | public Integer duration; 14 | public Boolean supports_streaming; 15 | 16 | public InputMediaVideo() { 17 | } 18 | 19 | public InputMediaVideo(String media) { 20 | super(media); 21 | } 22 | 23 | public InputMediaVideo(String type, InputStream mediaStream, String filename) { 24 | super(mediaStream, filename); 25 | } 26 | 27 | public InputMediaVideo(String type, InputStream mediaStream, String filename, InputStream thumbStream) { 28 | super(mediaStream, filename, thumbStream); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/PhotoSize.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | /** 4 | * @see Sticker 5 | */ 6 | public class PhotoSize { 7 | public String file_id; 8 | public int width; 9 | public int height; 10 | public int file_size; 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/UserProfilePhotos.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | /** 4 | * User profile photos as an array of arrays where each array is a single profile photo represented in different sizes. 5 | * 6 | * @see UserProfilePhotos 7 | */ 8 | public class UserProfilePhotos { 9 | public int total_count; 10 | public PhotoSize[][] photos; 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/Video.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | /** 4 | * @see Video 5 | */ 6 | public class Video { 7 | public String file_id; 8 | public int width; 9 | public int height; 10 | public int duration; 11 | public PhotoSize thumb; 12 | public String mime_type; 13 | public long file_size; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/VideoNote.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | /** 4 | * @see VideoNote 5 | */ 6 | public class VideoNote { 7 | public String file_id; 8 | public int length; 9 | public int duration; 10 | public PhotoSize thumb; 11 | public int file_size; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/file/Voice.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.file; 2 | 3 | /** 4 | * @see Voice 5 | */ 6 | public class Voice { 7 | public String file_id; 8 | public int duration; 9 | public String mime_type; 10 | public int file_size; 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/games/Animation.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.games; 2 | 3 | import se.anyro.tgbotapi.types.file.PhotoSize; 4 | 5 | /** 6 | * @see Animation 7 | */ 8 | public class Animation { 9 | public String file_id; 10 | public PhotoSize thumb; 11 | public String file_name; 12 | public String mime_type; 13 | public int file_size; 14 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/games/CallbackGame.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.games; 2 | 3 | /** 4 | * A placeholder, currently holds no information. 5 | * 6 | * @see CallbackGame 7 | */ 8 | public class CallbackGame { 9 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/games/Game.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.games; 2 | 3 | import se.anyro.tgbotapi.types.MessageEntity; 4 | import se.anyro.tgbotapi.types.file.PhotoSize; 5 | 6 | /** 7 | * @see Game 8 | */ 9 | public class Game { 10 | public String title; 11 | public String description; 12 | public PhotoSize[] photo; 13 | public String text; 14 | public MessageEntity[] text_entities; 15 | public Animation animation; 16 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/games/GameHighScore.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.games; 2 | 3 | import se.anyro.tgbotapi.types.User; 4 | 5 | /** 6 | * One row of the high scores table for a game. 7 | * 8 | * @see GameHighScore 9 | */ 10 | public class GameHighScore { 11 | public int position; 12 | public User user; 13 | public int score; 14 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/CallbackQuery.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.Message; 4 | import se.anyro.tgbotapi.types.User; 5 | 6 | /** 7 | * @see Official documentation of CallbackQuery 8 | */ 9 | public class CallbackQuery { 10 | public String id; 11 | public User from; 12 | public Message message; 13 | public String inline_message_id; 14 | public String chat_instance; 15 | public String data; 16 | public String game_short_name; 17 | 18 | public boolean isInline() { 19 | return inline_message_id != null; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/ChosenInlineResult.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.Location; 4 | import se.anyro.tgbotapi.types.User; 5 | 6 | /** 7 | * @see Official documentation of ChosenInlineResult 8 | */ 9 | public class ChosenInlineResult { 10 | public String result_id; 11 | public User from; 12 | public Location location; 13 | public String inline_message_id; 14 | public String query; 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQuery.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.User; 4 | 5 | /** 6 | * @see Official documentation of InlineQuery 7 | */ 8 | public class InlineQuery { 9 | public String id; 10 | public User from; 11 | public String query; 12 | public String offset; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResult.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | /** 4 | * Base class of the inline query result classes. 5 | * 6 | * @see Official documentation of InlineQueryResult 7 | */ 8 | public abstract class InlineQueryResult { 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultArticle.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultArticle 8 | */ 9 | public class InlineQueryResultArticle extends InlineQueryResult { 10 | public String type = "article"; 11 | public String id; 12 | public String title; 13 | public InputMessageContent input_message_content; 14 | public InlineKeyboardMarkup reply_markup; 15 | public String url; 16 | public boolean hide_url; 17 | public String description; 18 | public String thumb_url; 19 | public int thumb_width; 20 | public int thumb_height; 21 | 22 | public InlineQueryResultArticle(String id, String title, String messageText) { 23 | this(id, title, new InputTextMessageContent(messageText)); 24 | } 25 | 26 | public InlineQueryResultArticle(String id, String title, InputMessageContent inputMessageContent) { 27 | this.id = id; 28 | this.title = title; 29 | this.input_message_content = inputMessageContent; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultAudio.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultAudio 8 | */ 9 | public class InlineQueryResultAudio extends InlineQueryResult { 10 | public String type = "audio"; 11 | public String id; 12 | public String audio_url; 13 | public String title; 14 | public String caption; 15 | public String parse_mode; 16 | public String performer; 17 | public int audio_duration; 18 | public InlineKeyboardMarkup reply_markup; 19 | public InputMessageContent input_message_content; 20 | 21 | public InlineQueryResultAudio(String id, String audioUrl, String title) { 22 | this.id = id; 23 | this.audio_url = audioUrl; 24 | this.title = title; 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultCachedAudio.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultCachedAudio 8 | */ 9 | public class InlineQueryResultCachedAudio extends InlineQueryResult { 10 | public String type = "audio"; 11 | public String id; 12 | public String audio_file_id; 13 | public String caption; 14 | public String parse_mode; 15 | public InlineKeyboardMarkup reply_markup; 16 | public InputMessageContent input_message_content; 17 | 18 | public InlineQueryResultCachedAudio(String id, String fileId) { 19 | this.id = id; 20 | this.audio_file_id = fileId; 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultCachedDocument.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultCachedDocument 8 | */ 9 | public class InlineQueryResultCachedDocument extends InlineQueryResult { 10 | public String type = "document"; 11 | public String id; 12 | public String title; 13 | public String document_file_id; 14 | public String description; 15 | public String caption; 16 | public String parse_mode; 17 | public InlineKeyboardMarkup reply_markup; 18 | public InputMessageContent input_message_content; 19 | 20 | public InlineQueryResultCachedDocument(String id, String fileId, String title) { 21 | this.id = id; 22 | this.document_file_id = fileId; 23 | this.title = title; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultCachedGif.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultCachedGif 8 | */ 9 | public class InlineQueryResultCachedGif extends InlineQueryResult { 10 | public String type = "gif"; 11 | public String id; 12 | public String gif_file_id; 13 | public String title; 14 | public String caption; 15 | public String parse_mode; 16 | public InlineKeyboardMarkup reply_markup; 17 | public InputMessageContent input_message_content; 18 | 19 | public InlineQueryResultCachedGif(String id, String fileId) { 20 | this.id = id; 21 | this.gif_file_id = fileId; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultCachedMpeg4Gif.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultCachedMpeg4Gif 8 | */ 9 | public class InlineQueryResultCachedMpeg4Gif extends InlineQueryResult { 10 | public String type = "mpeg4_gif"; 11 | public String id; 12 | public String mpeg4_file_id; 13 | public String title; 14 | public String caption; 15 | public String parse_mode; 16 | public InlineKeyboardMarkup reply_markup; 17 | public InputMessageContent input_message_content; 18 | 19 | public InlineQueryResultCachedMpeg4Gif(String id, String fileId) { 20 | this.id = id; 21 | this.mpeg4_file_id = fileId; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultCachedPhoto.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultCachedPhoto 8 | */ 9 | public class InlineQueryResultCachedPhoto extends InlineQueryResult { 10 | public String type = "photo"; 11 | public String id; 12 | public String photo_file_id; 13 | public String title; 14 | public String description; 15 | public String caption; 16 | public String parse_mode; 17 | public InlineKeyboardMarkup reply_markup; 18 | public InputMessageContent input_message_content; 19 | 20 | public InlineQueryResultCachedPhoto(String id, String fileId) { 21 | this.id = id; 22 | this.photo_file_id = fileId; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultCachedSticker.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultCachedSticker 8 | */ 9 | public class InlineQueryResultCachedSticker extends InlineQueryResult { 10 | public String type = "gif"; 11 | public String id; 12 | public String sticker_file_id; 13 | public InlineKeyboardMarkup reply_markup; 14 | public InputMessageContent input_message_content; 15 | 16 | public InlineQueryResultCachedSticker(String id, String fileId) { 17 | this.id = id; 18 | this.sticker_file_id = fileId; 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultCachedVideo.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultCachedVideo 8 | */ 9 | public class InlineQueryResultCachedVideo extends InlineQueryResult { 10 | public String type = "video"; 11 | public String id; 12 | public String video_file_id; 13 | public String title; 14 | public String description; 15 | public String caption; 16 | public String parse_mode; 17 | public InlineKeyboardMarkup reply_markup; 18 | public InputMessageContent input_message_content; 19 | 20 | public InlineQueryResultCachedVideo(String id, String fileId, String title) { 21 | this.id = id; 22 | this.video_file_id = fileId; 23 | this.title = title; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultCachedVoice.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultCachedVoice 8 | */ 9 | public class InlineQueryResultCachedVoice extends InlineQueryResult { 10 | public String type = "voice"; 11 | public String id; 12 | public String voice_file_id; 13 | public String title; 14 | public String caption; 15 | public String parse_mode; 16 | public InlineKeyboardMarkup reply_markup; 17 | public InputMessageContent input_message_content; 18 | 19 | public InlineQueryResultCachedVoice(String id, String fileId, String title) { 20 | this.id = id; 21 | this.voice_file_id = fileId; 22 | this.title = title; 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultContact.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultContact 8 | */ 9 | public class InlineQueryResultContact extends InlineQueryResult { 10 | public String type = "contact"; 11 | public String id; 12 | public String phone_number; 13 | public String first_name; 14 | public String last_name; 15 | public String vcard; 16 | public InlineKeyboardMarkup reply_markup; 17 | public InputMessageContent input_message_content; 18 | public String thumb_url; 19 | public int thumb_width; 20 | public int thumb_height; 21 | 22 | public InlineQueryResultContact(String id, String phoneNumber, String firstName, String lastName) { 23 | this.id = id; 24 | this.phone_number = phoneNumber; 25 | this.first_name = firstName; 26 | this.last_name = lastName; // Optional but added here for consistency 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultDocument.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultDocument 8 | */ 9 | public class InlineQueryResultDocument extends InlineQueryResult { 10 | public String type = "document"; 11 | public String id; 12 | public String title; 13 | public String caption; 14 | public String parse_mode; 15 | public String document_url; 16 | public String mime_type; 17 | public String description; 18 | public InlineKeyboardMarkup reply_markup; 19 | public InputMessageContent input_message_content; 20 | public String thumb_url; 21 | public int thumb_width; 22 | public int thumb_height; 23 | 24 | public static final String MIME_PDF = "application/pdf"; 25 | public static final String MIME_ZIP = "application/zip"; 26 | 27 | public InlineQueryResultDocument(String id, String documentUrl, String title, String mimeType) { 28 | this.id = id; 29 | this.document_url = documentUrl; 30 | this.title = title; 31 | this.mime_type = mimeType; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultGame.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultGame 8 | */ 9 | public class InlineQueryResultGame extends InlineQueryResult { 10 | public String type = "game"; 11 | public String id; 12 | public String game_short_name; 13 | public InlineKeyboardMarkup reply_markup; 14 | 15 | public InlineQueryResultGame(String id, String gameShortName) { 16 | this.id = id; 17 | this.game_short_name = gameShortName; 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultGif.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultGif 8 | */ 9 | public class InlineQueryResultGif extends InlineQueryResult { 10 | public String type = "gif"; 11 | public String id; 12 | public String gif_url; 13 | public int gif_width; 14 | public int gif_height; 15 | public int gif_duration; 16 | public String thumb_url; 17 | public String title; 18 | public String caption; 19 | public String parse_mode; 20 | public InlineKeyboardMarkup reply_markup; 21 | public InputMessageContent input_message_content; 22 | 23 | public InlineQueryResultGif(String id, String gifUrl, String thumbUrl) { 24 | this.id = id; 25 | this.gif_url = gifUrl; 26 | this.thumb_url = thumbUrl; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultLocation.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultLocation 8 | */ 9 | public class InlineQueryResultLocation extends InlineQueryResult { 10 | public String type = "location"; 11 | public String id; 12 | public float latitude; 13 | public float longitude; 14 | public String title; 15 | public InlineKeyboardMarkup reply_markup; 16 | public InputMessageContent input_message_content; 17 | public String thumb_url; 18 | public int thumb_width; 19 | public int thumb_height; 20 | 21 | public InlineQueryResultLocation(String id, float latitude, float longitude, String title) { 22 | this.id = id; 23 | this.latitude = latitude; 24 | this.longitude = longitude; 25 | this.title = title; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultMpeg4Gif.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultMpeg4Gif 8 | */ 9 | public class InlineQueryResultMpeg4Gif extends InlineQueryResult { 10 | public String type = "mpeg4_gif"; 11 | public String id; 12 | public String mpeg4_url; 13 | public int mpeg4_width; 14 | public int mpeg4_height; 15 | public int mpeg4_duration; 16 | public String thumb_url; 17 | public String title; 18 | public String caption; 19 | public String parse_mode; 20 | public InlineKeyboardMarkup reply_markup; 21 | public InputMessageContent input_message_content; 22 | 23 | public InlineQueryResultMpeg4Gif(String id, String mpeg4_url, String thumb_url) { 24 | this.id = id; 25 | this.mpeg4_url = mpeg4_url; 26 | this.thumb_url = thumb_url; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultPhoto.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultPhoto 8 | */ 9 | public class InlineQueryResultPhoto extends InlineQueryResult { 10 | public String type = "photo"; 11 | public String id; 12 | public String photo_url; 13 | public String thumb_url; 14 | public int photo_width; 15 | public int photo_height; 16 | public String title; 17 | public String description; 18 | public String caption; 19 | public String parse_mode; 20 | public InlineKeyboardMarkup reply_markup; 21 | public InputMessageContent input_message_content; 22 | 23 | public InlineQueryResultPhoto(String id, String photoUrl, String thumbUrl) { 24 | this.id = id; 25 | this.photo_url = photoUrl; 26 | this.thumb_url = thumbUrl; 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultVenue.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultVenue 8 | */ 9 | public class InlineQueryResultVenue extends InlineQueryResult { 10 | public String type = "venue"; 11 | public String id; 12 | public float latitude; 13 | public float longitude; 14 | public String title; 15 | public String address; 16 | public String foursquare_id; 17 | public String foursquare_type; 18 | public InlineKeyboardMarkup reply_markup; 19 | public InputMessageContent input_message_content; 20 | public String thumb_url; 21 | public int thumb_width; 22 | public int thumb_height; 23 | 24 | public InlineQueryResultVenue(String id, float latitude, float longitude, String title, String address) { 25 | this.id = id; 26 | this.latitude = latitude; 27 | this.longitude = longitude; 28 | this.title = title; 29 | this.address = address; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultVideo.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultVideo 8 | */ 9 | public class InlineQueryResultVideo extends InlineQueryResult { 10 | public String type = "video"; 11 | public String id; 12 | public String video_url; 13 | public String mime_type; 14 | public int video_width; 15 | public int video_height; 16 | public int video_duration; 17 | public String thumb_url; 18 | public String title; 19 | public String caption; 20 | public String parse_mode; 21 | public String description; 22 | public InlineKeyboardMarkup reply_markup; 23 | public InputMessageContent input_message_content; 24 | 25 | public static final String MIME_HTML = "text/html"; 26 | public static final String MIME_MP4 = "video/mp4"; 27 | 28 | public InlineQueryResultVideo(String id, String videoUrl, String mimeType, String thumbUrl, String title) { 29 | this.id = id; 30 | this.video_url = videoUrl; 31 | this.mime_type = mimeType; 32 | this.thumb_url = thumbUrl; 33 | this.title = title; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InlineQueryResultVoice.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.reply_markup.InlineKeyboardMarkup; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InlineQueryResultVoice 8 | */ 9 | public class InlineQueryResultVoice extends InlineQueryResult { 10 | public String type = "voice"; 11 | public String id; 12 | public String voice_url; 13 | public String title; 14 | public String caption; 15 | public String parse_mode; 16 | public int voice_duration; 17 | public InlineKeyboardMarkup reply_markup; 18 | public InputMessageContent input_message_content; 19 | 20 | public InlineQueryResultVoice(String id, String voiceUrl, String title) { 21 | this.id = id; 22 | this.voice_url = voiceUrl; 23 | this.title = title; 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InputContactMessageContent.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | /** 4 | * @see Official documentation of 5 | * InputContactMessageContent 6 | */ 7 | public class InputContactMessageContent extends InputMessageContent { 8 | public String phone_number; 9 | public String first_name; 10 | public String last_name; 11 | public String vcard; 12 | 13 | public InputContactMessageContent(String phoneNumber, String firstName, String lastName) { 14 | this.phone_number = phoneNumber; 15 | this.first_name = firstName; 16 | this.last_name = lastName; // Optional but added here for consistency 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InputLocationMessageContent.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | /** 4 | * @see Official documentation of 5 | * InputLocationMessageContent 6 | */ 7 | public class InputLocationMessageContent extends InputMessageContent { 8 | 9 | public float latitude; 10 | public float longitude; 11 | 12 | public InputLocationMessageContent(float latitude, float longitude) { 13 | this.latitude = latitude; 14 | this.longitude = longitude; 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InputMessageContent.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | /** 4 | * Base class of the input message content classes. 5 | * 6 | * @see Official documentation of 7 | * InputMessageContent 8 | */ 9 | public abstract class InputMessageContent { 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InputTextMessageContent.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | import se.anyro.tgbotapi.types.ParseMode; 4 | 5 | /** 6 | * @see Official documentation of 7 | * InputTextMessageContent 8 | */ 9 | public class InputTextMessageContent extends InputMessageContent { 10 | public String message_text; 11 | public String parse_mode; 12 | public boolean disable_web_page_preview; 13 | 14 | public InputTextMessageContent(String messageText) { 15 | this.message_text = messageText; 16 | } 17 | 18 | public InputTextMessageContent(String messageText, ParseMode parseMode, boolean disableWebPagePreview) { 19 | this.message_text = messageText; 20 | if (parseMode != null) { 21 | this.parse_mode = parseMode.VALUE; 22 | } 23 | this.disable_web_page_preview = disableWebPagePreview; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/inline/InputVenueMessageContent.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.inline; 2 | 3 | /** 4 | * @see Official documentation of 5 | * InputVenueMessageContent 6 | */ 7 | public class InputVenueMessageContent extends InputMessageContent { 8 | 9 | public float latitude; 10 | public float longitude; 11 | public String title; 12 | public String address; 13 | public String foursquare_id; 14 | public String foursquare_type; 15 | 16 | public InputVenueMessageContent(float latitude, float longitude, String title, String address) { 17 | this.latitude = latitude; 18 | this.longitude = longitude; 19 | this.title = title; 20 | this.address = address; 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/passport/EncryptedCredentials.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.passport; 2 | 3 | /** 4 | * @see EncryptedCredentials 5 | */ 6 | public class EncryptedCredentials { 7 | public String data; 8 | public String hash; 9 | public String secret; 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/passport/EncryptedPassportElement.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.passport; 2 | 3 | 4 | /** 5 | * @see EncryptedPassportElement 6 | */ 7 | public class EncryptedPassportElement { 8 | public String type; 9 | public String data; 10 | public String phone_number; 11 | public String email; 12 | public PassportFile[] files; 13 | public PassportFile front_side; 14 | public PassportFile reverse_side; 15 | public PassportFile selfie; 16 | public PassportFile[] translation; 17 | public String hash; 18 | 19 | public enum Type { 20 | PERSONAL_DETAILS, PASSPORT, DRIVER_LICENSE, IDENTITY_CARD, INTERNAL_PASSPORT, ADDRESS, UTILITY_BILL, 21 | BANK_STATEMENT, RENTAL_AGREEMENT, PASSPORT_REGISTRATION, TEMPORARY_REGISTRATION, PHONE_NUMBER, EMAIL 22 | } 23 | 24 | /** 25 | * Get the type field as an enum value. 26 | */ 27 | public Type getType() { 28 | try { 29 | return Type.valueOf(type.toUpperCase()); 30 | } catch (Exception e) { 31 | return null; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/passport/PassportData.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.passport; 2 | 3 | /** 4 | * @see PassportData 5 | */ 6 | public class PassportData { 7 | public EncryptedPassportElement[] data; 8 | public EncryptedCredentials credentials; 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/passport/PassportElementError.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.passport; 2 | 3 | /** 4 | * @see PassportElementError 5 | */ 6 | public class PassportElementError { 7 | public final String source; 8 | public String type; 9 | public String message; 10 | 11 | protected PassportElementError(String source) { 12 | this.source = source; 13 | } 14 | 15 | protected PassportElementError(String source, String type, String message) { 16 | this(source); 17 | this.type = type; 18 | this.message = message; 19 | } 20 | 21 | // Base class for single file errors (FrontSide, ReverseSide, Selfie, Unspecified, etc.) 22 | public static class File extends PassportElementError { 23 | public String file_hash; 24 | 25 | protected File(String source) { 26 | super(source); 27 | } 28 | 29 | protected File(String source, String type, String fileHash, String message) { 30 | super(source, type, message); 31 | this.file_hash = fileHash; 32 | } 33 | } 34 | 35 | // Base class for multi-file errors (TranslationFiles and Files) 36 | public static class Files extends PassportElementError { 37 | public String[] file_hashes; 38 | 39 | protected Files(String source) { 40 | super(source); 41 | } 42 | 43 | protected Files(String source, String type, String[] fileHashes, String message) { 44 | super(source, type, message); 45 | this.file_hashes = fileHashes; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/passport/PassportElementErrorDataField.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.passport; 2 | 3 | /** 4 | * @see PassportElementErrorDataField 5 | */ 6 | public class PassportElementErrorDataField extends PassportElementError { 7 | public String field_name; 8 | public String data_hash; 9 | 10 | public PassportElementErrorDataField() { 11 | super("data"); 12 | } 13 | 14 | public PassportElementErrorDataField(String type, String fieldName, String dataHash, String message) { 15 | super("data", type, message); 16 | this.field_name = fieldName; 17 | this.data_hash = dataHash; 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/passport/PassportElementErrorFile.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.passport; 2 | 3 | /** 4 | * @see PassportElementErrorFile 5 | */ 6 | public class PassportElementErrorFile extends PassportElementError.File { 7 | public PassportElementErrorFile() { 8 | super("file"); 9 | } 10 | 11 | protected PassportElementErrorFile(String type, String fileHash, String message) { 12 | super("file", type, fileHash, message); 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/passport/PassportElementErrorFiles.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.passport; 2 | 3 | /** 4 | * @see PassportElementErrorFiles 5 | */ 6 | public class PassportElementErrorFiles extends PassportElementError.Files { 7 | 8 | public PassportElementErrorFiles() { 9 | super("files"); 10 | } 11 | 12 | public PassportElementErrorFiles(String type, String[] fileHashes, String message) { 13 | super("files", type, fileHashes, message); 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/passport/PassportElementErrorFrontSide.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.passport; 2 | 3 | /** 4 | * @see PassportElementErrorFrontSide 5 | */ 6 | public class PassportElementErrorFrontSide extends PassportElementError.File { 7 | public PassportElementErrorFrontSide() { 8 | super("front_side"); 9 | } 10 | 11 | protected PassportElementErrorFrontSide(String type, String fileHash, String message) { 12 | super("front_side", type, fileHash, message); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/passport/PassportElementErrorReverseSide.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.passport; 2 | 3 | /** 4 | * @see PassportElementErrorReverseSide 5 | */ 6 | public class PassportElementErrorReverseSide extends PassportElementError.File { 7 | public PassportElementErrorReverseSide() { 8 | super("reverse_side"); 9 | } 10 | 11 | protected PassportElementErrorReverseSide(String type, String fileHash, String message) { 12 | super("reverse_side", type, fileHash, message); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/passport/PassportElementErrorSelfie.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.passport; 2 | 3 | /** 4 | * @see PassportElementErrorSelfie 5 | */ 6 | public class PassportElementErrorSelfie extends PassportElementError.File { 7 | public PassportElementErrorSelfie() { 8 | super("selfie"); 9 | } 10 | 11 | protected PassportElementErrorSelfie(String type, String fileHash, String message) { 12 | super("selfie", type, fileHash, message); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/passport/PassportElementErrorTranslationFile.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.passport; 2 | 3 | /** 4 | * @see PassportElementErrorTranslationFile 6 | */ 7 | public class PassportElementErrorTranslationFile extends PassportElementError.File { 8 | public PassportElementErrorTranslationFile() { 9 | super("translation_file"); 10 | } 11 | 12 | protected PassportElementErrorTranslationFile(String type, String fileHash, String message) { 13 | super("translation_file", type, fileHash, message); 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/passport/PassportElementErrorTranslationFiles.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.passport; 2 | 3 | /** 4 | * @see PassportElementErrorTranslationFiles 6 | */ 7 | public class PassportElementErrorTranslationFiles extends PassportElementError.Files { 8 | 9 | public PassportElementErrorTranslationFiles() { 10 | super("files"); 11 | } 12 | 13 | public PassportElementErrorTranslationFiles(String type, String[] fileHashes, String message) { 14 | super("files", type, fileHashes, message); 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/passport/PassportElementErrorUnspecified.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.passport; 2 | 3 | /** 4 | * @see PassportElementErrorUnspecified 5 | */ 6 | public class PassportElementErrorUnspecified extends PassportElementError { 7 | public String element_hash; 8 | 9 | public PassportElementErrorUnspecified() { 10 | super("unspecified"); 11 | } 12 | 13 | public PassportElementErrorUnspecified(String type, String elementHash, String message) { 14 | super("unspecified", type, message); 15 | this.element_hash = elementHash; 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/passport/PassportFile.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.passport; 2 | 3 | /** 4 | * @see PassportFile 5 | */ 6 | public class PassportFile { 7 | public String file_id; 8 | public int file_size; 9 | public int file_date; 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/payments/Invoice.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.payments; 2 | 3 | /** 4 | * @see Invoice 5 | */ 6 | public class Invoice { 7 | public String title; 8 | public String description; 9 | public String start_parameter; 10 | public String currency; 11 | public int total_amount; 12 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/payments/LabeledPrice.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.payments; 2 | 3 | /** 4 | * @see LabeledPrice 5 | */ 6 | public class LabeledPrice { 7 | public String label; 8 | public int amount; 9 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/payments/OrderInfo.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.payments; 2 | 3 | /** 4 | * @see OrderInfo 5 | */ 6 | public class OrderInfo { 7 | public String name; 8 | public String phone_number; 9 | public String email; 10 | public ShippingAddress shipping_address; 11 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/payments/PreCheckoutQuery.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.payments; 2 | 3 | import se.anyro.tgbotapi.types.User; 4 | 5 | /** 6 | * @see PreCheckoutQuery 7 | */ 8 | public class PreCheckoutQuery { 9 | public String id; 10 | public User from; 11 | public String currency; 12 | public int total_amount; 13 | public String invoice_payload; 14 | public String shipping_option_id; 15 | public OrderInfo order_info; 16 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/payments/ShippingAddress.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.payments; 2 | 3 | /** 4 | * @see ShippingAddress 5 | */ 6 | public class ShippingAddress { 7 | public String country_code; 8 | public String state; 9 | public String city; 10 | public String street_line1; 11 | public String street_line2; 12 | public String post_code; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/payments/ShippingOption.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.payments; 2 | 3 | /** 4 | * @see ShippingOption 5 | */ 6 | public class ShippingOption { 7 | public String id; 8 | public String title; 9 | public LabeledPrice[] prices; 10 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/payments/ShippingQuery.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.payments; 2 | 3 | import se.anyro.tgbotapi.types.User; 4 | 5 | /** 6 | * @see ShippingQuery 7 | */ 8 | public class ShippingQuery { 9 | public String id; 10 | public User from; 11 | public String invoice_payload; 12 | public ShippingAddress shipping_address; 13 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/payments/SuccessfulPayment.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.payments; 2 | 3 | /** 4 | * @see SuccessfulPayment 5 | */ 6 | public class SuccessfulPayment { 7 | public String currency; 8 | public int total_amount; 9 | public String invoice_payload; 10 | public String shipping_option_id; 11 | public OrderInfo[] order_info; 12 | public String telegram_payment_charge_id; 13 | public String provider_payment_charge_id; 14 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/poll/Poll.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.poll; 2 | 3 | import se.anyro.tgbotapi.types.MessageEntity; 4 | 5 | public class Poll { 6 | public String id; 7 | public String question; 8 | public PollOption[] options; 9 | public int total_voter_count; 10 | public boolean is_closed; 11 | public boolean is_anonymous; 12 | public String type; 13 | public boolean allows_multiple_answers; 14 | public int correct_option_id; 15 | public String explanation; 16 | public MessageEntity[] explanation_entities; 17 | public int open_period; 18 | public int close_date; 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/poll/PollAnswer.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.poll; 2 | 3 | import se.anyro.tgbotapi.types.User; 4 | 5 | public class PollAnswer { 6 | public String poll_id; 7 | public User user; 8 | public int[] option_ids; 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/poll/PollOption.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.poll; 2 | 3 | public class PollOption { 4 | public String text; 5 | public int voter_count; 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/reply_markup/ForceReply.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.reply_markup; 2 | 3 | /** 4 | * @see Official documentation of ForceReply 5 | */ 6 | public class ForceReply extends ReplyMarkup { 7 | public boolean force_reply = true; 8 | public Boolean selective; 9 | 10 | public ForceReply() { 11 | } 12 | 13 | public ForceReply(boolean selective) { 14 | this.selective = selective; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/reply_markup/InlineKeyboardButton.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.reply_markup; 2 | 3 | import se.anyro.tgbotapi.types.games.CallbackGame; 4 | 5 | 6 | /** 7 | * Note! You must use exactly one of the optional fields. 8 | * 9 | * @see Official documentation of 10 | * InlineKeyboardButton 11 | */ 12 | public class InlineKeyboardButton { 13 | 14 | public String text; 15 | public String url; 16 | public String callback_data; 17 | public String switch_inline_query; 18 | public String switch_inline_query_current_chat; 19 | public CallbackGame callback_game; 20 | public Boolean pay; 21 | 22 | public InlineKeyboardButton(String text) { 23 | this.text = text; 24 | } 25 | 26 | /* 27 | * Helper methods for creating specific button types 28 | */ 29 | 30 | public static InlineKeyboardButton url(String text, String url) { 31 | InlineKeyboardButton button = new InlineKeyboardButton(text); 32 | button.url = url; 33 | return button; 34 | } 35 | 36 | public static InlineKeyboardButton callbackData(String text, String data) { 37 | InlineKeyboardButton button = new InlineKeyboardButton(text); 38 | button.callback_data = data; 39 | return button; 40 | } 41 | 42 | public static InlineKeyboardButton switchInlineQuery(String text, String query) { 43 | InlineKeyboardButton button = new InlineKeyboardButton(text); 44 | button.switch_inline_query = query; 45 | return button; 46 | } 47 | 48 | public static InlineKeyboardButton switchInlineQueryCurrent(String text, String query) { 49 | InlineKeyboardButton button = new InlineKeyboardButton(text); 50 | button.switch_inline_query_current_chat = query; 51 | return button; 52 | } 53 | 54 | public static InlineKeyboardButton callbackGame(String text) { 55 | InlineKeyboardButton button = new InlineKeyboardButton(text); 56 | button.callback_game = new CallbackGame(); 57 | return button; 58 | } 59 | 60 | public static InlineKeyboardButton pay(String text) { 61 | InlineKeyboardButton button = new InlineKeyboardButton(text); 62 | button.pay = true; 63 | return button; 64 | } 65 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/reply_markup/InlineKeyboardMarkup.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.reply_markup; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | /** 8 | * @see Official documentation of 9 | * InlineKeyboardMarkup 10 | */ 11 | public class InlineKeyboardMarkup extends ReplyMarkup { 12 | 13 | public InlineKeyboardButton[][] inline_keyboard; 14 | 15 | public InlineKeyboardMarkup() { 16 | } 17 | 18 | public InlineKeyboardMarkup(InlineKeyboardButton[]... buttonRows) { 19 | inline_keyboard = buttonRows; 20 | } 21 | 22 | /** 23 | * Converting strings arrays to InlineKeyboardButton objects. 24 | */ 25 | public InlineKeyboardMarkup(String[]... buttonTextRows) { 26 | int numRows = buttonTextRows.length; 27 | inline_keyboard = new InlineKeyboardButton[numRows][]; 28 | for (int i = 0; i < numRows; ++i) { 29 | int numButtons = buttonTextRows[i].length; 30 | InlineKeyboardButton[] buttonRow = new InlineKeyboardButton[numButtons]; 31 | for (int j = 0; j < numButtons; ++j) { 32 | buttonRow[j] = InlineKeyboardButton.callbackData(buttonTextRows[i][j], buttonTextRows[i][j]); 33 | } 34 | inline_keyboard[i] = buttonRow; 35 | } 36 | } 37 | 38 | /** 39 | * Creates an InlineKeyboardMarkup with one button per line. 40 | */ 41 | public static InlineKeyboardMarkup createVertical(InlineKeyboardButton... buttons) { 42 | int numButtons = buttons.length; 43 | InlineKeyboardButton[][] keyboard = new InlineKeyboardButton[numButtons][]; 44 | for (int i = 0; i < numButtons; ++i) { 45 | keyboard[i] = new InlineKeyboardButton[] { buttons[i] }; 46 | } 47 | return new InlineKeyboardMarkup(keyboard); 48 | } 49 | 50 | /** 51 | * Creates an InlineKeyboardMarkup with one button per line from strings. The buttons will have the callback data 52 | * set to the same string as the button text. 53 | */ 54 | public static InlineKeyboardMarkup createVertical(String... buttonTexts) { 55 | int numRows = buttonTexts.length; 56 | InlineKeyboardButton[][] keyboard = new InlineKeyboardButton[numRows][]; 57 | for (int i = 0; i < numRows; ++i) { 58 | InlineKeyboardButton button = InlineKeyboardButton.callbackData(buttonTexts[i], buttonTexts[i]); 59 | keyboard[i] = new InlineKeyboardButton[] { button }; 60 | } 61 | return new InlineKeyboardMarkup(keyboard); 62 | } 63 | 64 | /** 65 | * Create an InlineKeyboardMarkup with just one row of buttons. 66 | */ 67 | public static InlineKeyboardMarkup createHorizontal(InlineKeyboardButton... buttons) { 68 | int numButtons = buttons.length; 69 | InlineKeyboardButton[][] keyboard = new InlineKeyboardButton[1][numButtons]; 70 | for (int i = 0; i < numButtons; ++i) { 71 | keyboard[0][i] = buttons[i]; 72 | } 73 | return new InlineKeyboardMarkup(keyboard); 74 | } 75 | 76 | /** 77 | * Class for dynamically building a keyboard line by line. Call addRow() to add a new row and then call the 78 | * add*Button() methods to add buttons to that row. Finally call toMarkup() to create the InlineKeyboardMarkup 79 | * object. 80 | */ 81 | public static class Builder { 82 | 83 | public List> keyboard = new ArrayList>(); 84 | 85 | public Builder addRow() { 86 | keyboard.add(new ArrayList()); 87 | return this; 88 | } 89 | 90 | public Builder addRow(InlineKeyboardButton... buttons) { 91 | keyboard.add(Arrays.asList(buttons)); 92 | return this; 93 | } 94 | 95 | public Builder addButton(InlineKeyboardButton button) { 96 | if (keyboard.size() == 0) { 97 | addRow(); 98 | } 99 | keyboard.get(keyboard.size() - 1).add(button); 100 | return this; 101 | } 102 | 103 | public Builder addUrlButton(String text, String url) { 104 | return addButton(InlineKeyboardButton.url(text, url)); 105 | } 106 | 107 | public Builder addCallbackDataButton(String text, String data) { 108 | return addButton(InlineKeyboardButton.callbackData(text, data)); 109 | } 110 | 111 | // Short cut since callback buttons are so common 112 | public Builder addButton(String text, String data) { 113 | return addCallbackDataButton(text, data); 114 | } 115 | 116 | public Builder addSwitchInlineQueryButton(String text, String query) { 117 | return addButton(InlineKeyboardButton.switchInlineQuery(text, query)); 118 | } 119 | 120 | public InlineKeyboardMarkup toMarkup() { 121 | int numRows = this.keyboard.size(); 122 | InlineKeyboardButton[][] keyboard = new InlineKeyboardButton[numRows][]; 123 | for (int i = 0; i < numRows; ++i) { 124 | List row = this.keyboard.get(i); 125 | int numButtons = row.size(); 126 | keyboard[i] = row.toArray(new InlineKeyboardButton[numButtons]); 127 | } 128 | return new InlineKeyboardMarkup(keyboard); 129 | } 130 | } 131 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/reply_markup/KeyboardButton.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.reply_markup; 2 | 3 | /** 4 | * Button for reply keyboard. 5 | * 6 | * @see Official documentation of KeyboardButton 7 | */ 8 | public class KeyboardButton { 9 | 10 | public String text; 11 | public Boolean request_contact; 12 | public Boolean request_location; 13 | 14 | public KeyboardButton(String text) { 15 | this.text = text; 16 | } 17 | 18 | public static KeyboardButton textButton(String text) { 19 | return new KeyboardButton(text); 20 | } 21 | 22 | public static KeyboardButton contactButton(String text) { 23 | KeyboardButton button = new KeyboardButton(text); 24 | button.request_contact = true; 25 | return button; 26 | } 27 | 28 | public static KeyboardButton locationButton(String text) { 29 | KeyboardButton button = new KeyboardButton(text); 30 | button.request_location = true; 31 | return button; 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/reply_markup/ReplyKeyboardMarkup.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.reply_markup; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | /** 8 | * @see Official documentation of 9 | * ReplyKeyboardMarkup 10 | */ 11 | public class ReplyKeyboardMarkup extends ReplyMarkup { 12 | 13 | public KeyboardButton[][] keyboard; 14 | public boolean resize_keyboard = true; 15 | public Boolean one_time_keyboard; 16 | /** 17 | * Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has 18 | * reply_to_message_id), sender of the original message. 19 | */ 20 | public Boolean selective; 21 | 22 | public ReplyKeyboardMarkup(KeyboardButton[]... buttonRows) { 23 | keyboard = buttonRows; 24 | } 25 | 26 | /** 27 | * Converting array of strings to arrays of KeyboardButton objects. 28 | */ 29 | public ReplyKeyboardMarkup(String[]... buttonTextRows) { 30 | int numRows = buttonTextRows.length; 31 | keyboard = new KeyboardButton[numRows][]; 32 | for (int i = 0; i < numRows; ++i) { 33 | int numButtons = buttonTextRows[i].length; 34 | KeyboardButton[] buttonRow = new KeyboardButton[numButtons]; 35 | for (int j = 0; j < numButtons; ++j) { 36 | buttonRow[j] = new KeyboardButton(buttonTextRows[i][j]); 37 | } 38 | keyboard[i] = buttonRow; 39 | } 40 | } 41 | 42 | /** 43 | * Create ReplyKeyboardMarkup with one button per row. 44 | */ 45 | public static ReplyKeyboardMarkup createVertical(KeyboardButton... buttons) { 46 | int numRows = buttons.length; 47 | KeyboardButton[][] keyboard = new KeyboardButton[numRows][]; 48 | for (int i = 0; i < numRows; ++i) { 49 | keyboard[i] = new KeyboardButton[] { buttons[i] }; 50 | } 51 | return new ReplyKeyboardMarkup(keyboard); 52 | } 53 | 54 | /** 55 | * Create ReplyKeyboardButton with one button per line from strings. 56 | */ 57 | public static ReplyKeyboardMarkup createVertical(String... buttonTexts) { 58 | int numRows = buttonTexts.length; 59 | KeyboardButton[][] keyboard = new KeyboardButton[numRows][]; 60 | for (int i = 0; i < numRows; ++i) { 61 | keyboard[i] = new KeyboardButton[] { new KeyboardButton(buttonTexts[i]) }; 62 | } 63 | return new ReplyKeyboardMarkup(keyboard); 64 | } 65 | 66 | /** 67 | * Create a ReplyKeyboardMarkup with just one row of buttons. 68 | */ 69 | public static ReplyKeyboardMarkup createHorizontal(KeyboardButton... buttons) { 70 | int numButtons = buttons.length; 71 | KeyboardButton[][] keyboard = new KeyboardButton[1][numButtons]; 72 | for (int i = 0; i < numButtons; ++i) { 73 | keyboard[0][i] = buttons[i]; 74 | } 75 | return new ReplyKeyboardMarkup(keyboard); 76 | } 77 | 78 | /** 79 | * Create a ReplyKeyboardMarkup with just one row of buttons from strings. 80 | */ 81 | public static ReplyKeyboardMarkup createHorizontal(String... buttonTexts) { 82 | int numButtons = buttonTexts.length; 83 | KeyboardButton[][] keyboard = new KeyboardButton[1][numButtons]; 84 | for (int i = 0; i < numButtons; ++i) { 85 | keyboard[0][i] = new KeyboardButton(buttonTexts[i]); 86 | } 87 | return new ReplyKeyboardMarkup(keyboard); 88 | } 89 | 90 | /** 91 | * Class for dynamically building a keyboard line by line. Call addRow() to add a new row and then call the 92 | * addButton methods to add buttons to that row. Finally call toMarkup() to create the ReplyKeyboardMarkup object. 93 | */ 94 | 95 | public static class Builder { 96 | 97 | public List> keyboard = new ArrayList>(); 98 | 99 | public Builder addRow() { 100 | keyboard.add(new ArrayList()); 101 | return this; 102 | } 103 | 104 | public Builder addRow(KeyboardButton... buttons) { 105 | keyboard.add(Arrays.asList(buttons)); 106 | return this; 107 | } 108 | 109 | public Builder addButton(KeyboardButton button) { 110 | keyboard.get(keyboard.size() - 1).add(button); 111 | return this; 112 | } 113 | 114 | public Builder addButton(String text) { 115 | addButton(new KeyboardButton(text)); 116 | return this; 117 | } 118 | 119 | public Builder addContactButton(String text) { 120 | KeyboardButton button = new KeyboardButton(text); 121 | button.request_contact = true; 122 | return addButton(button); 123 | } 124 | 125 | public Builder addLocationButton(String text) { 126 | KeyboardButton button = new KeyboardButton(text); 127 | button.request_location = true; 128 | return addButton(button); 129 | } 130 | 131 | public ReplyKeyboardMarkup toMarkup() { 132 | int numRows = this.keyboard.size(); 133 | KeyboardButton[][] keyboard = new KeyboardButton[numRows][]; 134 | for (int i = 0; i < numRows; ++i) { 135 | List row = this.keyboard.get(i); 136 | int numButtons = row.size(); 137 | keyboard[i] = row.toArray(new KeyboardButton[numButtons]); 138 | } 139 | return new ReplyKeyboardMarkup(keyboard); 140 | } 141 | } 142 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/reply_markup/ReplyKeyboardRemove.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.reply_markup; 2 | 3 | /** 4 | * @see Official documentation of ReplyKeyboardHide 5 | */ 6 | public class ReplyKeyboardRemove extends ReplyMarkup { 7 | public boolean remove_keyboard = true; 8 | public Boolean selective; 9 | 10 | public ReplyKeyboardRemove() { 11 | } 12 | 13 | public ReplyKeyboardRemove(boolean selective) { 14 | this.selective = selective; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/reply_markup/ReplyMarkup.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.reply_markup; 2 | 3 | /** 4 | * Base class of the replyMarkup classes. 5 | */ 6 | public abstract class ReplyMarkup { 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/stickers/MaskPosition.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.stickers; 2 | 3 | 4 | /** 5 | * @see MaskPosition 6 | */ 7 | public class MaskPosition { 8 | public String point; 9 | public float x_shift; 10 | public float y_shift; 11 | public float zoom; 12 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/stickers/Sticker.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.stickers; 2 | 3 | import se.anyro.tgbotapi.types.file.PhotoSize; 4 | 5 | /** 6 | * @see Sticker 7 | */ 8 | public class Sticker { 9 | public String file_id; 10 | public int width; 11 | public int height; 12 | public PhotoSize thumb; 13 | public String emoji; 14 | public String set_name; 15 | public MaskPosition mask_position; 16 | public int file_size; 17 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/types/stickers/StickerSet.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.types.stickers; 2 | 3 | 4 | /** 5 | * @see StickerSet 6 | */ 7 | public class StickerSet { 8 | public String name; 9 | public String title; 10 | public boolean isMasks; 11 | public Sticker[] stickers; 12 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/utils/FileSender.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.utils; 2 | 3 | import java.io.BufferedOutputStream; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.InputStreamReader; 9 | import java.io.OutputStream; 10 | import java.io.Reader; 11 | import java.net.HttpURLConnection; 12 | import java.net.URL; 13 | import java.nio.charset.StandardCharsets; 14 | 15 | import se.anyro.tgbotapi.HttpResponseException; 16 | import se.anyro.tgbotapi.types.ResponseParameters; 17 | 18 | import com.google.gson.Gson; 19 | import com.google.gson.JsonElement; 20 | import com.google.gson.JsonObject; 21 | import com.google.gson.JsonParser; 22 | 23 | /** 24 | * Simple multipart HTTP POST for sending a file and optionally parse the response. 25 | */ 26 | public class FileSender { 27 | 28 | private static final String CONTENT_TYPE = "Content-Type"; 29 | private static final String BOUNDARY = "===y5twmnRq4X1rSQ8tJ8HfC3YxqkxcQd==="; 30 | private static final String MULTIPART_FORM_DATA = "multipart/form-data; boundary=" + BOUNDARY; 31 | private static final byte[] BOUNDARY_LINE = ("--" + BOUNDARY + "\r\n").getBytes(); 32 | private static final byte[] BOUNDARY_END = ("--" + BOUNDARY + "--\r\n").getBytes(); 33 | private static final byte[] CONTENT_DISPOSITION = "Content-Disposition: form-data; name=\"".getBytes(); 34 | private static final byte[] FILENAME = "\"; filename=\"".getBytes(); 35 | private static final byte[] CR_LF = "\r\n".getBytes(); 36 | private static final byte[] QUOTE_CR_LF = "\"\r\n".getBytes(); 37 | private static final byte[] CONTENT_TYPE_TEXT = "Content-Type: text/plain; charset=UTF-8\r\n".getBytes(); 38 | private static final byte[] CONTENT_TYPE_FILE = "Content-Type: application/octet-stream\r\n".getBytes(); 39 | private static final byte[] TRANSFER_ENCODING_BINARY = "Content-Transfer-Encoding: binary\r\n".getBytes(); 40 | 41 | private static final Gson GSON = new Gson(); 42 | private static final JsonParser PARSER = new JsonParser(); 43 | 44 | private HttpURLConnection connection; 45 | private OutputStream out; 46 | 47 | public FileSender(String requestUrl) throws IOException { 48 | URL url = new URL(requestUrl); 49 | connection = (HttpURLConnection) url.openConnection(); 50 | connection.setUseCaches(false); 51 | connection.setDoOutput(true); 52 | connection.setRequestProperty(CONTENT_TYPE, MULTIPART_FORM_DATA); 53 | connection.connect(); 54 | out = new BufferedOutputStream(connection.getOutputStream()); 55 | } 56 | 57 | public void addFormField(String name, String value) throws IOException { 58 | out.write(BOUNDARY_LINE); 59 | writeContentDisposition(name); 60 | out.write(CONTENT_TYPE_TEXT); 61 | out.write(CR_LF); 62 | out.write(value.getBytes(StandardCharsets.UTF_8)); 63 | out.write(CR_LF); 64 | } 65 | 66 | public void addFormField(String name, long value) throws IOException { 67 | addFormField(name, String.valueOf(value)); 68 | } 69 | 70 | private void writeContentDisposition(String key) throws IOException { 71 | out.write(CONTENT_DISPOSITION); 72 | out.write(key.getBytes(StandardCharsets.UTF_8)); 73 | out.write(QUOTE_CR_LF); 74 | } 75 | 76 | private void writeContentDisposition(String key, String filename) throws IOException { 77 | out.write(CONTENT_DISPOSITION); 78 | out.write(key.getBytes(StandardCharsets.UTF_8)); 79 | out.write(FILENAME); 80 | out.write(filename.getBytes(StandardCharsets.UTF_8)); 81 | out.write(QUOTE_CR_LF); 82 | } 83 | 84 | public void addFilePart(String fieldName, File file) throws IOException { 85 | FileInputStream inputStream = new FileInputStream(file); 86 | addFilePart(fieldName, inputStream, file.getName()); 87 | inputStream.close(); 88 | } 89 | 90 | public void addFilePart(String fieldName, InputStream inputStream, String fileName) throws IOException { 91 | out.write(BOUNDARY_LINE); 92 | writeContentDisposition(fieldName, fileName); 93 | out.write(CONTENT_TYPE_FILE); 94 | out.write(TRANSFER_ENCODING_BINARY); 95 | out.write(CR_LF); 96 | 97 | byte[] buffer = new byte[4096]; 98 | int bytesRead = 0; 99 | while ((bytesRead = inputStream.read(buffer)) != -1) { 100 | out.write(buffer, 0, bytesRead); 101 | } 102 | inputStream.close(); 103 | out.write(CR_LF); 104 | } 105 | 106 | /** 107 | * Write the last part and close the stream. Response data is ignored. 108 | */ 109 | public int finish() throws IOException { 110 | out.write(BOUNDARY_END); 111 | out.close(); 112 | int responseCode = connection.getResponseCode(); 113 | closeInputStream(connection); // Close to let the connection be reused 114 | return responseCode; 115 | } 116 | 117 | /** 118 | * Write the last part and parse the response. 119 | */ 120 | public T finish(Class responseClass) throws IOException { 121 | out.write(BOUNDARY_END); 122 | out.close(); 123 | try (Reader reader = new InputStreamReader(connection.getInputStream())) { 124 | JsonObject response = (JsonObject) PARSER.parse(reader); 125 | if (response.getAsJsonPrimitive("ok").getAsBoolean()) { 126 | JsonElement result = response.get("result"); 127 | return GSON.fromJson(result, responseClass); 128 | } else { 129 | int errorCode = response.getAsJsonPrimitive("error_code").getAsInt(); 130 | String description = response.getAsJsonPrimitive("description").getAsString(); 131 | JsonElement parameters = response.get("parameters"); 132 | ResponseParameters responseParameters = GSON.fromJson(parameters, ResponseParameters.class); 133 | throw new HttpResponseException(errorCode, description, responseParameters); 134 | } 135 | } 136 | } 137 | 138 | private void closeInputStream(HttpURLConnection con) { 139 | try { 140 | con.getInputStream().close(); 141 | } catch (IOException e) { 142 | // Ignore 143 | } 144 | } 145 | } -------------------------------------------------------------------------------- /src/main/java/se/anyro/tgbotapi/utils/Markdown.java: -------------------------------------------------------------------------------- 1 | package se.anyro.tgbotapi.utils; 2 | 3 | import se.anyro.tgbotapi.types.MessageEntity; 4 | import se.anyro.tgbotapi.types.MessageEntity.Type; 5 | 6 | public class Markdown { 7 | 8 | /** 9 | * Escape text for markdown format 10 | */ 11 | public static String escape(String text) { 12 | return text.replace("_", "\\_").replace("*", "\\*").replace("`", "\\`").replace("[", "\\["); 13 | } 14 | 15 | /** 16 | * Restore markdown escape characters from the entities of a Message 17 | */ 18 | public static String applyFromEntities(String text, MessageEntity[] entities) { 19 | if (entities == null || entities.length == 0) { 20 | return text; 21 | } 22 | int pos = 0; 23 | StringBuilder builder = new StringBuilder(); 24 | for (MessageEntity entity : entities) { 25 | 26 | // Plain text before the entity 27 | String plainText = text.substring(pos, pos = entity.offset); 28 | builder.append(escape(plainText)); 29 | 30 | // Start tag 31 | String startTag = getStartTag(entity.getType()); 32 | if (startTag != null) { 33 | builder.append(startTag); 34 | } 35 | 36 | // Text inside entity 37 | String entityText = text.substring(pos, pos += entity.length); 38 | builder.append(escape(entityText)); 39 | 40 | // End tag 41 | String endTag = getEndTag(entity.getType()); 42 | if (endTag != null) { 43 | builder.append(endTag); 44 | } 45 | 46 | // Extra for text_link and text_mention 47 | if (entity.url != null) { 48 | builder.append('(').append(entity.url).append(')'); 49 | } else if (entity.user != null) { 50 | builder.append('(').append(entity.user.getUrl()).append(')'); 51 | } 52 | } 53 | 54 | // Final plain text after the last tag 55 | builder.append(text.substring(pos, text.length())); 56 | 57 | return builder.toString(); 58 | } 59 | 60 | private static String getStartTag(Type entityType) { 61 | switch (entityType) { 62 | case BOLD: 63 | return "*"; 64 | case CODE: 65 | return "`"; 66 | case ITALIC: 67 | return "_"; 68 | case PRE: 69 | return "```"; 70 | case TEXT_LINK: 71 | case TEXT_MENTION: 72 | return "["; 73 | default: 74 | return null; 75 | } 76 | } 77 | 78 | private static String getEndTag(Type entityType) { 79 | switch (entityType) { 80 | case TEXT_LINK: 81 | case TEXT_MENTION: 82 | return "]"; 83 | default: 84 | return getStartTag(entityType); 85 | } 86 | } 87 | } 88 | --------------------------------------------------------------------------------