From 416ff1816fad24ad6de34498a89796047e290ba8 Mon Sep 17 00:00:00 2001 From: Rubenlagu Date: Sun, 16 Aug 2015 21:20:57 +0200 Subject: [PATCH 1/2] 1. Some api updates --- src/main/java/org/telegram/api/Message.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/org/telegram/api/Message.java b/src/main/java/org/telegram/api/Message.java index 8761a15..2321ca1 100644 --- a/src/main/java/org/telegram/api/Message.java +++ b/src/main/java/org/telegram/api/Message.java @@ -81,6 +81,9 @@ public class Message { public static final String REPLYTOMESSAGE_FIELD = "reply_to_message"; @JsonProperty(REPLYTOMESSAGE_FIELD) private Message replyToMessage; + public static final String VOICE_FIELD = "voice"; + @JsonProperty(VOICE_FIELD) + private Voice voice; ///< Optional. Message is a voice message, information about the file public Message() { super(); @@ -126,6 +129,9 @@ public class Message { if (jsonObject.has(LOCATION_FIELD)) { this.location = new Location(jsonObject.getJSONObject(LOCATION_FIELD)); } + if (jsonObject.has(VOICE_FIELD)) { + this.voice = new Voice(jsonObject.getJSONObject(VOICE_FIELD)); + } if (jsonObject.has(NEWCHATPARTICIPANT_FIELD)) { this.newChatParticipant = new User(jsonObject.getJSONObject(NEWCHATPARTICIPANT_FIELD)); } @@ -342,4 +348,12 @@ public class Message { public boolean hasLocation() { return location != null; } + + public Voice getVoice() { + return voice; + } + + public void setVoice(Voice voice) { + this.voice = voice; + } } From 392dc6f5f02b9a8d4f69b3aa573e495ec9e0d649 Mon Sep 17 00:00:00 2001 From: Rubenlagu Date: Wed, 7 Oct 2015 23:50:56 +0200 Subject: [PATCH 2/2] 1. Webhooks with self-signed certs --- .idea/dataSources.xml | 18 + ...ackson_core_jackson_annotations_2_5_4.xml} | 8 +- ...erxml_jackson_core_jackson_core_2_5_4.xml} | 8 +- ...l_jackson_core_jackson_databind_2_5_4.xml} | 8 +- ...ackson_jaxrs_jackson_jaxrs_base_2_5_4.xml} | 8 +- ...xrs_jackson_jaxrs_json_provider_2_5_4.xml} | 8 +- ...jackson_module_jaxb_annotations_2_5_4.xml} | 8 +- ...en__mysql_mysql_connector_java_5_1_36.xml} | 8 +- ...pache_httpcomponents_httpclient_4_5_1.xml} | 8 +- ..._apache_httpcomponents_httpcore_4_4_3.xml} | 8 +- ..._apache_httpcomponents_httpmime_4_5_1.xml} | 8 +- ...fish_grizzly_grizzly_framework_2_3_22.xml} | 8 +- ...glassfish_grizzly_grizzly_http_2_3_22.xml} | 8 +- ...sh_grizzly_grizzly_http_server_2_3_22.xml} | 8 +- ...rnal_aopalliance_repackaged_2_4_0_b31.xml} | 8 +- ...h_hk2_external_javax_inject_2_4_0_b31.xml} | 8 +- ...__org_glassfish_hk2_hk2_api_2_4_0_b31.xml} | 8 +- ...g_glassfish_hk2_hk2_locator_2_4_0_b31.xml} | 8 +- ...org_glassfish_hk2_hk2_utils_2_4_0_b31.xml} | 8 +- ..._bundles_repackaged_jersey_guava_2_21.xml} | 8 +- ...s_jersey_container_grizzly2_http_2_21.xml} | 8 +- ...ssfish_jersey_core_jersey_client_2_21.xml} | 8 +- ...ssfish_jersey_core_jersey_common_2_21.xml} | 8 +- ...ssfish_jersey_core_jersey_server_2_21.xml} | 8 +- ...rsey_ext_jersey_entity_filtering_2_21.xml} | 8 +- ...h_jersey_media_jersey_media_jaxb_2_21.xml} | 8 +- ..._media_jersey_media_json_jackson_2_21.xml} | 8 +- .../Maven__org_jsoup_jsoup_1_8_2.xml | 13 - .../Maven__org_jsoup_jsoup_1_8_3.xml | 13 + .idea/workspace.xml | 1356 +++++++++-------- BotAPi.iml | 56 +- pom.xml | 16 +- src/main/java/org/telegram/BotConfig.java | 12 +- src/main/java/org/telegram/BuildVars.java | 7 +- src/main/java/org/telegram/Main.java | 29 +- src/main/java/org/telegram/SenderHelper.java | 108 +- src/main/java/org/telegram/api/Contact.java | 38 - src/main/java/org/telegram/api/PhotoSize.java | 70 - .../java/org/telegram/api/ReplyKeyboard.java | 13 - src/main/java/org/telegram/api/Sticker.java | 46 - src/main/java/org/telegram/api/Update.java | 55 - src/main/java/org/telegram/api/User.java | 54 - .../org/telegram/api/UserProfilePhotos.java | 43 - .../telegram/api/interfaces/BotApiObject.java | 13 + .../org/telegram/api/interfaces/IToJson.java | 18 + .../telegram/api/methods/BotApiMethod.java | 28 + .../telegram/{ => api}/methods/Constants.java | 2 +- .../telegram/api/methods/ForwardMessage.java | 98 ++ .../org/telegram/api/methods/GetFile.java | 79 + .../java/org/telegram/api/methods/GetMe.java | 52 + .../{ => api}/methods/GetUpdates.java | 22 +- .../api/methods/GetUserProfilePhotos.java | 111 ++ .../telegram/{ => api}/methods/SendAudio.java | 69 +- .../telegram/api/methods/SendChatAction.java | 89 ++ .../{ => api}/methods/SendDocument.java | 4 +- .../telegram/api/methods/SendLocation.java | 137 ++ .../org/telegram/api/methods/SendMessage.java | 168 ++ .../telegram/{ => api}/methods/SendPhoto.java | 4 +- .../{ => api}/methods/SendSticker.java | 4 +- .../telegram/{ => api}/methods/SendVideo.java | 4 +- .../telegram/{ => api}/methods/SendVoice.java | 4 +- .../org/telegram/api/methods/SetWebhook.java | 39 + .../org/telegram/api/{ => objects}/Audio.java | 68 +- .../org/telegram/api/{ => objects}/Chat.java | 54 +- .../org/telegram/api/objects/Contact.java | 78 + .../telegram/api/{ => objects}/Document.java | 59 +- .../java/org/telegram/api/objects/File.java | 95 ++ .../api/{ => objects}/ForceReplyKeyboard.java | 33 +- .../telegram/api/{ => objects}/Location.java | 28 +- .../telegram/api/{ => objects}/Message.java | 167 +- .../org/telegram/api/objects/PhotoSize.java | 104 ++ .../telegram/api/objects/ReplyKeyboard.java | 13 + .../api/{ => objects}/ReplyKeyboardHide.java | 34 +- .../{ => objects}/ReplyKeyboardMarkup.java | 68 +- .../org/telegram/api/objects/Sticker.java | 84 + .../java/org/telegram/api/objects/Update.java | 74 + .../java/org/telegram/api/objects/User.java | 94 ++ .../api/objects/UserProfilePhotos.java | 104 ++ .../org/telegram/api/{ => objects}/Video.java | 60 +- .../org/telegram/api/{ => objects}/Voice.java | 48 +- .../org/telegram/methods/ForwardMessage.java | 46 - src/main/java/org/telegram/methods/GetMe.java | 12 - .../methods/GetUserProfilePhotos.java | 57 - .../org/telegram/methods/SendChatAction.java | 31 - .../org/telegram/methods/SendLocation.java | 24 - .../org/telegram/methods/SendMessage.java | 68 - .../java/org/telegram/methods/SetWebhook.java | 17 - .../telegram/services/TransifexService.java | 2 +- .../updateshandlers/DirectionsHandlers.java | 98 +- .../updateshandlers/FilesHandlers.java | 57 +- .../updateshandlers/SentCallback.java | 26 + .../updateshandlers/TransifexHandlers.java | 38 +- .../updateshandlers/UpdatesCallback.java | 15 +- .../updateshandlers/WeatherHandlers.java | 424 ++++-- .../telegram/updatesreceivers/RestApi.java | 33 +- .../updatesreceivers/UpdatesThread.java | 22 +- .../telegram/updatesreceivers/Webhook.java | 32 +- .../resources/localisation/strings.properties | 52 +- 98 files changed, 3641 insertions(+), 1778 deletions(-) create mode 100644 .idea/dataSources.xml rename .idea/libraries/{Maven__com_fasterxml_jackson_core_jackson_annotations_2_5_1.xml => Maven__com_fasterxml_jackson_core_jackson_annotations_2_5_4.xml} (65%) rename .idea/libraries/{Maven__com_fasterxml_jackson_core_jackson_core_2_5_1.xml => Maven__com_fasterxml_jackson_core_jackson_core_2_5_4.xml} (66%) rename .idea/libraries/{Maven__com_fasterxml_jackson_core_jackson_databind_2_5_1.xml => Maven__com_fasterxml_jackson_core_jackson_databind_2_5_4.xml} (65%) rename .idea/libraries/{Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_base_2_5_1.xml => Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_base_2_5_4.xml} (65%) rename .idea/libraries/{Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_json_provider_2_5_1.xml => Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_json_provider_2_5_4.xml} (56%) rename .idea/libraries/{Maven__com_fasterxml_jackson_module_jackson_module_jaxb_annotations_2_5_1.xml => Maven__com_fasterxml_jackson_module_jackson_module_jaxb_annotations_2_5_4.xml} (53%) rename .idea/libraries/{Maven__mysql_mysql_connector_java_5_1_35.xml => Maven__mysql_mysql_connector_java_5_1_36.xml} (57%) rename .idea/libraries/{Maven__org_apache_httpcomponents_httpclient_4_5.xml => Maven__org_apache_httpcomponents_httpclient_4_5_1.xml} (68%) rename .idea/libraries/{Maven__org_apache_httpcomponents_httpcore_4_4_1.xml => Maven__org_apache_httpcomponents_httpcore_4_4_3.xml} (59%) rename .idea/libraries/{Maven__org_apache_httpcomponents_httpmime_4_5.xml => Maven__org_apache_httpcomponents_httpmime_4_5_1.xml} (58%) rename .idea/libraries/{Maven__org_glassfish_grizzly_grizzly_framework_2_3_19.xml => Maven__org_glassfish_grizzly_grizzly_framework_2_3_22.xml} (65%) rename .idea/libraries/{Maven__org_glassfish_grizzly_grizzly_http_2_3_19.xml => Maven__org_glassfish_grizzly_grizzly_http_2_3_22.xml} (56%) rename .idea/libraries/{Maven__org_glassfish_grizzly_grizzly_http_server_2_3_19.xml => Maven__org_glassfish_grizzly_grizzly_http_server_2_3_22.xml} (65%) rename .idea/libraries/{Maven__org_glassfish_hk2_external_aopalliance_repackaged_2_4_0_b12.xml => Maven__org_glassfish_hk2_external_aopalliance_repackaged_2_4_0_b31.xml} (56%) rename .idea/libraries/{Maven__org_glassfish_hk2_external_javax_inject_2_4_0_b12.xml => Maven__org_glassfish_hk2_external_javax_inject_2_4_0_b31.xml} (65%) rename .idea/libraries/{Maven__org_glassfish_hk2_hk2_api_2_4_0_b12.xml => Maven__org_glassfish_hk2_hk2_api_2_4_0_b31.xml} (60%) rename .idea/libraries/{Maven__org_glassfish_hk2_hk2_locator_2_4_0_b12.xml => Maven__org_glassfish_hk2_hk2_locator_2_4_0_b31.xml} (57%) rename .idea/libraries/{Maven__org_glassfish_hk2_hk2_utils_2_4_0_b12.xml => Maven__org_glassfish_hk2_hk2_utils_2_4_0_b31.xml} (58%) rename .idea/libraries/{Maven__org_glassfish_jersey_bundles_repackaged_jersey_guava_2_18.xml => Maven__org_glassfish_jersey_bundles_repackaged_jersey_guava_2_21.xml} (64%) rename .idea/libraries/{Maven__org_glassfish_jersey_containers_jersey_container_grizzly2_http_2_18.xml => Maven__org_glassfish_jersey_containers_jersey_container_grizzly2_http_2_21.xml} (53%) rename .idea/libraries/{Maven__org_glassfish_jersey_core_jersey_client_2_18.xml => Maven__org_glassfish_jersey_core_jersey_client_2_21.xml} (67%) rename .idea/libraries/{Maven__org_glassfish_jersey_core_jersey_common_2_18.xml => Maven__org_glassfish_jersey_core_jersey_common_2_21.xml} (67%) rename .idea/libraries/{Maven__org_glassfish_jersey_core_jersey_server_2_18.xml => Maven__org_glassfish_jersey_core_jersey_server_2_21.xml} (67%) rename .idea/libraries/{Maven__org_glassfish_jersey_ext_jersey_entity_filtering_2_18.xml => Maven__org_glassfish_jersey_ext_jersey_entity_filtering_2_21.xml} (65%) rename .idea/libraries/{Maven__org_glassfish_jersey_media_jersey_media_jaxb_2_18.xml => Maven__org_glassfish_jersey_media_jersey_media_jaxb_2_21.xml} (65%) rename .idea/libraries/{Maven__org_glassfish_jersey_media_jersey_media_json_jackson_2_18.xml => Maven__org_glassfish_jersey_media_jersey_media_json_jackson_2_21.xml} (58%) delete mode 100644 .idea/libraries/Maven__org_jsoup_jsoup_1_8_2.xml create mode 100644 .idea/libraries/Maven__org_jsoup_jsoup_1_8_3.xml delete mode 100644 src/main/java/org/telegram/api/Contact.java delete mode 100644 src/main/java/org/telegram/api/PhotoSize.java delete mode 100644 src/main/java/org/telegram/api/ReplyKeyboard.java delete mode 100644 src/main/java/org/telegram/api/Sticker.java delete mode 100644 src/main/java/org/telegram/api/Update.java delete mode 100644 src/main/java/org/telegram/api/User.java delete mode 100644 src/main/java/org/telegram/api/UserProfilePhotos.java create mode 100644 src/main/java/org/telegram/api/interfaces/BotApiObject.java create mode 100644 src/main/java/org/telegram/api/interfaces/IToJson.java create mode 100644 src/main/java/org/telegram/api/methods/BotApiMethod.java rename src/main/java/org/telegram/{ => api}/methods/Constants.java (85%) create mode 100644 src/main/java/org/telegram/api/methods/ForwardMessage.java create mode 100644 src/main/java/org/telegram/api/methods/GetFile.java create mode 100644 src/main/java/org/telegram/api/methods/GetMe.java rename src/main/java/org/telegram/{ => api}/methods/GetUpdates.java (73%) create mode 100644 src/main/java/org/telegram/api/methods/GetUserProfilePhotos.java rename src/main/java/org/telegram/{ => api}/methods/SendAudio.java (55%) create mode 100644 src/main/java/org/telegram/api/methods/SendChatAction.java rename src/main/java/org/telegram/{ => api}/methods/SendDocument.java (96%) create mode 100644 src/main/java/org/telegram/api/methods/SendLocation.java create mode 100644 src/main/java/org/telegram/api/methods/SendMessage.java rename src/main/java/org/telegram/{ => api}/methods/SendPhoto.java (96%) rename src/main/java/org/telegram/{ => api}/methods/SendSticker.java (96%) rename src/main/java/org/telegram/{ => api}/methods/SendVideo.java (97%) rename src/main/java/org/telegram/{ => api}/methods/SendVoice.java (94%) create mode 100644 src/main/java/org/telegram/api/methods/SetWebhook.java rename src/main/java/org/telegram/api/{ => objects}/Audio.java (51%) rename src/main/java/org/telegram/api/{ => objects}/Chat.java (51%) create mode 100644 src/main/java/org/telegram/api/objects/Contact.java rename src/main/java/org/telegram/api/{ => objects}/Document.java (53%) create mode 100644 src/main/java/org/telegram/api/objects/File.java rename src/main/java/org/telegram/api/{ => objects}/ForceReplyKeyboard.java (63%) rename src/main/java/org/telegram/api/{ => objects}/Location.java (52%) rename src/main/java/org/telegram/api/{ => objects}/Message.java (66%) create mode 100644 src/main/java/org/telegram/api/objects/PhotoSize.java create mode 100644 src/main/java/org/telegram/api/objects/ReplyKeyboard.java rename src/main/java/org/telegram/api/{ => objects}/ReplyKeyboardHide.java (60%) rename src/main/java/org/telegram/api/{ => objects}/ReplyKeyboardMarkup.java (61%) create mode 100644 src/main/java/org/telegram/api/objects/Sticker.java create mode 100644 src/main/java/org/telegram/api/objects/Update.java create mode 100644 src/main/java/org/telegram/api/objects/User.java create mode 100644 src/main/java/org/telegram/api/objects/UserProfilePhotos.java rename src/main/java/org/telegram/api/{ => objects}/Video.java (58%) rename src/main/java/org/telegram/api/{ => objects}/Voice.java (51%) delete mode 100644 src/main/java/org/telegram/methods/ForwardMessage.java delete mode 100644 src/main/java/org/telegram/methods/GetMe.java delete mode 100644 src/main/java/org/telegram/methods/GetUserProfilePhotos.java delete mode 100644 src/main/java/org/telegram/methods/SendChatAction.java delete mode 100644 src/main/java/org/telegram/methods/SendLocation.java delete mode 100644 src/main/java/org/telegram/methods/SendMessage.java delete mode 100644 src/main/java/org/telegram/methods/SetWebhook.java create mode 100644 src/main/java/org/telegram/updateshandlers/SentCallback.java diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..f8ce7d9 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,18 @@ + + + + + mysql + true + com.mysql.jdbc.Driver + jdbc:mysql://localhost:3306/telegrambot + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_5_1.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_5_4.xml similarity index 65% rename from .idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_5_1.xml rename to .idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_5_4.xml index d0c6958..086f4e9 100644 --- a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_5_1.xml +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_5_4.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_5_1.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_5_4.xml similarity index 66% rename from .idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_5_1.xml rename to .idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_5_4.xml index dd95d35..40f4bc8 100644 --- a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_5_1.xml +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_5_4.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_5_1.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_5_4.xml similarity index 65% rename from .idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_5_1.xml rename to .idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_5_4.xml index 83e4ab9..8adb4b6 100644 --- a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_5_1.xml +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_5_4.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_base_2_5_1.xml b/.idea/libraries/Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_base_2_5_4.xml similarity index 65% rename from .idea/libraries/Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_base_2_5_1.xml rename to .idea/libraries/Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_base_2_5_4.xml index 0488e16..a64dd1e 100644 --- a/.idea/libraries/Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_base_2_5_1.xml +++ b/.idea/libraries/Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_base_2_5_4.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_json_provider_2_5_1.xml b/.idea/libraries/Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_json_provider_2_5_4.xml similarity index 56% rename from .idea/libraries/Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_json_provider_2_5_1.xml rename to .idea/libraries/Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_json_provider_2_5_4.xml index 7898c3d..996db03 100644 --- a/.idea/libraries/Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_json_provider_2_5_1.xml +++ b/.idea/libraries/Maven__com_fasterxml_jackson_jaxrs_jackson_jaxrs_json_provider_2_5_4.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_jaxb_annotations_2_5_1.xml b/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_jaxb_annotations_2_5_4.xml similarity index 53% rename from .idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_jaxb_annotations_2_5_1.xml rename to .idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_jaxb_annotations_2_5_4.xml index 618a1f5..9f5e5cd 100644 --- a/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_jaxb_annotations_2_5_1.xml +++ b/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_jaxb_annotations_2_5_4.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__mysql_mysql_connector_java_5_1_35.xml b/.idea/libraries/Maven__mysql_mysql_connector_java_5_1_36.xml similarity index 57% rename from .idea/libraries/Maven__mysql_mysql_connector_java_5_1_35.xml rename to .idea/libraries/Maven__mysql_mysql_connector_java_5_1_36.xml index da90023..a298445 100644 --- a/.idea/libraries/Maven__mysql_mysql_connector_java_5_1_35.xml +++ b/.idea/libraries/Maven__mysql_mysql_connector_java_5_1_36.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_5.xml b/.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_5_1.xml similarity index 68% rename from .idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_5.xml rename to .idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_5_1.xml index 6d383f2..958a9fa 100644 --- a/.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_5.xml +++ b/.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_5_1.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_4_1.xml b/.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_4_3.xml similarity index 59% rename from .idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_4_1.xml rename to .idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_4_3.xml index 24a6857..a9f8d49 100644 --- a/.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_4_1.xml +++ b/.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_4_3.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_httpcomponents_httpmime_4_5.xml b/.idea/libraries/Maven__org_apache_httpcomponents_httpmime_4_5_1.xml similarity index 58% rename from .idea/libraries/Maven__org_apache_httpcomponents_httpmime_4_5.xml rename to .idea/libraries/Maven__org_apache_httpcomponents_httpmime_4_5_1.xml index b47fa2b..793e63d 100644 --- a/.idea/libraries/Maven__org_apache_httpcomponents_httpmime_4_5.xml +++ b/.idea/libraries/Maven__org_apache_httpcomponents_httpmime_4_5_1.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_grizzly_grizzly_framework_2_3_19.xml b/.idea/libraries/Maven__org_glassfish_grizzly_grizzly_framework_2_3_22.xml similarity index 65% rename from .idea/libraries/Maven__org_glassfish_grizzly_grizzly_framework_2_3_19.xml rename to .idea/libraries/Maven__org_glassfish_grizzly_grizzly_framework_2_3_22.xml index 0e72c5a..a65bfbe 100644 --- a/.idea/libraries/Maven__org_glassfish_grizzly_grizzly_framework_2_3_19.xml +++ b/.idea/libraries/Maven__org_glassfish_grizzly_grizzly_framework_2_3_22.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_grizzly_grizzly_http_2_3_19.xml b/.idea/libraries/Maven__org_glassfish_grizzly_grizzly_http_2_3_22.xml similarity index 56% rename from .idea/libraries/Maven__org_glassfish_grizzly_grizzly_http_2_3_19.xml rename to .idea/libraries/Maven__org_glassfish_grizzly_grizzly_http_2_3_22.xml index 3d9c159..34ec704 100644 --- a/.idea/libraries/Maven__org_glassfish_grizzly_grizzly_http_2_3_19.xml +++ b/.idea/libraries/Maven__org_glassfish_grizzly_grizzly_http_2_3_22.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_grizzly_grizzly_http_server_2_3_19.xml b/.idea/libraries/Maven__org_glassfish_grizzly_grizzly_http_server_2_3_22.xml similarity index 65% rename from .idea/libraries/Maven__org_glassfish_grizzly_grizzly_http_server_2_3_19.xml rename to .idea/libraries/Maven__org_glassfish_grizzly_grizzly_http_server_2_3_22.xml index b807cb3..7a5c530 100644 --- a/.idea/libraries/Maven__org_glassfish_grizzly_grizzly_http_server_2_3_19.xml +++ b/.idea/libraries/Maven__org_glassfish_grizzly_grizzly_http_server_2_3_22.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_hk2_external_aopalliance_repackaged_2_4_0_b12.xml b/.idea/libraries/Maven__org_glassfish_hk2_external_aopalliance_repackaged_2_4_0_b31.xml similarity index 56% rename from .idea/libraries/Maven__org_glassfish_hk2_external_aopalliance_repackaged_2_4_0_b12.xml rename to .idea/libraries/Maven__org_glassfish_hk2_external_aopalliance_repackaged_2_4_0_b31.xml index 9900ea1..874c890 100644 --- a/.idea/libraries/Maven__org_glassfish_hk2_external_aopalliance_repackaged_2_4_0_b12.xml +++ b/.idea/libraries/Maven__org_glassfish_hk2_external_aopalliance_repackaged_2_4_0_b31.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_hk2_external_javax_inject_2_4_0_b12.xml b/.idea/libraries/Maven__org_glassfish_hk2_external_javax_inject_2_4_0_b31.xml similarity index 65% rename from .idea/libraries/Maven__org_glassfish_hk2_external_javax_inject_2_4_0_b12.xml rename to .idea/libraries/Maven__org_glassfish_hk2_external_javax_inject_2_4_0_b31.xml index 22eb972..87ed334 100644 --- a/.idea/libraries/Maven__org_glassfish_hk2_external_javax_inject_2_4_0_b12.xml +++ b/.idea/libraries/Maven__org_glassfish_hk2_external_javax_inject_2_4_0_b31.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_hk2_hk2_api_2_4_0_b12.xml b/.idea/libraries/Maven__org_glassfish_hk2_hk2_api_2_4_0_b31.xml similarity index 60% rename from .idea/libraries/Maven__org_glassfish_hk2_hk2_api_2_4_0_b12.xml rename to .idea/libraries/Maven__org_glassfish_hk2_hk2_api_2_4_0_b31.xml index dd75e09..14746f4 100644 --- a/.idea/libraries/Maven__org_glassfish_hk2_hk2_api_2_4_0_b12.xml +++ b/.idea/libraries/Maven__org_glassfish_hk2_hk2_api_2_4_0_b31.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_hk2_hk2_locator_2_4_0_b12.xml b/.idea/libraries/Maven__org_glassfish_hk2_hk2_locator_2_4_0_b31.xml similarity index 57% rename from .idea/libraries/Maven__org_glassfish_hk2_hk2_locator_2_4_0_b12.xml rename to .idea/libraries/Maven__org_glassfish_hk2_hk2_locator_2_4_0_b31.xml index 3fd5a97..e57e76f 100644 --- a/.idea/libraries/Maven__org_glassfish_hk2_hk2_locator_2_4_0_b12.xml +++ b/.idea/libraries/Maven__org_glassfish_hk2_hk2_locator_2_4_0_b31.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_hk2_hk2_utils_2_4_0_b12.xml b/.idea/libraries/Maven__org_glassfish_hk2_hk2_utils_2_4_0_b31.xml similarity index 58% rename from .idea/libraries/Maven__org_glassfish_hk2_hk2_utils_2_4_0_b12.xml rename to .idea/libraries/Maven__org_glassfish_hk2_hk2_utils_2_4_0_b31.xml index 2bc8886..e99f973 100644 --- a/.idea/libraries/Maven__org_glassfish_hk2_hk2_utils_2_4_0_b12.xml +++ b/.idea/libraries/Maven__org_glassfish_hk2_hk2_utils_2_4_0_b31.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_jersey_bundles_repackaged_jersey_guava_2_18.xml b/.idea/libraries/Maven__org_glassfish_jersey_bundles_repackaged_jersey_guava_2_21.xml similarity index 64% rename from .idea/libraries/Maven__org_glassfish_jersey_bundles_repackaged_jersey_guava_2_18.xml rename to .idea/libraries/Maven__org_glassfish_jersey_bundles_repackaged_jersey_guava_2_21.xml index 99b92a1..36cb9da 100644 --- a/.idea/libraries/Maven__org_glassfish_jersey_bundles_repackaged_jersey_guava_2_18.xml +++ b/.idea/libraries/Maven__org_glassfish_jersey_bundles_repackaged_jersey_guava_2_21.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_jersey_containers_jersey_container_grizzly2_http_2_18.xml b/.idea/libraries/Maven__org_glassfish_jersey_containers_jersey_container_grizzly2_http_2_21.xml similarity index 53% rename from .idea/libraries/Maven__org_glassfish_jersey_containers_jersey_container_grizzly2_http_2_18.xml rename to .idea/libraries/Maven__org_glassfish_jersey_containers_jersey_container_grizzly2_http_2_21.xml index 2318d58..56d7136 100644 --- a/.idea/libraries/Maven__org_glassfish_jersey_containers_jersey_container_grizzly2_http_2_18.xml +++ b/.idea/libraries/Maven__org_glassfish_jersey_containers_jersey_container_grizzly2_http_2_21.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_jersey_core_jersey_client_2_18.xml b/.idea/libraries/Maven__org_glassfish_jersey_core_jersey_client_2_21.xml similarity index 67% rename from .idea/libraries/Maven__org_glassfish_jersey_core_jersey_client_2_18.xml rename to .idea/libraries/Maven__org_glassfish_jersey_core_jersey_client_2_21.xml index b7d8fb1..e107b60 100644 --- a/.idea/libraries/Maven__org_glassfish_jersey_core_jersey_client_2_18.xml +++ b/.idea/libraries/Maven__org_glassfish_jersey_core_jersey_client_2_21.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_jersey_core_jersey_common_2_18.xml b/.idea/libraries/Maven__org_glassfish_jersey_core_jersey_common_2_21.xml similarity index 67% rename from .idea/libraries/Maven__org_glassfish_jersey_core_jersey_common_2_18.xml rename to .idea/libraries/Maven__org_glassfish_jersey_core_jersey_common_2_21.xml index 57e4677..7c1bf6c 100644 --- a/.idea/libraries/Maven__org_glassfish_jersey_core_jersey_common_2_18.xml +++ b/.idea/libraries/Maven__org_glassfish_jersey_core_jersey_common_2_21.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_jersey_core_jersey_server_2_18.xml b/.idea/libraries/Maven__org_glassfish_jersey_core_jersey_server_2_21.xml similarity index 67% rename from .idea/libraries/Maven__org_glassfish_jersey_core_jersey_server_2_18.xml rename to .idea/libraries/Maven__org_glassfish_jersey_core_jersey_server_2_21.xml index ab8278a..5b375de 100644 --- a/.idea/libraries/Maven__org_glassfish_jersey_core_jersey_server_2_18.xml +++ b/.idea/libraries/Maven__org_glassfish_jersey_core_jersey_server_2_21.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_jersey_ext_jersey_entity_filtering_2_18.xml b/.idea/libraries/Maven__org_glassfish_jersey_ext_jersey_entity_filtering_2_21.xml similarity index 65% rename from .idea/libraries/Maven__org_glassfish_jersey_ext_jersey_entity_filtering_2_18.xml rename to .idea/libraries/Maven__org_glassfish_jersey_ext_jersey_entity_filtering_2_21.xml index 71f8355..70c1791 100644 --- a/.idea/libraries/Maven__org_glassfish_jersey_ext_jersey_entity_filtering_2_18.xml +++ b/.idea/libraries/Maven__org_glassfish_jersey_ext_jersey_entity_filtering_2_21.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_jersey_media_jersey_media_jaxb_2_18.xml b/.idea/libraries/Maven__org_glassfish_jersey_media_jersey_media_jaxb_2_21.xml similarity index 65% rename from .idea/libraries/Maven__org_glassfish_jersey_media_jersey_media_jaxb_2_18.xml rename to .idea/libraries/Maven__org_glassfish_jersey_media_jersey_media_jaxb_2_21.xml index 0ab63a6..6af14c3 100644 --- a/.idea/libraries/Maven__org_glassfish_jersey_media_jersey_media_jaxb_2_18.xml +++ b/.idea/libraries/Maven__org_glassfish_jersey_media_jersey_media_jaxb_2_21.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_jersey_media_jersey_media_json_jackson_2_18.xml b/.idea/libraries/Maven__org_glassfish_jersey_media_jersey_media_json_jackson_2_21.xml similarity index 58% rename from .idea/libraries/Maven__org_glassfish_jersey_media_jersey_media_json_jackson_2_18.xml rename to .idea/libraries/Maven__org_glassfish_jersey_media_jersey_media_json_jackson_2_21.xml index d116180..e063501 100644 --- a/.idea/libraries/Maven__org_glassfish_jersey_media_jersey_media_json_jackson_2_18.xml +++ b/.idea/libraries/Maven__org_glassfish_jersey_media_jersey_media_json_jackson_2_21.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jsoup_jsoup_1_8_2.xml b/.idea/libraries/Maven__org_jsoup_jsoup_1_8_2.xml deleted file mode 100644 index b78f11b..0000000 --- a/.idea/libraries/Maven__org_jsoup_jsoup_1_8_2.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jsoup_jsoup_1_8_3.xml b/.idea/libraries/Maven__org_jsoup_jsoup_1_8_3.xml new file mode 100644 index 0000000..de00ad0 --- /dev/null +++ b/.idea/libraries/Maven__org_jsoup_jsoup_1_8_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index c3a5faa..62f9d18 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,32 +1,102 @@ - - - - + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + - - - - + + - + + + - - - @@ -42,7 +112,7 @@ - - - + + - + @@ -84,120 +154,37 @@ - + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -225,57 +212,57 @@ @@ -321,43 +308,8 @@ - - - - - - - - + + + + + + + + + @@ -770,6 +780,15 @@ @@ -791,6 +810,15 @@ @@ -815,6 +843,65 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -938,6 +1046,19 @@ + + + + + + + + @@ -1027,6 +1176,24 @@ + + + + + + + + + $PROJECT_DIR$ + true + + bdd + + DIRECTORY + + false + + @@ -1123,7 +1290,33 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + 1434854005227 @@ -1341,11 +1534,77 @@ - - @@ -1360,66 +1619,66 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1434,16 +1693,6 @@ - - - - - - - - - - @@ -1459,7 +1708,17 @@ - @@ -1484,19 +1743,19 @@ file://$PROJECT_DIR$/src/main/java/org/telegram/updateshandlers/DirectionsHandlers.java - 65 + 71 file://$PROJECT_DIR$/src/main/java/org/telegram/updateshandlers/DirectionsHandlers.java - 59 + 65 file://$PROJECT_DIR$/src/main/java/org/telegram/updateshandlers/DirectionsHandlers.java - 56 + 62 @@ -1507,566 +1766,425 @@ - - - - - - - + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + + - + - - + + - + - - + + - + - - + + - + - - - + + - + - - + + - + - - + + - + - - + + - + - - + + - - - - - - - - - + + + + - + - - + + + + + - + - - + + - - - - - - - - - + + + + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + + - + - - + + - + - - + + + - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - + + + + + - + - - + + + - + - - + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + - - + + - + - - + + - + - - - + + - + - - + - + - - - + + - + - - - + + - + - - - + + - + - - - + + - + - - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - + - - + + - - - - + - - - + + - - - + + + + + + + - - + + - - - - + - - + + - - - - + - - - + + + + + + + + + + diff --git a/BotAPi.iml b/BotAPi.iml index 11ee1a7..2f3870b 100644 --- a/BotAPi.iml +++ b/BotAPi.iml @@ -11,33 +11,33 @@ - - - - - - + + + + + + - - - - - + + + + + - - - + + + - - - - - - - - + + + + + + + + @@ -48,13 +48,13 @@ - - + + + - - - - + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 7d05241..10f9e3e 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,8 @@ UTF-8 UTF-8 - 2.18 + 2.21 + 4.5.1 @@ -51,11 +52,6 @@ json 20141113 - - org.apache.httpcomponents - httpclient - 4.4.1 - commons-io commons-io @@ -64,22 +60,22 @@ org.apache.httpcomponents httpclient - 4.5 + ${httpcompontents.version} org.apache.httpcomponents httpmime - 4.5 + ${httpcompontents.version} mysql mysql-connector-java - 5.1.35 + 5.1.36 org.jsoup jsoup - 1.8.2 + 1.8.3 diff --git a/src/main/java/org/telegram/BotConfig.java b/src/main/java/org/telegram/BotConfig.java index 1bf8c3a..7c0e841 100644 --- a/src/main/java/org/telegram/BotConfig.java +++ b/src/main/java/org/telegram/BotConfig.java @@ -7,8 +7,12 @@ package org.telegram; * @date 20 of June of 2015 */ public class BotConfig { - public static final String TOKENWEATHER = ""; - public static final String TOKENTRANSIFEX = ""; - public static final String TOKENFILES = ""; - public static final String TOKENDIRECTIONS = ""; + public static final String TOKENWEATHER = ""; + public static final String USERNAMEWEATHER = "weatherbot"; + public static final String TOKENTRANSIFEX = ""; + public static final String USERNAMETRANSIFEX = "TGlanguagesbot"; + public static final String TOKENFILES = ""; + public static final String USERNAMEFILES = "filesbot"; + public static final String TOKENDIRECTIONS = ""; + public static final String USERNAMEDIRECTIONS = "directionsbot"; } diff --git a/src/main/java/org/telegram/BuildVars.java b/src/main/java/org/telegram/BuildVars.java index fb0452c..9a973a0 100644 --- a/src/main/java/org/telegram/BuildVars.java +++ b/src/main/java/org/telegram/BuildVars.java @@ -9,8 +9,11 @@ package org.telegram; public class BuildVars { public static final Boolean debug = true; public static final Boolean useWebHook = true; - public static final String BASEWEBHOOKURL = "http://YOUREXTERNALADDRES"; - public static final String INTERNALWEBHOOKURL = "http://localhost"; + public static final int PORT = 8443; + public static final String EXTERNALWEBHOOKURL = "your-external-url:" + PORT; + public static final String INTERNALWEBHOOKURL = "your-internal-url:" + PORT; + public static final String pathToCertificatePublicKey = "path/to/my/certkey.pem"; + public static final String certificatePublicKeyFileName = "certkey.pem"; public static final String OPENWEATHERAPIKEY = ""; diff --git a/src/main/java/org/telegram/Main.java b/src/main/java/org/telegram/Main.java index 9faf2bb..a765cc3 100644 --- a/src/main/java/org/telegram/Main.java +++ b/src/main/java/org/telegram/Main.java @@ -1,7 +1,10 @@ package org.telegram; import org.telegram.updateshandlers.*; -import org.telegram.updatesreceivers.UpdatesThread; +import org.telegram.updatesreceivers.Webhook; + +import java.util.logging.Level; +import java.util.logging.Logger; /** * @author Ruben Bermudez @@ -10,10 +13,26 @@ import org.telegram.updatesreceivers.UpdatesThread; * @date 20 of June of 2015 */ public class Main { + private static Webhook webhook; + public static void main(String[] args) { - UpdatesCallback weatherBot = new WeatherHandlers(); - UpdatesCallback transifexBot = new TransifexHandlers(); - UpdatesCallback filesBot = new FilesHandlers(); - UpdatesCallback directionsBot = new DirectionsHandlers(); + + if (BuildVars.useWebHook) { + webhook = new Webhook(); + } + + initBots(); + + if (BuildVars.useWebHook) { + webhook.startDebugServer(); + //webhook.startServer(); + } + } + + private static void initBots() { + UpdatesCallback weatherBot = new WeatherHandlers(webhook); + UpdatesCallback transifexBot = new TransifexHandlers(webhook); + UpdatesCallback filesBot = new FilesHandlers(webhook); + UpdatesCallback directionsBot = new DirectionsHandlers(webhook); } } diff --git a/src/main/java/org/telegram/SenderHelper.java b/src/main/java/org/telegram/SenderHelper.java index 50c1d13..841d1b4 100644 --- a/src/main/java/org/telegram/SenderHelper.java +++ b/src/main/java/org/telegram/SenderHelper.java @@ -8,6 +8,7 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.entity.BufferedHttpEntity; import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; @@ -15,15 +16,20 @@ import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.json.JSONObject; -import org.telegram.api.Message; -import org.telegram.methods.*; +import org.telegram.api.objects.Message; +import org.telegram.api.methods.*; import org.telegram.services.BotLogger; +import org.telegram.updateshandlers.SentCallback; import java.io.File; import java.io.IOException; import java.io.InvalidObjectException; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; /** * @author Ruben Bermudez @@ -33,46 +39,7 @@ import java.util.List; */ public class SenderHelper { private static volatile BotLogger log = BotLogger.getLogger(SenderHelper.class.getName()); - - public static Message SendMessage(SendMessage message, String botToken) { - try { - CloseableHttpClient httpclient = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); - String url = Constants.BASEURL + botToken + "/" + SendMessage.PATH; - HttpPost httppost = new HttpPost(url); - httppost.addHeader("Content-type", "application/x-www-form-urlencoded"); - httppost.addHeader("charset", "UTF-8"); - List nameValuePairs = new ArrayList(); - nameValuePairs.add(new BasicNameValuePair(SendMessage.CHATID_FIELD, message.getChatId().toString())); - nameValuePairs.add(new BasicNameValuePair(SendMessage.TEXT_FIELD, message.getText())); - if (message.getDisableWebPagePreview() != null) { - nameValuePairs.add(new BasicNameValuePair(SendMessage.DISABLEWEBPAGEPREVIEW_FIELD, message.getDisableWebPagePreview().toString())); - } - if (message.getReplayMarkup() != null) { - nameValuePairs.add(new BasicNameValuePair(SendMessage.REPLYMARKUP_FIELD, message.getReplayMarkup().toJson().toString())); - } - if (message.getReplayToMessageId() != null) { - nameValuePairs.add(new BasicNameValuePair(SendMessage.REPLYTOMESSAGEID_FIELD, message.getReplayToMessageId().toString())); - } - httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8")); - log.debug(httppost.toString()); - log.debug(nameValuePairs.toString()); - CloseableHttpResponse response = httpclient.execute(httppost); - HttpEntity ht = response.getEntity(); - - BufferedHttpEntity buf = new BufferedHttpEntity(ht); - String responseContent = EntityUtils.toString(buf, "UTF-8"); - - JSONObject jsonObject = new JSONObject(responseContent); - if (!jsonObject.getBoolean("ok")) { - throw new InvalidObjectException(jsonObject.toString()); - } - JSONObject jsonMessage = jsonObject.getJSONObject("result"); - return new Message(jsonMessage); - } catch (IOException e) { - log.error(e); - return null; - } - } + private static final ExecutorService exe = Executors.newSingleThreadExecutor(); public static void SendDocument(SendDocument sendDocument, String botToken) { try { @@ -253,21 +220,68 @@ public class SenderHelper { try { CloseableHttpClient httpclient = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); String url = Constants.BASEURL + botToken + "/" + SetWebhook.PATH; + HttpPost httppost = new HttpPost(url); - httppost.addHeader("Content-type", "application/x-www-form-urlencoded"); - httppost.addHeader("charset", "UTF-8"); - List nameValuePairs = new ArrayList<>(); - nameValuePairs.add(new BasicNameValuePair(SetWebhook.URL_FIELD, webHookURL)); - httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8")); + MultipartEntityBuilder builder = MultipartEntityBuilder.create(); + builder.addTextBody(SetWebhook.URL_FIELD, webHookURL); + if (BuildVars.pathToCertificatePublicKey != null) { + builder.addBinaryBody(SetWebhook.CERTIFICATE_FIELD, new File(BuildVars.pathToCertificatePublicKey), ContentType.APPLICATION_OCTET_STREAM, BuildVars.certificatePublicKeyFileName); + } + HttpEntity multipart = builder.build(); + httppost.setEntity(multipart); CloseableHttpResponse response = httpclient.execute(httppost); HttpEntity ht = response.getEntity(); + BufferedHttpEntity buf = new BufferedHttpEntity(ht); + String responseContent = EntityUtils.toString(buf, "UTF-8"); + log.debug(responseContent); + } catch (IOException e) { + log.error(e); + } + + } + public static void SendApiMethod(BotApiMethod method, String botToken) { + try { + CloseableHttpClient httpclient = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); + String url = Constants.BASEURL + botToken + "/" + method.getPath(); + HttpPost httppost = new HttpPost(url); + httppost.addHeader("charset", "UTF-8"); + httppost.setEntity(new StringEntity(method.toJson().toString(), ContentType.APPLICATION_JSON)); + CloseableHttpResponse response = httpclient.execute(httppost); + HttpEntity ht = response.getEntity(); BufferedHttpEntity buf = new BufferedHttpEntity(ht); String responseContent = EntityUtils.toString(buf, "UTF-8"); + JSONObject jsonObject = new JSONObject(responseContent); + if (!jsonObject.getBoolean("ok")) { + throw new InvalidObjectException(jsonObject.toString()); + } } catch (IOException e) { log.error(e); } + } + + public static void SendApiMethodAsync(BotApiMethod method, String botToken, SentCallback callback) { + exe.submit(() -> { + try { + CloseableHttpClient httpclient = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); + String url = Constants.BASEURL + botToken + "/" + method.getPath(); + HttpPost httppost = new HttpPost(url); + httppost.addHeader("charset", "UTF-8"); + httppost.setEntity(new StringEntity(method.toJson().toString(), ContentType.APPLICATION_JSON)); + CloseableHttpResponse response = httpclient.execute(httppost); + HttpEntity ht = response.getEntity(); + BufferedHttpEntity buf = new BufferedHttpEntity(ht); + String responseContent = EntityUtils.toString(buf, "UTF-8"); + JSONObject jsonObject = new JSONObject(responseContent); + if (!jsonObject.getBoolean("ok")) { + callback.onError(method, jsonObject); + } + callback.onResult(method, jsonObject); + } catch (IOException e) { + log.error(e); + } + }); } } diff --git a/src/main/java/org/telegram/api/Contact.java b/src/main/java/org/telegram/api/Contact.java deleted file mode 100644 index 53b893b..0000000 --- a/src/main/java/org/telegram/api/Contact.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.telegram.api; - -import com.fasterxml.jackson.annotation.JsonProperty; -import org.json.JSONObject; - -/** - * @author Ruben Bermudez - * @version 1.0 - * @brief This object represents a phone contact. - * @date 20 of June of 2015 - */ -public class Contact { - - public static final String PHONENUMBER_FIELD = "phone_number"; - @JsonProperty(PHONENUMBER_FIELD) - private String phoneNumber; ///< Contact's phone number - public static final String FIRSTNAME_FIELD = "first_name"; - @JsonProperty(FIRSTNAME_FIELD) - private String firstName; ///< Contact's first name - public static final String LASTNAME_FIELD = "last_name"; - @JsonProperty(LASTNAME_FIELD) - private String lastName; ///< Optional. Contact's last name - public static final String USERID_FIELD = "user_id"; - @JsonProperty(USERID_FIELD) - private Integer userID; ///< Optional. Contact's user identifier in Telegram - - public Contact() { - super(); - } - - public Contact(JSONObject jsonObject) { - super(); - this.phoneNumber = jsonObject.getString(PHONENUMBER_FIELD); - this.firstName = jsonObject.getString(FIRSTNAME_FIELD); - this.lastName = jsonObject.optString(LASTNAME_FIELD, ""); - this.userID = jsonObject.optInt(USERID_FIELD, 0); - } -} diff --git a/src/main/java/org/telegram/api/PhotoSize.java b/src/main/java/org/telegram/api/PhotoSize.java deleted file mode 100644 index 293faa9..0000000 --- a/src/main/java/org/telegram/api/PhotoSize.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.telegram.api; - -import com.fasterxml.jackson.annotation.JsonProperty; -import org.json.JSONObject; - -/** - * @author Ruben Bermudez - * @version 1.0 - * @brief This object represents one size of a photo or a file / sticker thumbnail. - * @date 20 of June of 2015 - */ -public class PhotoSize { - - public static final String FILEID_FIELD = "file_id"; - @JsonProperty(FILEID_FIELD) - private String fileId; ///< Unique identifier for this file - public static final String WIDTH_FIELD = "width"; - @JsonProperty(WIDTH_FIELD) - private Integer width; ///< Photo width - public static final String HEIGHT_FIELD = "height"; - @JsonProperty(HEIGHT_FIELD) - private Integer height; ///< Photo height - public static final String FILESIZE_FIELD = "file_size"; - @JsonProperty(FILESIZE_FIELD) - private Integer fileSize; ///< Optional. File size - - public PhotoSize() { - super(); - } - - public PhotoSize(JSONObject jsonObject) { - super(); - this.fileId = jsonObject.optString(FILEID_FIELD, ""); - this.width = jsonObject.optInt(WIDTH_FIELD, 0); - this.height = jsonObject.optInt(HEIGHT_FIELD, 0); - this.fileSize = jsonObject.optInt(FILESIZE_FIELD, 0); - } - - public String getFileId() { - return fileId; - } - - public void setFileId(String fileId) { - this.fileId = fileId; - } - - public Integer getWidth() { - return width; - } - - public void setWidth(Integer width) { - this.width = width; - } - - public Integer getHeight() { - return height; - } - - public void setHeight(Integer height) { - this.height = height; - } - - public Integer getFileSize() { - return fileSize; - } - - public void setFileSize(Integer fileSize) { - this.fileSize = fileSize; - } -} diff --git a/src/main/java/org/telegram/api/ReplyKeyboard.java b/src/main/java/org/telegram/api/ReplyKeyboard.java deleted file mode 100644 index d19efbf..0000000 --- a/src/main/java/org/telegram/api/ReplyKeyboard.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.telegram.api; - -import org.json.JSONObject; - -/** - * @author Ruben Bermudez - * @version 1.0 - * @brief Reply keyboard abstract type - * @date 20 of June of 2015 - */ -public interface ReplyKeyboard { - JSONObject toJson(); -} diff --git a/src/main/java/org/telegram/api/Sticker.java b/src/main/java/org/telegram/api/Sticker.java deleted file mode 100644 index a5e756e..0000000 --- a/src/main/java/org/telegram/api/Sticker.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.telegram.api; - -import com.fasterxml.jackson.annotation.JsonProperty; -import org.json.JSONObject; - -/** - * @author Ruben Bermudez - * @version 1.0 - * @brief This object represents a sticker. - * @date 20 of June of 2015 - */ -public class Sticker { - - public static final String FILEID_FIELD = "file_id"; - @JsonProperty(FILEID_FIELD) - private String fileId; ///< Unique identifier for this file - public static final String WIDTH_FIELD = "width"; - @JsonProperty(WIDTH_FIELD) - private Integer width; ///< Sticker width - public static final String HEIGHT_FIELD = "height"; - @JsonProperty(HEIGHT_FIELD) - private Integer height; ///< Sticker height - public static final String THUMB_FIELD = "thumb"; - @JsonProperty(THUMB_FIELD) - private PhotoSize thumb; ///< Sticker thumbnail in .webp or .jpg format - public static final String FILESIZE_FIELD = "file_size"; - @JsonProperty(FILESIZE_FIELD) - private Integer fileSize; ///< Optional. File size - - public Sticker() { - super(); - } - - public Sticker(JSONObject jsonObject) { - super(); - this.fileId = jsonObject.getString(FILEID_FIELD); - this.width = jsonObject.getInt(WIDTH_FIELD); - this.height = jsonObject.getInt(HEIGHT_FIELD); - if (jsonObject.has(THUMB_FIELD)) { - this.thumb = new PhotoSize(jsonObject.getJSONObject(THUMB_FIELD)); - } else { - this.thumb = null; - } - this.fileSize = jsonObject.optInt(FILESIZE_FIELD, 0); - } -} diff --git a/src/main/java/org/telegram/api/Update.java b/src/main/java/org/telegram/api/Update.java deleted file mode 100644 index 5f88d6c..0000000 --- a/src/main/java/org/telegram/api/Update.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.telegram.api; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import org.json.JSONObject; -import sun.print.UnixPrintJob; - -/** - * @author Ruben Bermudez - * @version 1.0 - * @brief TODO - * @date 20 of June of 2015 - */ -public class Update { - /* - update_id Integer -message Message - */ - public static final String UPDATEID_FIELD = "update_id"; - /** - * The update‘s unique identifier. - * Update identifiers start from a certain positive number and increase sequentially. - * This ID becomes especially handy if you’re using Webhooks, - * since it allows you to ignore repeated updates or to restore the - * correct update sequence, should they get out of order. - */ - @JsonProperty(UPDATEID_FIELD) - private Integer updateId; - public static final String MESSAGE_FIELD = "message"; - @JsonProperty(MESSAGE_FIELD) - private Message message; ///< Optional. New incoming message of any kind — text, photo, sticker, etc. - - public Update() { - super(); - } - - public Update(JSONObject jsonObject) { - super(); - this.updateId = jsonObject.getInt(UPDATEID_FIELD); - JSONObject messageJSON = jsonObject.optJSONObject(MESSAGE_FIELD); - if (messageJSON == null) { - this.message = null; - } else { - this.message = new Message(messageJSON); - } - } - - public Integer getUpdateId() { - return updateId; - } - - public Message getMessage() { - return message; - } -} diff --git a/src/main/java/org/telegram/api/User.java b/src/main/java/org/telegram/api/User.java deleted file mode 100644 index 3af2788..0000000 --- a/src/main/java/org/telegram/api/User.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.telegram.api; - -import com.fasterxml.jackson.annotation.JsonProperty; -import org.json.JSONObject; - -/** - * @author Ruben Bermudez - * @version 1.0 - * @brief This object represents a Telegram user or bot. - * @date 20 of June of 2015 - */ -public class User { - - public static final String ID_FIELD = "id"; - @JsonProperty(ID_FIELD) - private Integer id; ///< Unique identifier for this user or bot - public static final String FIRSTNAME_FIELD = "first_name"; - @JsonProperty(FIRSTNAME_FIELD) - private String firstName; ///< User‘s or bot’s first name - public static final String LASTNAME_FIELD = "last_name"; - @JsonProperty(LASTNAME_FIELD) - private String lastName; ///< Optional. User‘s or bot’s last name - public static final String USERNAME_FIELD = "username"; - @JsonProperty(USERNAME_FIELD) - private String userName; ///< Optional. User‘s or bot’s username - - public User() { - super(); - } - - public User(JSONObject jsonObject) { - super(); - this.id = jsonObject.getInt(ID_FIELD); - this.firstName = jsonObject.getString(FIRSTNAME_FIELD); - this.lastName = jsonObject.optString(LASTNAME_FIELD, ""); - this.userName = jsonObject.optString(USERNAME_FIELD, ""); - } - - public Integer getId() { - return id; - } - - public String getFirstName() { - return firstName; - } - - public String getLastName() { - return lastName; - } - - public String getUserName() { - return userName; - } -} diff --git a/src/main/java/org/telegram/api/UserProfilePhotos.java b/src/main/java/org/telegram/api/UserProfilePhotos.java deleted file mode 100644 index a3b2ca1..0000000 --- a/src/main/java/org/telegram/api/UserProfilePhotos.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.telegram.api; - -import com.fasterxml.jackson.annotation.JsonProperty; -import org.json.JSONArray; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Ruben Bermudez - * @version 1.0 - * @brief This object represent a user's profile pictures. - * @date 22 of June of 2015 - */ -public class UserProfilePhotos { - - public static final String TOTALCOUNT_FIELD = "total_count"; - @JsonProperty(TOTALCOUNT_FIELD) - private Integer totalCount; ///< Total number of profile pictures the target user has - public static final String PHOTOS_FIELD = "photos"; - @JsonProperty(PHOTOS_FIELD) - private List> photos; ///< Requested profile pictures (in up to 4 sizes each) - - public UserProfilePhotos() { - super(); - } - - public UserProfilePhotos(JSONObject jsonObject) { - super(); - this.totalCount = jsonObject.getInt(TOTALCOUNT_FIELD); - this.photos = new ArrayList<>(); - JSONArray photos = jsonObject.getJSONArray(PHOTOS_FIELD); - for (int i = 0; i < photos.length(); i++) { - JSONArray innerArray = photos.getJSONArray(i); - List innerPhotos = new ArrayList<>(); - for (int j = 0; j < innerArray.length(); j ++) { - innerPhotos.add(new PhotoSize(innerArray.getJSONObject(j))); - } - this.photos.add(innerPhotos); - } - } -} diff --git a/src/main/java/org/telegram/api/interfaces/BotApiObject.java b/src/main/java/org/telegram/api/interfaces/BotApiObject.java new file mode 100644 index 0000000..fac118d --- /dev/null +++ b/src/main/java/org/telegram/api/interfaces/BotApiObject.java @@ -0,0 +1,13 @@ +package org.telegram.api.interfaces; + +import com.fasterxml.jackson.databind.JsonSerializable; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief An object of Telegram Bots Api + * @date 07 of September of 2015 + */ +public interface BotApiObject extends JsonSerializable { +} diff --git a/src/main/java/org/telegram/api/interfaces/IToJson.java b/src/main/java/org/telegram/api/interfaces/IToJson.java new file mode 100644 index 0000000..921bfbe --- /dev/null +++ b/src/main/java/org/telegram/api/interfaces/IToJson.java @@ -0,0 +1,18 @@ +package org.telegram.api.interfaces; + +import org.json.JSONObject; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief Add conversion to JSON object + * @date 08 of September of 2015 + */ +public interface IToJson { + + /** + * Convert to json object + * @return JSONObject created in the conversion + */ + JSONObject toJson(); +} diff --git a/src/main/java/org/telegram/api/methods/BotApiMethod.java b/src/main/java/org/telegram/api/methods/BotApiMethod.java new file mode 100644 index 0000000..c6a2582 --- /dev/null +++ b/src/main/java/org/telegram/api/methods/BotApiMethod.java @@ -0,0 +1,28 @@ +package org.telegram.api.methods; + +import com.fasterxml.jackson.databind.JsonSerializable; +import org.json.JSONObject; +import org.telegram.api.interfaces.IToJson; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief A method of Telegram Bots Api that is fully supported in json format + * @date 07 of September of 2015 + */ +public abstract class BotApiMethod implements JsonSerializable, IToJson { + protected static final String METHOD_FIELD = "method"; + + /** + * Getter for method path (that is the same as method name) + * @return Method path + */ + public abstract String getPath(); + + /** + * Deserialize a json answer to the response type to a method + * @param answer Json answer received + * @return Answer for the method + */ + public abstract T deserializeResponse(JSONObject answer); +} diff --git a/src/main/java/org/telegram/methods/Constants.java b/src/main/java/org/telegram/api/methods/Constants.java similarity index 85% rename from src/main/java/org/telegram/methods/Constants.java rename to src/main/java/org/telegram/api/methods/Constants.java index 0c39bb6..8464418 100644 --- a/src/main/java/org/telegram/methods/Constants.java +++ b/src/main/java/org/telegram/api/methods/Constants.java @@ -1,4 +1,4 @@ -package org.telegram.methods; +package org.telegram.api.methods; /** * @author Ruben Bermudez diff --git a/src/main/java/org/telegram/api/methods/ForwardMessage.java b/src/main/java/org/telegram/api/methods/ForwardMessage.java new file mode 100644 index 0000000..714afe8 --- /dev/null +++ b/src/main/java/org/telegram/api/methods/ForwardMessage.java @@ -0,0 +1,98 @@ +package org.telegram.api.methods; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.json.JSONObject; +import org.telegram.api.objects.Message; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief Use this method to send text messages. On success, the sent Message is returned. + * @date 20 of June of 2015 + */ +public class ForwardMessage extends BotApiMethod { + public static final String PATH = "forwardmessage"; + + public static final String CHATID_FIELD = "chat_id"; + private Integer chatId; ///< Unique identifier for the message recepient — User or GroupChat id + public static final String FROMCHATID_FIELD = "from_chat_id"; + private Integer fromChatId; ///< Unique identifier for the chat where the original message was sent — User or GroupChat id + public static final String MESSAGEID_FIELD = "message_id"; + private Integer messageId; ///< Unique message identifier + + public ForwardMessage() { + super(); + } + + public Integer getChatId() { + return chatId; + } + + public void setChatId(Integer chatId) { + this.chatId = chatId; + } + + public Integer getFromChatId() { + return fromChatId; + } + + public void setFromChatId(Integer fromChatId) { + this.fromChatId = fromChatId; + } + + public Integer getMessageId() { + return messageId; + } + + public void setMessageId(Integer messageId) { + this.messageId = messageId; + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(METHOD_FIELD, PATH); + gen.writeNumberField(CHATID_FIELD, chatId); + gen.writeNumberField(FROMCHATID_FIELD, fromChatId); + gen.writeNumberField(MESSAGEID_FIELD, messageId); + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeStringField(METHOD_FIELD, PATH); + gen.writeNumberField(CHATID_FIELD, chatId); + gen.writeNumberField(FROMCHATID_FIELD, fromChatId); + gen.writeNumberField(MESSAGEID_FIELD, messageId); + gen.writeEndObject(); + gen.flush(); + } + + @Override + public JSONObject toJson() { + JSONObject jsonObject = new JSONObject(); + jsonObject.put(CHATID_FIELD, chatId); + jsonObject.put(FROMCHATID_FIELD, fromChatId); + jsonObject.put(MESSAGEID_FIELD, messageId); + return jsonObject; + } + + @Override + public String getPath() { + return PATH; + } + + @Override + public Message deserializeResponse(JSONObject answer) { + if (answer.getBoolean("ok")) { + return new Message(answer.getJSONObject("result")); + } + return null; + } +} diff --git a/src/main/java/org/telegram/api/methods/GetFile.java b/src/main/java/org/telegram/api/methods/GetFile.java new file mode 100644 index 0000000..7c1e705 --- /dev/null +++ b/src/main/java/org/telegram/api/methods/GetFile.java @@ -0,0 +1,79 @@ +package org.telegram.api.methods; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.json.JSONObject; +import org.telegram.api.objects.File; +import org.telegram.api.objects.Message; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief Use this method to get basic info about a file and prepare it for downloading. + * For the moment, bots can download files of up to 20MB in size. + * On success, a File object is returned. + * The file can then be downloaded via the link https://api.telegram.org/file/bot/, + * where is taken from the response. + * It is guaranteed that the link will be valid for at least 1 hour. + * When the link expires, a new one can be requested by calling getFile again. + * @date 20 of June of 2015 + */ +public class GetFile extends BotApiMethod { + public static final String PATH = "getfield"; + + public static final String FILEID_FIELD = "file_id"; + private String fileId; ///< File identifier to get info about + + public GetFile() { + super(); + } + + public String getFileId() { + return fileId; + } + + public void setFileId(String fileId) { + this.fileId = fileId; + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(METHOD_FIELD, PATH); + gen.writeStringField(FILEID_FIELD, fileId); + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeStringField(METHOD_FIELD, PATH); + gen.writeStringField(FILEID_FIELD, fileId); + gen.writeEndObject(); + gen.flush(); + } + + @Override + public JSONObject toJson() { + JSONObject jsonObject = new JSONObject(); + jsonObject.put(FILEID_FIELD, fileId); + return jsonObject; + } + + @Override + public String getPath() { + return PATH; + } + + @Override + public File deserializeResponse(JSONObject answer) { + if (answer.getBoolean("ok")) { + return new File(answer.getJSONObject("result")); + } + return null; + } +} diff --git a/src/main/java/org/telegram/api/methods/GetMe.java b/src/main/java/org/telegram/api/methods/GetMe.java new file mode 100644 index 0000000..a925df1 --- /dev/null +++ b/src/main/java/org/telegram/api/methods/GetMe.java @@ -0,0 +1,52 @@ +package org.telegram.api.methods; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.json.JSONObject; +import org.telegram.api.objects.User; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief A simple method for testing your bot's auth token. Requires no parameters. + * Returns basic information about the bot in form of a User object + * @date 20 of June of 2015 + */ +public class GetMe extends BotApiMethod { + public static final String PATH = "getme"; + + @Override + public JSONObject toJson() { + return new JSONObject(); + } + + @Override + public String getPath() { + return PATH; + } + + @Override + public User deserializeResponse(JSONObject answer) { + if (answer.getBoolean("ok")) { + return new User(answer.getJSONObject("result")); + } + return null; + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(METHOD_FIELD, PATH); + gen.writeEndObject(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeStringField(METHOD_FIELD, PATH); + gen.writeEndObject(); + } +} diff --git a/src/main/java/org/telegram/methods/GetUpdates.java b/src/main/java/org/telegram/api/methods/GetUpdates.java similarity index 73% rename from src/main/java/org/telegram/methods/GetUpdates.java rename to src/main/java/org/telegram/api/methods/GetUpdates.java index 2291fe8..f4ed66c 100644 --- a/src/main/java/org/telegram/methods/GetUpdates.java +++ b/src/main/java/org/telegram/api/methods/GetUpdates.java @@ -1,4 +1,7 @@ -package org.telegram.methods; +package org.telegram.api.methods; + +import org.json.JSONObject; +import org.telegram.api.interfaces.IToJson; /** * @author Ruben Bermudez @@ -7,7 +10,7 @@ package org.telegram.methods; * An Array of Update objects is returned. * @date 20 of June of 2015 */ -public class GetUpdates { +public class GetUpdates implements IToJson { public static final String PATH = "getupdates"; public static final String OFFSET_FIELD = "offset"; @@ -57,7 +60,18 @@ public class GetUpdates { this.timeout = timeout; } - public String getUrlParams() { - return "?" + OFFSET_FIELD + "=" + offset ; + @Override + public JSONObject toJson() { + JSONObject jsonObject = new JSONObject(); + if (offset != null) { + jsonObject.put(OFFSET_FIELD, offset); + } + if (limit != null) { + jsonObject.put(LIMIT_FIELD, limit); + } + if (timeout != null) { + jsonObject.put(TIMEOUT_FIELD, timeout); + } + return jsonObject; } } diff --git a/src/main/java/org/telegram/api/methods/GetUserProfilePhotos.java b/src/main/java/org/telegram/api/methods/GetUserProfilePhotos.java new file mode 100644 index 0000000..161bdfe --- /dev/null +++ b/src/main/java/org/telegram/api/methods/GetUserProfilePhotos.java @@ -0,0 +1,111 @@ +package org.telegram.api.methods; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.json.JSONObject; +import org.telegram.api.objects.Message; +import org.telegram.api.objects.UserProfilePhotos; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief Use this method to get a list of profile pictures for a user. Returns a UserProfilePhotos object. + * @date 20 of June of 2015 + */ +public class GetUserProfilePhotos extends BotApiMethod { + public static final String PATH = "getuserprofilephotos"; + + public static final String USERID_FIELD = "user_id"; + private Integer userId; ///< Unique identifier of the target user + public static final String OFFSET_FIELD = "offset"; + /** + * Sequential number of the first photo to be returned. By default, all photos are returned. + */ + private Integer offset; + public static final String LIMIT_FIELD = "limit"; + /** + * Optional. Limits the number of photos to be retrieved. Values between 1—100 are accepted. Defaults to 100. + */ + private Integer limit; + + public GetUserProfilePhotos() { + super(); + } + + + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + public Integer getOffset() { + return offset; + } + + public void setOffset(Integer offset) { + this.offset = offset; + } + + public Integer getLimit() { + return limit; + } + + public void setLimit(Integer limit) { + this.limit = limit; + } + @Override + public JSONObject toJson() { + JSONObject jsonObject = new JSONObject(); + jsonObject.put(USERID_FIELD, userId); + jsonObject.put(OFFSET_FIELD, offset); + if (limit != null) { + jsonObject.put(LIMIT_FIELD, limit); + } + return jsonObject; + } + + @Override + public String getPath() { + return PATH; + } + + @Override + public UserProfilePhotos deserializeResponse(JSONObject answer) { + if (answer.getBoolean("ok")) { + return new UserProfilePhotos(answer.getJSONObject("result")); + } + return null; + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(METHOD_FIELD, PATH); + gen.writeNumberField(USERID_FIELD, userId); + gen.writeNumberField(OFFSET_FIELD, offset); + if (limit != null) { + gen.writeNumberField(LIMIT_FIELD, limit); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeStringField(METHOD_FIELD, PATH); + gen.writeNumberField(USERID_FIELD, userId); + gen.writeNumberField(OFFSET_FIELD, offset); + if (limit != null) { + gen.writeNumberField(LIMIT_FIELD, limit); + } + gen.writeEndObject(); + gen.flush(); + } +} diff --git a/src/main/java/org/telegram/methods/SendAudio.java b/src/main/java/org/telegram/api/methods/SendAudio.java similarity index 55% rename from src/main/java/org/telegram/methods/SendAudio.java rename to src/main/java/org/telegram/api/methods/SendAudio.java index a2c216e..19fbb53 100644 --- a/src/main/java/org/telegram/methods/SendAudio.java +++ b/src/main/java/org/telegram/api/methods/SendAudio.java @@ -1,6 +1,6 @@ -package org.telegram.methods; +package org.telegram.api.methods; -import org.telegram.api.ReplyKeyboard; +import org.telegram.api.objects.ReplyKeyboard; /** * @author Ruben Bermudez @@ -32,8 +32,73 @@ public class SendAudio { private String performer; ///< Optional. Performer of sent audio public static final String TITLE_FIELD = "title"; private String title; ///< Optional. Title of sent audio + private boolean isNewAudio; + private String audioName; public SendAudio() { super(); } + + public Integer getChatId() { + return chatId; + } + + public void setChatId(Integer chatId) { + this.chatId = chatId; + } + + public String getAudio() { + return audio; + } + + public void setAudio(String audio) { + this.audio = audio; + this.isNewAudio = false; + } + + public void setNewAudio(String audio, String audioName) { + this.audio = audio; + this.isNewAudio = true; + this.audioName = audioName; + } + + public Integer getReplayToMessageId() { + return replayToMessageId; + } + + public void setReplayToMessageId(Integer replayToMessageId) { + this.replayToMessageId = replayToMessageId; + } + + public ReplyKeyboard getReplayMarkup() { + return replayMarkup; + } + + public void setReplayMarkup(ReplyKeyboard replayMarkup) { + this.replayMarkup = replayMarkup; + } + + public String getPerformer() { + return performer; + } + + public void setPerformer(String performer) { + this.performer = performer; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public boolean isNewAudio() { + return isNewAudio; + } + + public String getAudioName() { + return audioName; + } } diff --git a/src/main/java/org/telegram/api/methods/SendChatAction.java b/src/main/java/org/telegram/api/methods/SendChatAction.java new file mode 100644 index 0000000..d5b11fc --- /dev/null +++ b/src/main/java/org/telegram/api/methods/SendChatAction.java @@ -0,0 +1,89 @@ +package org.telegram.api.methods; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.json.JSONObject; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief Use this method when you need to tell the user that something is happening on the bot's side. + * The status is set for 5 seconds or less (when a message arrives from your bot, + * Telegram clients clear its typing status). + * @date 20 of June of 2015 + */ +public class SendChatAction extends BotApiMethod{ + + public static final String PATH = "sendChatAction"; + + public static final String CHATID_FIELD = "chat_id"; + private Integer chatId; ///< Unique identifier for the message recepient — User or GroupChat id + public static final String ACTION_FIELD = "action"; + /** + * Type of action to broadcast. + * Choose one, depending on what the user is about to receive: + * 'typing' for text messages + * 'upload_photo' for photos + * 'record_video' or 'upload_video' for videos + * 'record_audio' or 'upload_audio' for audio files + * 'upload_document' for general files, + * 'find_location' for location data. + */ + private String action; + + public Integer getChatId() { + return chatId; + } + + public void setChatId(Integer chatId) { + this.chatId = chatId; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + @Override + public String getPath() { + return PATH; + } + + @Override + public Boolean deserializeResponse(JSONObject answer) { + if (answer.getBoolean("ok")) { + return answer.getBoolean("result"); + } + return null; + } + + @Override + public JSONObject toJson() { + JSONObject jsonObject = new JSONObject(); + jsonObject.put(CHATID_FIELD, chatId); + jsonObject.put(ACTION_FIELD, action); + return jsonObject; + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeNumberField(CHATID_FIELD, chatId); + gen.writeStringField(ACTION_FIELD, action); + gen.writeEndObject(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeNumberField(CHATID_FIELD, chatId); + gen.writeStringField(ACTION_FIELD, action); + gen.writeEndObject(); + } +} diff --git a/src/main/java/org/telegram/methods/SendDocument.java b/src/main/java/org/telegram/api/methods/SendDocument.java similarity index 96% rename from src/main/java/org/telegram/methods/SendDocument.java rename to src/main/java/org/telegram/api/methods/SendDocument.java index 757c7c0..8e5a959 100644 --- a/src/main/java/org/telegram/methods/SendDocument.java +++ b/src/main/java/org/telegram/api/methods/SendDocument.java @@ -1,6 +1,6 @@ -package org.telegram.methods; +package org.telegram.api.methods; -import org.telegram.api.ReplyKeyboard; +import org.telegram.api.objects.ReplyKeyboard; /** * @author Ruben Bermudez diff --git a/src/main/java/org/telegram/api/methods/SendLocation.java b/src/main/java/org/telegram/api/methods/SendLocation.java new file mode 100644 index 0000000..5f1b7da --- /dev/null +++ b/src/main/java/org/telegram/api/methods/SendLocation.java @@ -0,0 +1,137 @@ +package org.telegram.api.methods; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.json.JSONObject; +import org.telegram.api.objects.Message; +import org.telegram.api.objects.ReplyKeyboard; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief Use this method to send point on the map. On success, the sent Message is returned. + * @date 20 of June of 2015 + */ +public class SendLocation extends BotApiMethod { + public static final String PATH = "sendlocation"; + + public static final String CHATID_FIELD = "chat_id"; + private Integer chatId; ///< Unique identifier for the message recepient — User or GroupChat id + public static final String LATITUDE_FIELD = "latitude"; + private Float latitude; ///< Latitude of location + public static final String LONGITUDE_FIELD = "longitude"; + private Float longitude; ///< Longitude of location + public static final String REPLYTOMESSAGEID_FIELD = "reply_to_message_id"; + private Integer replayToMessageId; ///< Optional. If the message is a reply, ID of the original message + public static final String REPLYMARKUP_FIELD = "reply_markup"; + private ReplyKeyboard replayMarkup; ///< Optional. JSON-serialized object for a custom reply keyboard + + public Integer getChatId() { + return chatId; + } + + public void setChatId(Integer chatId) { + this.chatId = chatId; + } + + public Float getLatitude() { + return latitude; + } + + public void setLatitude(Float latitude) { + this.latitude = latitude; + } + + public Float getLongitude() { + return longitude; + } + + public void setLongitude(Float longitude) { + this.longitude = longitude; + } + + public Integer getReplayToMessageId() { + return replayToMessageId; + } + + public void setReplayToMessageId(Integer replayToMessageId) { + this.replayToMessageId = replayToMessageId; + } + + public ReplyKeyboard getReplayMarkup() { + return replayMarkup; + } + + public void setReplayMarkup(ReplyKeyboard replayMarkup) { + this.replayMarkup = replayMarkup; + } + + @Override + public String getPath() { + return PATH; + } + + @Override + public Message deserializeResponse(JSONObject answer) { + if (answer.getBoolean("ok")) { + return new Message(answer.getJSONObject("result")); + } + return null; + } + + @Override + public JSONObject toJson() { + JSONObject jsonObject = new JSONObject(); + + jsonObject.put(CHATID_FIELD, chatId); + jsonObject.put(LATITUDE_FIELD, latitude); + jsonObject.put(LONGITUDE_FIELD, longitude); + if (replayToMessageId != null) { + jsonObject.put(REPLYTOMESSAGEID_FIELD, replayToMessageId); + } + if (replayMarkup != null) { + jsonObject.put(REPLYMARKUP_FIELD, replayMarkup.toJson()); + } + + return jsonObject; + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(METHOD_FIELD, PATH); + gen.writeNumberField(CHATID_FIELD, chatId); + gen.writeNumberField(LATITUDE_FIELD, latitude); + gen.writeNumberField(LONGITUDE_FIELD, longitude); + if (replayToMessageId != null) { + gen.writeNumberField(REPLYTOMESSAGEID_FIELD, replayToMessageId); + } + if (replayMarkup != null) { + gen.writeObjectField(REPLYMARKUP_FIELD, replayMarkup); + } + + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeStringField(METHOD_FIELD, PATH); + gen.writeNumberField(CHATID_FIELD, chatId); + gen.writeNumberField(LATITUDE_FIELD, latitude); + gen.writeNumberField(LONGITUDE_FIELD, longitude); + if (replayToMessageId != null) { + gen.writeNumberField(REPLYTOMESSAGEID_FIELD, replayToMessageId); + } + if (replayMarkup != null) { + gen.writeObjectField(REPLYMARKUP_FIELD, replayMarkup); + } + + gen.writeEndObject(); + gen.flush(); + } +} diff --git a/src/main/java/org/telegram/api/methods/SendMessage.java b/src/main/java/org/telegram/api/methods/SendMessage.java new file mode 100644 index 0000000..907dfa4 --- /dev/null +++ b/src/main/java/org/telegram/api/methods/SendMessage.java @@ -0,0 +1,168 @@ +package org.telegram.api.methods; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.json.JSONObject; +import org.telegram.api.objects.Message; +import org.telegram.api.objects.ReplyKeyboard; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief Use this method to send text messages. On success, the sent Message is returned. + * @date 20 of June of 2015 + */ +public class SendMessage extends BotApiMethod { + public static final String PATH = "sendmessage"; + + public static final String CHATID_FIELD = "chat_id"; + private Integer chatId; ///< Unique identifier for the message recepient — User or GroupChat id + public static final String TEXT_FIELD = "text"; + private String text; ///< Text of the message to be sent + public static final String PARSEMODE_FIELD = "parse_mode"; + private String parseMode; ///< Optional. Send Markdown, if you want Telegram apps to show bold, italic and URL text in your bot's message. + public static final String DISABLEWEBPAGEPREVIEW_FIELD = "disable_web_page_preview"; + private Boolean disableWebPagePreview; ///< Optional. Disables link previews for links in this message + public static final String REPLYTOMESSAGEID_FIELD = "reply_to_message_id"; + private Integer replayToMessageId; ///< Optional. If the message is a reply, ID of the original message + public static final String REPLYMARKUP_FIELD = "reply_markup"; + private ReplyKeyboard replayMarkup; ///< Optional. JSON-serialized object for a custom reply keyboard + + public SendMessage() { + super(); + } + + public Integer getChatId() { + return chatId; + } + + public void setChatId(Integer chatId) { + this.chatId = chatId; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public Integer getReplayToMessageId() { + return replayToMessageId; + } + + public void setReplayToMessageId(Integer replayToMessageId) { + this.replayToMessageId = replayToMessageId; + } + + public ReplyKeyboard getReplayMarkup() { + return replayMarkup; + } + + public void setReplayMarkup(ReplyKeyboard replayMarkup) { + this.replayMarkup = replayMarkup; + } + + public Boolean getDisableWebPagePreview() { + return disableWebPagePreview; + } + + public void setDisableWebPagePreview(Boolean disableWebPagePreview) { + this.disableWebPagePreview = disableWebPagePreview; + } + + public void enableMarkdown(boolean enable) { + if (enable) { + this.parseMode = "Markdown"; + } else { + this.parseMode = null; + } + } + + @Override + public JSONObject toJson() { + JSONObject jsonObject = new JSONObject(); + + jsonObject.put(CHATID_FIELD, chatId); + jsonObject.put(TEXT_FIELD, text); + if (parseMode != null) { + jsonObject.put(PARSEMODE_FIELD, parseMode); + } + if (disableWebPagePreview != null) { + jsonObject.put(DISABLEWEBPAGEPREVIEW_FIELD, disableWebPagePreview); + } + if (replayToMessageId != null) { + jsonObject.put(REPLYTOMESSAGEID_FIELD, replayToMessageId); + } + if (replayMarkup != null) { + jsonObject.put(REPLYMARKUP_FIELD, replayMarkup.toJson()); + } + + return jsonObject; + } + + @Override + public String getPath() { + return PATH; + } + + @Override + public Message deserializeResponse(JSONObject answer) { + if (answer.getBoolean("ok")) { + return new Message(answer.getJSONObject("result")); + } + return null; + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(METHOD_FIELD, PATH); + gen.writeNumberField(CHATID_FIELD, chatId); + gen.writeStringField(TEXT_FIELD, text); + + if (parseMode != null) { + gen.writeStringField(PARSEMODE_FIELD, parseMode); + } + if (disableWebPagePreview != null) { + gen.writeBooleanField(DISABLEWEBPAGEPREVIEW_FIELD, disableWebPagePreview); + } + if (replayToMessageId != null) { + gen.writeNumberField(REPLYTOMESSAGEID_FIELD, replayToMessageId); + } + if (replayMarkup != null) { + gen.writeObjectField(REPLYMARKUP_FIELD, replayMarkup); + } + + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeStringField(METHOD_FIELD, PATH); + gen.writeNumberField(CHATID_FIELD, chatId); + gen.writeStringField(TEXT_FIELD, text); + + if (parseMode != null) { + gen.writeStringField(PARSEMODE_FIELD, parseMode); + } + if (disableWebPagePreview != null) { + gen.writeBooleanField(DISABLEWEBPAGEPREVIEW_FIELD, disableWebPagePreview); + } + if (replayToMessageId != null) { + gen.writeNumberField(REPLYTOMESSAGEID_FIELD, replayToMessageId); + } + if (replayMarkup != null) { + gen.writeObjectField(REPLYMARKUP_FIELD, replayMarkup); + } + + gen.writeEndObject(); + gen.flush(); + } +} diff --git a/src/main/java/org/telegram/methods/SendPhoto.java b/src/main/java/org/telegram/api/methods/SendPhoto.java similarity index 96% rename from src/main/java/org/telegram/methods/SendPhoto.java rename to src/main/java/org/telegram/api/methods/SendPhoto.java index 82b4ed0..06adc91 100644 --- a/src/main/java/org/telegram/methods/SendPhoto.java +++ b/src/main/java/org/telegram/api/methods/SendPhoto.java @@ -1,6 +1,6 @@ -package org.telegram.methods; +package org.telegram.api.methods; -import org.telegram.api.ReplyKeyboard; +import org.telegram.api.objects.ReplyKeyboard; /** * @author Ruben Bermudez diff --git a/src/main/java/org/telegram/methods/SendSticker.java b/src/main/java/org/telegram/api/methods/SendSticker.java similarity index 96% rename from src/main/java/org/telegram/methods/SendSticker.java rename to src/main/java/org/telegram/api/methods/SendSticker.java index 3b703ee..77d7f39 100644 --- a/src/main/java/org/telegram/methods/SendSticker.java +++ b/src/main/java/org/telegram/api/methods/SendSticker.java @@ -1,6 +1,6 @@ -package org.telegram.methods; +package org.telegram.api.methods; -import org.telegram.api.ReplyKeyboard; +import org.telegram.api.objects.ReplyKeyboard; /** * @author Ruben Bermudez diff --git a/src/main/java/org/telegram/methods/SendVideo.java b/src/main/java/org/telegram/api/methods/SendVideo.java similarity index 97% rename from src/main/java/org/telegram/methods/SendVideo.java rename to src/main/java/org/telegram/api/methods/SendVideo.java index 5b6e7bd..98b7593 100644 --- a/src/main/java/org/telegram/methods/SendVideo.java +++ b/src/main/java/org/telegram/api/methods/SendVideo.java @@ -1,6 +1,6 @@ -package org.telegram.methods; +package org.telegram.api.methods; -import org.telegram.api.ReplyKeyboard; +import org.telegram.api.objects.ReplyKeyboard; /** * @author Ruben Bermudez diff --git a/src/main/java/org/telegram/methods/SendVoice.java b/src/main/java/org/telegram/api/methods/SendVoice.java similarity index 94% rename from src/main/java/org/telegram/methods/SendVoice.java rename to src/main/java/org/telegram/api/methods/SendVoice.java index 4f07500..9e9a225 100644 --- a/src/main/java/org/telegram/methods/SendVoice.java +++ b/src/main/java/org/telegram/api/methods/SendVoice.java @@ -1,6 +1,6 @@ -package org.telegram.methods; +package org.telegram.api.methods; -import org.telegram.api.ReplyKeyboard; +import org.telegram.api.objects.ReplyKeyboard; /** * @author Ruben Bermudez diff --git a/src/main/java/org/telegram/api/methods/SetWebhook.java b/src/main/java/org/telegram/api/methods/SetWebhook.java new file mode 100644 index 0000000..5da3ab5 --- /dev/null +++ b/src/main/java/org/telegram/api/methods/SetWebhook.java @@ -0,0 +1,39 @@ +package org.telegram.api.methods; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief Use this method to specify a url and receive incoming updates via an outgoing webhook. + * Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url, + * containing a JSON-serialized Update. In case of an unsuccessful request, + * we will give up after a reasonable amount of attempts. + * @date 20 of June of 2015 + */ +public class SetWebhook { + public static final String PATH = "setwebhook"; + + public static final String URL_FIELD = "url"; + private String url; ///< Optional. HTTPS url to send updates to. Use an empty string to remove webhook integration + public static final String CERTIFICATE_FIELD = "certificate"; + private String certificateFile; ///< Optional. Upload your public key certificate so that the root certificate in use can be checked + + public SetWebhook() { + this.url = ""; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getCertificateFile() { + return certificateFile; + } + + public void setCertificateFile(String certificateFile) { + this.certificateFile = certificateFile; + } +} diff --git a/src/main/java/org/telegram/api/Audio.java b/src/main/java/org/telegram/api/objects/Audio.java similarity index 51% rename from src/main/java/org/telegram/api/Audio.java rename to src/main/java/org/telegram/api/objects/Audio.java index 21cbb29..54fa19a 100644 --- a/src/main/java/org/telegram/api/Audio.java +++ b/src/main/java/org/telegram/api/objects/Audio.java @@ -1,7 +1,13 @@ -package org.telegram.api; +package org.telegram.api.objects; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import org.json.JSONObject; +import org.telegram.api.interfaces.BotApiObject; + +import java.io.IOException; /** * @author Ruben Bermudez @@ -9,7 +15,7 @@ import org.json.JSONObject; * @brief This object represents an audio file * @date 16 of July of 2015 */ -public class Audio { +public class Audio implements BotApiObject { public static final String FILEID_FIELD = "file_id"; @JsonProperty(FILEID_FIELD) @@ -38,10 +44,18 @@ public class Audio { super(); this.fileId = jsonObject.getString(FILEID_FIELD); this.duration = jsonObject.getInt(DURATION_FIELD); - this.mimeType = jsonObject.optString(MIMETYPE_FIELD, ""); - this.fileSize = jsonObject.optInt(FILESIZE_FIELD, 0); - this.title = jsonObject.optString(TITLE_FIELD, ""); - this.performer = jsonObject.optString(PERFORMER_FIELD, ""); + if (jsonObject.has(MIMETYPE_FIELD)) { + this.mimeType = jsonObject.getString(MIMETYPE_FIELD); + } + if (jsonObject.has(FILEID_FIELD)) { + this.fileSize = jsonObject.getInt(FILESIZE_FIELD); + } + if (jsonObject.has(TITLE_FIELD)) { + this.title = jsonObject.getString(TITLE_FIELD); + } + if (jsonObject.has(PERFORMER_FIELD)) { + this.performer = jsonObject.getString(PERFORMER_FIELD); + } } public String getFileId() { @@ -91,4 +105,46 @@ public class Audio { public void setPerformer(String performer) { this.performer = performer; } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(FILEID_FIELD, fileId); + gen.writeNumberField(DURATION_FIELD, duration); + if (mimeType != null) { + gen.writeStringField(MIMETYPE_FIELD, mimeType); + } + if (fileSize != null) { + gen.writeNumberField(FILESIZE_FIELD, fileSize); + } + if (title != null) { + gen.writeStringField(TITLE_FIELD, title); + } + if (performer != null) { + gen.writeStringField(PERFORMER_FIELD, performer); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeStringField(FILEID_FIELD, fileId); + gen.writeNumberField(DURATION_FIELD, duration); + if (mimeType != null) { + gen.writeStringField(MIMETYPE_FIELD, mimeType); + } + if (fileSize != null) { + gen.writeNumberField(FILESIZE_FIELD, fileSize); + } + if (title != null) { + gen.writeStringField(TITLE_FIELD, title); + } + if (performer != null) { + gen.writeStringField(PERFORMER_FIELD, performer); + } + gen.writeEndObject(); + gen.flush(); + } } diff --git a/src/main/java/org/telegram/api/Chat.java b/src/main/java/org/telegram/api/objects/Chat.java similarity index 51% rename from src/main/java/org/telegram/api/Chat.java rename to src/main/java/org/telegram/api/objects/Chat.java index 2c05947..7e2e6a2 100644 --- a/src/main/java/org/telegram/api/Chat.java +++ b/src/main/java/org/telegram/api/objects/Chat.java @@ -1,7 +1,13 @@ -package org.telegram.api; +package org.telegram.api.objects; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import org.json.JSONObject; +import org.telegram.api.interfaces.BotApiObject; + +import java.io.IOException; /** * @author Ruben Bermudez @@ -9,11 +15,14 @@ import org.json.JSONObject; * @brief This object represents a Telegram chat with an user or a group * @date 24 of June of 2015 */ -public class Chat { +public class Chat implements BotApiObject { public static final String ID_FIELD = "id"; @JsonProperty(ID_FIELD) private Integer id; ///< Unique identifier for this chat + public static final String TITLE_FIELD = "title"; + @JsonProperty(TITLE_FIELD) + private String title; ///< Group name public static final String FIRSTNAME_FIELD = "first_name"; @JsonProperty(FIRSTNAME_FIELD) private String firstName; ///< User‘s or bot’s first name @@ -23,9 +32,6 @@ public class Chat { public static final String USERNAME_FIELD = "username"; @JsonProperty(USERNAME_FIELD) private String userName; ///< Optional. User‘s or bot’s username - public static final String TITLE_FIELD = "title"; - @JsonProperty(TITLE_FIELD) - private String title; ///< Group name public Chat() { super(); @@ -36,8 +42,12 @@ public class Chat { this.id = jsonObject.getInt(ID_FIELD); if (this.id > 0) { this.firstName = jsonObject.getString(FIRSTNAME_FIELD); - this.lastName = jsonObject.optString(LASTNAME_FIELD, ""); - this.userName = jsonObject.optString(USERNAME_FIELD, ""); + if (jsonObject.has(LASTNAME_FIELD)) { + this.lastName = jsonObject.getString(LASTNAME_FIELD); + } + if (jsonObject.has(USERNAME_FIELD)) { + this.userName = jsonObject.getString(USERNAME_FIELD); + } } else { this.title = jsonObject.getString(TITLE_FIELD); } @@ -70,4 +80,34 @@ public class Chat { public String getUserName() { return userName; } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeNumberField(ID_FIELD, id); + if (id > 0) { + gen.writeStringField(FIRSTNAME_FIELD, firstName); + gen.writeStringField(LASTNAME_FIELD, lastName); + gen.writeStringField(USERNAME_FIELD, userName); + } else { + gen.writeStringField(TITLE_FIELD, title); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeNumberField(ID_FIELD, id); + if (id > 0) { + gen.writeStringField(FIRSTNAME_FIELD, firstName); + gen.writeStringField(LASTNAME_FIELD, lastName); + gen.writeStringField(USERNAME_FIELD, userName); + } else { + gen.writeStringField(TITLE_FIELD, title); + } + gen.writeEndObject(); + gen.flush(); + } } diff --git a/src/main/java/org/telegram/api/objects/Contact.java b/src/main/java/org/telegram/api/objects/Contact.java new file mode 100644 index 0000000..7c0b4d0 --- /dev/null +++ b/src/main/java/org/telegram/api/objects/Contact.java @@ -0,0 +1,78 @@ +package org.telegram.api.objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.json.JSONObject; +import org.telegram.api.interfaces.BotApiObject; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief This object represents a phone contact. + * @date 20 of June of 2015 + */ +public class Contact implements BotApiObject { + + public static final String PHONENUMBER_FIELD = "phone_number"; + @JsonProperty(PHONENUMBER_FIELD) + private String phoneNumber; ///< Contact's phone number + public static final String FIRSTNAME_FIELD = "first_name"; + @JsonProperty(FIRSTNAME_FIELD) + private String firstName; ///< Contact's first name + public static final String LASTNAME_FIELD = "last_name"; + @JsonProperty(LASTNAME_FIELD) + private String lastName; ///< Optional. Contact's last name + public static final String USERID_FIELD = "user_id"; + @JsonProperty(USERID_FIELD) + private Integer userID; ///< Optional. Contact's user identifier in Telegram + + public Contact() { + super(); + } + + public Contact(JSONObject jsonObject) { + super(); + this.phoneNumber = jsonObject.getString(PHONENUMBER_FIELD); + this.firstName = jsonObject.getString(FIRSTNAME_FIELD); + if (jsonObject.has(LASTNAME_FIELD)) { + this.lastName = jsonObject.getString(LASTNAME_FIELD); + } + if (jsonObject.has(USERID_FIELD)) { + this.userID = jsonObject.getInt(USERID_FIELD); + } + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(PHONENUMBER_FIELD, phoneNumber); + gen.writeStringField(FIRSTNAME_FIELD, firstName); + if (lastName != null) { + gen.writeStringField(LASTNAME_FIELD, lastName); + } + if (userID != null) { + gen.writeNumberField(USERID_FIELD, userID); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeStringField(PHONENUMBER_FIELD, phoneNumber); + gen.writeStringField(FIRSTNAME_FIELD, firstName); + if (lastName != null) { + gen.writeStringField(LASTNAME_FIELD, lastName); + } + if (userID != null) { + gen.writeNumberField(USERID_FIELD, userID); + } + gen.writeEndObject(); + gen.flush(); + } +} diff --git a/src/main/java/org/telegram/api/Document.java b/src/main/java/org/telegram/api/objects/Document.java similarity index 53% rename from src/main/java/org/telegram/api/Document.java rename to src/main/java/org/telegram/api/objects/Document.java index 23274c3..c6d0af1 100644 --- a/src/main/java/org/telegram/api/Document.java +++ b/src/main/java/org/telegram/api/objects/Document.java @@ -1,7 +1,13 @@ -package org.telegram.api; +package org.telegram.api.objects; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import org.json.JSONObject; +import org.telegram.api.interfaces.BotApiObject; + +import java.io.IOException; /** * @author Ruben Bermudez @@ -10,7 +16,7 @@ import org.json.JSONObject; * Telegram users can send files of any type of up to 1.5 GB in size. * @date 20 of June of 2015 */ -public class Document { +public class Document implements BotApiObject { public static final String FILEID_FIELD = "file_id"; @JsonProperty(FILEID_FIELD) @@ -37,12 +43,15 @@ public class Document { if (jsonObject.has(THUMB_FIELD)) { this.thumb = new PhotoSize(jsonObject.getJSONObject(THUMB_FIELD)); } - else { - this.thumb = null; + if (jsonObject.has(FILENAME_FIELD)) { + this.fileName = jsonObject.getString(FILENAME_FIELD); + } + if (jsonObject.has(MIMETYPE_FIELD)) { + this.mimeType = jsonObject.getString(MIMETYPE_FIELD); + } + if (jsonObject.has(FILESIZE_FIELD)) { + this.fileSize = jsonObject.getInt(FILESIZE_FIELD); } - this.fileName = jsonObject.optString(FILENAME_FIELD, ""); - this.mimeType = jsonObject.optString(MIMETYPE_FIELD, ""); - this.fileSize = jsonObject.optInt(FILESIZE_FIELD, 0); } public String getFileId() { @@ -84,4 +93,40 @@ public class Document { public void setFileSize(Integer fileSize) { this.fileSize = fileSize; } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(FILEID_FIELD, fileId); + gen.writeObjectField(THUMB_FIELD, thumb); + if (fileName != null) { + gen.writeStringField(FILENAME_FIELD, fileName); + } + if (mimeType != null) { + gen.writeStringField(MIMETYPE_FIELD, mimeType); + } + if (fileSize != null) { + gen.writeNumberField(FILESIZE_FIELD, fileSize); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeStringField(FILEID_FIELD, fileId); + gen.writeObjectField(THUMB_FIELD, thumb); + if (fileName != null) { + gen.writeStringField(FILENAME_FIELD, fileName); + } + if (mimeType != null) { + gen.writeStringField(MIMETYPE_FIELD, mimeType); + } + if (fileSize != null) { + gen.writeNumberField(FILESIZE_FIELD, fileSize); + } + gen.writeEndObject(); + gen.flush(); + } } diff --git a/src/main/java/org/telegram/api/objects/File.java b/src/main/java/org/telegram/api/objects/File.java new file mode 100644 index 0000000..1f20cc1 --- /dev/null +++ b/src/main/java/org/telegram/api/objects/File.java @@ -0,0 +1,95 @@ +package org.telegram.api.objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.json.JSONObject; +import org.telegram.api.interfaces.BotApiObject; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief This object represents a file ready to be downloaded + * @date 24 of June of 2015 + */ +public class File implements BotApiObject { + public static final String FILE_ID = "file_id"; + @JsonProperty(FILE_ID) + private String fileId; ///< Unique identifier for this file + public static final String FILE_SIZE_FIELD = "file_size"; + @JsonProperty(FILE_SIZE_FIELD) + private Integer fileSize; ///< Optional. File size, if known + public static final String FILE_PATH_FIELD = "first_name"; + @JsonProperty(FILE_PATH_FIELD) + private String filePath; ///< Optional. File path. Use https://api.telegram.org/file/bot/ to get the file. + + public File() { + super(); + } + + public File(JSONObject jsonObject) { + super(); + this.fileId = jsonObject.getString(FILE_ID); + if (jsonObject.has(FILE_SIZE_FIELD)) { + this.fileSize = jsonObject.getInt(FILE_SIZE_FIELD); + } + if (jsonObject.has(FILE_PATH_FIELD)) { + this.filePath = jsonObject.getString(FILE_PATH_FIELD); + } + } + + public String getFileId() { + return fileId; + } + + public void setFileId(String fileId) { + this.fileId = fileId; + } + + public Integer getFileSize() { + return fileSize; + } + + public void setFileSize(Integer fileSize) { + this.fileSize = fileSize; + } + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(FILE_ID, fileId); + if (fileSize != null) { + gen.writeNumberField(FILE_SIZE_FIELD, fileSize); + } + if (filePath != null) { + gen.writeStringField(FILE_PATH_FIELD, filePath); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeStringField(FILE_ID, fileId); + if (fileSize != null) { + gen.writeNumberField(FILE_SIZE_FIELD, fileSize); + } + if (filePath != null) { + gen.writeStringField(FILE_PATH_FIELD, filePath); + } + gen.writeEndObject(); + gen.flush(); + } +} diff --git a/src/main/java/org/telegram/api/ForceReplyKeyboard.java b/src/main/java/org/telegram/api/objects/ForceReplyKeyboard.java similarity index 63% rename from src/main/java/org/telegram/api/ForceReplyKeyboard.java rename to src/main/java/org/telegram/api/objects/ForceReplyKeyboard.java index 6c7ec94..d7c41e5 100644 --- a/src/main/java/org/telegram/api/ForceReplyKeyboard.java +++ b/src/main/java/org/telegram/api/objects/ForceReplyKeyboard.java @@ -1,8 +1,13 @@ -package org.telegram.api; +package org.telegram.api.objects; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import org.json.JSONObject; +import java.io.IOException; + /** * @author Ruben Bermudez * @version 1.0 @@ -37,8 +42,12 @@ public class ForceReplyKeyboard implements ReplyKeyboard { public ForceReplyKeyboard(JSONObject jsonObject) { super(); - this.forceReply = jsonObject.optBoolean(FORCEREPLY_FIELD, true); - this.selective = jsonObject.optBoolean(SELECTIVE_FIELD, false); + if (jsonObject.has(FORCEREPLY_FIELD)) { + this.forceReply = jsonObject.getBoolean(FORCEREPLY_FIELD); + } + if (jsonObject.has(SELECTIVE_FIELD)) { + this.selective = jsonObject.getBoolean(SELECTIVE_FIELD); + } } public Boolean getForceReply() { @@ -68,4 +77,22 @@ public class ForceReplyKeyboard implements ReplyKeyboard { return jsonObject; } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeBooleanField(FORCEREPLY_FIELD, forceReply); + gen.writeBooleanField(SELECTIVE_FIELD, selective); + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeBooleanField(FORCEREPLY_FIELD, forceReply); + gen.writeBooleanField(SELECTIVE_FIELD, selective); + gen.writeEndObject(); + gen.flush(); + } } diff --git a/src/main/java/org/telegram/api/Location.java b/src/main/java/org/telegram/api/objects/Location.java similarity index 52% rename from src/main/java/org/telegram/api/Location.java rename to src/main/java/org/telegram/api/objects/Location.java index 42a5c3e..bf1a63b 100644 --- a/src/main/java/org/telegram/api/Location.java +++ b/src/main/java/org/telegram/api/objects/Location.java @@ -1,7 +1,13 @@ -package org.telegram.api; +package org.telegram.api.objects; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import org.json.JSONObject; +import org.telegram.api.interfaces.BotApiObject; + +import java.io.IOException; /** * @author Ruben Bermudez @@ -9,7 +15,7 @@ import org.json.JSONObject; * @brief This object represents a point on the map. * @date 20 of June of 2015 */ -public class Location { +public class Location implements BotApiObject { public static final String LONGITUDE_FIELD = "longitude"; @JsonProperty(LONGITUDE_FIELD) @@ -43,4 +49,22 @@ public class Location { public void setLatitude(Double latitude) { this.latitude = latitude; } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeNumberField(LONGITUDE_FIELD, longitude); + gen.writeNumberField(LATITUDE_FIELD, latitude); + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeNumberField(LONGITUDE_FIELD, longitude); + gen.writeNumberField(LATITUDE_FIELD, latitude); + gen.writeEndObject(); + gen.flush(); + } } diff --git a/src/main/java/org/telegram/api/Message.java b/src/main/java/org/telegram/api/objects/Message.java similarity index 66% rename from src/main/java/org/telegram/api/Message.java rename to src/main/java/org/telegram/api/objects/Message.java index 2321ca1..e6e66b7 100644 --- a/src/main/java/org/telegram/api/Message.java +++ b/src/main/java/org/telegram/api/objects/Message.java @@ -1,9 +1,14 @@ -package org.telegram.api; +package org.telegram.api.objects; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import org.json.JSONArray; import org.json.JSONObject; +import org.telegram.api.interfaces.BotApiObject; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -13,7 +18,7 @@ import java.util.List; * @brief This object represents a message. * @date 20 of June of 2015 */ -public class Message { +public class Message implements BotApiObject { public static final String MESSAGEID_FIELD = "message_id"; @JsonProperty(MESSAGEID_FIELD) private Integer messageId; ///< Integer Unique message identifier @@ -110,8 +115,8 @@ public class Message { if (jsonObject.has(DOCUMENT_FIELD)) { this.document = new Document(jsonObject.getJSONObject(DOCUMENT_FIELD)); } - this.photo = new ArrayList<>(); if (jsonObject.has(PHOTO_FIELD)) { + this.photo = new ArrayList<>(); JSONArray photos = jsonObject.getJSONArray(PHOTO_FIELD); for (int i = 0; i < photos.length(); i++) { this.photo.add(new PhotoSize(photos.getJSONObject(i))); @@ -141,7 +146,9 @@ public class Message { if (jsonObject.has(REPLYTOMESSAGE_FIELD)) { this.replyToMessage = new Message(jsonObject.getJSONObject(REPLYTOMESSAGE_FIELD)); } - this.newChatTitle = jsonObject.optString(NEWCHATTITLE_FIELD, ""); + if (jsonObject.has(NEWCHATTITLE_FIELD)) { + this.newChatTitle = jsonObject.getString(NEWCHATTITLE_FIELD); + } if (jsonObject.has(NEWCHATPHOTO_FIELD)) { JSONArray photoArray = jsonObject.getJSONArray(NEWCHATPHOTO_FIELD); this.newChatPhoto = new ArrayList<>(); @@ -149,8 +156,12 @@ public class Message { this.newChatPhoto.add(new PhotoSize(photoArray.getJSONObject(i))); } } - this.deleteChatPhoto = jsonObject.optBoolean(DELETECHATPHOTO_FIELD, false); - this.groupchatCreated = jsonObject.optBoolean(GROUPCHATCREATED_FIELD, false); + if (jsonObject.has(DELETECHATPHOTO_FIELD)) { + this.deleteChatPhoto = jsonObject.getBoolean(DELETECHATPHOTO_FIELD); + } + if (jsonObject.has(GROUPCHATCREATED_FIELD)) { + this.groupchatCreated = jsonObject.getBoolean(GROUPCHATCREATED_FIELD); + } } public Integer getMessageId() { @@ -356,4 +367,148 @@ public class Message { public void setVoice(Voice voice) { this.voice = voice; } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + + gen.writeNumberField(MESSAGEID_FIELD, messageId); + gen.writeObjectField(FROM_FIELD, from); + gen.writeNumberField(DATE_FIELD, date); + gen.writeObjectField(CHAT_FIELD, chat); + + if (forwardFrom != null) { + gen.writeObjectField(FORWARDFROM_FIELD, forwardFrom); + } + if (forwardDate != null) { + gen.writeNumberField(FORWARDDATE_FIELD, forwardDate); + } + if (text != null) { + gen.writeStringField(TEXT_FIELD, text); + } + if (audio != null) { + gen.writeObjectField(AUDIO_FIELD, audio); + } + if (document != null) { + gen.writeObjectField(DOCUMENT_FIELD, document); + } + if (photo != null && photo.size() > 0) { + gen.writeArrayFieldStart(PHOTO_FIELD); + for (PhotoSize photoSize : photo) { + gen.writeObject(photoSize); + } + gen.writeEndArray(); + } + if (sticker != null) { + gen.writeObjectField(STICKER_FIELD, sticker); + } + if (video != null) { + gen.writeObjectField(VIDEO_FIELD, video); + } + if (contact != null) { + gen.writeObjectField(CONTACT_FIELD, contact); + } + if (location != null) { + gen.writeObjectField(LOCATION_FIELD, location); + } + if (voice != null) { + gen.writeObjectField(VOICE_FIELD, voice); + } + if (newChatParticipant != null) { + gen.writeObjectField(NEWCHATPARTICIPANT_FIELD, newChatParticipant); + } + if (leftChatParticipant != null) { + gen.writeObjectField(LEFTCHATPARTICIPANT_FIELD, leftChatParticipant); + } + if (replyToMessage != null) { + gen.writeObjectField(REPLYTOMESSAGE_FIELD, replyToMessage); + } + if (newChatTitle != null) { + gen.writeStringField(NEWCHATTITLE_FIELD, newChatTitle); + } + if (newChatPhoto != null && newChatPhoto.size() > 0) { + gen.writeArrayFieldStart(NEWCHATPHOTO_FIELD); + for (PhotoSize photoSize: newChatPhoto) { + gen.writeObject(photoSize); + } + gen.writeEndArray(); + } + if (deleteChatPhoto != null) { + gen.writeBooleanField(DELETECHATPHOTO_FIELD, deleteChatPhoto); + } + if (groupchatCreated != null) { + gen.writeBooleanField(GROUPCHATCREATED_FIELD, groupchatCreated); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + if (forwardFrom != null) { + gen.writeObjectField(FORWARDFROM_FIELD, forwardFrom); + } + if (forwardDate != null) { + gen.writeNumberField(FORWARDDATE_FIELD, forwardDate); + } + if (text != null) { + gen.writeStringField(TEXT_FIELD, text); + } + if (audio != null) { + gen.writeObjectField(AUDIO_FIELD, audio); + } + if (document != null) { + gen.writeObjectField(DOCUMENT_FIELD, document); + } + if (photo != null && photo.size() > 0) { + gen.writeArrayFieldStart(PHOTO_FIELD); + for (PhotoSize photoSize : photo) { + gen.writeObject(photoSize); + } + gen.writeEndArray(); + } + if (sticker != null) { + gen.writeObjectField(STICKER_FIELD, sticker); + } + if (video != null) { + gen.writeObjectField(VIDEO_FIELD, video); + } + if (contact != null) { + gen.writeObjectField(CONTACT_FIELD, contact); + } + if (location != null) { + gen.writeObjectField(LOCATION_FIELD, location); + } + if (voice != null) { + gen.writeObjectField(VOICE_FIELD, voice); + } + if (newChatParticipant != null) { + gen.writeObjectField(NEWCHATPARTICIPANT_FIELD, newChatParticipant); + } + if (leftChatParticipant != null) { + gen.writeObjectField(LEFTCHATPARTICIPANT_FIELD, leftChatParticipant); + } + if (replyToMessage != null) { + gen.writeObjectField(REPLYTOMESSAGE_FIELD, replyToMessage); + } + if (newChatTitle != null) { + gen.writeStringField(NEWCHATTITLE_FIELD, newChatTitle); + } + if (newChatPhoto != null && newChatPhoto.size() > 0) { + gen.writeArrayFieldStart(NEWCHATPHOTO_FIELD); + for (PhotoSize photoSize: newChatPhoto) { + gen.writeObject(photoSize); + } + gen.writeEndArray(); + } + if (deleteChatPhoto != null) { + gen.writeBooleanField(DELETECHATPHOTO_FIELD, deleteChatPhoto); + } + if (groupchatCreated != null) { + gen.writeBooleanField(GROUPCHATCREATED_FIELD, groupchatCreated); + } + gen.writeEndObject(); + gen.flush(); + + } } diff --git a/src/main/java/org/telegram/api/objects/PhotoSize.java b/src/main/java/org/telegram/api/objects/PhotoSize.java new file mode 100644 index 0000000..888616e --- /dev/null +++ b/src/main/java/org/telegram/api/objects/PhotoSize.java @@ -0,0 +1,104 @@ +package org.telegram.api.objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.json.JSONObject; +import org.telegram.api.interfaces.BotApiObject; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief This object represents one size of a photo or a file / sticker thumbnail. + * @date 20 of June of 2015 + */ +public class PhotoSize implements BotApiObject { + + public static final String FILEID_FIELD = "file_id"; + @JsonProperty(FILEID_FIELD) + private String fileId; ///< Unique identifier for this file + public static final String WIDTH_FIELD = "width"; + @JsonProperty(WIDTH_FIELD) + private Integer width; ///< Photo width + public static final String HEIGHT_FIELD = "height"; + @JsonProperty(HEIGHT_FIELD) + private Integer height; ///< Photo height + public static final String FILESIZE_FIELD = "file_size"; + @JsonProperty(FILESIZE_FIELD) + private Integer fileSize; ///< Optional. File size + + public PhotoSize() { + super(); + } + + public PhotoSize(JSONObject jsonObject) { + super(); + this.fileId = jsonObject.getString(FILEID_FIELD); + this.width = jsonObject.getInt(WIDTH_FIELD); + this.height = jsonObject.getInt(HEIGHT_FIELD); + if (jsonObject.has(FILESIZE_FIELD)) { + this.fileSize = jsonObject.getInt(FILESIZE_FIELD); + } + } + + public String getFileId() { + return fileId; + } + + public void setFileId(String fileId) { + this.fileId = fileId; + } + + public Integer getWidth() { + return width; + } + + public void setWidth(Integer width) { + this.width = width; + } + + public Integer getHeight() { + return height; + } + + public void setHeight(Integer height) { + this.height = height; + } + + public Integer getFileSize() { + return fileSize; + } + + public void setFileSize(Integer fileSize) { + this.fileSize = fileSize; + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(FILEID_FIELD, fileId); + gen.writeNumberField(WIDTH_FIELD, width); + gen.writeNumberField(HEIGHT_FIELD, height); + if (fileSize != null) { + gen.writeNumberField(FILESIZE_FIELD, fileSize); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeStringField(FILEID_FIELD, fileId); + gen.writeNumberField(WIDTH_FIELD, width); + gen.writeNumberField(HEIGHT_FIELD, height); + if (fileSize != null) { + gen.writeNumberField(FILESIZE_FIELD, fileSize); + } + gen.writeEndObject(); + gen.flush(); + } +} diff --git a/src/main/java/org/telegram/api/objects/ReplyKeyboard.java b/src/main/java/org/telegram/api/objects/ReplyKeyboard.java new file mode 100644 index 0000000..3e742a2 --- /dev/null +++ b/src/main/java/org/telegram/api/objects/ReplyKeyboard.java @@ -0,0 +1,13 @@ +package org.telegram.api.objects; + +import org.telegram.api.interfaces.BotApiObject; +import org.telegram.api.interfaces.IToJson; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief Reply keyboard abstract type + * @date 20 of June of 2015 + */ +public interface ReplyKeyboard extends BotApiObject, IToJson { +} diff --git a/src/main/java/org/telegram/api/ReplyKeyboardHide.java b/src/main/java/org/telegram/api/objects/ReplyKeyboardHide.java similarity index 60% rename from src/main/java/org/telegram/api/ReplyKeyboardHide.java rename to src/main/java/org/telegram/api/objects/ReplyKeyboardHide.java index 76afe22..0f40d43 100644 --- a/src/main/java/org/telegram/api/ReplyKeyboardHide.java +++ b/src/main/java/org/telegram/api/objects/ReplyKeyboardHide.java @@ -1,8 +1,13 @@ -package org.telegram.api; +package org.telegram.api.objects; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import org.json.JSONObject; +import java.io.IOException; + /** * @author Ruben Bermudez * @version 1.0 @@ -13,7 +18,7 @@ import org.json.JSONObject; * (@see ReplyKeyboardMarkup). * @date 20 of June of 2015 */ -public class ReplyKeyboardHide implements ReplyKeyboard{ +public class ReplyKeyboardHide implements ReplyKeyboard { public static final String HIDEKEYBOARD_FIELD = "hide_keyboard"; @JsonProperty(HIDEKEYBOARD_FIELD) @@ -35,8 +40,12 @@ public class ReplyKeyboardHide implements ReplyKeyboard{ public ReplyKeyboardHide(JSONObject jsonObject) { super(); - this.hideKeyboard = jsonObject.optBoolean(HIDEKEYBOARD_FIELD, true); - this.selective = jsonObject.optBoolean(SELECTIVE_FIELD, true); + if (jsonObject.has(HIDEKEYBOARD_FIELD)) { + this.hideKeyboard = jsonObject.getBoolean(HIDEKEYBOARD_FIELD); + } + if (jsonObject.has(SELECTIVE_FIELD)) { + this.selective = jsonObject.getBoolean(SELECTIVE_FIELD); + } } public Boolean getHideKeyboard() { @@ -63,4 +72,21 @@ public class ReplyKeyboardHide implements ReplyKeyboard{ return jsonObject; } + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeBooleanField(HIDEKEYBOARD_FIELD, hideKeyboard); + gen.writeBooleanField(SELECTIVE_FIELD, selective); + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeBooleanField(HIDEKEYBOARD_FIELD, hideKeyboard); + gen.writeBooleanField(SELECTIVE_FIELD, selective); + gen.writeEndObject(); + gen.flush(); + } } diff --git a/src/main/java/org/telegram/api/ReplyKeyboardMarkup.java b/src/main/java/org/telegram/api/objects/ReplyKeyboardMarkup.java similarity index 61% rename from src/main/java/org/telegram/api/ReplyKeyboardMarkup.java rename to src/main/java/org/telegram/api/objects/ReplyKeyboardMarkup.java index c5aafee..eaaa2ed 100644 --- a/src/main/java/org/telegram/api/ReplyKeyboardMarkup.java +++ b/src/main/java/org/telegram/api/objects/ReplyKeyboardMarkup.java @@ -1,9 +1,13 @@ -package org.telegram.api; +package org.telegram.api.objects; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import org.json.JSONArray; import org.json.JSONObject; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -50,9 +54,15 @@ public class ReplyKeyboardMarkup implements ReplyKeyboard { } this.keyboard.add(row); } - this.resizeKeyboard = jsonObject.optBoolean(RESIZEKEYBOARD_FIELD, false); - this.oneTimeKeyboad = jsonObject.optBoolean(ONETIMEKEYBOARD_FIELD, false); - this.selective = jsonObject.optBoolean(SELECTIVE_FIELD, false); + if (jsonObject.has(RESIZEKEYBOARD_FIELD)) { + this.resizeKeyboard = jsonObject.getBoolean(RESIZEKEYBOARD_FIELD); + } + if (jsonObject.has(ONETIMEKEYBOARD_FIELD)) { + this.oneTimeKeyboad = jsonObject.getBoolean(ONETIMEKEYBOARD_FIELD); + } + if (jsonObject.has(SELECTIVE_FIELD)) { + this.selective = jsonObject.getBoolean(SELECTIVE_FIELD); + } } public List> getKeyboard() { @@ -113,4 +123,54 @@ public class ReplyKeyboardMarkup implements ReplyKeyboard { return jsonObject; } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeArrayFieldStart(KEYBOARD_FIELD); + for (List innerRow : keyboard) { + gen.writeStartArray(); + for (String element: innerRow) { + gen.writeString(element); + } + gen.writeEndArray(); + } + gen.writeEndArray(); + if (this.oneTimeKeyboad != null) { + gen.writeBooleanField(ONETIMEKEYBOARD_FIELD, oneTimeKeyboad); + } + if (this.resizeKeyboard != null) { + gen.writeBooleanField(RESIZEKEYBOARD_FIELD, resizeKeyboard); + } + if (this.selective != null) { + gen.writeBooleanField(SELECTIVE_FIELD, selective); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeArrayFieldStart(KEYBOARD_FIELD); + for (List innerRow : keyboard) { + gen.writeStartArray(); + for (String element: innerRow) { + gen.writeString(element); + } + gen.writeEndArray(); + } + gen.writeEndArray(); + if (this.oneTimeKeyboad != null) { + gen.writeBooleanField(ONETIMEKEYBOARD_FIELD, oneTimeKeyboad); + } + if (this.resizeKeyboard != null) { + gen.writeBooleanField(RESIZEKEYBOARD_FIELD, resizeKeyboard); + } + if (this.selective != null) { + gen.writeBooleanField(SELECTIVE_FIELD, selective); + } + gen.writeEndObject(); + gen.flush(); + } } diff --git a/src/main/java/org/telegram/api/objects/Sticker.java b/src/main/java/org/telegram/api/objects/Sticker.java new file mode 100644 index 0000000..01860ef --- /dev/null +++ b/src/main/java/org/telegram/api/objects/Sticker.java @@ -0,0 +1,84 @@ +package org.telegram.api.objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.json.JSONObject; +import org.telegram.api.interfaces.BotApiObject; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief This object represents a sticker. + * @date 20 of June of 2015 + */ +public class Sticker implements BotApiObject { + + public static final String FILEID_FIELD = "file_id"; + @JsonProperty(FILEID_FIELD) + private String fileId; ///< Unique identifier for this file + public static final String WIDTH_FIELD = "width"; + @JsonProperty(WIDTH_FIELD) + private Integer width; ///< Sticker width + public static final String HEIGHT_FIELD = "height"; + @JsonProperty(HEIGHT_FIELD) + private Integer height; ///< Sticker height + public static final String THUMB_FIELD = "thumb"; + @JsonProperty(THUMB_FIELD) + private PhotoSize thumb; ///< Optional. Sticker thumbnail in .webp or .jpg format + public static final String FILESIZE_FIELD = "file_size"; + @JsonProperty(FILESIZE_FIELD) + private Integer fileSize; ///< Optional. File size + + public Sticker() { + super(); + } + + public Sticker(JSONObject jsonObject) { + super(); + this.fileId = jsonObject.getString(FILEID_FIELD); + this.width = jsonObject.getInt(WIDTH_FIELD); + this.height = jsonObject.getInt(HEIGHT_FIELD); + if (jsonObject.has(THUMB_FIELD)) { + this.thumb = new PhotoSize(jsonObject.getJSONObject(THUMB_FIELD)); + } + if (jsonObject.has(FILESIZE_FIELD)) { + this.fileSize = jsonObject.getInt(FILESIZE_FIELD); + } + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(FILEID_FIELD, fileId); + gen.writeNumberField(WIDTH_FIELD, width); + gen.writeNumberField(HEIGHT_FIELD, height); + if (thumb != null) { + gen.writeObjectField(THUMB_FIELD, thumb); + } + if (fileSize != null) { + gen.writeNumberField(FILESIZE_FIELD, fileSize); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeStringField(FILEID_FIELD, fileId); + gen.writeNumberField(WIDTH_FIELD, width); + gen.writeNumberField(HEIGHT_FIELD, height); + if (thumb != null) { + gen.writeObjectField(THUMB_FIELD, thumb); + } + if (fileSize != null) { + gen.writeNumberField(FILESIZE_FIELD, fileSize); + } + gen.writeEndObject(); + gen.flush(); + } +} diff --git a/src/main/java/org/telegram/api/objects/Update.java b/src/main/java/org/telegram/api/objects/Update.java new file mode 100644 index 0000000..69d297d --- /dev/null +++ b/src/main/java/org/telegram/api/objects/Update.java @@ -0,0 +1,74 @@ +package org.telegram.api.objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.json.JSONObject; +import org.telegram.api.interfaces.BotApiObject; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief TODO + * @date 20 of June of 2015 + */ +public class Update implements BotApiObject { + public static final String UPDATEID_FIELD = "update_id"; + /** + * The update‘s unique identifier. + * Update identifiers start from a certain positive number and increase sequentially. + * This ID becomes especially handy if you’re using Webhooks, + * since it allows you to ignore repeated updates or to restore the + * correct update sequence, should they get out of order. + */ + @JsonProperty(UPDATEID_FIELD) + private Integer updateId; + public static final String MESSAGE_FIELD = "message"; + @JsonProperty(MESSAGE_FIELD) + private Message message; ///< Optional. New incoming message of any kind — text, photo, sticker, etc. + + public Update() { + super(); + } + + public Update(JSONObject jsonObject) { + super(); + this.updateId = jsonObject.getInt(UPDATEID_FIELD); + if (jsonObject.has(MESSAGE_FIELD)) { + this.message = new Message(jsonObject.getJSONObject(MESSAGE_FIELD)); + } + } + + public Integer getUpdateId() { + return updateId; + } + + public Message getMessage() { + return message; + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeNumberField(UPDATEID_FIELD, updateId); + if (message != null) { + gen.writeObjectField(MESSAGE_FIELD, message); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeNumberField(UPDATEID_FIELD, updateId); + if (message != null) { + gen.writeObjectField(MESSAGE_FIELD, message); + } + gen.writeEndObject(); + gen.flush(); + } +} diff --git a/src/main/java/org/telegram/api/objects/User.java b/src/main/java/org/telegram/api/objects/User.java new file mode 100644 index 0000000..a767af6 --- /dev/null +++ b/src/main/java/org/telegram/api/objects/User.java @@ -0,0 +1,94 @@ +package org.telegram.api.objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.json.JSONObject; +import org.telegram.api.interfaces.BotApiObject; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief This object represents a Telegram user or bot. + * @date 20 of June of 2015 + */ +public class User implements BotApiObject { + + public static final String ID_FIELD = "id"; + @JsonProperty(ID_FIELD) + private Integer id; ///< Unique identifier for this user or bot + public static final String FIRSTNAME_FIELD = "first_name"; + @JsonProperty(FIRSTNAME_FIELD) + private String firstName; ///< User‘s or bot’s first name + public static final String LASTNAME_FIELD = "last_name"; + @JsonProperty(LASTNAME_FIELD) + private String lastName; ///< Optional. User‘s or bot’s last name + public static final String USERNAME_FIELD = "username"; + @JsonProperty(USERNAME_FIELD) + private String userName; ///< Optional. User‘s or bot’s username + + public User() { + super(); + } + + public User(JSONObject jsonObject) { + super(); + this.id = jsonObject.getInt(ID_FIELD); + this.firstName = jsonObject.getString(FIRSTNAME_FIELD); + if (jsonObject.has(LASTNAME_FIELD)) { + this.lastName = jsonObject.getString(LASTNAME_FIELD); + } + if (jsonObject.has(USERNAME_FIELD)) { + this.userName = jsonObject.getString(USERNAME_FIELD); + } + } + + public Integer getId() { + return id; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + public String getUserName() { + return userName; + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeNumberField(ID_FIELD, id); + gen.writeStringField(FIRSTNAME_FIELD, firstName); + if (lastName != null) { + gen.writeStringField(LASTNAME_FIELD, lastName); + } + if (userName != null) { + gen.writeStringField(USERNAME_FIELD, userName); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeNumberField(ID_FIELD, id); + gen.writeStringField(FIRSTNAME_FIELD, firstName); + if (lastName != null) { + gen.writeStringField(LASTNAME_FIELD, lastName); + } + if (userName != null) { + gen.writeStringField(USERNAME_FIELD, userName); + } + gen.writeEndObject(); + gen.flush(); + } +} diff --git a/src/main/java/org/telegram/api/objects/UserProfilePhotos.java b/src/main/java/org/telegram/api/objects/UserProfilePhotos.java new file mode 100644 index 0000000..962e631 --- /dev/null +++ b/src/main/java/org/telegram/api/objects/UserProfilePhotos.java @@ -0,0 +1,104 @@ +package org.telegram.api.objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import org.json.JSONArray; +import org.json.JSONObject; +import org.telegram.api.interfaces.BotApiObject; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief This object represent a user's profile pictures. + * @date 22 of June of 2015 + */ +public class UserProfilePhotos implements BotApiObject { + + public static final String TOTALCOUNT_FIELD = "total_count"; + @JsonProperty(TOTALCOUNT_FIELD) + private Integer totalCount; ///< Total number of profile pictures the target user has + public static final String PHOTOS_FIELD = "photos"; + @JsonProperty(PHOTOS_FIELD) + private List> photos; ///< Requested profile pictures (in up to 4 sizes each) + + public UserProfilePhotos() { + super(); + } + + public UserProfilePhotos(JSONObject jsonObject) { + super(); + this.totalCount = jsonObject.getInt(TOTALCOUNT_FIELD); + if (totalCount > 0) { + this.photos = new ArrayList<>(); + JSONArray photos = jsonObject.getJSONArray(PHOTOS_FIELD); + for (int i = 0; i < photos.length(); i++) { + JSONArray innerArray = photos.getJSONArray(i); + List innerPhotos = new ArrayList<>(); + for (int j = 0; j < innerArray.length(); j++) { + innerPhotos.add(new PhotoSize(innerArray.getJSONObject(j))); + } + this.photos.add(innerPhotos); + } + } + } + + public Integer getTotalCount() { + return totalCount; + } + + public void setTotalCount(Integer totalCount) { + this.totalCount = totalCount; + } + + public List> getPhotos() { + return photos; + } + + public void setPhotos(List> photos) { + this.photos = photos; + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeNumberField(TOTALCOUNT_FIELD, totalCount); + if (totalCount > 0) { + gen.writeArrayFieldStart(PHOTOS_FIELD); + for (List photoSizeList : photos) { + gen.writeStartArray(); + for (PhotoSize photoSize: photoSizeList) { + gen.writeObject(photoSize); + } + gen.writeEndArray(); + } + gen.writeEndArray(); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeNumberField(TOTALCOUNT_FIELD, totalCount); + if (totalCount > 0) { + gen.writeArrayFieldStart(PHOTOS_FIELD); + for (List photoSizeList : photos) { + gen.writeStartArray(); + for (PhotoSize photoSize: photoSizeList) { + gen.writeObject(photoSize); + } + gen.writeEndArray(); + } + gen.writeEndArray(); + } + gen.writeEndObject(); + gen.flush(); + } +} diff --git a/src/main/java/org/telegram/api/Video.java b/src/main/java/org/telegram/api/objects/Video.java similarity index 58% rename from src/main/java/org/telegram/api/Video.java rename to src/main/java/org/telegram/api/objects/Video.java index a0a2607..dbd0f06 100644 --- a/src/main/java/org/telegram/api/Video.java +++ b/src/main/java/org/telegram/api/objects/Video.java @@ -1,7 +1,13 @@ -package org.telegram.api; +package org.telegram.api.objects; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import org.json.JSONObject; +import org.telegram.api.interfaces.BotApiObject; + +import java.io.IOException; /** * @author Ruben Bermudez @@ -9,7 +15,7 @@ import org.json.JSONObject; * @brief This object represents a video file. * @date 20 of June of 2015 */ -public class Video { +public class Video implements BotApiObject { public static final String FILEID_FIELD = "file_id"; @JsonProperty(FILEID_FIELD) @@ -44,11 +50,13 @@ public class Video { this.duration = jsonObject.getInt(DURATION_FIELD); if (jsonObject.has(THUMB_FIELD)) { this.thumb = new PhotoSize(jsonObject.getJSONObject(THUMB_FIELD)); - } else { - this.thumb = null; } - this.mimeType = jsonObject.optString(MIMETYPE_FIELD, ""); - this.fileSize = jsonObject.optInt(FILESIZE_FIELD, 0); + if (jsonObject.has(MIMETYPE_FIELD)) { + this.mimeType = jsonObject.getString(MIMETYPE_FIELD); + } + if (jsonObject.has(FILESIZE_FIELD)) { + this.fileSize = jsonObject.getInt(FILESIZE_FIELD); + } } public Integer getWidth() { @@ -106,4 +114,44 @@ public class Video { public void setFileSize(Integer fileSize) { this.fileSize = fileSize; } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(FILEID_FIELD, fileId); + gen.writeNumberField(WIDTH_FIELD, width); + gen.writeNumberField(HEIGHT_FIELD, height); + gen.writeNumberField(DURATION_FIELD, duration); + if (thumb != null) { + gen.writeObjectField(THUMB_FIELD, thumb); + } + if (mimeType != null) { + gen.writeStringField(MIMETYPE_FIELD, mimeType); + } + if (fileSize != null) { + gen.writeNumberField(FILESIZE_FIELD, fileSize); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeStringField(FILEID_FIELD, fileId); + gen.writeNumberField(WIDTH_FIELD, width); + gen.writeNumberField(HEIGHT_FIELD, height); + gen.writeNumberField(DURATION_FIELD, duration); + if (thumb != null) { + gen.writeObjectField(THUMB_FIELD, thumb); + } + if (mimeType != null) { + gen.writeStringField(MIMETYPE_FIELD, mimeType); + } + if (fileSize != null) { + gen.writeNumberField(FILESIZE_FIELD, fileSize); + } + gen.writeEndObject(); + gen.flush(); + } } diff --git a/src/main/java/org/telegram/api/Voice.java b/src/main/java/org/telegram/api/objects/Voice.java similarity index 51% rename from src/main/java/org/telegram/api/Voice.java rename to src/main/java/org/telegram/api/objects/Voice.java index d9f9949..ea01d3d 100644 --- a/src/main/java/org/telegram/api/Voice.java +++ b/src/main/java/org/telegram/api/objects/Voice.java @@ -1,7 +1,13 @@ -package org.telegram.api; +package org.telegram.api.objects; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import org.json.JSONObject; +import org.telegram.api.interfaces.BotApiObject; + +import java.io.IOException; /** * @author Ruben Bermudez @@ -9,7 +15,7 @@ import org.json.JSONObject; * @brief This object represents a voice note * @date 16 of July of 2015 */ -public class Voice { +public class Voice implements BotApiObject { public static final String FILEID_FIELD = "file_id"; @JsonProperty(FILEID_FIELD) private String fileId; ///< Unique identifier for this file @@ -31,8 +37,12 @@ public class Voice { super(); this.fileId = jsonObject.getString(FILEID_FIELD); this.duration = jsonObject.getInt(DURATION_FIELD); - this.mimeType = jsonObject.optString(MIMETYPE_FIELD, ""); - this.fileSize = jsonObject.optInt(FILESIZE_FIELD, 0); + if (jsonObject.has(MIMETYPE_FIELD)) { + this.mimeType = jsonObject.getString(MIMETYPE_FIELD); + } + if (jsonObject.has(FILESIZE_FIELD)) { + this.fileSize = jsonObject.getInt(FILESIZE_FIELD); + } } public String getFileId() { @@ -66,4 +76,34 @@ public class Voice { public void setFileSize(Integer fileSize) { this.fileSize = fileSize; } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(FILEID_FIELD, fileId); + gen.writeNumberField(DURATION_FIELD, duration); + if (mimeType != null) { + gen.writeStringField(MIMETYPE_FIELD, mimeType); + } + if (fileSize != null) { + gen.writeNumberField(FILESIZE_FIELD, fileSize); + } + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + gen.writeStartObject(); + gen.writeStringField(FILEID_FIELD, fileId); + gen.writeNumberField(DURATION_FIELD, duration); + if (mimeType != null) { + gen.writeStringField(MIMETYPE_FIELD, mimeType); + } + if (fileSize != null) { + gen.writeNumberField(FILESIZE_FIELD, fileSize); + } + gen.writeEndObject(); + gen.flush(); + } } diff --git a/src/main/java/org/telegram/methods/ForwardMessage.java b/src/main/java/org/telegram/methods/ForwardMessage.java deleted file mode 100644 index 0599155..0000000 --- a/src/main/java/org/telegram/methods/ForwardMessage.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.telegram.methods; - -/** - * @author Ruben Bermudez - * @version 1.0 - * @brief Use this method to send text messages. On success, the sent Message is returned. - * @date 20 of June of 2015 - */ -public class ForwardMessage { - public static final String PATH = "forwardmessage"; - - public static final String CHATID_FIELD = "chat_id"; - private Integer chatId; ///< Unique identifier for the message recepient — User or GroupChat id - public static final String FROMCHATID_FIELD = "from_chat_id"; - private Integer fromChatId; ///< Unique identifier for the chat where the original message was sent — User or GroupChat id - public static final String MESSAGEID_FIELD = "message_id"; - private Integer messageId; ///< Unique message identifier - - public ForwardMessage() { - super(); - } - - public Integer getChatId() { - return chatId; - } - - public void setChatId(Integer chatId) { - this.chatId = chatId; - } - - public Integer getFromChatId() { - return fromChatId; - } - - public void setFromChatId(Integer fromChatId) { - this.fromChatId = fromChatId; - } - - public Integer getMessageId() { - return messageId; - } - - public void setMessageId(Integer messageId) { - this.messageId = messageId; - } -} diff --git a/src/main/java/org/telegram/methods/GetMe.java b/src/main/java/org/telegram/methods/GetMe.java deleted file mode 100644 index 42019a5..0000000 --- a/src/main/java/org/telegram/methods/GetMe.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.telegram.methods; - -/** - * @author Ruben Bermudez - * @version 1.0 - * @brief A simple method for testing your bot's auth token. Requires no parameters. - * Returns basic information about the bot in form of a User object - * @date 20 of June of 2015 - */ -public class GetMe { - public static final String PATH = "getme"; -} diff --git a/src/main/java/org/telegram/methods/GetUserProfilePhotos.java b/src/main/java/org/telegram/methods/GetUserProfilePhotos.java deleted file mode 100644 index 97254c9..0000000 --- a/src/main/java/org/telegram/methods/GetUserProfilePhotos.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.telegram.methods; - -/** - * @author Ruben Bermudez - * @version 1.0 - * @brief Use this method to get a list of profile pictures for a user. Returns a UserProfilePhotos object. - * @date 20 of June of 2015 - */ -public class GetUserProfilePhotos { - public static final String PATH = "getuserprofilephotos"; -/* -user_id Integer Yes -offset Integer -limit Integer Optional - */ - public static final String USERID_FIELD = "user_id"; - private Integer userId; ///< Unique identifier of the target user - public static final String OFFSET_FIELD = "offset"; - /** - * Sequential number of the first photo to be returned. By default, all photos are returned. - */ - private Integer offset; - public static final String LIMIT_FIELD = "limit"; - /** - * Limits the number of photos to be retrieved. Values between 1—100 are accepted. Defaults to 100. - */ - private Integer limit; - - public GetUserProfilePhotos() { - super(); - } - - - public Integer getUserId() { - return userId; - } - - public void setUserId(Integer userId) { - this.userId = userId; - } - - public Integer getOffset() { - return offset; - } - - public void setOffset(Integer offset) { - this.offset = offset; - } - - public Integer getLimit() { - return limit; - } - - public void setLimit(Integer limit) { - this.limit = limit; - } -} diff --git a/src/main/java/org/telegram/methods/SendChatAction.java b/src/main/java/org/telegram/methods/SendChatAction.java deleted file mode 100644 index f68e668..0000000 --- a/src/main/java/org/telegram/methods/SendChatAction.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.telegram.methods; - -import org.telegram.api.ReplyKeyboard; - -/** - * @author Ruben Bermudez - * @version 1.0 - * @brief Use this method when you need to tell the user that something is happening on the bot's side. - * The status is set for 5 seconds or less (when a message arrives from your bot, - * Telegram clients clear its typing status). - * @date 20 of June of 2015 - */ -public class SendChatAction { - - public static final String PATH = "sendChatAction"; - - public static final String CHATID_FIELD = "chat_id"; - private Integer chatId; ///< Unique identifier for the message recepient — User or GroupChat id - public static final String ACTION_FIELD = "action"; - /** - * Type of action to broadcast. - * Choose one, depending on what the user is about to receive: - * 'typing' for text messages - * 'upload_photo' for photos - * 'record_video' or 'upload_video' for videos - * 'record_audio' or 'upload_audio' for audio files - * 'upload_document' for general files, - * 'find_location' for location data. - */ - private Float action; -} diff --git a/src/main/java/org/telegram/methods/SendLocation.java b/src/main/java/org/telegram/methods/SendLocation.java deleted file mode 100644 index fb30147..0000000 --- a/src/main/java/org/telegram/methods/SendLocation.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.telegram.methods; - -import org.telegram.api.ReplyKeyboard; - -/** - * @author Ruben Bermudez - * @version 1.0 - * @brief Use this method to send point on the map. On success, the sent Message is returned. - * @date 20 of June of 2015 - */ -public class SendLocation { - public static final String PATH = "sendlocation"; - - public static final String CHATID_FIELD = "chat_id"; - private Integer chatId; ///< Unique identifier for the message recepient — User or GroupChat id - public static final String LATITUDE_FIELD = "latitude"; - private Float latitude; ///< Latitude of location - public static final String LONGITUDE_FIELD = "longitude"; - private Float longitude; ///< Longitude of location - public static final String REPLYTOMESSAGEID_FIELD = "reply_to_message_id"; - private Integer replayToMessageId; ///< Optional. If the message is a reply, ID of the original message - public static final String REPLYMARKUP_FIELD = "reply_markup"; - private ReplyKeyboard replayMarkup; ///< Optional. JSON-serialized object for a custom reply keyboard -} diff --git a/src/main/java/org/telegram/methods/SendMessage.java b/src/main/java/org/telegram/methods/SendMessage.java deleted file mode 100644 index ea1abd8..0000000 --- a/src/main/java/org/telegram/methods/SendMessage.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.telegram.methods; - -import org.telegram.api.ReplyKeyboard; - -/** - * @author Ruben Bermudez - * @version 1.0 - * @brief Use this method to send text messages. On success, the sent Message is returned. - * @date 20 of June of 2015 - */ -public class SendMessage { - public static final String PATH = "sendmessage"; - - public static final String CHATID_FIELD = "chat_id"; - private Integer chatId; ///< Unique identifier for the message recepient — User or GroupChat id - public static final String TEXT_FIELD = "text"; - private String text; ///< Text of the message to be sent - public static final String DISABLEWEBPAGEPREVIEW_FIELD = "disable_web_page_preview"; - private Boolean disableWebPagePreview; ///< Disables link previews for links in this message - public static final String REPLYTOMESSAGEID_FIELD = "reply_to_message_id"; - private Integer replayToMessageId; ///< Optional. If the message is a reply, ID of the original message - public static final String REPLYMARKUP_FIELD = "reply_markup"; - private ReplyKeyboard replayMarkup; ///< Optional. JSON-serialized object for a custom reply keyboard - - public SendMessage() { - super(); - } - - public Integer getChatId() { - return chatId; - } - - public void setChatId(Integer chatId) { - this.chatId = chatId; - } - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - public Integer getReplayToMessageId() { - return replayToMessageId; - } - - public void setReplayToMessageId(Integer replayToMessageId) { - this.replayToMessageId = replayToMessageId; - } - - public ReplyKeyboard getReplayMarkup() { - return replayMarkup; - } - - public void setReplayMarkup(ReplyKeyboard replayMarkup) { - this.replayMarkup = replayMarkup; - } - - public Boolean getDisableWebPagePreview() { - return disableWebPagePreview; - } - - public void setDisableWebPagePreview(Boolean disableWebPagePreview) { - this.disableWebPagePreview = disableWebPagePreview; - } -} diff --git a/src/main/java/org/telegram/methods/SetWebhook.java b/src/main/java/org/telegram/methods/SetWebhook.java deleted file mode 100644 index 732a797..0000000 --- a/src/main/java/org/telegram/methods/SetWebhook.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.telegram.methods; - -/** - * @author Ruben Bermudez - * @version 1.0 - * @brief Use this method to specify a url and receive incoming updates via an outgoing webhook. - * Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url, - * containing a JSON-serialized Update. In case of an unsuccessful request, - * we will give up after a reasonable amount of attempts. - * @date 20 of June of 2015 - */ -public class SetWebhook { - public static final String PATH = "setwebhook"; - - public static final String URL_FIELD = "url"; - private String url; ///< HTTPS url to send updates to. Use an empty string to remove webhook integration -} diff --git a/src/main/java/org/telegram/services/TransifexService.java b/src/main/java/org/telegram/services/TransifexService.java index e5519a2..1c7e2bb 100644 --- a/src/main/java/org/telegram/services/TransifexService.java +++ b/src/main/java/org/telegram/services/TransifexService.java @@ -8,7 +8,7 @@ import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.telegram.BuildVars; -import org.telegram.methods.SendDocument; +import org.telegram.api.methods.SendDocument; import java.io.*; diff --git a/src/main/java/org/telegram/updateshandlers/DirectionsHandlers.java b/src/main/java/org/telegram/updateshandlers/DirectionsHandlers.java index 7efd862..38658f2 100644 --- a/src/main/java/org/telegram/updateshandlers/DirectionsHandlers.java +++ b/src/main/java/org/telegram/updateshandlers/DirectionsHandlers.java @@ -1,9 +1,11 @@ package org.telegram.updateshandlers; +import org.json.JSONObject; import org.telegram.*; -import org.telegram.api.*; +import org.telegram.api.objects.*; import org.telegram.database.DatabaseManager; -import org.telegram.methods.SendMessage; +import org.telegram.api.methods.BotApiMethod; +import org.telegram.api.methods.SendMessage; import org.telegram.services.DirectionsService; import org.telegram.services.LocalisationService; import org.telegram.updatesreceivers.UpdatesThread; @@ -23,22 +25,20 @@ import java.util.concurrent.ConcurrentLinkedQueue; */ public class DirectionsHandlers implements UpdatesCallback { private static final String TOKEN = BotConfig.TOKENDIRECTIONS; - private static final String webhookPath = "directionsBot"; - private final Webhook webhook; - private final UpdatesThread updatesThread; + private static final String BOTNAME = BotConfig.USERNAMEDIRECTIONS; + private static final boolean USEWEBHOOK = false; + private static final int WATING_ORIGIN_STATUS = 0; private static final int WATING_DESTINY_STATUS = 1; private final ConcurrentLinkedQueue languageMessages = new ConcurrentLinkedQueue<>(); - public DirectionsHandlers() { - if (BuildVars.useWebHook) { - webhook = new Webhook(this, webhookPath); - updatesThread = null; - SenderHelper.SendWebhook(webhook.getURL(), TOKEN); + public DirectionsHandlers(Webhook webhook) { + if (USEWEBHOOK) { + webhook.registerWebhook(this, BOTNAME); + SenderHelper.SendWebhook(Webhook.getExternalURL(BOTNAME), TOKEN); } else { - webhook = null; SenderHelper.SendWebhook("", TOKEN); - updatesThread = new UpdatesThread(TOKEN, this); + new UpdatesThread(TOKEN, this); } } @@ -47,6 +47,12 @@ public class DirectionsHandlers implements UpdatesCallback { handleDirections(update); } + @Override + public BotApiMethod onWebhookUpdateReceived(Update update) { + // Webhook not supported in this example + return null; + } + public void handleDirections(Update update) { Message message = update.getMessage(); if (message != null && message.hasText()) { @@ -79,7 +85,7 @@ public class DirectionsHandlers implements UpdatesCallback { SendMessage sendMessageRequest = new SendMessage(); sendMessageRequest.setText(LocalisationService.getInstance().getString("youNeedReplyDirections", language)); sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); } } } @@ -100,11 +106,21 @@ public class DirectionsHandlers implements UpdatesCallback { Message sentMessage = null; for (String direction : directions) { sendMessageRequest.setText(direction); - sentMessage = SenderHelper.SendMessage(sendMessageRequest, TOKEN); - } - if (sentMessage != null) { - DatabaseManager.getInstance().deleteUserForDirections(message.getFrom().getId()); + SenderHelper.SendApiMethodAsync(sendMessageRequest, TOKEN, new SentCallback() { + @Override + public void onResult(BotApiMethod method, JSONObject jsonObject) { + Message sentMessage = method.deserializeResponse(jsonObject); + if (sentMessage != null) { + DatabaseManager.getInstance().deleteUserForDirections(message.getFrom().getId()); + } + } + + @Override + public void onError(BotApiMethod method, JSONObject jsonObject) { + } + }); } + } private void onOriginReceived(Message message, String language) { @@ -115,11 +131,22 @@ public class DirectionsHandlers implements UpdatesCallback { forceReplyKeyboard.setSelective(true); sendMessageRequest.setReplayMarkup(forceReplyKeyboard); sendMessageRequest.setText(LocalisationService.getInstance().getString("sendDestination", language)); - Message sentMessage = SenderHelper.SendMessage(sendMessageRequest, TOKEN); - if (sentMessage != null) { - DatabaseManager.getInstance().addUserForDirection(message.getFrom().getId(), WATING_DESTINY_STATUS, - sentMessage.getMessageId(), message.getText()); - } + + SenderHelper.SendApiMethodAsync(sendMessageRequest, TOKEN, new SentCallback() { + @Override + public void onResult(BotApiMethod method, JSONObject jsonObject) { + Message sentMessage = method.deserializeResponse(jsonObject); + if (sentMessage != null) { + DatabaseManager.getInstance().addUserForDirection(message.getFrom().getId(), WATING_DESTINY_STATUS, + sentMessage.getMessageId(), message.getText()); + } + } + + @Override + public void onError(BotApiMethod method, JSONObject jsonObject) { + } + }); + } private void sendHelpMessage(Message message, String language) { @@ -129,7 +156,7 @@ public class DirectionsHandlers implements UpdatesCallback { Commands.startDirectionCommand); sendMessageRequest.setText(helpDirectionsFormated); sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); } private void onStartdirectionsCommand(Message message, String language) { @@ -140,11 +167,22 @@ public class DirectionsHandlers implements UpdatesCallback { forceReplyKeyboard.setSelective(true); sendMessageRequest.setReplayMarkup(forceReplyKeyboard); sendMessageRequest.setText(LocalisationService.getInstance().getString("initDirections", language)); - Message sentMessage = SenderHelper.SendMessage(sendMessageRequest, TOKEN); - if (sentMessage != null) { - DatabaseManager.getInstance().addUserForDirection(message.getFrom().getId(), WATING_ORIGIN_STATUS, - sentMessage.getMessageId(), null); - } + + SenderHelper.SendApiMethodAsync(sendMessageRequest, TOKEN, new SentCallback() { + @Override + public void onResult(BotApiMethod method, JSONObject jsonObject) { + Message sentMessage = method.deserializeResponse(jsonObject); + if (sentMessage != null) { + DatabaseManager.getInstance().addUserForDirection(message.getFrom().getId(), WATING_ORIGIN_STATUS, + sentMessage.getMessageId(), null); + } + } + + @Override + public void onError(BotApiMethod method, JSONObject jsonObject) { + } + }); + } private void onSetLanguageCommand(Message message, String language) { @@ -164,7 +202,7 @@ public class DirectionsHandlers implements UpdatesCallback { replyKeyboardMarkup.setSelective(true); sendMessageRequest.setReplayMarkup(replyKeyboardMarkup); sendMessageRequest.setText(LocalisationService.getInstance().getString("chooselanguage", language)); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); languageMessages.add(message.getFrom().getId()); } @@ -183,7 +221,7 @@ public class DirectionsHandlers implements UpdatesCallback { replyKeyboardHide.setHideKeyboard(true); replyKeyboardHide.setSelective(true); sendMessageRequest.setReplayMarkup(replyKeyboardHide); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); languageMessages.remove(message.getFrom().getId()); } } diff --git a/src/main/java/org/telegram/updateshandlers/FilesHandlers.java b/src/main/java/org/telegram/updateshandlers/FilesHandlers.java index e55237b..391e249 100644 --- a/src/main/java/org/telegram/updateshandlers/FilesHandlers.java +++ b/src/main/java/org/telegram/updateshandlers/FilesHandlers.java @@ -4,13 +4,14 @@ import org.telegram.BotConfig; import org.telegram.BuildVars; import org.telegram.Commands; import org.telegram.SenderHelper; -import org.telegram.api.Message; -import org.telegram.api.ReplyKeyboardHide; -import org.telegram.api.ReplyKeyboardMarkup; -import org.telegram.api.Update; +import org.telegram.api.objects.Message; +import org.telegram.api.objects.ReplyKeyboardHide; +import org.telegram.api.objects.ReplyKeyboardMarkup; +import org.telegram.api.objects.Update; import org.telegram.database.DatabaseManager; -import org.telegram.methods.SendDocument; -import org.telegram.methods.SendMessage; +import org.telegram.api.methods.BotApiMethod; +import org.telegram.api.methods.SendDocument; +import org.telegram.api.methods.SendMessage; import org.telegram.services.Emoji; import org.telegram.services.LocalisationService; import org.telegram.updatesreceivers.UpdatesThread; @@ -26,27 +27,25 @@ import java.util.concurrent.ConcurrentLinkedQueue; * @author Ruben Bermudez * @version 1.0 * @brief Handler for updates to Files Bot + * This bot is an example for the use of sendMessage asynchronously * @date 24 of June of 2015 */ public class FilesHandlers implements UpdatesCallback { private static final String TOKEN = BotConfig.TOKENFILES; - private static final String webhookPath = "filesBot"; + private static final String BOTNAME = BotConfig.USERNAMEFILES; + private static final boolean USEWEBHOOK = false; private static final int INITIAL_UPLOAD_STATUS = 0; private static final int DELETE_UPLOADED_STATUS = 1; - private final Webhook webhook; - private final UpdatesThread updatesThread; private final ConcurrentLinkedQueue languageMessages = new ConcurrentLinkedQueue<>(); - public FilesHandlers() { - if (BuildVars.useWebHook) { - webhook = new Webhook(this, webhookPath); - updatesThread = null; - SenderHelper.SendWebhook(webhook.getURL(), TOKEN); + public FilesHandlers(Webhook webhook) { + if (USEWEBHOOK) { + webhook.registerWebhook(this, BOTNAME); + SenderHelper.SendWebhook(Webhook.getExternalURL(BOTNAME), TOKEN); } else { - webhook = null; SenderHelper.SendWebhook("", TOKEN); - updatesThread = new UpdatesThread(TOKEN, this); + new UpdatesThread(TOKEN, this); } } @@ -55,6 +54,12 @@ public class FilesHandlers implements UpdatesCallback { handleFileUpdate(update); } + @Override + public BotApiMethod onWebhookUpdateReceived(Update update) { + // Webhook not supported in this example + return null; + } + public void handleFileUpdate(Update update) { Message message = update.getMessage(); if (message != null && message.hasText()) { @@ -95,7 +100,7 @@ public class FilesHandlers implements UpdatesCallback { sendMessageRequest.setText(LocalisationService.getInstance().getString("fileUploaded", language) + LocalisationService.getInstance().getString("uploadedFileURL", language) + message.getDocument().getFileId()); sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); } } @@ -116,7 +121,7 @@ public class FilesHandlers implements UpdatesCallback { ReplyKeyboardHide replyKeyboardHide = new ReplyKeyboardHide(); replyKeyboardHide.setHideKeyboard(true); sendMessageRequest.setReplayMarkup(replyKeyboardHide); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); } private void onDeleteCommand(Message message, String language, String[] parts) { @@ -148,7 +153,7 @@ public class FilesHandlers implements UpdatesCallback { replyKeyboardMarkup.setKeyboard(commands); } sendMessageRequest.setReplayMarkup(replyKeyboardMarkup); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); } private void onDeleteCommandWithParameters(Message message, String language, String part) { @@ -161,7 +166,7 @@ public class FilesHandlers implements UpdatesCallback { sendMessageRequest.setText(LocalisationService.getInstance().getString("wrongFileId", language)); } sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); DatabaseManager.getInstance().deleteUserForFile(message.getFrom().getId()); } @@ -170,7 +175,7 @@ public class FilesHandlers implements UpdatesCallback { SendMessage sendMessageRequest = new SendMessage(); sendMessageRequest.setText(LocalisationService.getInstance().getString("processFinished", language)); sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); } private void onUploadCommand(Message message, String language) { @@ -178,7 +183,7 @@ public class FilesHandlers implements UpdatesCallback { SendMessage sendMessageRequest = new SendMessage(); sendMessageRequest.setText(LocalisationService.getInstance().getString("sendFileToUpload", language)); sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); } private void sendHelpMessage(Message message, String language) { @@ -189,7 +194,7 @@ public class FilesHandlers implements UpdatesCallback { Commands.listCommand); sendMessageRequest.setText(formatedString); sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); } private void onStartWithParameters(Message message, String language, String part) { @@ -202,7 +207,7 @@ public class FilesHandlers implements UpdatesCallback { SendMessage sendMessageRequest = new SendMessage(); sendMessageRequest.setText(LocalisationService.getInstance().getString("wrongFileId", language)); sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); } } @@ -223,7 +228,7 @@ public class FilesHandlers implements UpdatesCallback { replyKeyboardMarkup.setSelective(true); sendMessageRequest.setReplayMarkup(replyKeyboardMarkup); sendMessageRequest.setText(LocalisationService.getInstance().getString("chooselanguage", language)); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); languageMessages.add(message.getFrom().getId()); } @@ -242,7 +247,7 @@ public class FilesHandlers implements UpdatesCallback { replyKeyboardHide.setHideKeyboard(true); replyKeyboardHide.setSelective(true); sendMessageRequest.setReplayMarkup(replyKeyboardHide); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); languageMessages.remove(message.getFrom().getId()); } } diff --git a/src/main/java/org/telegram/updateshandlers/SentCallback.java b/src/main/java/org/telegram/updateshandlers/SentCallback.java new file mode 100644 index 0000000..24d6839 --- /dev/null +++ b/src/main/java/org/telegram/updateshandlers/SentCallback.java @@ -0,0 +1,26 @@ +package org.telegram.updateshandlers; + +import org.json.JSONObject; +import org.telegram.api.methods.BotApiMethod; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief Callback to execute api method asynchronously + * @date 10 of September of 2015 + */ +public interface SentCallback { + /** + * Called when the request is successful + * @param method Method executed + * @param jsonObject Answer from Telegram server + */ + void onResult(BotApiMethod method, JSONObject jsonObject); + + /** + * Called when the request fails + * @param method Method executed + * @param jsonObject Answer from Telegram server (contains error information) + */ + void onError(BotApiMethod method, JSONObject jsonObject); +} diff --git a/src/main/java/org/telegram/updateshandlers/TransifexHandlers.java b/src/main/java/org/telegram/updateshandlers/TransifexHandlers.java index c483803..c7e1cd6 100644 --- a/src/main/java/org/telegram/updateshandlers/TransifexHandlers.java +++ b/src/main/java/org/telegram/updateshandlers/TransifexHandlers.java @@ -1,18 +1,17 @@ package org.telegram.updateshandlers; import org.telegram.*; -import org.telegram.api.Message; -import org.telegram.api.Update; +import org.telegram.api.objects.Message; +import org.telegram.api.objects.Update; import org.telegram.database.DatabaseManager; -import org.telegram.methods.SendDocument; -import org.telegram.methods.SendMessage; +import org.telegram.api.methods.BotApiMethod; +import org.telegram.api.methods.SendDocument; +import org.telegram.api.methods.SendMessage; import org.telegram.services.LocalisationService; import org.telegram.services.TransifexService; import org.telegram.updatesreceivers.UpdatesThread; import org.telegram.updatesreceivers.Webhook; -import java.util.List; - /** * @author Ruben Bermudez * @version 1.0 @@ -21,19 +20,16 @@ import java.util.List; */ public class TransifexHandlers implements UpdatesCallback { private static final String TOKEN = BotConfig.TOKENTRANSIFEX; - private static final String webhookPath = "transifexBot"; - private final Webhook webhook; - private final UpdatesThread updatesThread; + private static final String BOTNAME = BotConfig.USERNAMETRANSIFEX; + private static final boolean USEWEBHOOK = false; - public TransifexHandlers() { - if (BuildVars.useWebHook) { - webhook = new Webhook(this, webhookPath); - updatesThread = null; - SenderHelper.SendWebhook(webhook.getURL(), TOKEN); + public TransifexHandlers(Webhook webhook) { + if (USEWEBHOOK) { + webhook.registerWebhook(this, BOTNAME); + SenderHelper.SendWebhook(Webhook.getExternalURL(BOTNAME), TOKEN); } else { - webhook = null; SenderHelper.SendWebhook("", TOKEN); - updatesThread = new UpdatesThread(TOKEN, this); + new UpdatesThread(TOKEN, this); } } @@ -42,6 +38,12 @@ public class TransifexHandlers implements UpdatesCallback { sendTransifexFile(update); } + @Override + public BotApiMethod onWebhookUpdateReceived(Update update) { + // Webhook not supported in this example + return null; + } + public void sendTransifexFile(Update update) { Message message = update.getMessage(); if (message != null && message.hasText()) { @@ -73,7 +75,7 @@ public class TransifexHandlers implements UpdatesCallback { Commands.transifexAndroidSupportCommand); sendMessageRequest.setText(helpFormated); sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); } if (sendDocument != null) { @@ -90,7 +92,7 @@ public class TransifexHandlers implements UpdatesCallback { Commands.transifexAndroidSupportCommand); sendMessageRequest.setText(helpFormated); sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + SenderHelper.SendApiMethod(sendMessageRequest, TOKEN); } } } diff --git a/src/main/java/org/telegram/updateshandlers/UpdatesCallback.java b/src/main/java/org/telegram/updateshandlers/UpdatesCallback.java index 570acd2..ee9469a 100644 --- a/src/main/java/org/telegram/updateshandlers/UpdatesCallback.java +++ b/src/main/java/org/telegram/updateshandlers/UpdatesCallback.java @@ -1,8 +1,7 @@ package org.telegram.updateshandlers; -import org.telegram.api.Update; - -import java.util.List; +import org.telegram.api.objects.Update; +import org.telegram.api.methods.BotApiMethod; /** * @author Ruben Bermudez @@ -11,5 +10,15 @@ import java.util.List; * @date 20 of June of 2015 */ public interface UpdatesCallback { + /** + * This method is called when receiving updates via org.telegram.api.methods.GetUpdates method + * @param update Update received + */ void onUpdateReceived(Update update); + + /** + * This method is called when receiving updates via webhook + * @param update Update received + */ + BotApiMethod onWebhookUpdateReceived(Update update); } diff --git a/src/main/java/org/telegram/updateshandlers/WeatherHandlers.java b/src/main/java/org/telegram/updateshandlers/WeatherHandlers.java index 29dc47e..8f88009 100644 --- a/src/main/java/org/telegram/updateshandlers/WeatherHandlers.java +++ b/src/main/java/org/telegram/updateshandlers/WeatherHandlers.java @@ -4,15 +4,15 @@ import org.telegram.BotConfig; import org.telegram.BuildVars; import org.telegram.Commands; import org.telegram.SenderHelper; -import org.telegram.api.*; +import org.telegram.api.objects.*; import org.telegram.database.DatabaseManager; -import org.telegram.methods.SendMessage; +import org.telegram.api.methods.BotApiMethod; +import org.telegram.api.methods.SendMessage; import org.telegram.services.*; import org.telegram.structure.WeatherAlert; import org.telegram.updatesreceivers.UpdatesThread; import org.telegram.updatesreceivers.Webhook; -import javax.swing.text.JTextComponent; import java.util.ArrayList; import java.util.List; @@ -20,10 +20,14 @@ import java.util.List; * @author Ruben Bermudez * @version 1.0 * @brief Handler for updates to Weather Bot + * This is a use case that works with both Webhooks and GetUpdates methods * @date 24 of June of 2015 */ public class WeatherHandlers implements UpdatesCallback { private static final String TOKEN = BotConfig.TOKENWEATHER; + private static final String BOTNAME = BotConfig.USERNAMEWEATHER; + private static final boolean USEWEBHOOK = true; + private static final int STARTSTATE = 0; private static final int MAINMENU = 1; private static final int CURRENTWEATHER = 2; @@ -38,13 +42,13 @@ public class WeatherHandlers implements UpdatesCallback { private static final int SETTINGS = 11; private static final int LANGUAGE = 12; private static final int UNITS = 13; - private static final String webhookPath = "weatherBot"; - public WeatherHandlers() { - Webhook webhook; - if (BuildVars.useWebHook) { - webhook = new Webhook(this, webhookPath); - SenderHelper.SendWebhook(webhook.getURL(), TOKEN); + private final Object webhookLock = new Object(); + + public WeatherHandlers(Webhook webhook) { + if (USEWEBHOOK) { + webhook.registerWebhook(this, BOTNAME); + SenderHelper.SendWebhook(Webhook.getExternalURL(BOTNAME), TOKEN); } else { SenderHelper.SendWebhook("", TOKEN); new UpdatesThread(TOKEN, this); @@ -75,6 +79,7 @@ public class WeatherHandlers implements UpdatesCallback { String weather = WeatherService.getInstance().fetchWeatherAlert(weatherAlert.getCityId(), weatherAlert.getUserId(), userOptions[0], userOptions[1]); SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setChatId(weatherAlert.getUserId()); sendMessage.setText(weather); sendBuiltMessage(sendMessage); @@ -85,72 +90,88 @@ public class WeatherHandlers implements UpdatesCallback { public void onUpdateReceived(Update update) { Message message = update.getMessage(); if (message != null) { - handleIncomingMessage(message); + BotApiMethod botApiMethod = handleIncomingMessage(message); + SenderHelper.SendApiMethod(botApiMethod, TOKEN); } } - private static void onCancelCommand(Integer chatId, Integer userId, Integer messageId, ReplyKeyboard replyKeyboard, String language) { + @Override + public BotApiMethod onWebhookUpdateReceived(Update update) { + Message message = update.getMessage(); + if (message != null) { + synchronized (webhookLock) { + return handleIncomingMessage(message); + } + } + return null; + } + + private static BotApiMethod onCancelCommand(Integer chatId, Integer userId, Integer messageId, ReplyKeyboard replyKeyboard, String language) { SendMessage sendMessage = new SendMessage(); sendMessage.setChatId(chatId); + sendMessage.enableMarkdown(true); sendMessage.setReplayMarkup(getMainMenuKeyboard(language)); sendMessage.setReplayToMessageId(messageId); sendMessage.setReplayMarkup(replyKeyboard); sendMessage.setText(LocalisationService.getInstance().getString("backToMainMenu", language)); - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(userId, chatId, MAINMENU); + return sendMessage; } // region Incoming messages handlers - private static void handleIncomingMessage(Message message) { + private static BotApiMethod handleIncomingMessage(Message message) { final int state = DatabaseManager.getInstance().getWeatherState(message.getFrom().getId(), message.getChatId()); final String language = DatabaseManager.getInstance().getUserWeatherOptions(message.getFrom().getId())[0]; if (message.isGroupMessage() && message.hasText()) { if (isCommandForOther(message.getText())) { - return; + return null; } else if (message.getText().startsWith(Commands.STOPCOMMAND)){ sendHideKeyboard(message.getFrom().getId(), message.getChatId(), message.getMessageId()); - return; + return null; } } + BotApiMethod botApiMethod; switch(state) { case MAINMENU: - messageOnMainMenu(message, language); + botApiMethod = messageOnMainMenu(message, language); break; case CURRENTWEATHER: case CURRENTNEWWEATHER: case CURRENTLOCATIONWEATHER: - messageOnCurrentWeather(message, language, state); + botApiMethod = messageOnCurrentWeather(message, language, state); break; case FORECASTWEATHER: case FORECASTNEWWEATHER: case FORECASTLOCATIONWEATHER: - messageOnForecastWeather(message, language, state); + botApiMethod = messageOnForecastWeather(message, language, state); break; case ALERT: case ALERTNEW: case ALERTDELETE: - messageOnAlert(message, language, state); + botApiMethod = messageOnAlert(message, language, state); break; case SETTINGS: - messageOnSetting(message, language); + botApiMethod = messageOnSetting(message, language); break; case LANGUAGE: - messageOnLanguage(message, language); + botApiMethod = messageOnLanguage(message, language); break; case UNITS: - messageOnUnits(message, language); + botApiMethod = messageOnUnits(message, language); break; default: - sendMessageDefault(message, language); + botApiMethod = sendMessageDefault(message, language); break; } + return botApiMethod; } private static void sendHideKeyboard(Integer userId, Integer chatId, Integer messageId) { SendMessage sendMessage = new SendMessage(); sendMessage.setChatId(chatId); + sendMessage.enableMarkdown(true); sendMessage.setReplayToMessageId(messageId); sendMessage.setText(Emoji.WAVING_HAND_SIGN.toString()); @@ -159,7 +180,7 @@ public class WeatherHandlers implements UpdatesCallback { replyKeyboardHide.setHideKeyboard(true); sendMessage.setReplayMarkup(replyKeyboardHide); - SenderHelper.SendMessage(sendMessage, TOKEN); + SenderHelper.SendApiMethod(sendMessage, TOKEN); DatabaseManager.getInstance().insertWeatherState(userId, chatId, STARTSTATE); } @@ -174,106 +195,123 @@ public class WeatherHandlers implements UpdatesCallback { // region Alerts Menu Option selected - private static void messageOnAlert(Message message, String language, int state) { + private static BotApiMethod messageOnAlert(Message message, String language, int state) { + BotApiMethod botApiMethod = null; switch(state) { case ALERT: - onAlertOptionSelected(message, language); + botApiMethod = onAlertOptionSelected(message, language); break; case ALERTNEW: - onAlertNewOptionSelected(message, language); + botApiMethod = onAlertNewOptionSelected(message, language); break; case ALERTDELETE: - onAlertDeleteOptionSelected(message, language); + botApiMethod = onAlertDeleteOptionSelected(message, language); break; } + return botApiMethod; } - private static void onAlertDeleteOptionSelected(Message message, String language) { + private static BotApiMethod onAlertDeleteOptionSelected(Message message, String language) { + BotApiMethod botApiMethod = null; if (message.hasText()) { if (message.getText().equals(getCancelCommand(language))) { - onAlertDeleteBackOptionSelected(message, language); + botApiMethod = onAlertDeleteBackOptionSelected(message, language); } else if (DatabaseManager.getInstance().getAlertCitiesNameByUser(message.getFrom().getId()).contains(message.getText())) { - onAlertDeleteCityOptionSelected(message, language); + botApiMethod = onAlertDeleteCityOptionSelected(message, language); } else { - sendChooseOptionMessage(message.getChatId(), message.getMessageId(), getAlertsListKeyboard(message.getFrom().getId(), language), language); + botApiMethod = sendChooseOptionMessage(message.getChatId(), message.getMessageId(), getAlertsListKeyboard(message.getFrom().getId(), language), language); } } + + return botApiMethod; } - private static void onAlertDeleteCityOptionSelected(Message message, String language) { + private static BotApiMethod onAlertDeleteCityOptionSelected(Message message, String language) { DatabaseManager.getInstance().deleteAlertCity(message.getFrom().getId(), message.getText()); SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setReplayToMessageId(message.getMessageId()); sendMessage.setChatId(message.getChatId()); sendMessage.setReplayMarkup(getAlertsKeyboard(language)); sendMessage.setText(LocalisationService.getInstance().getString("alertDeleted", language)); - sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), ALERT); + return sendMessage; } - private static void onAlertDeleteBackOptionSelected(Message message, String language) { + private static BotApiMethod onAlertDeleteBackOptionSelected(Message message, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setReplayToMessageId(message.getMessageId()); sendMessage.setChatId(message.getChatId()); sendMessage.setReplayMarkup(getAlertsKeyboard(language)); sendMessage.setText(LocalisationService.getInstance().getString("alertsMenuMessage", language)); - sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), ALERT); + return sendMessage; } - private static void onAlertNewOptionSelected(Message message, String language) { + private static BotApiMethod onAlertNewOptionSelected(Message message, String language) { + BotApiMethod botApiMethod = null; if (message.hasText()) { if (message.getText().equals(getCancelCommand(language))) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setChatId(message.getChatId()); sendMessage.setReplayToMessageId(message.getMessageId()); sendMessage.setReplayMarkup(getAlertsKeyboard(language)); sendMessage.setText(LocalisationService.getInstance().getString("alertsMenuMessage", language)); - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), ALERT); + botApiMethod = sendMessage; } else { - onNewAlertCityReceived(message, language); + botApiMethod = onNewAlertCityReceived(message, language); } } + return botApiMethod; } - private static void onNewAlertCityReceived(Message message, String language) { + private static BotApiMethod onNewAlertCityReceived(Message message, String language) { int userId = message.getFrom().getId(); Integer cityId = DatabaseManager.getInstance().getRecentWeatherIdByCity(userId, message.getText()); if (cityId != null) { DatabaseManager.getInstance().createNewWeatherAlert(userId, cityId, message.getText()); SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.enableMarkdown(true); sendMessageRequest.setReplayMarkup(getAlertsKeyboard(language)); sendMessageRequest.setReplayToMessageId(message.getMessageId()); sendMessageRequest.setText(getChooseNewAlertSetMessage(message.getText(), language)); sendMessageRequest.setChatId(message.getChatId()); - sendBuiltMessage(sendMessageRequest); + DatabaseManager.getInstance().insertWeatherState(userId, message.getChatId(), ALERT); + return sendMessageRequest; } else { - sendChooseOptionMessage(message.getChatId(), message.getMessageId(), + return sendChooseOptionMessage(message.getChatId(), message.getMessageId(), getRecentsKeyboard(message.getFrom().getId(), language, false), language); } } - private static void onAlertOptionSelected(Message message, String language) { + private static BotApiMethod onAlertOptionSelected(Message message, String language) { + BotApiMethod botApiMethod = null; if (message.hasText()) { if (message.getText().equals(getNewCommand(language))) { - onNewAlertCommand(message, language); + botApiMethod = onNewAlertCommand(message, language); } else if (message.getText().equals(getDeleteCommand(language))) { - onDeleteAlertCommand(message, language); + botApiMethod = onDeleteAlertCommand(message, language); } else if (message.getText().equals(getListCommand(language))) { - onListAlertCommand(message, language); + botApiMethod = onListAlertCommand(message, language); } else if (message.getText().equals(getBackCommand(language))) { - onBackAlertCommand(message, language); + botApiMethod = onBackAlertCommand(message, language); } else { - sendChooseOptionMessage(message.getChatId(), message.getMessageId(), + botApiMethod = sendChooseOptionMessage(message.getChatId(), message.getMessageId(), getAlertsKeyboard(language), language); } } + return botApiMethod; } - private static void onBackAlertCommand(Message message, String language) { + private static BotApiMethod onBackAlertCommand(Message message, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); ReplyKeyboardMarkup replyKeyboardMarkup = getSettingsKeyboard(language); sendMessage.setReplayMarkup(replyKeyboardMarkup); @@ -281,12 +319,13 @@ public class WeatherHandlers implements UpdatesCallback { sendMessage.setChatId(message.getChatId()); sendMessage.setText(getSettingsMessage(language)); - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), SETTINGS); + return sendMessage; } - private static void onListAlertCommand(Message message, String language) { + private static BotApiMethod onListAlertCommand(Message message, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setChatId(message.getChatId()); sendMessage.setReplayToMessageId(message.getMessageId()); @@ -294,11 +333,12 @@ public class WeatherHandlers implements UpdatesCallback { sendMessage.setText(getAlertListMessage(message.getFrom().getId(), language)); sendMessage.setReplayToMessageId(message.getMessageId()); - sendBuiltMessage(sendMessage); + return sendMessage; } - private static void onDeleteAlertCommand(Message message, String language) { + private static BotApiMethod onDeleteAlertCommand(Message message, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setChatId(message.getChatId()); @@ -313,100 +353,109 @@ public class WeatherHandlers implements UpdatesCallback { } sendMessage.setReplayToMessageId(message.getMessageId()); - sendBuiltMessage(sendMessage); + return sendMessage; } - private static void onNewAlertCommand(Message message, String language) { + private static SendMessage onNewAlertCommand(Message message, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setChatId(message.getChatId()); sendMessage.setReplayMarkup(getRecentsKeyboard(message.getFrom().getId(), language, false)); sendMessage.setText(LocalisationService.getInstance().getString("chooseNewAlertCity", language)); sendMessage.setReplayToMessageId(message.getMessageId()); - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), ALERTNEW); + return sendMessage; } // endregion Alerts Menu Option selected // region Settings Menu Option selected - private static void messageOnSetting(Message message, String language) { + private static BotApiMethod messageOnSetting(Message message, String language) { + BotApiMethod botApiMethod = null; if (message.hasText()) { if (message.getText().startsWith(getLanguagesCommand(language))) { - onLanguageCommand(message, language); + botApiMethod = onLanguageCommand(message, language); } else if (message.getText().startsWith(getUnitsCommand(language))) { - onUnitsCommand(message, language); + botApiMethod = onUnitsCommand(message, language); } else if (message.getText().startsWith(getAlertsCommand(language))) { - onAlertsCommand(message, language); + botApiMethod = onAlertsCommand(message, language); } else if (message.getText().startsWith(getBackCommand(language))) { - sendMessageDefault(message, language); + botApiMethod = sendMessageDefault(message, language); } else { - sendChooseOptionMessage(message.getChatId(), message.getMessageId(), + botApiMethod = sendChooseOptionMessage(message.getChatId(), message.getMessageId(), getSettingsKeyboard(language), language); } } + return botApiMethod; } - private static void onAlertsCommand(Message message, String language) { + private static BotApiMethod onAlertsCommand(Message message, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setReplayToMessageId(message.getMessageId()); sendMessage.setChatId(message.getChatId()); sendMessage.setReplayMarkup(getAlertsKeyboard(language)); sendMessage.setText(LocalisationService.getInstance().getString("alertsMenuMessage", language)); - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), ALERT); + return sendMessage; } - private static void onUnitsCommand(Message message, String language) { + private static BotApiMethod onUnitsCommand(Message message, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setReplayToMessageId(message.getMessageId()); sendMessage.setChatId(message.getChatId()); sendMessage.setReplayMarkup(getUnitsKeyboard(language)); sendMessage.setText(getUnitsMessage(message.getFrom().getId(), language)); - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), UNITS); + return sendMessage; } - private static void onLanguageCommand(Message message, String language) { + private static BotApiMethod onLanguageCommand(Message message, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setReplayToMessageId(message.getMessageId()); sendMessage.setChatId(message.getChatId()); sendMessage.setReplayMarkup(getLanguagesKeyboard(language)); sendMessage.setText(getLanguageMessage(language)); - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), LANGUAGE); + return sendMessage; } // endregion Settings Menu Option selected // region Units Menu Option selected - private static void messageOnUnits(Message message, String language) { + private static BotApiMethod messageOnUnits(Message message, String language) { + BotApiMethod botApiMethod = null; if (message.hasText()) { if (message.getText().trim().equals(getCancelCommand(language))) { - onBackUnitsCommand(message, language); + botApiMethod = onBackUnitsCommand(message, language); } else if (message.getText().trim().equals(LocalisationService.getInstance().getString("metricSystem", language))) { - onUnitsChosen(message.getFrom().getId(), message.getChatId(), + botApiMethod = onUnitsChosen(message.getFrom().getId(), message.getChatId(), message.getMessageId(), WeatherService.METRICSYSTEM, language); } else if (message.getText().trim().equals(LocalisationService.getInstance().getString("imperialSystem", language))) { - onUnitsChosen(message.getFrom().getId(), message.getChatId(), + botApiMethod = onUnitsChosen(message.getFrom().getId(), message.getChatId(), message.getMessageId(), WeatherService.IMPERIALSYSTEM, language); } else { - onUnitsError(message.getChatId(), message.getMessageId(), language); + botApiMethod = onUnitsError(message.getChatId(), message.getMessageId(), language); } } + return botApiMethod; } - private static void onBackUnitsCommand(Message message, String language) { + private static BotApiMethod onBackUnitsCommand(Message message, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); ReplyKeyboardMarkup replyKeyboardMarkup = getSettingsKeyboard(language); sendMessage.setReplayMarkup(replyKeyboardMarkup); @@ -414,51 +463,57 @@ public class WeatherHandlers implements UpdatesCallback { sendMessage.setChatId(message.getChatId()); sendMessage.setText(getSettingsMessage(language)); - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), SETTINGS); + return sendMessage; } - private static void onUnitsError(Integer chatId, Integer messageId, String language) { + private static BotApiMethod onUnitsError(Integer chatId, Integer messageId, String language) { SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.enableMarkdown(true); sendMessageRequest.setChatId(chatId); sendMessageRequest.setReplayMarkup(getUnitsKeyboard(language)); sendMessageRequest.setText(LocalisationService.getInstance().getString("errorUnitsNotFound", language)); sendMessageRequest.setReplayToMessageId(messageId); - sendBuiltMessage(sendMessageRequest); + + return sendMessageRequest; } - private static void onUnitsChosen(Integer userId, Integer chatId, Integer messageId, String units, String language) { + private static BotApiMethod onUnitsChosen(Integer userId, Integer chatId, Integer messageId, String units, String language) { DatabaseManager.getInstance().putUserWeatherUnitsOption(userId, units); SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.enableMarkdown(true); sendMessageRequest.setChatId(chatId); sendMessageRequest.setText(LocalisationService.getInstance().getString("unitsUpdated", language)); sendMessageRequest.setReplayToMessageId(messageId); sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(language)); - sendBuiltMessage(sendMessageRequest); DatabaseManager.getInstance().insertWeatherState(userId, chatId, MAINMENU); + return sendMessageRequest; } // endregion Units Menu Option selected // region Language Menu Option selected - private static void messageOnLanguage(Message message, String language) { + private static BotApiMethod messageOnLanguage(Message message, String language) { + BotApiMethod botApiMethod = null; if (message.hasText()) { if (message.getText().trim().equals(getCancelCommand(language))) { - onBackLanguageCommand(message, language); + botApiMethod = onBackLanguageCommand(message, language); } else if (LocalisationService.getInstance().getSupportedLanguages().values().contains(message.getText().trim())) { - onLanguageChosen(message.getFrom().getId(), message.getChatId(), + botApiMethod = onLanguageChosen(message.getFrom().getId(), message.getChatId(), message.getMessageId(), message.getText().trim()); } else { - onLanguageError(message.getChatId(), message.getMessageId(), language); + botApiMethod = onLanguageError(message.getChatId(), message.getMessageId(), language); } } + return botApiMethod; } - private static void onBackLanguageCommand(Message message, String language) { + private static BotApiMethod onBackLanguageCommand(Message message, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); ReplyKeyboardMarkup replyKeyboardMarkup = getSettingsKeyboard(language); sendMessage.setReplayMarkup(replyKeyboardMarkup); @@ -466,123 +521,134 @@ public class WeatherHandlers implements UpdatesCallback { sendMessage.setChatId(message.getChatId()); sendMessage.setText(getSettingsMessage(language)); - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), SETTINGS); + return sendMessage; } - private static void onLanguageError(Integer chatId, Integer messageId, String language) { + private static BotApiMethod onLanguageError(Integer chatId, Integer messageId, String language) { SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.enableMarkdown(true); sendMessageRequest.setChatId(chatId); sendMessageRequest.setReplayMarkup(getLanguagesKeyboard(language)); sendMessageRequest.setText(LocalisationService.getInstance().getString("errorLanguageNotFound", language)); sendMessageRequest.setReplayToMessageId(messageId); - sendBuiltMessage(sendMessageRequest); + + return sendMessageRequest; } - private static void onLanguageChosen(Integer userId, Integer chatId, Integer messageId, String language) { + private static BotApiMethod onLanguageChosen(Integer userId, Integer chatId, Integer messageId, String language) { String languageCode = LocalisationService.getInstance().getLanguageCodeByName(language); DatabaseManager.getInstance().putUserWeatherLanguageOption(userId, languageCode); SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.enableMarkdown(true); sendMessageRequest.setChatId(chatId); sendMessageRequest.setText(LocalisationService.getInstance().getString("languageUpdated", languageCode)); sendMessageRequest.setReplayToMessageId(messageId); sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(languageCode)); - sendBuiltMessage(sendMessageRequest); DatabaseManager.getInstance().insertWeatherState(userId, chatId, MAINMENU); + return sendMessageRequest; } // endregion Language Menu Option selected // region Forecast Weather Menu Option selected - private static void messageOnForecastWeather(Message message, String language, int state) { + private static BotApiMethod messageOnForecastWeather(Message message, String language, int state) { + BotApiMethod botApiMethod = null; switch(state) { case FORECASTWEATHER: - onForecastWeather(message, language); + botApiMethod = onForecastWeather(message, language); break; case FORECASTNEWWEATHER: - onForecastNewWeather(message, language); + botApiMethod = onForecastNewWeather(message, language); break; case FORECASTLOCATIONWEATHER: - onForecastWeatherLocation(message, language); + botApiMethod = onForecastWeatherLocation(message, language); break; } + return botApiMethod; } - private static void onForecastWeather(Message message, String language) { + private static BotApiMethod onForecastWeather(Message message, String language) { + BotApiMethod botApiMethod = null; if (message.hasText()) { if (message.getText().startsWith(getNewCommand(language))) { - onNewForecastWeatherCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), language); + botApiMethod = onNewForecastWeatherCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), language); } else if (message.getText().startsWith(getLocationCommand(language))) { - onLocationForecastWeatherCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), language); + botApiMethod = onLocationForecastWeatherCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), language); } else if (message.getText().startsWith(getCancelCommand(language))) { - onCancelCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), + botApiMethod = onCancelCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), getMainMenuKeyboard(language), language); } else { - onForecastWeatherCityReceived(message.getChatId(), message.getFrom().getId(), message.getMessageId(), + botApiMethod = onForecastWeatherCityReceived(message.getChatId(), message.getFrom().getId(), message.getMessageId(), message.getText(), language); } } + return botApiMethod; } - private static void onForecastNewWeather(Message message, String language) { + private static BotApiMethod onForecastNewWeather(Message message, String language) { if (message.isReply()) { - onForecastWeatherReceived(message.getChatId(), message.getFrom().getId(), message.getMessageId(), message.getText(), language); + return onForecastWeatherReceived(message.getChatId(), message.getFrom().getId(), message.getMessageId(), message.getText(), language); } else { - sendMessageDefault(message, language); + return sendMessageDefault(message, language); } } - private static void onForecastWeatherCityReceived(Integer chatId, Integer userId, Integer messageId, String text, String language) { + private static BotApiMethod onForecastWeatherCityReceived(Integer chatId, Integer userId, Integer messageId, String text, String language) { Integer cityId = DatabaseManager.getInstance().getRecentWeatherIdByCity(userId, text); if (cityId != null) { String unitsSystem = DatabaseManager.getInstance().getUserWeatherOptions(userId)[1]; String weather = WeatherService.getInstance().fetchWeatherForecast(cityId.toString(), userId, language, unitsSystem); SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.enableMarkdown(true); sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(language)); sendMessageRequest.setReplayToMessageId(messageId); sendMessageRequest.setText(weather); sendMessageRequest.setChatId(chatId); - sendBuiltMessage(sendMessageRequest); + DatabaseManager.getInstance().insertWeatherState(userId, chatId, MAINMENU); + return sendMessageRequest; } else { - sendChooseOptionMessage(chatId, messageId, getRecentsKeyboard(userId, language), language); + return sendChooseOptionMessage(chatId, messageId, getRecentsKeyboard(userId, language), language); } } - private static void onLocationForecastWeatherCommand(Integer chatId, Integer userId, Integer messageId, String language) { + private static BotApiMethod onLocationForecastWeatherCommand(Integer chatId, Integer userId, Integer messageId, String language) { ForceReplyKeyboard forceReplyKeyboard = getForceReply(); SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setChatId(chatId); sendMessage.setReplayToMessageId(messageId); sendMessage.setReplayMarkup(forceReplyKeyboard); sendMessage.setText(LocalisationService.getInstance().getString("onWeatherLocationCommand", language)); - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(userId, chatId, FORECASTLOCATIONWEATHER); + return sendMessage; } - private static void onNewForecastWeatherCommand(Integer chatId, Integer userId, Integer messageId, String language) { + private static BotApiMethod onNewForecastWeatherCommand(Integer chatId, Integer userId, Integer messageId, String language) { ForceReplyKeyboard forceReplyKeyboard = getForceReply(); SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setChatId(chatId); sendMessage.setReplayToMessageId(messageId); sendMessage.setReplayMarkup(forceReplyKeyboard); sendMessage.setText(LocalisationService.getInstance().getString("onWeatherNewCommand", language)); - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(userId, chatId, FORECASTNEWWEATHER); + return sendMessage; } - private static void onForecastWeatherLocation(Message message, String language) { + private static BotApiMethod onForecastWeatherLocation(Message message, String language) { if (message.isReply() && message.hasLocation()) { - onForecastWeatherLocationReceived(message, language); + return onForecastWeatherLocationReceived(message, language); } else { - sendMessageDefault(message, language); + return sendMessageDefault(message, language); } } @@ -590,92 +656,100 @@ public class WeatherHandlers implements UpdatesCallback { // region Current Weather Menu Option selected - private static void messageOnCurrentWeather(Message message, String language, int state) { + private static BotApiMethod messageOnCurrentWeather(Message message, String language, int state) { + BotApiMethod botApiMethod = null; switch(state) { case CURRENTWEATHER: - onCurrentWeather(message, language); + botApiMethod = onCurrentWeather(message, language); break; case CURRENTNEWWEATHER: - onCurrentNewWeather(message, language); + botApiMethod = onCurrentNewWeather(message, language); break; case CURRENTLOCATIONWEATHER: - onCurrentWeatherLocation(message, language); + botApiMethod = onCurrentWeatherLocation(message, language); break; } + + return botApiMethod; } - private static void onCurrentWeather(Message message, String language) { + private static BotApiMethod onCurrentWeather(Message message, String language) { + BotApiMethod botApiMethod = null; if (message.hasText()) { if (message.getText().startsWith(getNewCommand(language))) { - onNewCurrentWeatherCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), language); + botApiMethod = onNewCurrentWeatherCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), language); } else if (message.getText().startsWith(getLocationCommand(language))) { - onLocationCurrentWeatherCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), language); + botApiMethod = onLocationCurrentWeatherCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), language); } else if (message.getText().startsWith(getCancelCommand(language))) { - onCancelCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), + botApiMethod = onCancelCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), getMainMenuKeyboard(language), language); } else { - onCurrentWeatherCityReceived(message.getChatId(), message.getFrom().getId(), message.getMessageId(), + botApiMethod = onCurrentWeatherCityReceived(message.getChatId(), message.getFrom().getId(), message.getMessageId(), message.getText(), language); } } + return botApiMethod; } - private static void onCurrentNewWeather(Message message, String language) { + private static BotApiMethod onCurrentNewWeather(Message message, String language) { if (message.isReply()) { - onCurrentWeatherReceived(message.getChatId(), message.getFrom().getId(), message.getMessageId(), message.getText(), language); + return onCurrentWeatherReceived(message.getChatId(), message.getFrom().getId(), message.getMessageId(), message.getText(), language); } else { - sendMessageDefault(message, language); + return sendMessageDefault(message, language); } } - private static void onCurrentWeatherCityReceived(Integer chatId, Integer userId, Integer messageId, String text, String language) { + private static BotApiMethod onCurrentWeatherCityReceived(Integer chatId, Integer userId, Integer messageId, String text, String language) { Integer cityId = DatabaseManager.getInstance().getRecentWeatherIdByCity(userId, text); if (cityId != null) { String unitsSystem = DatabaseManager.getInstance().getUserWeatherOptions(userId)[1]; String weather = WeatherService.getInstance().fetchWeatherCurrent(cityId.toString(), userId, language, unitsSystem); SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.enableMarkdown(true); sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(language)); sendMessageRequest.setReplayToMessageId(messageId); sendMessageRequest.setText(weather); sendMessageRequest.setChatId(chatId); - sendBuiltMessage(sendMessageRequest); DatabaseManager.getInstance().insertWeatherState(userId, chatId, MAINMENU); + return sendMessageRequest; } else { - sendChooseOptionMessage(chatId, messageId, getRecentsKeyboard(userId, language), language); + return sendChooseOptionMessage(chatId, messageId, getRecentsKeyboard(userId, language), language); } } - private static void onLocationCurrentWeatherCommand(Integer chatId, Integer userId, Integer messageId, String language) { + private static BotApiMethod onLocationCurrentWeatherCommand(Integer chatId, Integer userId, Integer messageId, String language) { ForceReplyKeyboard forceReplyKeyboard = getForceReply(); SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setChatId(chatId); sendMessage.setReplayToMessageId(messageId); sendMessage.setReplayMarkup(forceReplyKeyboard); sendMessage.setText(LocalisationService.getInstance().getString("onWeatherLocationCommand", language)); - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(userId, chatId, CURRENTLOCATIONWEATHER); + return sendMessage; } - private static void onNewCurrentWeatherCommand(Integer chatId, Integer userId, Integer messageId, String language) { + private static BotApiMethod onNewCurrentWeatherCommand(Integer chatId, Integer userId, Integer messageId, String language) { ForceReplyKeyboard forceReplyKeyboard = getForceReply(); SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setChatId(chatId); sendMessage.setReplayToMessageId(messageId); sendMessage.setReplayMarkup(forceReplyKeyboard); sendMessage.setText(LocalisationService.getInstance().getString("onWeatherNewCommand", language)); - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(userId, chatId, CURRENTNEWWEATHER); + return sendMessage; } - private static void onCurrentWeatherLocation(Message message, String language) { + private static BotApiMethod onCurrentWeatherLocation(Message message, String language) { if (message.isReply() && message.hasLocation()) { - onCurrentWeatherLocationReceived(message, language); + return onCurrentWeatherLocationReceived(message, language); } else { - sendMessageDefault(message, language); + return sendMessageDefault(message, language); } } @@ -683,28 +757,32 @@ public class WeatherHandlers implements UpdatesCallback { // region Main menu options selected - private static void messageOnMainMenu(Message message, String language) { + private static BotApiMethod messageOnMainMenu(Message message, String language) { + BotApiMethod botApiMethod; if (message.hasText()) { if (message.getText().equals(getCurrentCommand(language))) { - onCurrentChoosen(message, language); + botApiMethod = onCurrentChoosen(message, language); } else if (message.getText().equals(getForecastCommand(language))) { - onForecastChoosen(message, language); + botApiMethod = onForecastChoosen(message, language); } else if (message.getText().equals(getSettingsCommand(language))) { - onSettingsChoosen(message, language); + botApiMethod = onSettingsChoosen(message, language); } else if (message.getText().equals(getRateCommand(language))) { - sendRateMessage(message.getChatId(), message.getMessageId(), null, language); + botApiMethod = sendRateMessage(message.getChatId(), message.getMessageId(), null, language); } else { - sendChooseOptionMessage(message.getChatId(), message.getMessageId(), + botApiMethod = sendChooseOptionMessage(message.getChatId(), message.getMessageId(), getMainMenuKeyboard(language), language); } } else { - sendChooseOptionMessage(message.getChatId(), message.getMessageId(), + botApiMethod = sendChooseOptionMessage(message.getChatId(), message.getMessageId(), getMainMenuKeyboard(language), language); } + + return botApiMethod; } - private static void onSettingsChoosen(Message message, String language) { + private static BotApiMethod onSettingsChoosen(Message message, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); ReplyKeyboardMarkup replyKeyboardMarkup = getSettingsKeyboard(language); sendMessage.setReplayMarkup(replyKeyboardMarkup); @@ -712,12 +790,13 @@ public class WeatherHandlers implements UpdatesCallback { sendMessage.setChatId(message.getChatId()); sendMessage.setText(getSettingsMessage(language)); - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), SETTINGS); + return sendMessage; } - private static void onForecastChoosen(Message message, String language) { + private static BotApiMethod onForecastChoosen(Message message, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); ReplyKeyboardMarkup replyKeyboardMarkup = getRecentsKeyboard(message.getFrom().getId(), language); sendMessage.setReplayMarkup(replyKeyboardMarkup); @@ -729,12 +808,13 @@ public class WeatherHandlers implements UpdatesCallback { sendMessage.setText(LocalisationService.getInstance().getString("onForecastCommandWithoutHistory", language)); } - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), FORECASTWEATHER); + return sendMessage; } - private static void onCurrentChoosen(Message message, String language) { + private static BotApiMethod onCurrentChoosen(Message message, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); ReplyKeyboardMarkup replyKeyboardMarkup = getRecentsKeyboard(message.getFrom().getId(), language); sendMessage.setReplayMarkup(replyKeyboardMarkup); @@ -746,8 +826,8 @@ public class WeatherHandlers implements UpdatesCallback { sendMessage.setText(LocalisationService.getInstance().getString("onCurrentCommandWithoutHistory", language)); } - sendBuiltMessage(sendMessage); DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), CURRENTWEATHER); + return sendMessage; } // endregion Main menu options selected @@ -1040,11 +1120,6 @@ public class WeatherHandlers implements UpdatesCallback { Emoji.BLACK_RIGHT_POINTING_TRIANGLE.toString()); } - private static String getHelpCommand(String language) { - return String.format(LocalisationService.getInstance().getString("help", language), - Emoji.BLACK_QUESTION_MARK_ORNAMENT.toString()); - } - private static String getForecastCommand(String language) { return String.format(LocalisationService.getInstance().getString("forecast", language), Emoji.BLACK_RIGHT_POINTING_DOUBLE_TRIANGLE.toString()); @@ -1058,96 +1133,109 @@ public class WeatherHandlers implements UpdatesCallback { // region Send common messages - private static void sendMessageDefault(Message message, String language) { + private static BotApiMethod sendMessageDefault(Message message, String language) { ReplyKeyboardMarkup replyKeyboardMarkup = getMainMenuKeyboard(language); - sendHelpMessage(message.getChatId(), message.getMessageId(), replyKeyboardMarkup, language); DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), MAINMENU); + return sendHelpMessage(message.getChatId(), message.getMessageId(), replyKeyboardMarkup, language); } - private static void sendChooseOptionMessage(Integer chatId, Integer messageId, + private static BotApiMethod sendChooseOptionMessage(Integer chatId, Integer messageId, ReplyKeyboard replyKeyboard, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setChatId(chatId); sendMessage.setReplayToMessageId(messageId); sendMessage.setReplayMarkup(replyKeyboard); sendMessage.setText(LocalisationService.getInstance().getString("chooseOption", language)); - sendBuiltMessage(sendMessage); + + return sendMessage; } - private static void sendHelpMessage(Integer chatId, Integer messageId, ReplyKeyboardMarkup replyKeyboardMarkup, String language) { + private static BotApiMethod sendHelpMessage(Integer chatId, Integer messageId, ReplyKeyboardMarkup replyKeyboardMarkup, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setChatId(chatId); sendMessage.setReplayToMessageId(messageId); if (replyKeyboardMarkup != null) { sendMessage.setReplayMarkup(replyKeyboardMarkup); } sendMessage.setText(getHelpMessage(language)); - sendBuiltMessage(sendMessage); + return sendMessage; } - private static void sendRateMessage(Integer chatId, Integer messageId, ReplyKeyboardMarkup replyKeyboardMarkup, String language) { + private static BotApiMethod sendRateMessage(Integer chatId, Integer messageId, ReplyKeyboardMarkup replyKeyboardMarkup, String language) { SendMessage sendMessage = new SendMessage(); + sendMessage.enableMarkdown(true); sendMessage.setChatId(chatId); sendMessage.setReplayToMessageId(messageId); if (replyKeyboardMarkup != null) { sendMessage.setReplayMarkup(replyKeyboardMarkup); } sendMessage.setText(LocalisationService.getInstance().getString("rateMeMessage", language)); - sendBuiltMessage(sendMessage); + + return sendMessage; } // endregion Send common messages // region Send weather - private static void onForecastWeatherLocationReceived(Message message, String language) { + private static BotApiMethod onForecastWeatherLocationReceived(Message message, String language) { String unitsSystem = DatabaseManager.getInstance().getUserWeatherOptions(message.getFrom().getId())[1]; String weather = WeatherService.getInstance().fetchWeatherForecastByLocation(message.getLocation().getLongitude(), message.getLocation().getLatitude(), message.getFrom().getId(), language, unitsSystem); SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.enableMarkdown(true); sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(language)); sendMessageRequest.setReplayToMessageId(message.getMessageId()); sendMessageRequest.setText(weather); sendMessageRequest.setChatId(message.getChatId()); - sendBuiltMessage(sendMessageRequest); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), MAINMENU); + return sendMessageRequest; } - private static void onForecastWeatherReceived(Integer chatId, Integer userId, Integer messageId, String text, String language) { + private static BotApiMethod onForecastWeatherReceived(Integer chatId, Integer userId, Integer messageId, String text, String language) { String unitsSystem = DatabaseManager.getInstance().getUserWeatherOptions(userId)[1]; String weather = WeatherService.getInstance().fetchWeatherForecast(text, userId, language, unitsSystem); SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.enableMarkdown(true); sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(language)); sendMessageRequest.setReplayToMessageId(messageId); sendMessageRequest.setText(weather); sendMessageRequest.setChatId(chatId); - sendBuiltMessage(sendMessageRequest); + DatabaseManager.getInstance().insertWeatherState(userId, chatId, MAINMENU); + return sendMessageRequest; } - private static void onCurrentWeatherLocationReceived(Message message, String language) { + private static BotApiMethod onCurrentWeatherLocationReceived(Message message, String language) { String unitsSystem = DatabaseManager.getInstance().getUserWeatherOptions(message.getFrom().getId())[1]; String weather = WeatherService.getInstance().fetchWeatherCurrentByLocation(message.getLocation().getLongitude(), message.getLocation().getLatitude(), message.getFrom().getId(), language, unitsSystem); SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.enableMarkdown(true); sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(language)); sendMessageRequest.setReplayToMessageId(message.getMessageId()); sendMessageRequest.setText(weather); sendMessageRequest.setChatId(message.getChatId()); - sendBuiltMessage(sendMessageRequest); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), MAINMENU); + return sendMessageRequest; } - private static void onCurrentWeatherReceived(Integer chatId, Integer userId, Integer messageId, String text, String language) { + private static BotApiMethod onCurrentWeatherReceived(Integer chatId, Integer userId, Integer messageId, String text, String language) { String unitsSystem = DatabaseManager.getInstance().getUserWeatherOptions(userId)[1]; String weather = WeatherService.getInstance().fetchWeatherCurrent(text, userId, language, unitsSystem); SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.enableMarkdown(true); sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(language)); sendMessageRequest.setReplayToMessageId(messageId); sendMessageRequest.setText(weather); sendMessageRequest.setChatId(chatId); - sendBuiltMessage(sendMessageRequest); + DatabaseManager.getInstance().insertWeatherState(userId, chatId, MAINMENU); + return sendMessageRequest; } // endregion Send weather @@ -1155,7 +1243,7 @@ public class WeatherHandlers implements UpdatesCallback { // region Helper Methods private static void sendBuiltMessage(SendMessage sendMessage) { - SenderHelper.SendMessage(sendMessage, TOKEN); + SenderHelper.SendApiMethod(sendMessage, TOKEN); } // endregion Helper Methods diff --git a/src/main/java/org/telegram/updatesreceivers/RestApi.java b/src/main/java/org/telegram/updatesreceivers/RestApi.java index c12d89f..08d0d50 100644 --- a/src/main/java/org/telegram/updatesreceivers/RestApi.java +++ b/src/main/java/org/telegram/updatesreceivers/RestApi.java @@ -1,10 +1,12 @@ package org.telegram.updatesreceivers; -import org.telegram.api.Update; +import org.telegram.api.objects.Update; import org.telegram.updateshandlers.UpdatesCallback; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.concurrent.ConcurrentHashMap; /** * @author Ruben Bermudez @@ -15,21 +17,36 @@ import javax.ws.rs.core.MediaType; @Path("callback") public class RestApi { - private final UpdatesCallback callback; + private final ConcurrentHashMap callbacks = new ConcurrentHashMap<>(); - public RestApi(UpdatesCallback callback) { - this.callback = callback; + public RestApi() { + } + + public void registerCallback(UpdatesCallback callback, String botName) { + if (!callbacks.containsKey(botName)) { + callbacks.put(botName, callback); + } } @POST + @Path("/{botname}") @Consumes(MediaType.APPLICATION_JSON) - public void updateReceived(Update update) { - this.callback.onUpdateReceived(update); + @Produces(MediaType.APPLICATION_JSON) + public Response updateReceived(@PathParam("botname") String botname, Update update) { + if (callbacks.containsKey(botname)) { + return Response.ok(this.callbacks.get(botname).onWebhookUpdateReceived(update)).build(); + } + return Response.ok().build(); } @GET + @Path("/{botname}") @Produces(MediaType.APPLICATION_JSON) - public String testReceived() { - return "Hi there"; + public String testReceived(@PathParam("botname") String botname) { + if (callbacks.containsKey(botname)) { + return "Hi there " + botname + "!"; + } else { + return "Callback not found for " + botname; + } } } diff --git a/src/main/java/org/telegram/updatesreceivers/UpdatesThread.java b/src/main/java/org/telegram/updatesreceivers/UpdatesThread.java index 3baba0c..1562242 100644 --- a/src/main/java/org/telegram/updatesreceivers/UpdatesThread.java +++ b/src/main/java/org/telegram/updatesreceivers/UpdatesThread.java @@ -2,29 +2,26 @@ package org.telegram.updatesreceivers; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.entity.BufferedHttpEntity; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.telegram.api.Update; +import org.telegram.api.objects.Update; import org.telegram.database.DatabaseManager; -import org.telegram.methods.Constants; -import org.telegram.methods.GetUpdates; +import org.telegram.api.methods.Constants; +import org.telegram.api.methods.GetUpdates; import org.telegram.services.BotLogger; import org.telegram.updateshandlers.UpdatesCallback; import java.io.IOException; import java.io.InvalidObjectException; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.TimeUnit; @@ -66,16 +63,9 @@ public class UpdatesThread { CloseableHttpClient httpclient = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).setConnectionTimeToLive(20, TimeUnit.SECONDS).build(); String url = Constants.BASEURL + token + "/" + GetUpdates.PATH; HttpPost httpPost = new HttpPost(url); - List nameValuePairs = new ArrayList<>(); - nameValuePairs.add(new BasicNameValuePair(GetUpdates.OFFSET_FIELD, request.getOffset()+"")); - nameValuePairs.add(new BasicNameValuePair(GetUpdates.LIMIT_FIELD, request.getLimit()+"")); - if (request.getTimeout() != null) { - nameValuePairs.add(new BasicNameValuePair(GetUpdates.TIMEOUT_FIELD, request.getTimeout()+"")); - } try { - httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8")); - httpPost.addHeader("Content-type", "application/x-www-form-urlencoded"); httpPost.addHeader("charset", "UTF-8"); + httpPost.setEntity(new StringEntity(request.toJson().toString(), ContentType.APPLICATION_JSON)); HttpResponse response; log.debug(httpPost.toString()); response = httpclient.execute(httpPost); diff --git a/src/main/java/org/telegram/updatesreceivers/Webhook.java b/src/main/java/org/telegram/updatesreceivers/Webhook.java index 6f31abc..f1a1036 100644 --- a/src/main/java/org/telegram/updatesreceivers/Webhook.java +++ b/src/main/java/org/telegram/updatesreceivers/Webhook.java @@ -23,16 +23,20 @@ import java.net.URI; public class Webhook { private static volatile BotLogger log = BotLogger.getLogger(Webhook.class.getName()); - private static final int PORT = 443; private static final String KEYSTORE_SERVER_FILE = "./keystore_server"; private static final String KEYSTORE_SERVER_PWD = "asdfgh"; - private final String path; + private final RestApi restApi; + public Webhook() { + this.restApi = new RestApi(); + } + + public void registerWebhook(UpdatesCallback callback, String botName) { + restApi.registerCallback(callback, botName); + } - public Webhook(UpdatesCallback callback, String webhookPath) { - this.path = webhookPath; - RestApi restApi = new RestApi(callback); + public void startServer() { SSLContextConfigurator sslContext = new SSLContextConfigurator(); // set up security context @@ -43,7 +47,7 @@ public class Webhook { rc.register(restApi); rc.register(JacksonFeature.class); rc.property(JSONConfiguration.FEATURE_POJO_MAPPING, true); - + log.error("Internal webhook: " + getBaseURI().toString()); final HttpServer grizzlyServer = GrizzlyHttpServerFactory.createHttpServer( getBaseURI(), rc, @@ -56,11 +60,19 @@ public class Webhook { } } - private URI getBaseURI() { - return URI.create(String.format("%s:%d/%s", BuildVars.INTERNALWEBHOOKURL, PORT, this.path)); + public void startDebugServer() { + ResourceConfig rc = new ResourceConfig(); + rc.register(restApi); + rc.register(JacksonFeature.class); + rc.property(JSONConfiguration.FEATURE_POJO_MAPPING, true); + GrizzlyHttpServerFactory.createHttpServer(getBaseURI(), rc); + } + + public static String getExternalURL(String botName) { + return String.format("%s/callback/%s", BuildVars.EXTERNALWEBHOOKURL, botName); } - public String getURL() { - return String.format("%s/%s/callback", BuildVars.BASEWEBHOOKURL, this.path); + private static URI getBaseURI() { + return URI.create(BuildVars.INTERNALWEBHOOKURL); } } diff --git a/src/main/resources/localisation/strings.properties b/src/main/resources/localisation/strings.properties index ee3d874..eb71f57 100644 --- a/src/main/resources/localisation/strings.properties +++ b/src/main/resources/localisation/strings.properties @@ -44,42 +44,42 @@ delete=%sDelete showList=%sShow list rateMe=%sRate me metricSystem=Metric System -imperialSystem= Imperial System -selectLanguage=Your current language is %s. Select a language from the list to change to that language. +imperialSystem=Imperial System +selectLanguage=Your current language is *%s*. Select a language from the list to change to that language. languageUpdated=Your language setting has been updated. errorLanguageNotFound= We don't support that language or a typo was made. Please select one from the list. -selectUnits=Your current unit setting is %s. Select an option from the list to change it. +selectUnits=Your current unit setting is *%s*. Select an option from the list to change it. unitsUpdated=Your unit settings have been updated. errorUnitsNotFound= We don't support that unit system or a typo was made. Please select one from the list. -onWeatherNewCommand=Please send me the city you are interested in, please use this format: CITY,COUNTRY +onWeatherNewCommand=Please send me the city you are interested in using this format: *CITY,COUNTRY* onWeatherLocationCommand=Please send me the location you are interested in. -onCurrentCommandFromHistory=Select an option from your recent requests, "new" to send a new city or "location" to send me a location to get current weather. -onCurrentCommandWithoutHistory=Select "new" to send a new city or "location" to send me a location to get current weather. -onForecastCommandFromHistory=Select an option from your recent requests, "new" to send a new city or "location" to send me a location to get 3-day weather forecast. -onForecastCommandWithoutHistory=Select "new" to send a new city or "location" to send me a location to get a 3-day weather forecast. -weatherCurrent= The weather for %s is:\n\n %s -currentWeatherPartMetric=\t- Weather: %s\n\t- Cloudiness: %s\n\t- Temperature: %s ºC\n\n -currentWeatherPartImperial=\t- Weather: %s\n\t- Cloudiness: %s\n\t- Temperature: %s ºF\n\n -weatherForcast= The weather for %s will be:\n\n %s -forecastWeatherPartMetric= %s On %s \n\t- Forecast: %s\n\t- High temperature: %s ºC\n\t- Low temperature: %s ºC\n\n -forecastWeatherPartImperial= %s On %s \n\t- Forecast: %s\n\t- High temperature: %s ºF\n\t- Low temperature: %s ºF\n\n -weatherAlert= The weather for %s will be:\n\n %s -alertWeatherPartMetric=\t- Forecast: %s\n\t- High temperature: %s ºC\n\t- Low temperature: %s ºC\n\n -alertWeatherPartImperial=\t- Forecast: %s\n\t- High temperature: %s ºF\n\t- Low temperature: %s ºF\n\n +onCurrentCommandFromHistory=Select an option from your _recent requests_, *new* to send a new city or *location* to send me a location to get current weather. +onCurrentCommandWithoutHistory=Select *new* to send a new city or *location* to send me a location to get current weather. +onForecastCommandFromHistory=Select an option from your _recent requests_, *new* to send a new city or *location* to send me a location to get _3-days_ weather forecast. +onForecastCommandWithoutHistory=Select *new* to send a new city or *location* to send me a location to get a _3-days_ weather forecast. +weatherCurrent= The weather for *%s* is:\n\n %s +currentWeatherPartMetric=\t- _Weather:_ %s\n\t- _Cloudiness:_ %s\n\t- _Temperature:_ %s ºC\n\n +currentWeatherPartImperial=\t- _Weather:_ %s\n\t- _Cloudiness:_ %s\n\t- _Temperature:_ %s ºF\n\n +weatherForcast= The weather for *%s* will be:\n\n %s +forecastWeatherPartMetric= %s On *%s* \n\t- _Forecast:_ %s\n\t- _High temperature:_ %s ºC\n\t- _Low temperature:_ %s ºC\n\n +forecastWeatherPartImperial= %s On *%s* \n\t- _Forecast:_ %s\n\t- _High temperature:_ %s ºF\n\t- _Low temperature:_ %s ºF\n\n +weatherAlert= The weather for *%s* will be:\n\n %s +alertWeatherPartMetric=\t- _Forecast:_ %s\n\t- _High temperature:_ %s ºC\n\t- _Low temperature:_ %s ºC\n\n +alertWeatherPartImperial=\t- _Forecast:_ %s\n\t- _High temperature:_ %s ºF\n\t- _Low temperature:_ %s ºF\n\n chooseOption=Please, select an option from the menu. backToMainMenu=Process cancelled, back to main menu. onSettingsCommand=Please, select an option:\ -\n\t\t%s Languages: Select a forecast-language\ -\n\t\t%s Units: Select your preferred units\ -\n\t\t%s Alerts: Set daily alerts\ -\n\t\t%s Back: Return to main menu +\n\t\t%s *Languages*: Select a _forecast-language_\ +\n\t\t%s *Units*: Select your preferred _units_\ +\n\t\t%s *Alerts*: Set daily _alerts_\ +\n\t\t%s *Back*: Return to main menu alertsMenuMessage=Here you can manage your alerts or add new ones. -chooseNewAlertCity=Which city do you want to set an alert for? Select an option from your recent requests. -newAlertSaved=%s Your alert for %s has been correctly created, you will receive the weather update twice a day. -initialAlertList=You have %d alerts:\n\n%s -partialAlertList=%s%s\n +chooseNewAlertCity=Which city do you want to set an alert for? Select an option from your _recent requests_. +newAlertSaved=%s Your alert for *%s* has been correctly created, you will receive the weather update _twice a day_. +initialAlertList=You have *%d* alerts:\n\n%s +partialAlertList=%s *%s*\n noAlertList=I couldn't find any alert for you. alertDeleted=The selected alert has been deleted. cityNotFound= City not found errorFetchingWeather= We're sorry, there was an error fetching the weather. -rateMeMessage=If you like this bot, please rate it at https://telegram.me/storebot?start=weatherbot \ No newline at end of file +rateMeMessage=If you like this bot, please rate it using [@storebot](https://telegram.me/storebot?start=weatherbot) \ No newline at end of file