diff --git a/library/src/main/java/com/pengrad/telegrambot/TelegramBot.java b/library/src/main/java/com/pengrad/telegrambot/TelegramBot.java index 6f63828f..f98aed7f 100644 --- a/library/src/main/java/com/pengrad/telegrambot/TelegramBot.java +++ b/library/src/main/java/com/pengrad/telegrambot/TelegramBot.java @@ -8,15 +8,16 @@ import com.pengrad.telegrambot.request.BaseRequest; import com.pengrad.telegrambot.request.GetUpdates; import com.pengrad.telegrambot.response.BaseResponse; -import okhttp3.Interceptor; -import okhttp3.OkHttpClient; -import okhttp3.logging.HttpLoggingInterceptor; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.concurrent.TimeUnit; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; + /** * Stas Parshin * 16 October 2015 @@ -138,6 +139,7 @@ public TelegramBot build() { private static OkHttpClient client(Interceptor interceptor) { OkHttpClient.Builder builder = new OkHttpClient.Builder() .connectTimeout(75, TimeUnit.SECONDS) + .writeTimeout(75, TimeUnit.SECONDS) .readTimeout(75, TimeUnit.SECONDS); if (interceptor != null) builder.addInterceptor(interceptor); return builder.build(); diff --git a/library/src/main/java/com/pengrad/telegrambot/model/MessageEntity.java b/library/src/main/java/com/pengrad/telegrambot/model/MessageEntity.java index e29eb47c..9ff46506 100644 --- a/library/src/main/java/com/pengrad/telegrambot/model/MessageEntity.java +++ b/library/src/main/java/com/pengrad/telegrambot/model/MessageEntity.java @@ -19,6 +19,7 @@ public enum Type { private Integer length; private String url; private User user; + private String language; public Type type() { return type; @@ -40,6 +41,10 @@ public User user() { return user; } + public String language() { + return language; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -51,8 +56,8 @@ public boolean equals(Object o) { if (offset != null ? !offset.equals(that.offset) : that.offset != null) return false; if (length != null ? !length.equals(that.length) : that.length != null) return false; if (url != null ? !url.equals(that.url) : that.url != null) return false; - return user != null ? user.equals(that.user) : that.user == null; - + if (user != null ? !user.equals(that.user) : that.user != null) return false; + return language != null ? language.equals(that.language) : that.language == null; } @Override @@ -62,6 +67,7 @@ public int hashCode() { result = 31 * result + (length != null ? length.hashCode() : 0); result = 31 * result + (url != null ? url.hashCode() : 0); result = 31 * result + (user != null ? user.hashCode() : 0); + result = 31 * result + (language != null ? language.hashCode() : 0); return result; } @@ -73,6 +79,7 @@ public String toString() { ", length=" + length + ", url='" + url + '\'' + ", user=" + user + + ", language='" + language + '\'' + '}'; } } diff --git a/library/src/main/java/com/pengrad/telegrambot/model/Poll.java b/library/src/main/java/com/pengrad/telegrambot/model/Poll.java index 08cb7671..ad252701 100644 --- a/library/src/main/java/com/pengrad/telegrambot/model/Poll.java +++ b/library/src/main/java/com/pengrad/telegrambot/model/Poll.java @@ -10,10 +10,19 @@ public class Poll implements Serializable { private final static long serialVersionUID = 0L; + public enum Type { + quiz, regular + } + private String id; private String question; private PollOption[] options; + private Integer total_voter_count; private Boolean is_closed; + private Boolean is_anonymous; + private Type type; + private Boolean allows_multiple_answers; + private Integer correct_option_id; public String id() { return id; @@ -27,10 +36,30 @@ public PollOption[] options() { return options; } + public Integer totalVoterCount() { + return total_voter_count; + } + public Boolean isClosed() { return is_closed; } + public Boolean isAnonymous() { + return is_anonymous; + } + + public Type type() { + return type; + } + + public Boolean allowsMultipleAnswers() { + return allows_multiple_answers; + } + + public Integer correctOptionId() { + return correct_option_id; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -42,7 +71,14 @@ public boolean equals(Object o) { if (question != null ? !question.equals(poll.question) : poll.question != null) return false; // Probably incorrect - comparing Object[] arrays with Arrays.equals if (!Arrays.equals(options, poll.options)) return false; - return is_closed != null ? is_closed.equals(poll.is_closed) : poll.is_closed == null; + if (total_voter_count != null ? !total_voter_count.equals(poll.total_voter_count) : poll.total_voter_count != null) + return false; + if (is_closed != null ? !is_closed.equals(poll.is_closed) : poll.is_closed != null) return false; + if (is_anonymous != null ? !is_anonymous.equals(poll.is_anonymous) : poll.is_anonymous != null) return false; + if (type != poll.type) return false; + if (allows_multiple_answers != null ? !allows_multiple_answers.equals(poll.allows_multiple_answers) : poll.allows_multiple_answers != null) + return false; + return correct_option_id != null ? correct_option_id.equals(poll.correct_option_id) : poll.correct_option_id == null; } @Override @@ -56,7 +92,12 @@ public String toString() { "id='" + id + '\'' + ", question='" + question + '\'' + ", options=" + Arrays.toString(options) + + ", total_voter_count=" + total_voter_count + ", is_closed=" + is_closed + + ", is_anonymous=" + is_anonymous + + ", type=" + type + + ", allows_multiple_answers=" + allows_multiple_answers + + ", correct_option_id=" + correct_option_id + '}'; } } diff --git a/library/src/main/java/com/pengrad/telegrambot/model/PollAnswer.java b/library/src/main/java/com/pengrad/telegrambot/model/PollAnswer.java new file mode 100644 index 00000000..3a17ec9f --- /dev/null +++ b/library/src/main/java/com/pengrad/telegrambot/model/PollAnswer.java @@ -0,0 +1,58 @@ +package com.pengrad.telegrambot.model; + +import java.io.Serializable; +import java.util.Arrays; + +/** + * Stas Parshin + * 25 January 2020 + */ +public class PollAnswer implements Serializable { + private final static long serialVersionUID = 0L; + + private String poll_id; + private User user; + private Integer[] option_ids; + + public String pollId() { + return poll_id; + } + + public User user() { + return user; + } + + public Integer[] optionIds() { + return option_ids; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PollAnswer that = (PollAnswer) o; + + if (poll_id != null ? !poll_id.equals(that.poll_id) : that.poll_id != null) return false; + if (user != null ? !user.equals(that.user) : that.user != null) return false; + // Probably incorrect - comparing Object[] arrays with Arrays.equals + return Arrays.equals(option_ids, that.option_ids); + } + + @Override + public int hashCode() { + int result = poll_id != null ? poll_id.hashCode() : 0; + result = 31 * result + (user != null ? user.hashCode() : 0); + result = 31 * result + Arrays.hashCode(option_ids); + return result; + } + + @Override + public String toString() { + return "PollAnswer{" + + "poll_id='" + poll_id + '\'' + + ", user=" + user + + ", option_ids=" + Arrays.toString(option_ids) + + '}'; + } +} diff --git a/library/src/main/java/com/pengrad/telegrambot/model/Update.java b/library/src/main/java/com/pengrad/telegrambot/model/Update.java index 58187974..e038915e 100644 --- a/library/src/main/java/com/pengrad/telegrambot/model/Update.java +++ b/library/src/main/java/com/pengrad/telegrambot/model/Update.java @@ -20,6 +20,7 @@ public class Update implements Serializable { private ShippingQuery shipping_query; private PreCheckoutQuery pre_checkout_query; private Poll poll; + private PollAnswer poll_answer; public Integer updateId() { return update_id; @@ -65,6 +66,10 @@ public Poll poll() { return poll; } + public PollAnswer pollAnswer() { + return poll_answer; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -76,10 +81,12 @@ public boolean equals(Object o) { if (message != null ? !message.equals(update.message) : update.message != null) return false; if (edited_message != null ? !edited_message.equals(update.edited_message) : update.edited_message != null) return false; - if (channel_post != null ? !channel_post.equals(update.channel_post) : update.channel_post != null) return false; + if (channel_post != null ? !channel_post.equals(update.channel_post) : update.channel_post != null) + return false; if (edited_channel_post != null ? !edited_channel_post.equals(update.edited_channel_post) : update.edited_channel_post != null) return false; - if (inline_query != null ? !inline_query.equals(update.inline_query) : update.inline_query != null) return false; + if (inline_query != null ? !inline_query.equals(update.inline_query) : update.inline_query != null) + return false; if (chosen_inline_result != null ? !chosen_inline_result.equals(update.chosen_inline_result) : update.chosen_inline_result != null) return false; if (callback_query != null ? !callback_query.equals(update.callback_query) : update.callback_query != null) @@ -88,7 +95,8 @@ public boolean equals(Object o) { return false; if (pre_checkout_query != null ? !pre_checkout_query.equals(update.pre_checkout_query) : update.pre_checkout_query != null) return false; - return poll != null ? poll.equals(update.poll) : update.poll == null; + if (poll != null ? !poll.equals(update.poll) : update.poll != null) return false; + return poll_answer != null ? poll_answer.equals(update.poll_answer) : update.poll_answer == null; } @Override @@ -110,6 +118,7 @@ public String toString() { ", shipping_query=" + shipping_query + ", pre_checkout_query=" + pre_checkout_query + ", poll=" + poll + + ", poll_answer=" + poll_answer + '}'; } } diff --git a/library/src/main/java/com/pengrad/telegrambot/model/User.java b/library/src/main/java/com/pengrad/telegrambot/model/User.java index 3b2d4b6b..68ca25cf 100644 --- a/library/src/main/java/com/pengrad/telegrambot/model/User.java +++ b/library/src/main/java/com/pengrad/telegrambot/model/User.java @@ -15,6 +15,9 @@ public class User implements Serializable { private String last_name; private String username; private String language_code; + private Boolean can_join_groups; + private Boolean can_read_all_group_messages; + private Boolean supports_inline_queries; public Integer id() { return id; @@ -40,6 +43,18 @@ public String languageCode() { return language_code; } + public Boolean canJoinGroups() { + return can_join_groups; + } + + public Boolean canReadAllGroupMessages() { + return can_read_all_group_messages; + } + + public Boolean supportsInlineQueries() { + return supports_inline_queries; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -52,7 +67,13 @@ public boolean equals(Object o) { if (first_name != null ? !first_name.equals(user.first_name) : user.first_name != null) return false; if (last_name != null ? !last_name.equals(user.last_name) : user.last_name != null) return false; if (username != null ? !username.equals(user.username) : user.username != null) return false; - return language_code != null ? language_code.equals(user.language_code) : user.language_code == null; + if (language_code != null ? !language_code.equals(user.language_code) : user.language_code != null) + return false; + if (can_join_groups != null ? !can_join_groups.equals(user.can_join_groups) : user.can_join_groups != null) + return false; + if (can_read_all_group_messages != null ? !can_read_all_group_messages.equals(user.can_read_all_group_messages) : user.can_read_all_group_messages != null) + return false; + return supports_inline_queries != null ? supports_inline_queries.equals(user.supports_inline_queries) : user.supports_inline_queries == null; } @Override @@ -69,6 +90,9 @@ public String toString() { ", last_name='" + last_name + '\'' + ", username='" + username + '\'' + ", language_code='" + language_code + '\'' + + ", can_join_groups=" + can_join_groups + + ", can_read_all_group_messages=" + can_read_all_group_messages + + ", supports_inline_queries=" + supports_inline_queries + '}'; } } \ No newline at end of file diff --git a/library/src/main/java/com/pengrad/telegrambot/model/request/KeyboardButton.java b/library/src/main/java/com/pengrad/telegrambot/model/request/KeyboardButton.java index 4ded4881..8fa3451a 100644 --- a/library/src/main/java/com/pengrad/telegrambot/model/request/KeyboardButton.java +++ b/library/src/main/java/com/pengrad/telegrambot/model/request/KeyboardButton.java @@ -12,6 +12,7 @@ public class KeyboardButton implements Serializable { private String text; private boolean request_contact; private boolean request_location; + private KeyboardButtonPollType request_poll; public KeyboardButton(String text) { this.text = text; @@ -26,4 +27,9 @@ public KeyboardButton requestContact(boolean requestContact) { request_contact = requestContact; return this; } + + public KeyboardButton requestPoll(KeyboardButtonPollType poll) { + this.request_poll = poll; + return this; + } } diff --git a/library/src/main/java/com/pengrad/telegrambot/model/request/KeyboardButtonPollType.java b/library/src/main/java/com/pengrad/telegrambot/model/request/KeyboardButtonPollType.java new file mode 100644 index 00000000..8824c4bd --- /dev/null +++ b/library/src/main/java/com/pengrad/telegrambot/model/request/KeyboardButtonPollType.java @@ -0,0 +1,26 @@ +package com.pengrad.telegrambot.model.request; + +import com.pengrad.telegrambot.model.*; + +import java.io.Serializable; + +/** + * Stas Parshin + * 25 January 2020 + */ +public class KeyboardButtonPollType implements Serializable { + private final static long serialVersionUID = 0L; + + private String type; + + public KeyboardButtonPollType() { + } + + public KeyboardButtonPollType(String type) { + this.type = type; + } + + public KeyboardButtonPollType(Poll.Type type) { + this(type.name()); + } +} diff --git a/library/src/main/java/com/pengrad/telegrambot/request/SendPoll.java b/library/src/main/java/com/pengrad/telegrambot/request/SendPoll.java index acac3482..800a90c9 100644 --- a/library/src/main/java/com/pengrad/telegrambot/request/SendPoll.java +++ b/library/src/main/java/com/pengrad/telegrambot/request/SendPoll.java @@ -1,5 +1,7 @@ package com.pengrad.telegrambot.request; +import com.pengrad.telegrambot.model.Poll; + /** * Stas Parshin * 17 April 2019 @@ -11,4 +13,28 @@ public SendPoll(Object chatId, String question, String... options) { add("question", question); add("options", serialize(options)); } + + public SendPoll isAnonymous(boolean isAnonymous) { + return add("is_anonymous", isAnonymous); + } + + public SendPoll type(String type) { + return add("type", type); + } + + public SendPoll type(Poll.Type type) { + return add("type", type); + } + + public SendPoll correctOptionId(int correctOptionId) { + return add("correct_option_id", correctOptionId); + } + + public SendPoll allowsMultipleAnswers(boolean allowsMultipleAnswers) { + return add("allows_multiple_answers", allowsMultipleAnswers); + } + + public SendPoll isClosed(boolean isClosed) { + return add("is_closed", isClosed); + } } diff --git a/library/src/test/java/com/pengrad/telegrambot/TelegramBotTest.java b/library/src/test/java/com/pengrad/telegrambot/TelegramBotTest.java index 167e847d..af4cbb61 100644 --- a/library/src/test/java/com/pengrad/telegrambot/TelegramBotTest.java +++ b/library/src/test/java/com/pengrad/telegrambot/TelegramBotTest.java @@ -1,30 +1,25 @@ package com.pengrad.telegrambot; -import com.pengrad.telegrambot.impl.TelegramBotClient; +import com.pengrad.telegrambot.impl.*; import com.pengrad.telegrambot.model.*; import com.pengrad.telegrambot.model.request.*; +import com.pengrad.telegrambot.passport.Credentials; import com.pengrad.telegrambot.passport.*; import com.pengrad.telegrambot.request.*; import com.pengrad.telegrambot.response.*; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import org.junit.Test; + +import org.junit.*; import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; +import java.io.*; +import java.net.*; +import java.nio.file.*; import java.util.*; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; + +import okhttp3.*; -import static com.pengrad.telegrambot.request.ContentTypes.VIDEO_MIME_TYPE; +import static com.pengrad.telegrambot.request.ContentTypes.*; import static org.junit.Assert.*; /** @@ -104,8 +99,12 @@ public TelegramBotTest() throws IOException { @Test public void getMe() { GetMeResponse response = bot.execute(new GetMe()); - UserTest.checkUser(response.user()); - assertTrue(response.user().isBot()); + User user = response.user(); + UserTest.checkUser(user); + assertTrue(user.isBot()); + assertTrue(user.canJoinGroups()); + assertTrue(user.canReadAllGroupMessages()); + assertTrue(user.supportsInlineQueries()); } @Test @@ -657,6 +656,19 @@ public void underlineStrikethroughMarkdown() { assertEquals((Integer) 6, captionEntity.length()); } + @Test + public void preMessageEntity() { + String cap = "```java\n" + + "String s = new String();\n" + + "```"; + ParseMode parseMode = ParseMode.MarkdownV2; + SendAudio sendAudio = new SendAudio(chatId, audioFileId).caption(cap).parseMode(parseMode); + Message message = bot.execute(sendAudio).message(); + MessageTest.checkMessage(message); + assertEquals(1, message.captionEntities().length); + assertEquals("java", message.captionEntities()[0].language()); + } + @Test public void sendDocument() { Message message = bot.execute(new SendDocument(chatId, docFileId)).message(); @@ -1056,14 +1068,18 @@ private PreCheckoutQuery getLastPreCheckoutQuery() { } @Test - public void setChatAdministratorCustomTitle() { + public void setChatAdministratorCustomTitle() throws InterruptedException { BaseResponse response = bot.execute(new PromoteChatMember(groupId, memberBot).canPromoteMembers(true)); assertTrue(response.isOk()); + Thread.sleep(1000); + String customTitle = "aqi " + new Random().nextInt(999999); response = bot.execute(new SetChatAdministratorCustomTitle(groupId, memberBot, customTitle)); assertTrue(response.isOk()); + Thread.sleep(1000); + ChatMember member = bot.execute(new GetChatMember(groupId, memberBot)).chatMember(); ChatMemberTest.check(member); assertEquals(customTitle, member.customTitle()); @@ -1345,8 +1361,9 @@ public void editMessageMedia() { response = (SendResponse) bot.execute(new EditMessageMedia(chatId, messageId, new InputMediaAnimation(gifFileId))); assertTrue(response.isOk()); + AnimationTest.check(response.message().animation()); assertEquals(Integer.valueOf(3), response.message().animation().duration()); - assertEquals(gifFileId, response.message().animation().fileId()); + assertNotEquals(gifFileId, response.message().animation().fileId()); assertNotNull(response.message().document()); assertEquals((Integer) 57527, response.message().document().fileSize()); assertEquals("video/mp4", response.message().document().mimeType()); @@ -1482,9 +1499,15 @@ public void decryptPassport() throws Exception { public void sendPoll() { String question = "Question ?"; String[] answers = {"Answer 1", "Answer 2"}; - SendResponse sendResponse = bot.execute(new SendPoll(groupId, question, answers)); + SendResponse sendResponse = bot.execute( + new SendPoll(groupId, question, answers) + .isAnonymous(false) + .type(Poll.Type.quiz) + .allowsMultipleAnswers(false) + .correctOptionId(1) + .isClosed(true) + ); Poll poll = sendResponse.message().poll(); - assertFalse(poll.isClosed()); assertEquals(question, poll.question()); assertEquals(answers.length, poll.options().length); for (int i = 0; i < answers.length; i++) { @@ -1492,6 +1515,35 @@ public void sendPoll() { assertEquals(answers[i], option.text()); assertEquals(Integer.valueOf(0), option.voterCount()); } + assertFalse(poll.isAnonymous()); + assertEquals(poll.type(), Poll.Type.quiz); + assertFalse(poll.allowsMultipleAnswers()); + assertEquals(poll.totalVoterCount(), Integer.valueOf(0)); + assertEquals(poll.correctOptionId(), Integer.valueOf(1)); + assertTrue(poll.isClosed()); + } + + @Test + public void sendPollWithKeyboard() { + String question = "Question ?"; + String[] answers = {"Answer 1", "Answer 2"}; + SendResponse sendResponse = bot.execute( + new SendPoll(chatId, question, answers) + .type("regular") + .allowsMultipleAnswers(true) + .replyMarkup(new ReplyKeyboardMarkup(new KeyboardButton[]{ + new KeyboardButton("all polls").requestPoll(new KeyboardButtonPollType()), + new KeyboardButton("quiz").requestPoll(new KeyboardButtonPollType(Poll.Type.quiz)), + new KeyboardButton("regular").requestPoll(new KeyboardButtonPollType("regular")) + })) + ); + Poll poll = sendResponse.message().poll(); + assertEquals(question, poll.question()); + assertEquals(answers.length, poll.options().length); + assertTrue(poll.isAnonymous()); + assertEquals(poll.totalVoterCount(), Integer.valueOf(0)); + assertEquals(poll.type(), Poll.Type.regular); + assertTrue(poll.allowsMultipleAnswers()); } @Test diff --git a/library/src/test/java/com/pengrad/telegrambot/UpdateTest.java b/library/src/test/java/com/pengrad/telegrambot/UpdateTest.java index 313c164f..7e8de8c6 100644 --- a/library/src/test/java/com/pengrad/telegrambot/UpdateTest.java +++ b/library/src/test/java/com/pengrad/telegrambot/UpdateTest.java @@ -26,6 +26,7 @@ public static void check(List updates) { if (update.shippingQuery() != null) assertNotNull(update.shippingQuery().id()); if (update.preCheckoutQuery() != null) assertNotNull(update.preCheckoutQuery().id()); if (update.poll() != null) assertNotNull(update.poll().id()); + if (update.pollAnswer() != null) assertNotNull((update.pollAnswer().pollId())); } }