diff --git a/src/main/java/org/telegram/telegrambots/api/methods/AnswerCallbackQuery.java b/src/main/java/org/telegram/telegrambots/api/methods/AnswerCallbackQuery.java index a0028544..f044bf8c 100644 --- a/src/main/java/org/telegram/telegrambots/api/methods/AnswerCallbackQuery.java +++ b/src/main/java/org/telegram/telegrambots/api/methods/AnswerCallbackQuery.java @@ -25,6 +25,7 @@ public class AnswerCallbackQuery extends BotApiMethod { private static final String CALLBACKQUERYID_FIELD = "callback_query_id"; private static final String TEXT_FIELD = "text"; private static final String SHOWALERT_FIELD = "show_alert"; + private static final String URL_FIELD = "url"; @JsonProperty(CALLBACKQUERYID_FIELD) private String callbackQueryId; ///< Unique identifier for the query to be answered @@ -32,6 +33,8 @@ public class AnswerCallbackQuery extends BotApiMethod { private String text; ///< Optional Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters @JsonProperty(SHOWALERT_FIELD) private Boolean showAlert; ///< Optional. If true, an alert will be shown by the client instead of a notificaiton at the top of the chat screen. Defaults to false. + @JsonProperty(URL_FIELD) + private String url; ///< Optional. URL that will be opened by the user's client. To enable this option for your bot, please contact @Botfather, send the command /setcustomurls, and accept the terms. public AnswerCallbackQuery() { super(); @@ -49,16 +52,27 @@ public class AnswerCallbackQuery extends BotApiMethod { return this.text; } - public void setText(String text) { + public AnswerCallbackQuery setText(String text) { this.text = text; + return this; } public Boolean getShowAlert() { return this.showAlert; } - public void setShowAlert(Boolean showAlert) { + public AnswerCallbackQuery setShowAlert(Boolean showAlert) { this.showAlert = showAlert; + return this; + } + + public String getUrl() { + return url; + } + + public AnswerCallbackQuery setUrl(String url) { + this.url = url; + return this; } @Override @@ -71,6 +85,9 @@ public class AnswerCallbackQuery extends BotApiMethod { if (showAlert != null) { jsonObject.put(SHOWALERT_FIELD, showAlert); } + if (url != null) { + jsonObject.put(URL_FIELD, url); + } return jsonObject; } @@ -105,6 +122,9 @@ public class AnswerCallbackQuery extends BotApiMethod { if (showAlert != null) { gen.writeBooleanField(SHOWALERT_FIELD, showAlert); } + if (url != null) { + gen.writeStringField(URL_FIELD, url); + } gen.writeEndObject(); gen.flush(); } @@ -120,6 +140,7 @@ public class AnswerCallbackQuery extends BotApiMethod { "callbackQueryId='" + callbackQueryId + '\'' + ", text='" + text + '\'' + ", showAlert=" + showAlert + + ", url='" + url + '\'' + '}'; } } diff --git a/src/main/java/org/telegram/telegrambots/api/methods/games/GetGameHighScores.java b/src/main/java/org/telegram/telegrambots/api/methods/games/GetGameHighScores.java new file mode 100644 index 00000000..29df4fca --- /dev/null +++ b/src/main/java/org/telegram/telegrambots/api/methods/games/GetGameHighScores.java @@ -0,0 +1,194 @@ +/* + * This file is part of TelegramBots. + * + * Foobar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ +package org.telegram.telegrambots.api.methods.games; + +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.telegrambots.Constants; +import org.telegram.telegrambots.api.methods.BotApiMethod; +import org.telegram.telegrambots.api.objects.games.GameHighScore; +import org.telegram.telegrambots.exceptions.TelegramApiValidationException; + +import java.io.IOException; +import java.util.ArrayList; + +/** + * @author Ruben Bermudez + * @version 2.4 + * @brief Use this method to get game high score with a score of the specified user and some + * of its neighbours in the game. + * On success, Array of GameHighScore is returned. + * @date 16 of September of 2016 + */ +public class GetGameHighScores extends BotApiMethod> { + public static final String PATH = "setGameScore"; + + private static final String CHATID_FIELD = "chat_id"; + private static final String MESSAGEID_FIELD = "message_id"; + private static final String INLINE_MESSAGE_ID_FIELD = "inline_message_id"; + private static final String USER_ID_FIELD = "user_id"; + private static final String GAME_ID_FIELD = "game_id"; + + private String chatId; ///< Optional Required if inline_message_id is not specified. Unique identifier for the target chat (or username of the target channel in the format @channelusername) + private Integer messageId; ///< Optional Required if inline_message_id is not specified. Unique identifier of the sent message + private String inlineMessageId; ///< Optional Required if chat_id and message_id are not specified. Identifier of the inline message + private Integer userId; ///< User identifier + private Integer gameId; ///< Game identifier + + public GetGameHighScores() { + } + + public String getChatId() { + return chatId; + } + + public Integer getMessageId() { + return messageId; + } + + public String getInlineMessageId() { + return inlineMessageId; + } + + public Integer getUserId() { + return userId; + } + + public Integer getGameId() { + return gameId; + } + + public GetGameHighScores setChatId(String chatId) { + this.chatId = chatId; + return this; + } + + public GetGameHighScores setMessageId(Integer messageId) { + this.messageId = messageId; + return this; + } + + public GetGameHighScores setInlineMessageId(String inlineMessageId) { + this.inlineMessageId = inlineMessageId; + return this; + } + + public GetGameHighScores setUserId(Integer userId) { + this.userId = userId; + return this; + } + + public GetGameHighScores setGameId(Integer gameId) { + this.gameId = gameId; + return this; + } + + @Override + public String getPath() { + return PATH; + } + + @Override + public ArrayList deserializeResponse(JSONObject answer) { + if (answer.getBoolean(Constants.RESPONSEFIELDOK)) { + JSONArray highScores = answer.getJSONArray(Constants.RESPONSEFIELDRESULT); + ArrayList scores = new ArrayList<>(); + for (int i = 0; i < highScores.length(); i++) { + scores.add(new GameHighScore(highScores.getJSONObject(i))); + } + return scores; + } + return null; + } + + @Override + public void validate() throws TelegramApiValidationException { + if (userId == null) { + throw new TelegramApiValidationException("UserId parameter can't be empty", this); + } + if (gameId == null) { + throw new TelegramApiValidationException("GameId parameter can't be empty", this); + } + if (inlineMessageId == null) { + if (chatId == null) { + throw new TelegramApiValidationException("ChatId parameter can't be empty if inlineMessageId is not present", this); + } + if (messageId == null) { + throw new TelegramApiValidationException("MessageId parameter can't be empty if inlineMessageId is not present", this); + } + } else { + if (chatId != null) { + throw new TelegramApiValidationException("ChatId parameter must be empty if inlineMessageId is provided", this); + } + if (messageId != null) { + throw new TelegramApiValidationException("MessageId parameter must be empty if inlineMessageId is provided", this); + } + } + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + if (chatId != null) { + gen.writeStringField(CHATID_FIELD, chatId); + gen.writeNumberField(MESSAGEID_FIELD, messageId); + } + if (inlineMessageId != null) { + gen.writeStringField(INLINE_MESSAGE_ID_FIELD, inlineMessageId); + } + gen.writeNumberField(USER_ID_FIELD, userId); + gen.writeNumberField(GAME_ID_FIELD, gameId); + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + serialize(gen, serializers); + } + + @Override + public JSONObject toJson() { + JSONObject jsonObject = new JSONObject(); + if (chatId != null) { + jsonObject.put(CHATID_FIELD, chatId); + jsonObject.put(MESSAGEID_FIELD, messageId); + } + if (inlineMessageId != null) { + jsonObject.put(INLINE_MESSAGE_ID_FIELD, inlineMessageId); + } + jsonObject.put(USER_ID_FIELD, userId); + jsonObject.put(GAME_ID_FIELD, gameId); + + return jsonObject; + } + + @Override + public String toString() { + return "GetGameHighScores{" + + "chatId='" + chatId + '\'' + + ", messageId=" + messageId + + ", inlineMessageId='" + inlineMessageId + '\'' + + ", userId=" + userId + + ", gameId=" + gameId + + '}'; + } +} diff --git a/src/main/java/org/telegram/telegrambots/api/methods/games/SetGameScore.java b/src/main/java/org/telegram/telegrambots/api/methods/games/SetGameScore.java new file mode 100644 index 00000000..887580f1 --- /dev/null +++ b/src/main/java/org/telegram/telegrambots/api/methods/games/SetGameScore.java @@ -0,0 +1,232 @@ +/* + * This file is part of TelegramBots. + * + * Foobar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + +package org.telegram.telegrambots.api.methods.games; + +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.telegrambots.Constants; +import org.telegram.telegrambots.api.methods.BotApiMethod; +import org.telegram.telegrambots.api.objects.Message; +import org.telegram.telegrambots.exceptions.TelegramApiValidationException; + +import java.io.IOException; +import java.io.Serializable; + +/** + * @author Ruben Bermudez + * @version 2.4 + * @brief Use this method to set game score of the specified user in the game. + * On success, if edited message is sent by the bot, the edited Message is returned, + * otherwise True is returned. + * If score is not greater than current users score in the chat, + * an error with description “BOT_SCORE_NOT_MODIFIED” will be returned. + * @date 16 of September of 2016 + */ +public class SetGameScore extends BotApiMethod { + public static final String PATH = "setGameScore"; + + private static final String CHATID_FIELD = "chat_id"; + private static final String MESSAGEID_FIELD = "message_id"; + private static final String INLINE_MESSAGE_ID_FIELD = "inline_message_id"; + private static final String EDIT_MESSAGE_FIELD = "edit_message"; + private static final String USER_ID_FIELD = "user_id"; + private static final String GAME_ID_FIELD = "game_id"; + private static final String SCORE_FIELD = "score"; + + private String chatId; ///< Optional Required if inline_message_id is not specified. Unique identifier for the target chat (or username of the target channel in the format @channelusername) + private Integer messageId; ///< Optional Required if inline_message_id is not specified. Unique identifier of the sent message + private String inlineMessageId; ///< Optional Required if chat_id and message_id are not specified. Identifier of the inline message + private Boolean editMessage; ///< Optional Pass True, if the message should be edited to include the current scoreboard + private Integer userId; ///< User identifier + private Integer gameId; ///< Game identifier + private Integer score; ///< New score, must be positive + + public SetGameScore() { + } + + public String getChatId() { + return chatId; + } + + public Integer getMessageId() { + return messageId; + } + + public String getInlineMessageId() { + return inlineMessageId; + } + + public Boolean getEditMessage() { + return editMessage; + } + + public Integer getUserId() { + return userId; + } + + public Integer getGameId() { + return gameId; + } + + public Integer getScore() { + return score; + } + + public SetGameScore setChatId(String chatId) { + this.chatId = chatId; + return this; + } + + public SetGameScore setMessageId(Integer messageId) { + this.messageId = messageId; + return this; + } + + public SetGameScore setInlineMessageId(String inlineMessageId) { + this.inlineMessageId = inlineMessageId; + return this; + } + + public SetGameScore setEditMessage(Boolean editMessage) { + this.editMessage = editMessage; + return this; + } + + public SetGameScore setUserId(Integer userId) { + this.userId = userId; + return this; + } + + public SetGameScore setGameId(Integer gameId) { + this.gameId = gameId; + return this; + } + + public SetGameScore setScore(Integer score) { + this.score = score; + return this; + } + + @Override + public String getPath() { + return PATH; + } + + @Override + public Serializable deserializeResponse(JSONObject answer) { + if (answer.getBoolean(Constants.RESPONSEFIELDOK)) { + Object result = answer.get(Constants.RESPONSEFIELDRESULT); + if (result instanceof Boolean) { + return (Boolean) result; + } + if (result instanceof JSONObject) { + return new Message((JSONObject) result); + } + } + return null; + } + + @Override + public void validate() throws TelegramApiValidationException { + if (userId == null) { + throw new TelegramApiValidationException("UserId parameter can't be empty", this); + } + if (gameId == null) { + throw new TelegramApiValidationException("GameId parameter can't be empty", this); + } + if (score == null) { + throw new TelegramApiValidationException("Score parameter can't be empty", this); + } + if (inlineMessageId == null) { + if (chatId == null) { + throw new TelegramApiValidationException("ChatId parameter can't be empty if inlineMessageId is not present", this); + } + if (messageId == null) { + throw new TelegramApiValidationException("MessageId parameter can't be empty if inlineMessageId is not present", this); + } + } else { + if (chatId != null) { + throw new TelegramApiValidationException("ChatId parameter must be empty if inlineMessageId is provided", this); + } + if (messageId != null) { + throw new TelegramApiValidationException("MessageId parameter must be empty if inlineMessageId is provided", this); + } + } + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + if (chatId != null) { + gen.writeStringField(CHATID_FIELD, chatId); + gen.writeNumberField(MESSAGEID_FIELD, messageId); + } + if (inlineMessageId != null) { + gen.writeStringField(INLINE_MESSAGE_ID_FIELD, inlineMessageId); + } + if (editMessage != null) { + gen.writeBooleanField(EDIT_MESSAGE_FIELD, editMessage); + } + gen.writeNumberField(USER_ID_FIELD, userId); + gen.writeNumberField(GAME_ID_FIELD, gameId); + gen.writeNumberField(SCORE_FIELD, score); + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + serialize(gen, serializers); + } + + @Override + public JSONObject toJson() { + JSONObject jsonObject = new JSONObject(); + if (chatId != null) { + jsonObject.put(CHATID_FIELD, chatId); + jsonObject.put(MESSAGEID_FIELD, messageId); + } + if (inlineMessageId != null) { + jsonObject.put(INLINE_MESSAGE_ID_FIELD, inlineMessageId); + } + if (editMessage != null) { + jsonObject.put(EDIT_MESSAGE_FIELD, editMessage); + } + jsonObject.put(USER_ID_FIELD, userId); + jsonObject.put(GAME_ID_FIELD, gameId); + jsonObject.put(SCORE_FIELD, score); + + return jsonObject; + } + + @Override + public String toString() { + return "SetGameScore{" + + "chatId='" + chatId + '\'' + + ", messageId=" + messageId + + ", inlineMessageId='" + inlineMessageId + '\'' + + ", editMessage=" + editMessage + + ", userId=" + userId + + ", gameId=" + gameId + + ", score=" + score + + '}'; + } +} diff --git a/src/main/java/org/telegram/telegrambots/api/objects/CallbackQuery.java b/src/main/java/org/telegram/telegrambots/api/objects/CallbackQuery.java index 9ba89e0c..d0bb4cac 100644 --- a/src/main/java/org/telegram/telegrambots/api/objects/CallbackQuery.java +++ b/src/main/java/org/telegram/telegrambots/api/objects/CallbackQuery.java @@ -26,6 +26,9 @@ public class CallbackQuery implements IBotApiObject { private static final String MESSAGE_FIELD = "message"; private static final String INLINE_MESSAGE_ID_FIELD = "inline_message_id"; private static final String DATA_FIELD = "data"; + private static final String GAMEID_FIELD = "game_id"; + private static final String CHAT_INSTANCE_FIELD = "chat_instance"; + @JsonProperty(ID_FIELD) private String id; ///< Unique identifier for this query @JsonProperty(FROM_FIELD) @@ -47,6 +50,11 @@ public class CallbackQuery implements IBotApiObject { * @note Be aware that a bad client can send arbitrary data in this field */ private String data; + @JsonProperty(GAMEID_FIELD) + private Integer gameId; ///< Optional. Game identifier as specified in the callback game button. Be aware that a bad client can send an arbitrary identifier in this field. + @JsonProperty(CHAT_INSTANCE_FIELD) + private String chatInstance; ///< Identifier, uniquely corresponding to the chat a message with the callback button was sent to + public CallbackQuery() { super(); } @@ -55,6 +63,7 @@ public class CallbackQuery implements IBotApiObject { super(); this.id = jsonObject.getString(ID_FIELD); this.from = new User(jsonObject.getJSONObject(FROM_FIELD)); + chatInstance = jsonObject.getString(CHAT_INSTANCE_FIELD); if (jsonObject.has(MESSAGE_FIELD)) { this.message = new Message(jsonObject.getJSONObject(MESSAGE_FIELD)); } @@ -64,6 +73,9 @@ public class CallbackQuery implements IBotApiObject { if (jsonObject.has(DATA_FIELD)) { data = jsonObject.getString(DATA_FIELD); } + if (jsonObject.has(GAMEID_FIELD)) { + gameId = jsonObject.getInt(GAMEID_FIELD); + } } public String getId() { @@ -86,11 +98,20 @@ public class CallbackQuery implements IBotApiObject { return data; } + public Integer getGameId() { + return gameId; + } + + public String getChatInstance() { + return chatInstance; + } + @Override public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeStartObject(); gen.writeStringField(ID_FIELD, id); gen.writeObjectField(FROM_FIELD, from); + gen.writeStringField(CHAT_INSTANCE_FIELD, chatInstance); if (message != null) { gen.writeObjectField(MESSAGE_FIELD, message); } @@ -100,6 +121,9 @@ public class CallbackQuery implements IBotApiObject { if (data != null) { gen.writeStringField(DATA_FIELD, data); } + if (gameId != null) { + gen.writeNumberField(GAMEID_FIELD, gameId); + } gen.writeEndObject(); gen.flush(); } @@ -117,6 +141,8 @@ public class CallbackQuery implements IBotApiObject { ", message=" + message + ", inlineMessageId='" + inlineMessageId + '\'' + ", data='" + data + '\'' + + ", gameId=" + gameId + + ", chatInstance='" + chatInstance + '\'' + '}'; } } diff --git a/src/main/java/org/telegram/telegrambots/api/objects/games/CallbackGame.java b/src/main/java/org/telegram/telegrambots/api/objects/games/CallbackGame.java new file mode 100644 index 00000000..95d0027f --- /dev/null +++ b/src/main/java/org/telegram/telegrambots/api/objects/games/CallbackGame.java @@ -0,0 +1,109 @@ +/* + * This file is part of TelegramBots. + * + * Foobar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + +package org.telegram.telegrambots.api.objects.games; + +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.telegrambots.api.interfaces.IBotApiObject; +import org.telegram.telegrambots.api.interfaces.IValidable; +import org.telegram.telegrambots.exceptions.TelegramApiValidationException; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 2.4 + * @brief This object contains information about a game that will be returned as a response to a callback query. + * @date 16 of September of 2016 + */ +public class CallbackGame implements IBotApiObject, IValidable { + private static final String TITLE_FIELD = "title"; + private static final String ID_FIELD = "game_id"; + private static final String START_PARAMETER_FIELD = "start_parameter"; + + @JsonProperty(TITLE_FIELD) + private String title; ///< Game title, aim at 128 characters or lower + @JsonProperty(ID_FIELD) + private Integer gameId; ///< Game identifier + @JsonProperty(START_PARAMETER_FIELD) + private String startParameter; ///< Start parameter for the bot URL when users share the game with others. See deep linking for more info. + + public CallbackGame() { + super(); + } + + public CallbackGame(JSONObject object) { + super(); + title = object.getString(TITLE_FIELD); + gameId = object.getInt(ID_FIELD); + startParameter = object.getString(START_PARAMETER_FIELD); + } + + public String getTitle() { + return title; + } + + public Integer getGameId() { + return gameId; + } + + public String getStartParameter() { + return startParameter; + } + + @Override + public void validate() throws TelegramApiValidationException { + if (title == null || title.isEmpty()) { + throw new TelegramApiValidationException("Title parameter can't be empty", this); + } + if (gameId == null) { + throw new TelegramApiValidationException("Id parameter can't be empty", this); + } + if (startParameter == null || startParameter.isEmpty()) { + throw new TelegramApiValidationException("StartParameter parameter can't be empty", this); + } + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(TITLE_FIELD, title); + gen.writeNumberField(ID_FIELD, gameId); + gen.writeStringField(START_PARAMETER_FIELD, startParameter); + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + serialize(gen, serializers); + } + + @Override + public String toString() { + return "CallbackGame{" + + "title='" + title + '\'' + + ", gameId=" + gameId + + ", startParameter='" + startParameter + '\'' + + '}'; + } +} diff --git a/src/main/java/org/telegram/telegrambots/api/objects/games/GameHighScore.java b/src/main/java/org/telegram/telegrambots/api/objects/games/GameHighScore.java new file mode 100644 index 00000000..a56b7e71 --- /dev/null +++ b/src/main/java/org/telegram/telegrambots/api/objects/games/GameHighScore.java @@ -0,0 +1,90 @@ +/* + * This file is part of TelegramBots. + * + * Foobar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + +package org.telegram.telegrambots.api.objects.games; + +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.telegrambots.api.interfaces.IBotApiObject; +import org.telegram.telegrambots.api.objects.User; + +import java.io.IOException; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief This object represents one row of a game high scores table + * @date 25 of September of 2016 + */ +public class GameHighScore implements IBotApiObject { + private static final String POSITION_FIELD = "position"; + private static final String USER_FIELD = "user"; + private static final String SCORE_FIELD = "score"; + + @JsonProperty(POSITION_FIELD) + private Integer position; ///< Position in the game high score table + @JsonProperty(USER_FIELD) + private User user; ///< User + @JsonProperty(SCORE_FIELD) + private Integer score; ///< Score + + public GameHighScore(JSONObject object) { + position = object.getInt(POSITION_FIELD); + user = new User(object.getJSONObject(USER_FIELD)); + score = object.getInt(SCORE_FIELD); + } + + public Integer getPosition() { + return position; + } + + public User getUser() { + return user; + } + + public Integer getScore() { + return score; + } + + @Override + public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeNumberField(POSITION_FIELD, position); + gen.writeObjectField(USER_FIELD, user); + gen.writeNumberField(SCORE_FIELD, score); + gen.writeEndObject(); + gen.flush(); + } + + @Override + public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException { + serialize(gen, serializers); + } + + @Override + public String toString() { + return "GameHighScore{" + + "position=" + position + + ", user=" + user + + ", score=" + score + + '}'; + } +} diff --git a/src/main/java/org/telegram/telegrambots/api/objects/replykeyboard/buttons/InlineKeyboardButton.java b/src/main/java/org/telegram/telegrambots/api/objects/replykeyboard/buttons/InlineKeyboardButton.java index 6f126280..69e28c1a 100644 --- a/src/main/java/org/telegram/telegrambots/api/objects/replykeyboard/buttons/InlineKeyboardButton.java +++ b/src/main/java/org/telegram/telegrambots/api/objects/replykeyboard/buttons/InlineKeyboardButton.java @@ -9,6 +9,7 @@ import org.json.JSONObject; import org.telegram.telegrambots.api.interfaces.IBotApiObject; import org.telegram.telegrambots.api.interfaces.IToJson; import org.telegram.telegrambots.api.interfaces.IValidable; +import org.telegram.telegrambots.api.objects.games.CallbackGame; import org.telegram.telegrambots.exceptions.TelegramApiValidationException; import java.io.IOException; @@ -27,6 +28,7 @@ public class InlineKeyboardButton implements IBotApiObject, IToJson, IValidable private static final String TEXT_FIELD = "text"; private static final String URL_FIELD = "url"; private static final String CALLBACK_DATA_FIELD = "callback_data"; + private static final String CALLBACK_GAME_FIELD = "callback_game"; private static final String SWITCH_INLINE_QUERY_FIELD = "switch_inline_query"; private static final String SWITCH_INLINE_QUERY_CURRENT_CHAT_FIELD = "switch_inline_query_current_chat"; @JsonProperty(TEXT_FIELD) @@ -35,6 +37,8 @@ public class InlineKeyboardButton implements IBotApiObject, IToJson, IValidable private String url; ///< Optional. HTTP url to be opened when button is pressed @JsonProperty(CALLBACK_DATA_FIELD) private String callbackData; ///< Optional. Data to be sent in a callback query to the bot when button is pressed + @JsonProperty(CALLBACK_GAME_FIELD) + private CallbackGame callbackGame; ///< Optional. Description of the game that will be launched when the user presses the button @JsonProperty(SWITCH_INLINE_QUERY_FIELD) /** * Optional. @@ -68,6 +72,9 @@ public class InlineKeyboardButton implements IBotApiObject, IToJson, IValidable if (jsonObject.has(CALLBACK_DATA_FIELD)) { callbackData = jsonObject.getString(CALLBACK_DATA_FIELD); } + if (jsonObject.has(CALLBACK_GAME_FIELD)) { + callbackGame = new CallbackGame(jsonObject.getJSONObject(CALLBACK_GAME_FIELD)); + } if (jsonObject.has(SWITCH_INLINE_QUERY_FIELD)) { switchInlineQuery = jsonObject.getString(SWITCH_INLINE_QUERY_FIELD); } @@ -112,6 +119,15 @@ public class InlineKeyboardButton implements IBotApiObject, IToJson, IValidable return this; } + public CallbackGame getCallbackGame() { + return callbackGame; + } + + public InlineKeyboardButton setCallbackGame(CallbackGame callbackGame) { + this.callbackGame = callbackGame; + return this; + } + public String getSwitchInlineQueryCurrentChat() { return switchInlineQueryCurrentChat; } @@ -126,6 +142,9 @@ public class InlineKeyboardButton implements IBotApiObject, IToJson, IValidable if (text == null || text.isEmpty()) { throw new TelegramApiValidationException("Text parameter can't be empty", this); } + if (callbackGame != null) { + callbackGame.validate(); + } } @Override @@ -144,6 +163,9 @@ public class InlineKeyboardButton implements IBotApiObject, IToJson, IValidable if (switchInlineQueryCurrentChat != null) { jsonObject.put(SWITCH_INLINE_QUERY_CURRENT_CHAT_FIELD, switchInlineQueryCurrentChat); } + if (callbackGame != null) { + jsonObject.put(CALLBACK_GAME_FIELD, callbackGame); + } return jsonObject; } @@ -164,6 +186,9 @@ public class InlineKeyboardButton implements IBotApiObject, IToJson, IValidable if (switchInlineQueryCurrentChat != null) { gen.writeStringField(SWITCH_INLINE_QUERY_CURRENT_CHAT_FIELD, switchInlineQueryCurrentChat); } + if (callbackGame != null) { + gen.writeObjectField(CALLBACK_GAME_FIELD, callbackGame); + } gen.writeEndObject(); gen.flush(); } @@ -179,6 +204,7 @@ public class InlineKeyboardButton implements IBotApiObject, IToJson, IValidable "text='" + text + '\'' + ", url='" + url + '\'' + ", callbackData='" + callbackData + '\'' + + ", callbackGame=" + callbackGame + ", switchInlineQuery='" + switchInlineQuery + '\'' + ", switchInlineQueryCurrentChat='" + switchInlineQueryCurrentChat + '\'' + '}'; diff --git a/src/main/java/org/telegram/telegrambots/bots/AbsSender.java b/src/main/java/org/telegram/telegrambots/bots/AbsSender.java index 190fbfae..3aa1abb2 100644 --- a/src/main/java/org/telegram/telegrambots/bots/AbsSender.java +++ b/src/main/java/org/telegram/telegrambots/bots/AbsSender.java @@ -26,6 +26,8 @@ import org.telegram.telegrambots.api.methods.ForwardMessage; import org.telegram.telegrambots.api.methods.GetFile; import org.telegram.telegrambots.api.methods.GetMe; import org.telegram.telegrambots.api.methods.GetUserProfilePhotos; +import org.telegram.telegrambots.api.methods.games.GetGameHighScores; +import org.telegram.telegrambots.api.methods.games.SetGameScore; import org.telegram.telegrambots.api.methods.groupadministration.GetChat; import org.telegram.telegrambots.api.methods.groupadministration.GetChatAdministrators; import org.telegram.telegrambots.api.methods.groupadministration.GetChatMember; @@ -55,6 +57,7 @@ import org.telegram.telegrambots.api.objects.Message; import org.telegram.telegrambots.api.objects.User; import org.telegram.telegrambots.api.objects.UserProfilePhotos; import org.telegram.telegrambots.api.objects.WebhookInfo; +import org.telegram.telegrambots.api.objects.games.GameHighScore; import org.telegram.telegrambots.exceptions.TelegramApiException; import org.telegram.telegrambots.exceptions.TelegramApiRequestException; import org.telegram.telegrambots.exceptions.TelegramApiValidationException; @@ -302,6 +305,20 @@ public abstract class AbsSender { return output; } + public final Serializable setGameScore(SetGameScore setGameScore) throws TelegramApiException { + if(setGameScore == null){ + throw new TelegramApiException("Parameter setGameScore can not be null"); + } + return sendApiMethod(setGameScore); + } + + public final Serializable getGameHighScores(GetGameHighScores getGameHighScores) throws TelegramApiException { + if(getGameHighScores == null){ + throw new TelegramApiException("Parameter getGameHighScores can not be null"); + } + return sendApiMethod(getGameHighScores); + } + // Send Requests Async public final void sendMessageAsync(SendMessage sendMessage, SentCallback sentCallback) throws TelegramApiException { @@ -543,6 +560,26 @@ public abstract class AbsSender { sendApiMethodAsync(getWebhookInfo, sentCallback); } + public final void setGameScoreAsync(SetGameScore setGameScore, SentCallback sentCallback) throws TelegramApiException { + if (setGameScore == null) { + throw new TelegramApiException("Parameter setGameScore can not be null"); + } + if (sentCallback == null) { + throw new TelegramApiException("Parameter sentCallback can not be null"); + } + sendApiMethodAsync(setGameScore, sentCallback); + } + + public final void getGameHighScoresAsync(GetGameHighScores getGameHighScores, SentCallback> sentCallback) throws TelegramApiException { + if (getGameHighScores == null) { + throw new TelegramApiException("Parameter getGameHighScores can not be null"); + } + if (sentCallback == null) { + throw new TelegramApiException("Parameter sentCallback can not be null"); + } + sendApiMethodAsync(getGameHighScores, sentCallback); + } + public final void downloadFileAsync(File file, DownloadFileCallback callback) throws TelegramApiException { if(file == null){ throw new TelegramApiException("Parameter file can not be null"); diff --git a/src/main/java/org/telegram/telegrambots/bots/ITelegramLongPollingBot.java b/src/main/java/org/telegram/telegrambots/bots/ITelegramLongPollingBot.java index b40829e3..39894fda 100644 --- a/src/main/java/org/telegram/telegrambots/bots/ITelegramLongPollingBot.java +++ b/src/main/java/org/telegram/telegrambots/bots/ITelegramLongPollingBot.java @@ -24,4 +24,10 @@ public interface ITelegramLongPollingBot { * Return bot token to access Telegram API */ String getBotToken(); + + /** + * Called when the BotSession is being closed + */ + default void onClosing() { + } } diff --git a/src/main/java/org/telegram/telegrambots/updatesreceivers/BotSession.java b/src/main/java/org/telegram/telegrambots/updatesreceivers/BotSession.java index 9ff8a0ec..fa5bfc52 100644 --- a/src/main/java/org/telegram/telegrambots/updatesreceivers/BotSession.java +++ b/src/main/java/org/telegram/telegrambots/updatesreceivers/BotSession.java @@ -16,11 +16,11 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.telegram.telegrambots.Constants; -import org.telegram.telegrambots.exceptions.TelegramApiRequestException; import org.telegram.telegrambots.api.methods.updates.GetUpdates; import org.telegram.telegrambots.api.objects.Update; import org.telegram.telegrambots.bots.BotOptions; import org.telegram.telegrambots.bots.ITelegramLongPollingBot; +import org.telegram.telegrambots.exceptions.TelegramApiRequestException; import org.telegram.telegrambots.logging.BotLogger; import java.io.IOException; @@ -93,6 +93,9 @@ public class BotSession { BotLogger.severe(LOGTAG, e); } } + if (callback != null) { + callback.onClosing(); + } } private class ReaderThread extends Thread { @@ -117,36 +120,39 @@ public class BotSession { HttpEntity ht = response.getEntity(); BufferedHttpEntity buf = new BufferedHttpEntity(ht); String responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8); - JSONObject jsonObject = new JSONObject(responseContent); - if (!jsonObject.getBoolean(Constants.RESPONSEFIELDOK)) { - throw new TelegramApiRequestException("Error getting updates", - jsonObject.getString(Constants.ERRORDESCRIPTIONFIELD), - jsonObject.getInt(Constants.ERRORCODEFIELD)); - } - JSONArray jsonArray = jsonObject.getJSONArray(Constants.RESPONSEFIELDRESULT); - if (jsonArray.length() != 0) { - for (int i = 0; i < jsonArray.length(); i++) { - Update update = new Update(jsonArray.getJSONObject(i)); - if (update.getUpdateId() > lastReceivedUpdate) { - lastReceivedUpdate = update.getUpdateId(); - receivedUpdates.addFirst(update); + try { + JSONObject jsonObject = new JSONObject(responseContent); + if (!jsonObject.getBoolean(Constants.RESPONSEFIELDOK)) { + throw new TelegramApiRequestException("Error getting updates", + jsonObject.getString(Constants.ERRORDESCRIPTIONFIELD), + jsonObject.getInt(Constants.ERRORCODEFIELD)); + } + JSONArray jsonArray = jsonObject.getJSONArray(Constants.RESPONSEFIELDRESULT); + if (jsonArray.length() != 0) { + for (int i = 0; i < jsonArray.length(); i++) { + Update update = new Update(jsonArray.getJSONObject(i)); + if (update.getUpdateId() > lastReceivedUpdate) { + lastReceivedUpdate = update.getUpdateId(); + receivedUpdates.addFirst(update); + } } - } - synchronized (receivedUpdates) { - receivedUpdates.notifyAll(); - } - } else { - try { - synchronized (this) { - this.wait(500); + synchronized (receivedUpdates) { + receivedUpdates.notifyAll(); } - } catch (InterruptedException e) { - BotLogger.severe(LOGTAG, e); + } else { + synchronized (this) { + this.wait(500); + } } + } catch (JSONException e) { + BotLogger.severe(responseContent, LOGTAG, e); } - } catch (InvalidObjectException | JSONException | TelegramApiRequestException e) { + } catch (InvalidObjectException | TelegramApiRequestException e) { BotLogger.severe(LOGTAG, e); } + } catch (InterruptedException e) { + receivedUpdates.clear(); + BotLogger.debug(LOGTAG, e); } catch (Exception global) { BotLogger.severe(LOGTAG, global); try { @@ -154,10 +160,12 @@ public class BotSession { this.wait(500); } } catch (InterruptedException e) { - BotLogger.severe(LOGTAG, e); + receivedUpdates.clear(); + BotLogger.debug(LOGTAG, e); } } } + BotLogger.debug(LOGTAG, "Reader thread has being closed"); } } @@ -170,12 +178,7 @@ public class BotSession { Update update = receivedUpdates.pollLast(); if (update == null) { synchronized (receivedUpdates) { - try { - receivedUpdates.wait(); - } catch (InterruptedException e) { - BotLogger.severe(LOGTAG, e); - continue; - } + receivedUpdates.wait(); update = receivedUpdates.pollLast(); if (update == null) { continue; @@ -183,10 +186,13 @@ public class BotSession { } } callback.onUpdateReceived(update); + } catch (InterruptedException e) { + BotLogger.debug(LOGTAG, e); } catch (Exception e) { BotLogger.severe(LOGTAG, e); } } + BotLogger.debug(LOGTAG, "Handler thread has being closed"); } } }