replies() {
+ return replies;
+ }
+
/**
* This method contains the stream of actions that are applied on any update.
*
@@ -235,7 +256,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
* @param username the username of the required user
* @return the user
*/
- protected EndUser getUser(String username) {
+ protected User getUser(String username) {
Integer id = userIds().get(username.toLowerCase());
if (id == null) {
throw new IllegalStateException(format("Could not find ID corresponding to username [%s]", username));
@@ -250,26 +271,27 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
* @param id the id of the required user
* @return the user
*/
- protected EndUser getUser(int id) {
- EndUser endUser = users().get(id);
- if (endUser == null) {
+ protected User getUser(int id) {
+ User user = users().get(id);
+ if (user == null) {
throw new IllegalStateException(format("Could not find user corresponding to id [%d]", id));
}
- return endUser;
+ return user;
}
/**
* Gets the user with the specified username. If user was not found, the bot will send a message on Telegram.
*
* @param username the username of the required user
+ * @param ctx the message context with the originating user
* @return the id of the user
*/
- protected int getUserIdSendError(String username, long chatId) {
+ protected int getUserIdSendError(String username, MessageContext ctx) {
try {
- return getUser(username).id();
+ return getUser(username).getId();
} catch (IllegalStateException ex) {
- silent.send(format("Sorry, I could not find the user [%s].", username), chatId);
+ silent.send(getLocalizedMessage(USER_NOT_FOUND, ctx.user().getLanguageCode(), username), ctx.chatId());
throw propagate(ex);
}
}
@@ -292,9 +314,9 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
*/
public Ability reportCommands() {
return builder()
- .name(COMMANDS)
+ .name(REPORT)
.locality(ALL)
- .privacy(PUBLIC)
+ .privacy(CREATOR)
.input(0)
.action(ctx -> {
String commands = abilities.entrySet().stream()
@@ -306,7 +328,64 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
})
.sorted()
.reduce((a, b) -> format("%s%n%s", a, b))
- .orElse("No public commands found.");
+ .orElse(getLocalizedMessage(ABILITY_COMMANDS_NOT_FOUND, ctx.user().getLanguageCode()));
+
+ silent.send(commands, ctx.chatId());
+ })
+ .build();
+ }
+
+ /**
+ * Default format:
+ *
+ * PUBLIC
+ *
+ * [command1] - [description1]
+ *
+ * [command2] - [description2]
+ *
+ * GROUP_ADMIN
+ *
+ * [command1] - [description1]
+ *
+ * ...
+ *
+ * @return the ability to print commands based on the privacy of the requesting user
+ */
+ public Ability commands() {
+ return builder()
+ .name(COMMANDS)
+ .locality(USER)
+ .privacy(PUBLIC)
+ .input(0)
+ .action(ctx -> {
+ Privacy privacy = getPrivacy(ctx.update(), ctx.user().getId());
+
+ ListMultimap abilitiesPerPrivacy = abilities.entrySet().stream()
+ .map(entry -> {
+ String name = entry.getValue().name();
+ String info = entry.getValue().info();
+
+ if (!isEmpty(info))
+ return Pair.of(entry.getValue().privacy(), format("/%s - %s", name, info));
+ return Pair.of(entry.getValue().privacy(), format("/%s", name));
+ })
+ .sorted(comparing(Pair::b))
+ .collect(() -> hashKeys().arrayListValues().build(),
+ (map, pair) -> map.put(pair.a(), pair.b()),
+ Multimap::putAll);
+
+ String commands = abilitiesPerPrivacy.asMap().entrySet().stream()
+ .filter(entry -> privacy.compareTo(entry.getKey()) >= 0)
+ .sorted(comparing(Entry::getKey))
+ .map(entry ->
+ entry.getValue().stream()
+ .reduce(entry.getKey().toString(), (a, b) -> format("%s\n%s", a, b))
+ )
+ .collect(joining("\n"));
+
+ if (commands.isEmpty())
+ commands = getLocalizedMessage(ABILITY_COMMANDS_NOT_FOUND, ctx.user().getLanguageCode());
silent.send(commands, ctx.chatId());
})
@@ -361,23 +440,27 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
.locality(USER)
.privacy(CREATOR)
.input(0)
- .action(ctx -> silent.forceReply(RECOVERY_MESSAGE, ctx.chatId()))
+ .action(ctx -> silent.forceReply(
+ getLocalizedMessage(ABILITY_RECOVER_MESSAGE, ctx.user().getLanguageCode()), ctx.chatId()))
.reply(update -> {
- Long chatId = update.getMessage().getChatId();
- String fileId = update.getMessage().getDocument().getFileId();
+ String replyToMsg = update.getMessage().getReplyToMessage().getText();
+ String recoverMessage = getLocalizedMessage(ABILITY_RECOVER_MESSAGE, AbilityUtils.getUser(update).getLanguageCode());
+ if (!replyToMsg.equals(recoverMessage))
+ return;
+ String fileId = update.getMessage().getDocument().getFileId();
try (FileReader reader = new FileReader(downloadFileWithId(fileId))) {
String backupData = IOUtils.toString(reader);
if (db.recover(backupData)) {
- silent.send(RECOVER_SUCCESS, chatId);
+ send(ABILITY_RECOVER_SUCCESS, update);
} else {
- silent.send("Oops, something went wrong during recovery.", chatId);
+ send(ABILITY_RECOVER_FAIL, update);
}
} catch (Exception e) {
BotLogger.error("Could not recover DB from backup", TAG, e);
- silent.send("I have failed to recover.", chatId);
+ send(ABILITY_RECOVER_ERROR, update);
}
- }, MESSAGE, DOCUMENT, REPLY, isReplyTo(RECOVERY_MESSAGE))
+ }, MESSAGE, DOCUMENT, REPLY)
.build();
}
@@ -398,23 +481,23 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
.input(1)
.action(ctx -> {
String username = stripTag(ctx.firstArg());
- int userId = getUserIdSendError(username, ctx.chatId());
+ int userId = getUserIdSendError(username, ctx);
String bannedUser;
// Protection from abuse
if (userId == creatorId()) {
- userId = ctx.user().id();
- bannedUser = isNullOrEmpty(ctx.user().username()) ? addTag(ctx.user().username()) : ctx.user().shortName();
+ userId = ctx.user().getId();
+ bannedUser = isNullOrEmpty(ctx.user().getUserName()) ? addTag(ctx.user().getUserName()) : shortName(ctx.user());
} else {
bannedUser = addTag(username);
}
Set blacklist = blacklist();
if (blacklist.contains(userId))
- silent.sendMd(format("%s is already *banned*.", escape(bannedUser)), ctx.chatId());
+ sendMd(ABILITY_BAN_FAIL, ctx, escape(bannedUser));
else {
blacklist.add(userId);
- silent.sendMd(format("%s is now *banned*.", escape(bannedUser)), ctx.chatId());
+ sendMd(ABILITY_BAN_SUCCESS, ctx, escape(bannedUser));
}
})
.post(commitTo(db))
@@ -434,14 +517,14 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
.input(1)
.action(ctx -> {
String username = stripTag(ctx.firstArg());
- Integer userId = getUserIdSendError(username, ctx.chatId());
+ Integer userId = getUserIdSendError(username, ctx);
Set blacklist = blacklist();
if (!blacklist.remove(userId))
- silent.sendMd(format("@%s is *not* on the *blacklist*.", escape(username)), ctx.chatId());
+ silent.sendMd(getLocalizedMessage(ABILITY_UNBAN_FAIL, ctx.user().getLanguageCode(), escape(username)), ctx.chatId());
else {
- silent.sendMd(format("@%s, your ban has been *lifted*.", escape(username)), ctx.chatId());
+ silent.sendMd(getLocalizedMessage(ABILITY_UNBAN_SUCCESS, ctx.user().getLanguageCode(), escape(username)), ctx.chatId());
}
})
.post(commitTo(db))
@@ -459,14 +542,14 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
.input(1)
.action(ctx -> {
String username = stripTag(ctx.firstArg());
- Integer userId = getUserIdSendError(username, ctx.chatId());
+ Integer userId = getUserIdSendError(username, ctx);
Set admins = admins();
if (admins.contains(userId))
- silent.sendMd(format("@%s is already an *admin*.", escape(username)), ctx.chatId());
+ sendMd(ABILITY_PROMOTE_FAIL, ctx, escape(username));
else {
admins.add(userId);
- silent.sendMd(format("@%s has been *promoted*.", escape(username)), ctx.chatId());
+ sendMd(ABILITY_PROMOTE_SUCCESS, ctx, escape(username));
}
}).post(commitTo(db))
.build();
@@ -483,13 +566,13 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
.input(1)
.action(ctx -> {
String username = stripTag(ctx.firstArg());
- Integer userId = getUserIdSendError(username, ctx.chatId());
+ Integer userId = getUserIdSendError(username, ctx);
Set admins = admins();
if (admins.remove(userId)) {
- silent.sendMd(format("@%s has been *demoted*.", escape(username)), ctx.chatId());
+ sendMd(ABILITY_DEMOTE_SUCCESS, ctx, escape(username));
} else {
- silent.sendMd(format("@%s is *not* an *admin*.", escape(username)), ctx.chatId());
+ sendMd(ABILITY_DEMOTE_FAIL, ctx, escape(username));
}
})
.post(commitTo(db))
@@ -505,29 +588,36 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
return builder()
.name(CLAIM)
.locality(ALL)
- .privacy(PUBLIC)
+ .privacy(CREATOR)
.input(0)
.action(ctx -> {
- if (ctx.user().id() == creatorId()) {
- Set admins = admins();
- int id = creatorId();
- long chatId = ctx.chatId();
+ Set admins = admins();
+ int id = creatorId();
- if (admins.contains(id))
- silent.send("You're already my master.", chatId);
- else {
- admins.add(id);
- silent.send("You're now my master.", chatId);
- }
- } else {
- // This is not a joke
- abilities.get(BAN).action().accept(newContext(ctx.update(), ctx.user(), ctx.chatId(), ctx.user().username()));
+ if (admins.contains(id))
+ send(ABILITY_CLAIM_FAIL, ctx);
+ else {
+ admins.add(id);
+ send(ABILITY_CLAIM_SUCCESS, ctx);
}
})
.post(commitTo(db))
.build();
}
+ private Optional send(String message, MessageContext ctx, String... args) {
+ return silent.send(getLocalizedMessage(message, ctx.user().getLanguageCode(), args), ctx.chatId());
+ }
+
+ private Optional sendMd(String message, MessageContext ctx, String... args) {
+ return silent.sendMd(getLocalizedMessage(message, ctx.user().getLanguageCode(), args), ctx.chatId());
+ }
+
+ private Optional send(String message, Update upd) {
+ Long chatId = upd.getMessage().getChatId();
+ return silent.send(getLocalizedMessage(message, AbilityUtils.getUser(upd).getLanguageCode()), chatId);
+ }
+
/**
* Registers the declared abilities using method reflection. Also, replies are accumulated using the built abilities and standalone methods that return a Reply.
*
@@ -538,7 +628,10 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
abilities = stream(this.getClass().getMethods())
.filter(method -> method.getReturnType().equals(Ability.class))
.map(this::returnAbility)
- .collect(toMap(ability -> ability.name().toLowerCase(), identity()));
+ .collect(ImmutableMap::builder,
+ (b, a) -> b.put(a.name(), a),
+ (b1, b2) -> b1.putAll(b2.build()))
+ .build();
Stream methodReplies = stream(this.getClass().getMethods())
.filter(method -> method.getReturnType().equals(Reply.class))
@@ -547,7 +640,11 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
Stream abilityReplies = abilities.values().stream()
.flatMap(ability -> ability.replies().stream());
- replies = Stream.concat(methodReplies, abilityReplies).collect(toList());
+ replies = Stream.concat(methodReplies, abilityReplies).collect(
+ ImmutableList::builder,
+ Builder::add,
+ (b1, b2) -> b1.addAll(b2.build()))
+ .build();
} catch (IllegalStateException e) {
BotLogger.error(TAG, "Duplicate names found while registering abilities. Make sure that the abilities declared don't clash with the reserved ones.", e);
throw propagate(e);
@@ -597,7 +694,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
Pair getContext(Trio trio) {
Update update = trio.a();
- EndUser user = fromUser(AbilityUtils.getUser(update));
+ User user = AbilityUtils.getUser(update);
return Pair.of(newContext(update, user, getChatId(update), trio.c()), trio.b());
}
@@ -615,7 +712,12 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
boolean isOk = abilityTokens == 0 || (tokens.length > 0 && tokens.length == abilityTokens);
if (!isOk)
- silent.send(format("Sorry, this feature requires %d additional %s.", abilityTokens, abilityTokens == 1 ? "input" : "inputs"), getChatId(trio.a()));
+ silent.send(
+ getLocalizedMessage(
+ CHECK_INPUT_FAIL,
+ AbilityUtils.getUser(trio.a()).getLanguageCode(),
+ abilityTokens, abilityTokens == 1 ? "input" : "inputs"),
+ getChatId(trio.a()));
return isOk;
}
@@ -627,30 +729,46 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
boolean isOk = abilityLocality == ALL || locality == abilityLocality;
if (!isOk)
- silent.send(format("Sorry, %s-only feature.", abilityLocality.toString().toLowerCase()), getChatId(trio.a()));
+ silent.send(
+ getLocalizedMessage(
+ CHECK_LOCALITY_FAIL,
+ AbilityUtils.getUser(trio.a()).getLanguageCode(),
+ abilityLocality.toString().toLowerCase()),
+ getChatId(trio.a()));
return isOk;
}
boolean checkPrivacy(Trio trio) {
Update update = trio.a();
- EndUser user = fromUser(AbilityUtils.getUser(update));
+ User user = AbilityUtils.getUser(update);
Privacy privacy;
- int id = user.id();
+ int id = user.getId();
- privacy = isCreator(id) ? CREATOR : isAdmin(id) ? ADMIN : isGroupAdmin(update, id)? GROUP_ADMIN : PUBLIC;
+ privacy = getPrivacy(update, id);
boolean isOk = privacy.compareTo(trio.b().privacy()) >= 0;
if (!isOk)
- silent.send("Sorry, you don't have the required access level to do that.", getChatId(trio.a()));
-
+ silent.send(
+ getLocalizedMessage(
+ CHECK_PRIVACY_FAIL,
+ AbilityUtils.getUser(trio.a()).getLanguageCode()),
+ getChatId(trio.a()));
return isOk;
}
+ @NotNull
+ private Privacy getPrivacy(Update update, int id) {
+ return isCreator(id) ?
+ CREATOR : isAdmin(id) ?
+ ADMIN : (isGroupUpdate(update) || isSuperGroupUpdate(update)) && isGroupAdmin(update, id) ?
+ GROUP_ADMIN : PUBLIC;
+ }
+
private boolean isGroupAdmin(Update update, int id) {
GetChatAdministrators admins = new GetChatAdministrators().setChatId(getChatId(update));
- return isGroupUpdate(update) && silent.execute(admins)
+ return silent.execute(admins)
.orElse(new ArrayList<>()).stream()
.anyMatch(member -> member.getUser().getId() == id);
}
@@ -694,9 +812,9 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
}
Update addUser(Update update) {
- EndUser endUser = fromUser(AbilityUtils.getUser(update));
+ User endUser = AbilityUtils.getUser(update);
- users().compute(endUser.id(), (id, user) -> {
+ users().compute(endUser.getId(), (id, user) -> {
if (user == null) {
updateUserId(user, endUser);
return endUser;
@@ -714,15 +832,15 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
return update;
}
- private void updateUserId(EndUser oldUser, EndUser newUser) {
- if (oldUser != null && oldUser.username() != null) {
+ private void updateUserId(User oldUser, User newUser) {
+ if (oldUser != null && oldUser.getUserName() != null) {
// Remove old username -> ID
- userIds().remove(oldUser.username());
+ userIds().remove(oldUser.getUserName());
}
- if (newUser.username() != null) {
+ if (newUser.getUserName() != null) {
// Add new mapping with the new username
- userIds().put(newUser.username().toLowerCase(), newUser.id());
+ userIds().put(newUser.getUserName().toLowerCase(), newUser.getId());
}
}
@@ -750,6 +868,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
return sender.downloadFile(sender.execute(new GetFile().setFileId(fileId)));
}
+
private String escape(String username) {
return username.replace("_", "\\_");
}
diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/db/DBContext.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/db/DBContext.java
index c31a856f..f29e94dc 100644
--- a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/db/DBContext.java
+++ b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/db/DBContext.java
@@ -39,6 +39,13 @@ public interface DBContext extends Closeable {
*/
Set getSet(String name);
+ /**
+ * @param name the unique name of the {@link Var}
+ * @param the type that the variable holds
+ * @return the variable with the specified name
+ */
+ Var getVar(String name);
+
/**
* @return a high-level summary of the database structures (Sets, Lists, Maps, ...) present.
*/
diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/db/MapDBContext.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/db/MapDBContext.java
index 37707aed..a8f3db16 100644
--- a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/db/MapDBContext.java
+++ b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/db/MapDBContext.java
@@ -3,6 +3,7 @@ package org.telegram.abilitybots.api.db;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
+import org.mapdb.Atomic;
import org.mapdb.DB;
import org.mapdb.DBMaker;
import org.mapdb.Serializer;
@@ -93,6 +94,11 @@ public class MapDBContext implements DBContext {
return (Set) db.hashSet(name, JAVA).createOrOpen();
}
+ @Override
+ public Var getVar(String name) {
+ return new MapDBVar<>((Atomic.Var) db.atomicVar(name).createOrOpen());
+ }
+
@Override
public String summary() {
return stream(db.getAllNames().spliterator(), false)
diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/db/MapDBVar.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/db/MapDBVar.java
new file mode 100644
index 00000000..a325fd36
--- /dev/null
+++ b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/db/MapDBVar.java
@@ -0,0 +1,49 @@
+package org.telegram.abilitybots.api.db;
+
+import com.google.common.base.MoreObjects;
+import org.mapdb.Atomic;
+
+import java.util.Objects;
+
+/**
+ * The MapDB variant for {@link DBContext#getVar(String)}.
+ *
+ * @param the type of the inner variable
+ */
+public final class MapDBVar implements Var {
+ private Atomic.Var var;
+
+ public MapDBVar(Atomic.Var var) {
+ this.var = var;
+ }
+
+ @Override
+ public T get() {
+ return var.get();
+ }
+
+ @Override
+ public void set(T var) {
+ this.var.set(var);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ MapDBVar> mapDBVar = (MapDBVar>) o;
+ return Objects.equals(var, mapDBVar.var);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(var);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("var", var)
+ .toString();
+ }
+}
diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/db/Var.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/db/Var.java
new file mode 100644
index 00000000..b6ec4593
--- /dev/null
+++ b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/db/Var.java
@@ -0,0 +1,19 @@
+package org.telegram.abilitybots.api.db;
+
+/**
+ * The interface governing a variable for abstract getters and setters.
+ * @param the type of the variable
+ *
+ * @author Abbas Abou Daya
+ */
+public interface Var {
+ /**
+ * @return the variable contained
+ */
+ T get();
+
+ /**
+ * @param var the new variable value
+ */
+ void set(T var);
+}
diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/EndUser.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/EndUser.java
deleted file mode 100644
index f686e38f..00000000
--- a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/EndUser.java
+++ /dev/null
@@ -1,138 +0,0 @@
-package org.telegram.abilitybots.api.objects;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.common.base.MoreObjects;
-import org.telegram.telegrambots.meta.api.objects.User;
-
-import java.io.Serializable;
-import java.util.Objects;
-import java.util.StringJoiner;
-
-import static org.apache.commons.lang3.StringUtils.isEmpty;
-
-/**
- * This class serves the purpose of separating the basic Telegram {@link User} and the augmented {@link EndUser}.
- *
- * It adds proper hashCode, equals, toString as well as useful utility methods such as {@link EndUser#shortName} and {@link EndUser#fullName}.
- *
- * @author Abbas Abou Daya
- */
-public final class EndUser implements Serializable {
- @JsonProperty("id")
- private final Integer id;
- @JsonProperty("firstName")
- private final String firstName;
- @JsonProperty("lastName")
- private final String lastName;
- @JsonProperty("username")
- private final String username;
-
- private EndUser(Integer id, String firstName, String lastName, String username) {
- this.id = id;
- this.firstName = firstName;
- this.lastName = lastName;
- this.username = username;
- }
-
- @JsonCreator
- public static EndUser endUser(@JsonProperty("id") Integer id,
- @JsonProperty("firstName") String firstName,
- @JsonProperty("lastName") String lastName,
- @JsonProperty("username") String username) {
- return new EndUser(id, firstName, lastName, username);
- }
-
- /**
- * Constructs an {@link EndUser} from a {@link User}.
- *
- * @param user the Telegram user
- * @return an augmented end-user
- */
- public static EndUser fromUser(User user) {
- return new EndUser(user.getId(), user.getFirstName(), user.getLastName(), user.getUserName());
- }
-
- public int id() {
- return id;
- }
-
- public String firstName() {
- return firstName;
- }
-
- public String lastName() {
- return lastName;
- }
-
- public String username() {
- return username;
- }
-
- /**
- * The full name is identified as the concatenation of the first and last name, separated by a space.
- * This method can return an empty name if both first and last name are empty.
- *
- * @return the full name of the user
- */
- public String fullName() {
- StringJoiner name = new StringJoiner(" ");
-
- if (!isEmpty(firstName))
- name.add(firstName);
- if (!isEmpty(lastName))
- name.add(lastName);
-
- return name.toString();
- }
-
- /**
- * The short name is one of the following:
- *
- * - First name
- * - Last name
- * - Username
- *
- * The method will try to return the first valid name in the specified order.
- *
- * @return the short name of the user
- */
- public String shortName() {
- if (!isEmpty(firstName))
- return firstName;
-
- if (!isEmpty(lastName))
- return lastName;
-
- return username;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o)
- return true;
- if (o == null || getClass() != o.getClass())
- return false;
-
- EndUser endUser = (EndUser) o;
- return Objects.equals(id, endUser.id) &&
- Objects.equals(firstName, endUser.firstName) &&
- Objects.equals(lastName, endUser.lastName) &&
- Objects.equals(username, endUser.username);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(id, firstName, lastName, username);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("id", id)
- .add("firstName", firstName)
- .add("lastName", lastName)
- .add("username", username)
- .toString();
- }
-}
diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/Flag.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/Flag.java
index ac8e9613..f59cc25c 100644
--- a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/Flag.java
+++ b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/Flag.java
@@ -11,7 +11,7 @@ import static java.util.Objects.nonNull;
/**
* Flags are an conditions that are applied on an {@link Update}.
*
- * They can be used on {@link AbilityBuilder#flag(Flag...)} and on the post conditions in {@link AbilityBuilder#reply(Consumer, Predicate[])}.
+ * They can be used on {@link AbilityBuilder#flag(Predicate[])} and on the post conditions in {@link AbilityBuilder#reply(Consumer, Predicate[])}.
*
* @author Abbas Abou Daya
*/
diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/MessageContext.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/MessageContext.java
index c68a2868..c9fc2398 100644
--- a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/MessageContext.java
+++ b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/MessageContext.java
@@ -3,6 +3,7 @@ package org.telegram.abilitybots.api.objects;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import org.telegram.telegrambots.meta.api.objects.Update;
+import org.telegram.telegrambots.meta.api.objects.User;
import java.util.Arrays;
@@ -14,26 +15,26 @@ import java.util.Arrays;
* @author Abbas Abou Daya
*/
public class MessageContext {
- private final EndUser user;
+ private final User user;
private final Long chatId;
private final String[] arguments;
private final Update update;
- private MessageContext(Update update, EndUser user, Long chatId, String[] arguments) {
+ private MessageContext(Update update, User user, Long chatId, String[] arguments) {
this.user = user;
this.chatId = chatId;
this.update = update;
this.arguments = arguments;
}
- public static MessageContext newContext(Update update, EndUser user, Long chatId, String... arguments) {
+ public static MessageContext newContext(Update update, User user, Long chatId, String... arguments) {
return new MessageContext(update, user, chatId, arguments);
}
/**
* @return the originating Telegram user of this update
*/
- public EndUser user() {
+ public User user() {
return user;
}
diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/Reply.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/Reply.java
index 0d344ce2..a74e4e2f 100644
--- a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/Reply.java
+++ b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/Reply.java
@@ -14,7 +14,7 @@ import static java.util.Arrays.asList;
/**
* A reply consists of update conditionals and an action to be applied on the update.
*
- * If an update satisfies the {@link Reply#conditions}set by the reply, then it's safe to {@link Reply#actOn(Update)}.
+ * If an update satisfies the {@link Reply#conditions} set by the reply, then it's safe to {@link Reply#actOn(Update)}.
*
* @author Abbas Abou Daya
*/
diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/util/AbilityMessageCodes.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/util/AbilityMessageCodes.java
new file mode 100644
index 00000000..4f21f937
--- /dev/null
+++ b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/util/AbilityMessageCodes.java
@@ -0,0 +1,31 @@
+package org.telegram.abilitybots.api.util;
+
+public final class AbilityMessageCodes {
+ public static String USER_NOT_FOUND = "userNotFound";
+ public static String CHECK_INPUT_FAIL = "checkInput.fail";
+ public static String CHECK_LOCALITY_FAIL = "checkLocality.fail";
+ public static String CHECK_PRIVACY_FAIL = "checkPrivacy.fail";
+
+ public static String ABILITY_COMMANDS_NOT_FOUND = "ability.commands.notFound";
+
+ public static String ABILITY_RECOVER_SUCCESS = "ability.recover.success";
+ public static String ABILITY_RECOVER_FAIL = "ability.recover.fail";
+ public static String ABILITY_RECOVER_MESSAGE = "ability.recover.message";
+ public static String ABILITY_RECOVER_ERROR = "ability.recover.error";
+
+ public static String ABILITY_BAN_SUCCESS = "ability.ban.success";
+ public static String ABILITY_BAN_FAIL = "ability.ban.fail";
+
+ public static String ABILITY_UNBAN_SUCCESS = "ability.unban.success";
+ public static String ABILITY_UNBAN_FAIL = "ability.unban.fail";
+
+ public static String ABILITY_PROMOTE_SUCCESS = "ability.promote.success";
+ public static String ABILITY_PROMOTE_FAIL = "ability.promote.fail";
+
+ public static String ABILITY_DEMOTE_SUCCESS = "ability.demote.success";
+ public static String ABILITY_DEMOTE_FAIL = "ability.demote.fail";
+
+ public static String ABILITY_CLAIM_SUCCESS = "ability.claim.success";
+ public static String ABILITY_CLAIM_FAIL = "ability.claim.fail";
+
+}
diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/util/AbilityUtils.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/util/AbilityUtils.java
index a6d01324..749fd4a7 100644
--- a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/util/AbilityUtils.java
+++ b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/util/AbilityUtils.java
@@ -1,13 +1,23 @@
package org.telegram.abilitybots.api.util;
+import com.google.common.base.Strings;
import org.telegram.abilitybots.api.db.DBContext;
import org.telegram.abilitybots.api.objects.MessageContext;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.api.objects.User;
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.StringJoiner;
import java.util.function.Consumer;
import java.util.function.Predicate;
+import static java.util.ResourceBundle.Control.FORMAT_PROPERTIES;
+import static java.util.ResourceBundle.Control.getNoFallbackControl;
+import static java.util.ResourceBundle.getBundle;
+import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.telegram.abilitybots.api.objects.Flag.*;
/**
@@ -86,6 +96,28 @@ public final class AbilityUtils {
}
}
+ /**
+ * A "best-effort" boolean stating whether the update is a super-group message or not.
+ *
+ * @param update a Telegram {@link Update}
+ * @return whether the update is linked to a group
+ */
+ public static boolean isSuperGroupUpdate(Update update) {
+ if (MESSAGE.test(update)) {
+ return update.getMessage().isSuperGroupMessage();
+ } else if (CALLBACK_QUERY.test(update)) {
+ return update.getCallbackQuery().getMessage().isSuperGroupMessage();
+ } else if (CHANNEL_POST.test(update)) {
+ return update.getChannelPost().isSuperGroupMessage();
+ } else if (EDITED_CHANNEL_POST.test(update)) {
+ return update.getEditedChannelPost().isSuperGroupMessage();
+ } else if (EDITED_MESSAGE.test(update)) {
+ return update.getEditedMessage().isSuperGroupMessage();
+ } else {
+ return false;
+ }
+ }
+
/**
* Fetches the direct chat ID of the specified update.
*
@@ -150,4 +182,66 @@ public final class AbilityUtils {
public static Predicate isReplyTo(String msg) {
return update -> update.getMessage().getReplyToMessage().getText().equals(msg);
}
-}
+
+ public static String getLocalizedMessage(String messageCode, Locale locale, Object...arguments) {
+ ResourceBundle bundle;
+ if (locale == null) {
+ bundle = getBundle("messages", Locale.ROOT);
+ } else {
+ try {
+ bundle = getBundle(
+ "messages",
+ locale,
+ getNoFallbackControl(FORMAT_PROPERTIES));
+ } catch (MissingResourceException e) {
+ bundle = getBundle("messages", Locale.ROOT);
+ }
+ }
+ String message = bundle.getString(messageCode);
+ return MessageFormat.format(message, arguments);
+ }
+
+ public static String getLocalizedMessage(String messageCode, String languageCode, Object...arguments){
+ Locale locale = Strings.isNullOrEmpty(languageCode) ? null : Locale.forLanguageTag(languageCode);
+ return getLocalizedMessage(messageCode, locale, arguments);
+ }
+
+ /**
+ * The short name is one of the following:
+ *
+ * - First name
+ * - Last name
+ * - Username
+ *
+ * The method will try to return the first valid name in the specified order.
+ *
+ * @return the short name of the user
+ */
+ public static String shortName(User user) {
+ if (!isEmpty(user.getFirstName()))
+ return user.getFirstName();
+
+ if (!isEmpty(user.getLastName()))
+ return user.getLastName();
+
+ return user.getUserName();
+ }
+
+ /**
+ * The full name is identified as the concatenation of the first and last name, separated by a space.
+ * This method can return an empty name if both first and last name are empty.
+ *
+ * @return the full name of the user
+ * @param user
+ */
+ public static String fullName(User user) {
+ StringJoiner name = new StringJoiner(" ");
+
+ if (!isEmpty(user.getFirstName()))
+ name.add(user.getFirstName());
+ if (!isEmpty(user.getLastName()))
+ name.add(user.getLastName());
+
+ return name.toString();
+ }
+}
\ No newline at end of file
diff --git a/telegrambots-abilities/src/main/resources/messages.properties b/telegrambots-abilities/src/main/resources/messages.properties
new file mode 100644
index 00000000..57e2485b
--- /dev/null
+++ b/telegrambots-abilities/src/main/resources/messages.properties
@@ -0,0 +1,27 @@
+ability.commands.notFound=No available commands found.
+
+ability.recover.success=I have successfully recovered.
+ability.recover.fail=Oops, something went wrong during recovery.
+ability.recover.message=I am ready to receive the backup file. Please reply to this message with the backup file attached.
+ability.recover.error=I have failed to recover.
+
+ability.ban.success={0} is now *banned*.
+ability.ban.fail={0} is already *banned*.
+
+ability.unban.success=@{0}, your ban has been *lifted*.
+ability.unban.fail=@{0} is *not* on the *blacklist*.
+
+ability.promote.success=@{0} has been *promoted*.
+ability.promote.fail=@{0} is already an *admin*.
+
+ability.demote.success=@{0} has been *demoted*.
+ability.demote.fail=@{0} is *not* an *admin*.
+
+ability.claim.success=You''re now my master.
+ability.claim.fail=You''re already my master.
+
+checkInput.fail=Sorry, this feature requires {0,number,integer} additional {1}.
+checkLocality.fail=Sorry, {0}-only feature.
+checkPrivacy.fail=Sorry, you don''t have the required access level to do that.
+
+userNotFound=Sorry, I could not find the user [{0}].
\ No newline at end of file
diff --git a/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/bot/AbilityBotI18nTest.java b/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/bot/AbilityBotI18nTest.java
new file mode 100644
index 00000000..fd1b75f9
--- /dev/null
+++ b/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/bot/AbilityBotI18nTest.java
@@ -0,0 +1,81 @@
+package org.telegram.abilitybots.api.bot;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.telegram.abilitybots.api.db.DBContext;
+import org.telegram.abilitybots.api.objects.MessageContext;
+import org.telegram.abilitybots.api.sender.MessageSender;
+import org.telegram.abilitybots.api.sender.SilentSender;
+import org.telegram.telegrambots.api.objects.User;
+
+import java.io.IOException;
+
+import static org.apache.commons.lang3.StringUtils.EMPTY;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+import static org.telegram.abilitybots.api.bot.AbilityBotTest.mockContext;
+import static org.telegram.abilitybots.api.db.MapDBContext.offlineInstance;
+
+public class AbilityBotI18nTest {
+ private static final User NO_LANGUAGE_USER = new User(1, "first", false, "last", "username", null);
+ private static final User ITALIAN_USER = new User(2, "first", false, "last", "username", "it-IT");
+
+ private DBContext db;
+ private NoPublicCommandsBot bot;
+
+ private MessageSender sender;
+ private SilentSender silent;
+
+ @Before
+ public void setUp() {
+ db = offlineInstance("db");
+ bot = new NoPublicCommandsBot(EMPTY, EMPTY, db);
+
+ sender = mock(MessageSender.class);
+ silent = mock(SilentSender.class);
+
+ bot.sender = sender;
+ bot.silent = silent;
+
+ }
+
+ @Test
+ public void missingPublicCommandsLocalizedInEnglishByDefault() {
+ MessageContext context = mockContext(NO_LANGUAGE_USER);
+
+ bot.reportCommands().action().accept(context);
+
+ verify(silent, times(1))
+ .send("No available commands found.", NO_LANGUAGE_USER.getId());
+ }
+
+ @Test
+ public void missingPublicCommandsLocalizedInItalian() {
+ MessageContext context = mockContext(ITALIAN_USER);
+
+ bot.reportCommands().action().accept(context);
+
+ verify(silent, times(1))
+ .send("Non sono presenti comandi disponibile.", ITALIAN_USER.getId());
+ }
+
+ @After
+ public void tearDown() throws IOException {
+ db.clear();
+ db.close();
+ }
+
+ public static class NoPublicCommandsBot extends AbilityBot {
+
+ protected NoPublicCommandsBot(String botToken, String botUsername, DBContext db) {
+ super(botToken, botUsername, db);
+ }
+
+ @Override
+ public int creatorId() {
+ return 1;
+ }
+ }
+}
diff --git a/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/bot/AbilityBotTest.java b/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/bot/AbilityBotTest.java
index e4c0598b..7ad96030 100644
--- a/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/bot/AbilityBotTest.java
+++ b/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/bot/AbilityBotTest.java
@@ -36,11 +36,8 @@ import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
import static org.mockito.internal.verification.VerificationModeFactory.times;
-import static org.telegram.abilitybots.api.bot.AbilityBot.RECOVERY_MESSAGE;
-import static org.telegram.abilitybots.api.bot.AbilityBot.RECOVER_SUCCESS;
import static org.telegram.abilitybots.api.bot.DefaultBot.getDefaultBuilder;
import static org.telegram.abilitybots.api.db.MapDBContext.offlineInstance;
-import static org.telegram.abilitybots.api.objects.EndUser.endUser;
import static org.telegram.abilitybots.api.objects.Flag.DOCUMENT;
import static org.telegram.abilitybots.api.objects.Flag.MESSAGE;
import static org.telegram.abilitybots.api.objects.Locality.ALL;
@@ -49,12 +46,16 @@ import static org.telegram.abilitybots.api.objects.MessageContext.newContext;
import static org.telegram.abilitybots.api.objects.Privacy.*;
public class AbilityBotTest {
+ // Messages
+ private static final String RECOVERY_MESSAGE = "I am ready to receive the backup file. Please reply to this message with the backup file attached.";
+ private static final String RECOVER_SUCCESS = "I have successfully recovered.";
+
private static final String[] EMPTY_ARRAY = {};
private static final long GROUP_ID = 10L;
private static final String TEST = "test";
private static final String[] TEXT = {TEST};
- public static final EndUser MUSER = endUser(1, "first", "last", "username");
- public static final EndUser CREATOR = endUser(1337, "creatorFirst", "creatorLast", "creatorUsername");
+ public static final User USER = new User(1, "first", false, "last", "username", null);
+ public static final User CREATOR = new User(1337, "creatorFirst", false, "creatorLast", "creatorUsername", null);
private DefaultBot bot;
private DBContext db;
@@ -75,39 +76,39 @@ public class AbilityBotTest {
@Test
public void sendsPrivacyViolation() {
- Update update = mockFullUpdate(MUSER, "/admin");
+ Update update = mockFullUpdate(USER, "/admin");
bot.onUpdateReceived(update);
- verify(silent, times(1)).send("Sorry, you don't have the required access level to do that.", MUSER.id());
+ verify(silent, times(1)).send("Sorry, you don't have the required access level to do that.", USER.getId());
}
@Test
public void sendsLocalityViolation() {
- Update update = mockFullUpdate(MUSER, "/group");
+ Update update = mockFullUpdate(USER, "/group");
bot.onUpdateReceived(update);
- verify(silent, times(1)).send(format("Sorry, %s-only feature.", "group"), MUSER.id());
+ verify(silent, times(1)).send(format("Sorry, %s-only feature.", "group"), USER.getId());
}
@Test
public void sendsInputArgsViolation() {
- Update update = mockFullUpdate(MUSER, "/count 1 2 3");
+ Update update = mockFullUpdate(USER, "/count 1 2 3");
bot.onUpdateReceived(update);
- verify(silent, times(1)).send(format("Sorry, this feature requires %d additional inputs.", 4), MUSER.id());
+ verify(silent, times(1)).send(format("Sorry, this feature requires %d additional inputs.", 4), USER.getId());
}
@Test
public void canProcessRepliesIfSatisfyRequirements() {
- Update update = mockFullUpdate(MUSER, "must reply");
+ Update update = mockFullUpdate(USER, "must reply");
// False means the update was not pushed down the stream since it has been consumed by the reply
assertFalse(bot.filterReply(update));
- verify(silent, times(1)).send("reply", MUSER.id());
+ verify(silent, times(1)).send("reply", USER.getId());
}
@Test
@@ -144,8 +145,8 @@ public class AbilityBotTest {
@Test
public void canDemote() {
- addUsers(MUSER);
- bot.admins().add(MUSER.id());
+ addUsers(USER);
+ bot.admins().add(USER.getId());
MessageContext context = defaultContext();
@@ -158,33 +159,33 @@ public class AbilityBotTest {
@Test
public void canPromote() {
- addUsers(MUSER);
+ addUsers(USER);
MessageContext context = defaultContext();
bot.promoteAdmin().action().accept(context);
Set actual = bot.admins();
- Set expected = newHashSet(MUSER.id());
+ Set expected = newHashSet(USER.getId());
assertEquals("Could not sudo user", expected, actual);
}
@Test
public void canBanUser() {
- addUsers(MUSER);
+ addUsers(USER);
MessageContext context = defaultContext();
bot.banUser().action().accept(context);
Set actual = bot.blacklist();
- Set expected = newHashSet(MUSER.id());
+ Set expected = newHashSet(USER.getId());
assertEquals("The ban was not emplaced", expected, actual);
}
@Test
public void canUnbanUser() {
- addUsers(MUSER);
- bot.blacklist().add(MUSER.id());
+ addUsers(USER);
+ bot.blacklist().add(USER.getId());
MessageContext context = defaultContext();
@@ -197,65 +198,42 @@ public class AbilityBotTest {
@NotNull
private MessageContext defaultContext() {
- MessageContext context = mock(MessageContext.class);
- when(context.user()).thenReturn(CREATOR);
- when(context.firstArg()).thenReturn(MUSER.username());
- return context;
+ return mockContext(CREATOR, GROUP_ID, USER.getUserName());
}
@Test
public void cannotBanCreator() {
- addUsers(MUSER, CREATOR);
- MessageContext context = mock(MessageContext.class);
- when(context.user()).thenReturn(MUSER);
- when(context.firstArg()).thenReturn(CREATOR.username());
+ addUsers(USER, CREATOR);
+ MessageContext context = mockContext(USER, GROUP_ID, CREATOR.getUserName());
bot.banUser().action().accept(context);
Set actual = bot.blacklist();
- Set expected = newHashSet(MUSER.id());
+ Set expected = newHashSet(USER.getId());
assertEquals("Impostor was not added to the blacklist", expected, actual);
}
- private void addUsers(EndUser... users) {
+ private void addUsers(User... users) {
Arrays.stream(users).forEach(user -> {
- bot.users().put(user.id(), user);
- bot.userIds().put(user.username().toLowerCase(), user.id());
+ bot.users().put(user.getId(), user);
+ bot.userIds().put(user.getUserName().toLowerCase(), user.getId());
});
}
@Test
public void creatorCanClaimBot() {
- MessageContext context = mock(MessageContext.class);
- when(context.user()).thenReturn(CREATOR);
+ MessageContext context = mockContext(CREATOR, GROUP_ID);
bot.claimCreator().action().accept(context);
Set actual = bot.admins();
- Set expected = newHashSet(CREATOR.id());
+ Set expected = newHashSet(CREATOR.getId());
assertEquals("Creator was not properly added to the super admins set", expected, actual);
}
- @Test
- public void userGetsBannedIfClaimsBot() {
- addUsers(MUSER);
- MessageContext context = mock(MessageContext.class);
- when(context.user()).thenReturn(MUSER);
-
- bot.claimCreator().action().accept(context);
-
- Set actual = bot.blacklist();
- Set expected = newHashSet(MUSER.id());
- assertEquals("Could not find user on the blacklist", expected, actual);
-
- actual = bot.admins();
- expected = emptySet();
- assertEquals("Admins set is not empty", expected, actual);
- }
-
@Test
public void bannedCreatorPassesBlacklistCheck() {
- bot.blacklist().add(CREATOR.id());
+ bot.blacklist().add(CREATOR.getId());
Update update = mock(Update.class);
Message message = mock(Message.class);
User user = mock(User.class);
@@ -270,37 +248,35 @@ public class AbilityBotTest {
public void canAddUser() {
Update update = mock(Update.class);
Message message = mock(Message.class);
- User user = mock(User.class);
- mockAlternateUser(update, message, user, MUSER);
+ mockAlternateUser(update, message, USER);
bot.addUser(update);
- Map expectedUserIds = ImmutableMap.of(MUSER.username(), MUSER.id());
- Map expectedUsers = ImmutableMap.of(MUSER.id(), MUSER);
+ Map expectedUserIds = ImmutableMap.of(USER.getUserName(), USER.getId());
+ Map expectedUsers = ImmutableMap.of(USER.getId(), USER);
assertEquals("User was not added", expectedUserIds, bot.userIds());
assertEquals("User was not added", expectedUsers, bot.users());
}
@Test
public void canEditUser() {
- addUsers(MUSER);
+ addUsers(USER);
Update update = mock(Update.class);
Message message = mock(Message.class);
- User user = mock(User.class);
- String newUsername = MUSER.username() + "-test";
- String newFirstName = MUSER.firstName() + "-test";
- String newLastName = MUSER.lastName() + "-test";
- int sameId = MUSER.id();
- EndUser changedUser = endUser(sameId, newFirstName, newLastName, newUsername);
+ String newUsername = USER.getUserName() + "-test";
+ String newFirstName = USER.getFirstName() + "-test";
+ String newLastName = USER.getLastName() + "-test";
+ int sameId = USER.getId();
+ User changedUser = new User(sameId, newFirstName, false, newLastName, newUsername, null);
- mockAlternateUser(update, message, user, changedUser);
+ mockAlternateUser(update, message, changedUser);
bot.addUser(update);
- Map expectedUserIds = ImmutableMap.of(changedUser.username(), changedUser.id());
- Map expectedUsers = ImmutableMap.of(changedUser.id(), changedUser);
+ Map expectedUserIds = ImmutableMap.of(changedUser.getUserName(), changedUser.getId());
+ Map expectedUsers = ImmutableMap.of(changedUser.getId(), changedUser);
assertEquals("User was not properly edited", bot.userIds(), expectedUserIds);
assertEquals("User was not properly edited", expectedUsers, expectedUsers);
}
@@ -311,13 +287,13 @@ public class AbilityBotTest {
Ability validAbility = getDefaultBuilder().build();
Trio validPair = Trio.of(null, validAbility, null);
- assertEquals("Bot can't validate ability properly", false, bot.validateAbility(invalidPair));
- assertEquals("Bot can't validate ability properly", true, bot.validateAbility(validPair));
+ assertFalse("Bot can't validate ability properly", bot.validateAbility(invalidPair));
+ assertTrue("Bot can't validate ability properly", bot.validateAbility(validPair));
}
@Test
public void canCheckInput() {
- Update update = mockFullUpdate(MUSER, "/something");
+ Update update = mockFullUpdate(USER, "/something");
Ability abilityWithOneInput = getDefaultBuilder()
.build();
Ability abilityWithZeroInput = getDefaultBuilder()
@@ -327,15 +303,15 @@ public class AbilityBotTest {
Trio trioOneArg = Trio.of(update, abilityWithOneInput, TEXT);
Trio trioZeroArg = Trio.of(update, abilityWithZeroInput, TEXT);
- assertEquals("Unexpected result when applying token filter", true, bot.checkInput(trioOneArg));
+ assertTrue("Unexpected result when applying token filter", bot.checkInput(trioOneArg));
trioOneArg = Trio.of(update, abilityWithOneInput, addAll(TEXT, TEXT));
- assertEquals("Unexpected result when applying token filter", false, bot.checkInput(trioOneArg));
+ assertFalse("Unexpected result when applying token filter", bot.checkInput(trioOneArg));
- assertEquals("Unexpected result when applying token filter", true, bot.checkInput(trioZeroArg));
+ assertTrue("Unexpected result when applying token filter", bot.checkInput(trioZeroArg));
trioZeroArg = Trio.of(update, abilityWithZeroInput, EMPTY_ARRAY);
- assertEquals("Unexpected result when applying token filter", true, bot.checkInput(trioZeroArg));
+ assertTrue("Unexpected result when applying token filter", bot.checkInput(trioZeroArg));
}
@Test
@@ -355,14 +331,14 @@ public class AbilityBotTest {
mockUser(update, message, user);
- assertEquals("Unexpected result when checking for privacy", true, bot.checkPrivacy(publicTrio));
- assertEquals("Unexpected result when checking for privacy", false, bot.checkPrivacy(groupAdminTrio));
- assertEquals("Unexpected result when checking for privacy", false, bot.checkPrivacy(adminTrio));
- assertEquals("Unexpected result when checking for privacy", false, bot.checkPrivacy(creatorTrio));
+ assertTrue("Unexpected result when checking for privacy", bot.checkPrivacy(publicTrio));
+ assertFalse("Unexpected result when checking for privacy", bot.checkPrivacy(groupAdminTrio));
+ assertFalse("Unexpected result when checking for privacy", bot.checkPrivacy(adminTrio));
+ assertFalse("Unexpected result when checking for privacy", bot.checkPrivacy(creatorTrio));
}
@Test
- public void canValidateGroupAdminPrivacy() throws TelegramApiException {
+ public void canValidateGroupAdminPrivacy() {
Update update = mock(Update.class);
Message message = mock(Message.class);
User user = mock(User.class);
@@ -379,11 +355,11 @@ public class AbilityBotTest {
when(silent.execute(any(GetChatAdministrators.class))).thenReturn(Optional.of(newArrayList(member)));
- assertEquals("Unexpected result when checking for privacy", true, bot.checkPrivacy(groupAdminTrio));
+ assertTrue("Unexpected result when checking for privacy", bot.checkPrivacy(groupAdminTrio));
}
@Test
- public void canRestrictNormalUsersFromGroupAdminAbilities() throws TelegramApiException {
+ public void canRestrictNormalUsersFromGroupAdminAbilities() {
Update update = mock(Update.class);
Message message = mock(Message.class);
User user = mock(User.class);
@@ -396,7 +372,7 @@ public class AbilityBotTest {
when(silent.execute(any(GetChatAdministrators.class))).thenReturn(empty());
- assertEquals("Unexpected result when checking for privacy", false, bot.checkPrivacy(groupAdminTrio));
+ assertFalse("Unexpected result when checking for privacy", bot.checkPrivacy(groupAdminTrio));
}
@Test
@@ -408,10 +384,10 @@ public class AbilityBotTest {
Trio creatorTrio = Trio.of(update, creatorAbility, TEXT);
- bot.admins().add(MUSER.id());
+ bot.admins().add(USER.getId());
mockUser(update, message, user);
- assertEquals("Unexpected result when checking for privacy", false, bot.checkPrivacy(creatorTrio));
+ assertFalse("Unexpected result when checking for privacy", bot.checkPrivacy(creatorTrio));
}
@Test
@@ -430,24 +406,23 @@ public class AbilityBotTest {
mockUser(update, message, user);
when(message.isUserMessage()).thenReturn(true);
- assertEquals("Unexpected result when checking for locality", true, bot.checkLocality(publicTrio));
- assertEquals("Unexpected result when checking for locality", true, bot.checkLocality(userTrio));
- assertEquals("Unexpected result when checking for locality", false, bot.checkLocality(groupTrio));
+ assertTrue("Unexpected result when checking for locality", bot.checkLocality(publicTrio));
+ assertTrue("Unexpected result when checking for locality", bot.checkLocality(userTrio));
+ assertFalse("Unexpected result when checking for locality", bot.checkLocality(groupTrio));
}
@Test
public void canRetrieveContext() {
Update update = mock(Update.class);
Message message = mock(Message.class);
- User user = mock(User.class);
Ability ability = getDefaultBuilder().build();
Trio trio = Trio.of(update, ability, TEXT);
when(message.getChatId()).thenReturn(GROUP_ID);
- mockUser(update, message, user);
+ mockUser(update, message, USER);
Pair actualPair = bot.getContext(trio);
- Pair expectedPair = Pair.of(newContext(update, MUSER, GROUP_ID, TEXT), ability);
+ Pair expectedPair = Pair.of(newContext(update, USER, GROUP_ID, TEXT), ability);
assertEquals("Unexpected result when fetching for context", expectedPair, actualPair);
}
@@ -455,7 +430,7 @@ public class AbilityBotTest {
@Test
public void defaultGlobalFlagIsTrue() {
Update update = mock(Update.class);
- assertEquals("Unexpected result when checking for the default global flags", true, bot.checkGlobalFlags(update));
+ assertTrue("Unexpected result when checking for the default global flags", bot.checkGlobalFlags(update));
}
@Test(expected = ArithmeticException.class)
@@ -542,24 +517,69 @@ public class AbilityBotTest {
Trio docTrio = Trio.of(update, documentAbility, TEXT);
Trio textTrio = Trio.of(update, textAbility, TEXT);
- assertEquals("Unexpected result when checking for message flags", false, bot.checkMessageFlags(docTrio));
- assertEquals("Unexpected result when checking for message flags", true, bot.checkMessageFlags(textTrio));
+ assertFalse("Unexpected result when checking for message flags", bot.checkMessageFlags(docTrio));
+ assertTrue("Unexpected result when checking for message flags", bot.checkMessageFlags(textTrio));
}
@Test
public void canReportCommands() {
+ MessageContext context = mockContext(USER, GROUP_ID);
+
+ bot.reportCommands().action().accept(context);
+
+ verify(silent, times(1)).send("default - dis iz default command", GROUP_ID);
+ }
+
+ @NotNull
+ public static MessageContext mockContext(User user) {
+ return mockContext(user, user.getId());
+ }
+
+ @NotNull
+ public static MessageContext mockContext(User user, long groupId, String... args) {
+ Update update = mock(Update.class);
+ Message message = mock(Message.class);
+
+ when(update.hasMessage()).thenReturn(true);
+ when(update.getMessage()).thenReturn(message);
+
+ when(message.getFrom()).thenReturn(user);
+ when(message.hasText()).thenReturn(true);
+
+ return newContext(update, user, groupId, args);
+ }
+
+ @Test
+ public void canPrintCommandsBasedOnPrivacy() {
Update update = mock(Update.class);
Message message = mock(Message.class);
when(update.hasMessage()).thenReturn(true);
when(update.getMessage()).thenReturn(message);
when(message.hasText()).thenReturn(true);
- MessageContext context = mock(MessageContext.class);
- when(context.chatId()).thenReturn(GROUP_ID);
+ MessageContext creatorCtx = newContext(update, CREATOR, GROUP_ID);
- bot.reportCommands().action().accept(context);
+ bot.commands().action().accept(creatorCtx);
- verify(silent, times(1)).send("default - dis iz default command", GROUP_ID);
+ String expected = "PUBLIC\n/commands\n/count\n/default - dis iz default command\n/group\n/test\nADMIN\n/admin\n/ban\n/demote\n/promote\n/unban\nCREATOR\n/backup\n/claim\n/recover\n/report";
+ verify(silent, times(1)).send(expected, GROUP_ID);
+ }
+
+ @Test
+ public void printsOnlyPublicCommandsForNormalUser() {
+ Update update = mock(Update.class);
+ Message message = mock(Message.class);
+
+ when(update.hasMessage()).thenReturn(true);
+ when(update.getMessage()).thenReturn(message);
+ when(message.hasText()).thenReturn(true);
+
+ MessageContext userCtx = newContext(update, USER, GROUP_ID);
+
+ bot.commands().action().accept(userCtx);
+
+ String expected = "PUBLIC\n/commands\n/count\n/default - dis iz default command\n/group\n/test";
+ verify(silent, times(1)).send(expected, GROUP_ID);
}
@After
@@ -568,26 +588,14 @@ public class AbilityBotTest {
db.close();
}
- private User mockUser(EndUser fromUser) {
- User user = mock(User.class);
- when(user.getId()).thenReturn(fromUser.id());
- when(user.getUserName()).thenReturn(fromUser.username());
- when(user.getFirstName()).thenReturn(fromUser.firstName());
- when(user.getLastName()).thenReturn(fromUser.lastName());
-
- return user;
- }
-
@NotNull
- private Update mockFullUpdate(EndUser fromUser, String args) {
- bot.users().put(MUSER.id(), MUSER);
- bot.users().put(CREATOR.id(), CREATOR);
- bot.userIds().put(CREATOR.username(), CREATOR.id());
- bot.userIds().put(MUSER.username(), MUSER.id());
+ private Update mockFullUpdate(User user, String args) {
+ bot.users().put(USER.getId(), USER);
+ bot.users().put(CREATOR.getId(), CREATOR);
+ bot.userIds().put(CREATOR.getUserName(), CREATOR.getId());
+ bot.userIds().put(USER.getUserName(), USER.getId());
- bot.admins().add(CREATOR.id());
-
- User user = mockUser(fromUser);
+ bot.admins().add(CREATOR.getId());
Update update = mock(Update.class);
when(update.hasMessage()).thenReturn(true);
@@ -596,7 +604,7 @@ public class AbilityBotTest {
when(message.getText()).thenReturn(args);
when(message.hasText()).thenReturn(true);
when(message.isUserMessage()).thenReturn(true);
- when(message.getChatId()).thenReturn((long) fromUser.id());
+ when(message.getChatId()).thenReturn((long) user.getId());
when(update.getMessage()).thenReturn(message);
return update;
}
@@ -605,17 +613,9 @@ public class AbilityBotTest {
when(update.hasMessage()).thenReturn(true);
when(update.getMessage()).thenReturn(message);
when(message.getFrom()).thenReturn(user);
- when(user.getFirstName()).thenReturn(MUSER.firstName());
- when(user.getLastName()).thenReturn(MUSER.lastName());
- when(user.getId()).thenReturn(MUSER.id());
- when(user.getUserName()).thenReturn(MUSER.username());
}
- private void mockAlternateUser(Update update, Message message, User user, EndUser changedUser) {
- when(user.getId()).thenReturn(changedUser.id());
- when(user.getFirstName()).thenReturn(changedUser.firstName());
- when(user.getLastName()).thenReturn(changedUser.lastName());
- when(user.getUserName()).thenReturn(changedUser.username());
+ private void mockAlternateUser(Update update, Message message, User user) {
when(message.getFrom()).thenReturn(user);
when(update.hasMessage()).thenReturn(true);
when(update.getMessage()).thenReturn(message);
@@ -627,10 +627,12 @@ public class AbilityBotTest {
Message botMessage = mock(Message.class);
Document document = mock(Document.class);
+ when(message.getFrom()).thenReturn(CREATOR);
when(update.getMessage()).thenReturn(message);
when(message.getDocument()).thenReturn(document);
when(botMessage.getText()).thenReturn(RECOVERY_MESSAGE);
when(message.isReply()).thenReturn(true);
+ when(update.hasMessage()).thenReturn(true);
when(message.hasDocument()).thenReturn(true);
when(message.getReplyToMessage()).thenReturn(botMessage);
when(message.getChatId()).thenReturn(GROUP_ID);
diff --git a/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/db/MapDBContextTest.java b/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/db/MapDBContextTest.java
index 7e53584b..0f85ce36 100644
--- a/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/db/MapDBContextTest.java
+++ b/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/db/MapDBContextTest.java
@@ -3,7 +3,7 @@ package org.telegram.abilitybots.api.db;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.telegram.abilitybots.api.objects.EndUser;
+import org.telegram.telegrambots.api.objects.User;
import java.io.IOException;
import java.util.Map;
@@ -12,12 +12,11 @@ import java.util.Set;
import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Sets.newHashSet;
import static java.lang.String.format;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
import static org.telegram.abilitybots.api.bot.AbilityBot.USERS;
import static org.telegram.abilitybots.api.bot.AbilityBot.USER_ID;
import static org.telegram.abilitybots.api.bot.AbilityBotTest.CREATOR;
-import static org.telegram.abilitybots.api.bot.AbilityBotTest.MUSER;
+import static org.telegram.abilitybots.api.bot.AbilityBotTest.USER;
import static org.telegram.abilitybots.api.db.MapDBContext.offlineInstance;
public class MapDBContextTest {
@@ -32,22 +31,22 @@ public class MapDBContextTest {
@Test
public void canRecoverDB() {
- Map users = db.getMap(USERS);
+ Map users = db.getMap(USERS);
Map userIds = db.getMap(USER_ID);
- users.put(CREATOR.id(), CREATOR);
- users.put(MUSER.id(), MUSER);
- userIds.put(CREATOR.username(), CREATOR.id());
- userIds.put(MUSER.username(), MUSER.id());
+ users.put(CREATOR.getId(), CREATOR);
+ users.put(USER.getId(), USER);
+ userIds.put(CREATOR.getUserName(), CREATOR.getId());
+ userIds.put(USER.getUserName(), USER.getId());
db.getSet("AYRE").add(123123);
- Map originalUsers = newHashMap(users);
+ Map originalUsers = newHashMap(users);
String beforeBackupInfo = db.info(USERS);
Object jsonBackup = db.backup();
db.clear();
boolean recovered = db.recover(jsonBackup);
- Map recoveredUsers = db.getMap(USERS);
+ Map recoveredUsers = db.getMap(USERS);
String afterRecoveryInfo = db.info(USERS);
assertTrue("Could not recover database successfully", recovered);
@@ -56,24 +55,24 @@ public class MapDBContextTest {
}
@Test
- public void canFallbackDBIfRecoveryFails() throws IOException {
- Set users = db.getSet(USERS);
+ public void canFallbackDBIfRecoveryFails() {
+ Set users = db.getSet(USERS);
users.add(CREATOR);
- users.add(MUSER);
+ users.add(USER);
- Set originalSet = newHashSet(users);
+ Set originalSet = newHashSet(users);
Object jsonBackup = db.backup();
String corruptBackup = "!@#$" + String.valueOf(jsonBackup);
boolean recovered = db.recover(corruptBackup);
- Set recoveredSet = db.getSet(USERS);
+ Set recoveredSet = db.getSet(USERS);
- assertEquals("Recovery was successful from a CORRUPT backup", false, recovered);
+ assertFalse("Recovery was successful from a CORRUPT backup", recovered);
assertEquals("Set before and after corrupt recovery are not equal", originalSet, recoveredSet);
}
@Test
- public void canGetSummary() throws IOException {
+ public void canGetSummary() {
String anotherTest = TEST + 1;
db.getSet(TEST).add(TEST);
db.getSet(anotherTest).add(anotherTest);
@@ -86,7 +85,7 @@ public class MapDBContextTest {
}
@Test
- public void canGetInfo() throws IOException {
+ public void canGetInfo() {
db.getSet(TEST).add(TEST);
String actualInfo = db.info(TEST);
@@ -97,10 +96,27 @@ public class MapDBContextTest {
}
@Test(expected = IllegalStateException.class)
- public void cantGetInfoFromNonexistentDBStructureName() throws IOException {
+ public void cantGetInfoFromNonexistentDBStructureName() {
db.info(TEST);
}
+ @Test
+ public void canGetAndSetVariables() {
+ String varName = "somevar";
+ Var var = db.getVar(varName);
+ var.set(CREATOR);
+ db.commit();
+
+ var = db.getVar(varName);
+ assertEquals(var.get(), CREATOR);
+
+ var.set(USER);
+ db.commit();
+
+ Var changedVar = db.getVar(varName);
+ assertEquals(changedVar.get(), USER);
+ }
+
@After
public void tearDown() throws IOException {
db.clear();
diff --git a/telegrambots-abilities/src/test/resources/messages_it_IT.properties b/telegrambots-abilities/src/test/resources/messages_it_IT.properties
new file mode 100644
index 00000000..52f1377d
--- /dev/null
+++ b/telegrambots-abilities/src/test/resources/messages_it_IT.properties
@@ -0,0 +1 @@
+ability.commands.notFound=Non sono presenti comandi disponibile.
\ No newline at end of file
diff --git a/telegrambots-extensions/pom.xml b/telegrambots-extensions/pom.xml
index 35d22cd6..b28a6f6d 100644
--- a/telegrambots-extensions/pom.xml
+++ b/telegrambots-extensions/pom.xml
@@ -5,7 +5,7 @@
4.0.0
org.telegram
telegrambotsextensions
- 3.6.1
+ 3.6.2
jar
Telegram Bots Extensions
diff --git a/telegrambots-meta/pom.xml b/telegrambots-meta/pom.xml
index a37020bc..2e813f79 100644
--- a/telegrambots-meta/pom.xml
+++ b/telegrambots-meta/pom.xml
@@ -5,7 +5,7 @@
4.0.0
org.telegram
telegrambots-meta
- 3.6.1
+ 3.6.2
jar
Telegram Bots Meta
diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/api/objects/User.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/api/objects/User.java
index 536f931d..2776805a 100644
--- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/api/objects/User.java
+++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/api/objects/User.java
@@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import org.telegram.telegrambots.meta.api.interfaces.BotApiObject;
+import java.util.Objects;
+
/**
* @author Ruben Bermudez
* @version 3.0
@@ -35,6 +37,15 @@ public class User implements BotApiObject {
super();
}
+ public User(Integer id, String firstName, Boolean isBot, String lastName, String userName, String languageCode) {
+ this.id = id;
+ this.firstName = firstName;
+ this.isBot = isBot;
+ this.lastName = lastName;
+ this.userName = userName;
+ this.languageCode = languageCode;
+ }
+
public Integer getId() {
return id;
}
@@ -59,6 +70,24 @@ public class User implements BotApiObject {
return isBot;
}
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ User user = (User) o;
+ return Objects.equals(id, user.id) &&
+ Objects.equals(firstName, user.firstName) &&
+ Objects.equals(isBot, user.isBot) &&
+ Objects.equals(lastName, user.lastName) &&
+ Objects.equals(userName, user.userName) &&
+ Objects.equals(languageCode, user.languageCode);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, firstName, isBot, lastName, userName, languageCode);
+ }
+
@Override
public String toString() {
return "User{" +
diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/api/objects/WebhookInfo.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/api/objects/WebhookInfo.java
index 6b013a70..ba573b9b 100644
--- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/api/objects/WebhookInfo.java
+++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/api/objects/WebhookInfo.java
@@ -16,7 +16,7 @@ public class WebhookInfo implements BotApiObject {
private static final String URL_FIELD = "url";
private static final String HASCUSTOMCERTIFICATE_FIELD = "has_custom_certificate";
- private static final String PENDINGUPDATESCOUNT_FIELD = "pending_updates_count";
+ private static final String PENDINGUPDATECOUNT_FIELD = "pending_update_count";
private static final String MAXCONNECTIONS_FIELD = "max_connections";
private static final String ALLOWEDUPDATES_FIELD = "allowed_updates";
private static final String LASTERRORDATE_FIELD = "last_error_date";
@@ -26,7 +26,7 @@ public class WebhookInfo implements BotApiObject {
private String url; ///< Webhook URL, may be empty if webhook is not set up
@JsonProperty(HASCUSTOMCERTIFICATE_FIELD)
private Boolean hasCustomCertificate; ///< True, if a custom certificate was provided for webhook certificate checks
- @JsonProperty(PENDINGUPDATESCOUNT_FIELD)
+ @JsonProperty(PENDINGUPDATECOUNT_FIELD)
private Integer pendingUpdatesCount; ///< Number updates awaiting delivery
@JsonProperty(LASTERRORDATE_FIELD)
private Integer lastErrorDate; ///< Optional. Unix time for the most recent error that happened when trying to deliver an update via webhook
diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/bots/AbsSender.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/bots/AbsSender.java
index 96ffe561..6a391c8a 100644
--- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/bots/AbsSender.java
+++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/bots/AbsSender.java
@@ -54,7 +54,10 @@ public abstract class AbsSender {
}
// Send Requests
-
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see SendMessage
+ */
@Deprecated
public final Message sendMessage(SendMessage sendMessage) throws TelegramApiException {
if (sendMessage == null) {
@@ -64,6 +67,10 @@ public abstract class AbsSender {
return sendApiMethod(sendMessage);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see AnswerInlineQuery
+ */
@Deprecated
public final Boolean answerInlineQuery(AnswerInlineQuery answerInlineQuery) throws TelegramApiException {
if (answerInlineQuery == null) {
@@ -73,6 +80,10 @@ public abstract class AbsSender {
return sendApiMethod(answerInlineQuery);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see SendChatAction
+ */
@Deprecated
public final Boolean sendChatAction(SendChatAction sendChatAction) throws TelegramApiException {
if (sendChatAction == null) {
@@ -82,6 +93,10 @@ public abstract class AbsSender {
return sendApiMethod(sendChatAction);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see ForwardMessage
+ */
@Deprecated
public final Message forwardMessage(ForwardMessage forwardMessage) throws TelegramApiException {
if (forwardMessage == null) {
@@ -91,6 +106,10 @@ public abstract class AbsSender {
return sendApiMethod(forwardMessage);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see SendLocation
+ */
@Deprecated
public final Message sendLocation(SendLocation sendLocation) throws TelegramApiException {
if (sendLocation == null) {
@@ -100,6 +119,10 @@ public abstract class AbsSender {
return sendApiMethod(sendLocation);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see SendVenue
+ */
@Deprecated
public final Message sendVenue(SendVenue sendVenue) throws TelegramApiException {
if (sendVenue == null) {
@@ -109,6 +132,10 @@ public abstract class AbsSender {
return sendApiMethod(sendVenue);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see SendContact
+ */
@Deprecated
public final Message sendContact(SendContact sendContact) throws TelegramApiException {
if (sendContact == null) {
@@ -118,6 +145,10 @@ public abstract class AbsSender {
return sendApiMethod(sendContact);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see KickChatMember
+ */
@Deprecated
public final Boolean kickMember(KickChatMember kickChatMember) throws TelegramApiException {
if (kickChatMember == null) {
@@ -126,6 +157,10 @@ public abstract class AbsSender {
return sendApiMethod(kickChatMember);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see UnbanChatMember
+ */
@Deprecated
public final Boolean unbanMember(UnbanChatMember unbanChatMember) throws TelegramApiException {
if (unbanChatMember == null) {
@@ -134,6 +169,10 @@ public abstract class AbsSender {
return sendApiMethod(unbanChatMember);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see LeaveChat
+ */
@Deprecated
public final Boolean leaveChat(LeaveChat leaveChat) throws TelegramApiException {
if (leaveChat == null) {
@@ -142,6 +181,10 @@ public abstract class AbsSender {
return sendApiMethod(leaveChat);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see GetChat
+ */
@Deprecated
public final Chat getChat(GetChat getChat) throws TelegramApiException {
if (getChat == null) {
@@ -150,6 +193,10 @@ public abstract class AbsSender {
return sendApiMethod(getChat);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see ExportChatInviteLink
+ */
@Deprecated
public final String exportChatInviteLink(ExportChatInviteLink exportChatInviteLink) throws TelegramApiException {
if (exportChatInviteLink == null) {
@@ -158,6 +205,10 @@ public abstract class AbsSender {
return sendApiMethod(exportChatInviteLink);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see GetChatAdministrators
+ */
@Deprecated
public final List getChatAdministrators(GetChatAdministrators getChatAdministrators) throws TelegramApiException {
if (getChatAdministrators == null) {
@@ -166,6 +217,10 @@ public abstract class AbsSender {
return sendApiMethod(getChatAdministrators);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see GetChatMember
+ */
@Deprecated
public final ChatMember getChatMember(GetChatMember getChatMember) throws TelegramApiException {
if (getChatMember == null) {
@@ -174,6 +229,10 @@ public abstract class AbsSender {
return sendApiMethod(getChatMember);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see GetChatMemberCount
+ */
@Deprecated
public final Integer getChatMemberCount(GetChatMemberCount getChatMemberCount) throws TelegramApiException {
if (getChatMemberCount == null) {
@@ -182,6 +241,10 @@ public abstract class AbsSender {
return sendApiMethod(getChatMemberCount);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see EditMessageText
+ */
@Deprecated
public final Serializable editMessageText(EditMessageText editMessageText) throws TelegramApiException {
if (editMessageText == null) {
@@ -190,6 +253,10 @@ public abstract class AbsSender {
return sendApiMethod(editMessageText);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see EditMessageCaption
+ */
@Deprecated
public final Serializable editMessageCaption(EditMessageCaption editMessageCaption) throws TelegramApiException {
if (editMessageCaption == null) {
@@ -198,6 +265,10 @@ public abstract class AbsSender {
return sendApiMethod(editMessageCaption);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see EditMessageReplyMarkup
+ */
@Deprecated
public final Serializable editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup) throws TelegramApiException {
if (editMessageReplyMarkup == null) {
@@ -206,6 +277,10 @@ public abstract class AbsSender {
return sendApiMethod(editMessageReplyMarkup);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see AnswerCallbackQuery
+ */
@Deprecated
public final Boolean answerCallbackQuery(AnswerCallbackQuery answerCallbackQuery) throws TelegramApiException {
if (answerCallbackQuery == null) {
@@ -214,6 +289,10 @@ public abstract class AbsSender {
return sendApiMethod(answerCallbackQuery);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see GetUserProfilePhotos
+ */
@Deprecated
public final UserProfilePhotos getUserProfilePhotos(GetUserProfilePhotos getUserProfilePhotos) throws TelegramApiException {
if (getUserProfilePhotos == null) {
@@ -223,6 +302,10 @@ public abstract class AbsSender {
return sendApiMethod(getUserProfilePhotos);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see GetFile
+ */
@Deprecated
public final File getFile(GetFile getFile) throws TelegramApiException {
if(getFile == null){
@@ -243,6 +326,10 @@ public abstract class AbsSender {
return sendApiMethod(getWebhookInfo);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see SetGameScore
+ */
@Deprecated
public final Serializable setGameScore(SetGameScore setGameScore) throws TelegramApiException {
if(setGameScore == null){
@@ -251,6 +338,10 @@ public abstract class AbsSender {
return sendApiMethod(setGameScore);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see GetGameHighScores
+ */
@Deprecated
public final Serializable getGameHighScores(GetGameHighScores getGameHighScores) throws TelegramApiException {
if(getGameHighScores == null){
@@ -259,6 +350,10 @@ public abstract class AbsSender {
return sendApiMethod(getGameHighScores);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see SendGame
+ */
@Deprecated
public final Message sendGame(SendGame sendGame) throws TelegramApiException {
if(sendGame == null){
@@ -267,6 +362,10 @@ public abstract class AbsSender {
return sendApiMethod(sendGame);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see DeleteWebhook
+ */
@Deprecated
public final Boolean deleteWebhook(DeleteWebhook deleteWebhook) throws TelegramApiException {
if(deleteWebhook == null){
@@ -275,6 +374,10 @@ public abstract class AbsSender {
return sendApiMethod(deleteWebhook);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see SendInvoice
+ */
@Deprecated
public final Message sendInvoice(SendInvoice sendInvoice) throws TelegramApiException {
if(sendInvoice == null){
@@ -283,6 +386,10 @@ public abstract class AbsSender {
return sendApiMethod(sendInvoice);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see AnswerShippingQuery
+ */
@Deprecated
public final Boolean answerShippingQuery(AnswerShippingQuery answerShippingQuery) throws TelegramApiException {
if(answerShippingQuery == null){
@@ -291,6 +398,10 @@ public abstract class AbsSender {
return sendApiMethod(answerShippingQuery);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see AnswerPreCheckoutQuery
+ */
@Deprecated
public final Boolean answerPreCheckoutQuery(AnswerPreCheckoutQuery answerPreCheckoutQuery) throws TelegramApiException {
if(answerPreCheckoutQuery == null){
@@ -299,6 +410,10 @@ public abstract class AbsSender {
return sendApiMethod(answerPreCheckoutQuery);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see DeleteMessage
+ */
@Deprecated
public final Boolean deleteMessage(DeleteMessage deleteMessage) throws TelegramApiException {
if(deleteMessage == null){
@@ -307,6 +422,10 @@ public abstract class AbsSender {
return sendApiMethod(deleteMessage);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see DeleteChatPhoto
+ */
@Deprecated
public final Boolean deleteChatPhoto(DeleteChatPhoto deleteChatPhoto) throws TelegramApiException {
if(deleteChatPhoto == null){
@@ -315,6 +434,10 @@ public abstract class AbsSender {
return sendApiMethod(deleteChatPhoto);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see PinChatMessage
+ */
@Deprecated
public final Boolean pinChatMessage(PinChatMessage pinChatMessage) throws TelegramApiException {
if(pinChatMessage == null){
@@ -323,6 +446,10 @@ public abstract class AbsSender {
return sendApiMethod(pinChatMessage);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see UnpinChatMessage
+ */
@Deprecated
public final Boolean unpinChatMessage(UnpinChatMessage unpinChatMessage) throws TelegramApiException {
if(unpinChatMessage == null){
@@ -331,6 +458,10 @@ public abstract class AbsSender {
return sendApiMethod(unpinChatMessage);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see PromoteChatMember
+ */
@Deprecated
public final Boolean promoteChatMember(PromoteChatMember promoteChatMember) throws TelegramApiException {
if(promoteChatMember == null){
@@ -339,6 +470,10 @@ public abstract class AbsSender {
return sendApiMethod(promoteChatMember);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see RestrictChatMember
+ */
@Deprecated
public final Boolean restrictChatMember(RestrictChatMember restrictChatMember) throws TelegramApiException {
if(restrictChatMember == null){
@@ -347,6 +482,10 @@ public abstract class AbsSender {
return sendApiMethod(restrictChatMember);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see SetChatDescription
+ */
@Deprecated
public final Boolean setChatDescription(SetChatDescription setChatDescription) throws TelegramApiException {
if(setChatDescription == null){
@@ -355,6 +494,10 @@ public abstract class AbsSender {
return sendApiMethod(setChatDescription);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) execute} Method instead
+ * @see SetChatTitle
+ */
@Deprecated
public final Boolean setChatTitle(SetChatTitle setChatTitle) throws TelegramApiException {
if(setChatTitle == null){
@@ -365,6 +508,10 @@ public abstract class AbsSender {
// Send Requests Async
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see SendMessage
+ */
@Deprecated
public final void sendMessageAsync(SendMessage sendMessage, SentCallback sentCallback) throws TelegramApiException {
if (sendMessage == null) {
@@ -378,6 +525,10 @@ public abstract class AbsSender {
sendApiMethodAsync(sendMessage, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see AnswerInlineQuery
+ */
@Deprecated
public final void answerInlineQueryAsync(AnswerInlineQuery answerInlineQuery, SentCallback sentCallback) throws TelegramApiException {
if (answerInlineQuery == null) {
@@ -391,6 +542,10 @@ public abstract class AbsSender {
sendApiMethodAsync(answerInlineQuery, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see SendChatAction
+ */
@Deprecated
public final void sendChatActionAsync(SendChatAction sendChatAction, SentCallback sentCallback) throws TelegramApiException {
if (sendChatAction == null) {
@@ -404,6 +559,10 @@ public abstract class AbsSender {
sendApiMethodAsync(sendChatAction, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see ForwardMessage
+ */
@Deprecated
public final void forwardMessageAsync(ForwardMessage forwardMessage, SentCallback sentCallback) throws TelegramApiException {
if (forwardMessage == null) {
@@ -417,6 +576,10 @@ public abstract class AbsSender {
sendApiMethodAsync(forwardMessage, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see SendLocation
+ */
@Deprecated
public final void sendLocationAsync(SendLocation sendLocation, SentCallback sentCallback) throws TelegramApiException {
if (sendLocation == null) {
@@ -430,6 +593,10 @@ public abstract class AbsSender {
sendApiMethodAsync(sendLocation, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see SendVenue
+ */
@Deprecated
public final void sendVenueAsync(SendVenue sendVenue, SentCallback sentCallback) throws TelegramApiException {
if (sendVenue == null) {
@@ -443,6 +610,10 @@ public abstract class AbsSender {
sendApiMethodAsync(sendVenue, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see SendContact
+ */
@Deprecated
public final void sendContactAsync(SendContact sendContact, SentCallback sentCallback) throws TelegramApiException {
if (sendContact == null) {
@@ -455,6 +626,10 @@ public abstract class AbsSender {
sendApiMethodAsync(sendContact, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see KickChatMember
+ */
@Deprecated
public final void kickMemberAsync(KickChatMember kickChatMember, SentCallback sentCallback) throws TelegramApiException {
if (kickChatMember == null) {
@@ -467,6 +642,10 @@ public abstract class AbsSender {
sendApiMethodAsync(kickChatMember, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see UnbanChatMember
+ */
@Deprecated
public final void unbanMemberAsync(UnbanChatMember unbanChatMember, SentCallback sentCallback) throws TelegramApiException {
if (unbanChatMember == null) {
@@ -479,6 +658,10 @@ public abstract class AbsSender {
sendApiMethodAsync(unbanChatMember, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see LeaveChat
+ */
@Deprecated
public final void leaveChatAsync(LeaveChat leaveChat, SentCallback sentCallback) throws TelegramApiException {
if (leaveChat == null) {
@@ -490,6 +673,10 @@ public abstract class AbsSender {
sendApiMethodAsync(leaveChat, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see GetChat
+ */
@Deprecated
public final void getChatAsync(GetChat getChat, SentCallback sentCallback) throws TelegramApiException {
if (getChat == null) {
@@ -501,6 +688,10 @@ public abstract class AbsSender {
sendApiMethodAsync(getChat, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see ExportChatInviteLink
+ */
@Deprecated
public final void exportChatInviteLinkAsync(ExportChatInviteLink exportChatInviteLink, SentCallback sentCallback) throws TelegramApiException {
if (exportChatInviteLink == null) {
@@ -512,6 +703,10 @@ public abstract class AbsSender {
sendApiMethodAsync(exportChatInviteLink, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see GetChatAdministrators
+ */
@Deprecated
public final void getChatAdministratorsAsync(GetChatAdministrators getChatAdministrators, SentCallback> sentCallback) throws TelegramApiException {
if (getChatAdministrators == null) {
@@ -523,6 +718,10 @@ public abstract class AbsSender {
sendApiMethodAsync(getChatAdministrators, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see GetChatMember
+ */
@Deprecated
public final void getChatMemberAsync(GetChatMember getChatMember, SentCallback sentCallback) throws TelegramApiException {
if (getChatMember == null) {
@@ -534,6 +733,10 @@ public abstract class AbsSender {
sendApiMethodAsync(getChatMember, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see GetChatMemberCount
+ */
@Deprecated
public final void getChatMemberCountAsync(GetChatMemberCount getChatMemberCount, SentCallback sentCallback) throws TelegramApiException {
if (getChatMemberCount == null) {
@@ -546,6 +749,10 @@ public abstract class AbsSender {
sendApiMethodAsync(getChatMemberCount, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see EditMessageText
+ */
@Deprecated
public final void editMessageTextAsync(EditMessageText editMessageText, SentCallback sentCallback) throws TelegramApiException {
if (editMessageText == null) {
@@ -558,6 +765,10 @@ public abstract class AbsSender {
sendApiMethodAsync(editMessageText, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see EditMessageCaption
+ */
@Deprecated
public final void editMessageCaptionAsync(EditMessageCaption editMessageCaption, SentCallback sentCallback) throws TelegramApiException {
if (editMessageCaption == null) {
@@ -570,6 +781,10 @@ public abstract class AbsSender {
sendApiMethodAsync(editMessageCaption, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see EditMessageReplyMarkup
+ */
@Deprecated
public final void editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup, SentCallback sentCallback) throws TelegramApiException {
if (editMessageReplyMarkup == null) {
@@ -582,6 +797,10 @@ public abstract class AbsSender {
sendApiMethodAsync(editMessageReplyMarkup, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see AnswerCallbackQuery
+ */
@Deprecated
public final void answerCallbackQueryAsync(AnswerCallbackQuery answerCallbackQuery, SentCallback sentCallback) throws TelegramApiException {
if (answerCallbackQuery == null) {
@@ -594,6 +813,10 @@ public abstract class AbsSender {
sendApiMethodAsync(answerCallbackQuery, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see GetUserProfilePhotos
+ */
@Deprecated
public final void getUserProfilePhotosAsync(GetUserProfilePhotos getUserProfilePhotos, SentCallback sentCallback) throws TelegramApiException {
if (getUserProfilePhotos == null) {
@@ -606,6 +829,10 @@ public abstract class AbsSender {
sendApiMethodAsync(getUserProfilePhotos, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see GetFile
+ */
@Deprecated
public final void getFileAsync(GetFile getFile, SentCallback sentCallback) throws TelegramApiException {
if (getFile == null) {
@@ -632,6 +859,10 @@ public abstract class AbsSender {
sendApiMethodAsync(new GetWebhookInfo(), sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see SetGameScore
+ */
@Deprecated
public final void setGameScoreAsync(SetGameScore setGameScore, SentCallback sentCallback) throws TelegramApiException {
if (setGameScore == null) {
@@ -643,6 +874,10 @@ public abstract class AbsSender {
sendApiMethodAsync(setGameScore, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see GetGameHighScores
+ */
@Deprecated
public final void getGameHighScoresAsync(GetGameHighScores getGameHighScores, SentCallback> sentCallback) throws TelegramApiException {
if (getGameHighScores == null) {
@@ -654,6 +889,10 @@ public abstract class AbsSender {
sendApiMethodAsync(getGameHighScores, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see SendGame
+ */
@Deprecated
public final void sendGameAsync(SendGame sendGame, SentCallback sentCallback) throws TelegramApiException {
if (sendGame == null) {
@@ -665,6 +904,10 @@ public abstract class AbsSender {
sendApiMethodAsync(sendGame, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see DeleteWebhook
+ */
@Deprecated
public final void deleteWebhook(DeleteWebhook deleteWebhook, SentCallback sentCallback) throws TelegramApiException {
if (deleteWebhook == null) {
@@ -676,6 +919,10 @@ public abstract class AbsSender {
sendApiMethodAsync(deleteWebhook, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see SendInvoice
+ */
@Deprecated
public final void sendInvoice(SendInvoice sendInvoice, SentCallback sentCallback) throws TelegramApiException {
if (sendInvoice == null) {
@@ -687,6 +934,10 @@ public abstract class AbsSender {
sendApiMethodAsync(sendInvoice, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see AnswerShippingQuery
+ */
@Deprecated
public final void answerShippingQuery(AnswerShippingQuery answerShippingQuery, SentCallback sentCallback) throws TelegramApiException {
if (answerShippingQuery == null) {
@@ -698,6 +949,10 @@ public abstract class AbsSender {
sendApiMethodAsync(answerShippingQuery, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see AnswerPreCheckoutQuery
+ */
@Deprecated
public final void answerPreCheckoutQuery(AnswerPreCheckoutQuery answerPreCheckoutQuery, SentCallback sentCallback) throws TelegramApiException {
if (answerPreCheckoutQuery == null) {
@@ -709,6 +964,10 @@ public abstract class AbsSender {
sendApiMethodAsync(answerPreCheckoutQuery, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see DeleteMessage
+ */
@Deprecated
public final void deleteMessage(DeleteMessage deleteMessage, SentCallback sentCallback) throws TelegramApiException {
if (deleteMessage == null) {
@@ -720,6 +979,10 @@ public abstract class AbsSender {
sendApiMethodAsync(deleteMessage, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see DeleteChatPhoto
+ */
@Deprecated
public final void deleteChatPhoto(DeleteChatPhoto deleteChatPhoto, SentCallback sentCallback) throws TelegramApiException {
if (deleteChatPhoto == null) {
@@ -731,6 +994,10 @@ public abstract class AbsSender {
sendApiMethodAsync(deleteChatPhoto, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see PinChatMessage
+ */
@Deprecated
public final void pinChatMessage(PinChatMessage pinChatMessage, SentCallback sentCallback) throws TelegramApiException {
if (pinChatMessage == null) {
@@ -742,6 +1009,10 @@ public abstract class AbsSender {
sendApiMethodAsync(pinChatMessage, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see UnpinChatMessage
+ */
@Deprecated
public final void unpinChatMessage(UnpinChatMessage unpinChatMessage, SentCallback sentCallback) throws TelegramApiException {
if (unpinChatMessage == null) {
@@ -753,6 +1024,10 @@ public abstract class AbsSender {
sendApiMethodAsync(unpinChatMessage, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see PromoteChatMember
+ */
@Deprecated
public final void promoteChatMember(PromoteChatMember promoteChatMember, SentCallback sentCallback) throws TelegramApiException {
if (promoteChatMember == null) {
@@ -764,6 +1039,10 @@ public abstract class AbsSender {
sendApiMethodAsync(promoteChatMember, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see RestrictChatMember
+ */
@Deprecated
public final void restrictChatMember(RestrictChatMember restrictChatMember, SentCallback sentCallback) throws TelegramApiException {
if (restrictChatMember == null) {
@@ -775,6 +1054,10 @@ public abstract class AbsSender {
sendApiMethodAsync(restrictChatMember, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see SetChatDescription
+ */
@Deprecated
public final void setChatDescription(SetChatDescription setChatDescription, SentCallback sentCallback) throws TelegramApiException {
if (setChatDescription == null) {
@@ -786,6 +1069,10 @@ public abstract class AbsSender {
sendApiMethodAsync(setChatDescription, sentCallback);
}
+ /**
+ * Deprecated. Use {@link #execute(BotApiMethod) executeAsync} Method instead
+ * @see SetChatTitle
+ */
@Deprecated
public final void setChatTitle(SetChatTitle setChatTitle, SentCallback sentCallback) throws TelegramApiException {
if (setChatTitle == null) {
diff --git a/telegrambots-spring-boot-starter/README.md b/telegrambots-spring-boot-starter/README.md
index 8bb3f2a8..34b2cff5 100644
--- a/telegrambots-spring-boot-starter/README.md
+++ b/telegrambots-spring-boot-starter/README.md
@@ -25,7 +25,7 @@ Usage
**Gradle**
```gradle
- compile "org.telegram:telegrambots-spring-boot-starter:3.6"
+ compile "org.telegram:telegrambots-spring-boot-starter:3.6.1"
```
Motivation
@@ -39,8 +39,6 @@ Your main spring boot class should look like this:
```java
@SpringBootApplication
-//Add this annotation to enable automatic bots initializing
-@EnableTelegramBots
public class YourApplicationMainClass {
public static void main(String[] args) {
diff --git a/telegrambots-spring-boot-starter/pom.xml b/telegrambots-spring-boot-starter/pom.xml
index b40ff9c9..e3dee763 100644
--- a/telegrambots-spring-boot-starter/pom.xml
+++ b/telegrambots-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
4.0.0
org.telegram
telegrambots-spring-boot-starter
- 3.6.1
+ 3.6.2
jar
Telegram Bots Spring Boot Starter
@@ -60,7 +60,7 @@
UTF-8
UTF-8
3.6.1
- 1.5.10.RELEASE
+ 2.0.2.RELEASE
@@ -75,11 +75,41 @@
spring-boot
${spring-boot.version}
+
org.springframework.boot
spring-boot-autoconfigure
${spring-boot.version}
+
+
+ org.springframework.boot
+ spring-boot-test
+ ${spring-boot.version}
+ test
+
+
+
+ org.assertj
+ assertj-core
+ test
+ 3.9.1
+
+
+
+ org.mockito
+ mockito-all
+ 2.0.2-beta
+ test
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
diff --git a/telegrambots-spring-boot-starter/src/main/java/org/telegram/telegrambots/starter/EnableTelegramBots.java b/telegrambots-spring-boot-starter/src/main/java/org/telegram/telegrambots/starter/EnableTelegramBots.java
deleted file mode 100644
index 68c4acf9..00000000
--- a/telegrambots-spring-boot-starter/src/main/java/org/telegram/telegrambots/starter/EnableTelegramBots.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.telegram.telegrambots.starter;
-
-import org.springframework.context.annotation.Import;
-
-/**
- * Imports configuration #TelegramBotStarterConfiguration in spring context.
- */
-@Import(TelegramBotStarterConfiguration.class)
-public @interface EnableTelegramBots {
-}
diff --git a/telegrambots-spring-boot-starter/src/main/java/org/telegram/telegrambots/starter/TelegramBotInitializer.java b/telegrambots-spring-boot-starter/src/main/java/org/telegram/telegrambots/starter/TelegramBotInitializer.java
new file mode 100644
index 00000000..5348ae7c
--- /dev/null
+++ b/telegrambots-spring-boot-starter/src/main/java/org/telegram/telegrambots/starter/TelegramBotInitializer.java
@@ -0,0 +1,45 @@
+package org.telegram.telegrambots.starter;
+
+import java.util.List;
+import java.util.Objects;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.telegram.telegrambots.TelegramBotsApi;
+import org.telegram.telegrambots.exceptions.TelegramApiException;
+import org.telegram.telegrambots.generics.LongPollingBot;
+import org.telegram.telegrambots.generics.WebhookBot;
+
+/**
+ * Receives all beand which are #LongPollingBot and #WebhookBot and register them in #TelegramBotsApi.
+ */
+public class TelegramBotInitializer implements InitializingBean {
+
+ private final TelegramBotsApi telegramBotsApi;
+ private final List longPollingBots;
+ private final List webHookBots;
+
+ public TelegramBotInitializer(TelegramBotsApi telegramBotsApi,
+ List longPollingBots,
+ List webHookBots) {
+ Objects.requireNonNull(telegramBotsApi);
+ Objects.requireNonNull(longPollingBots);
+ Objects.requireNonNull(webHookBots);
+ this.telegramBotsApi = telegramBotsApi;
+ this.longPollingBots = longPollingBots;
+ this.webHookBots = webHookBots;
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ try {
+ for (LongPollingBot bot : longPollingBots) {
+ telegramBotsApi.registerBot(bot);
+ }
+ for (WebhookBot bot : webHookBots) {
+ telegramBotsApi.registerBot(bot);
+ }
+ } catch (TelegramApiException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/telegrambots-spring-boot-starter/src/main/java/org/telegram/telegrambots/starter/TelegramBotStarterConfiguration.java b/telegrambots-spring-boot-starter/src/main/java/org/telegram/telegrambots/starter/TelegramBotStarterConfiguration.java
index 26e48804..5fe34191 100644
--- a/telegrambots-spring-boot-starter/src/main/java/org/telegram/telegrambots/starter/TelegramBotStarterConfiguration.java
+++ b/telegrambots-spring-boot-starter/src/main/java/org/telegram/telegrambots/starter/TelegramBotStarterConfiguration.java
@@ -1,55 +1,37 @@
package org.telegram.telegrambots.starter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.CommandLineRunner;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.telegram.telegrambots.meta.TelegramBotsApi;
-import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.generics.LongPollingBot;
import org.telegram.telegrambots.meta.generics.WebhookBot;
-import java.util.List;
-
/**
- * Receives all beand which are #LongPollingBot and #WebhookBot and register them in #TelegramBotsApi.
* #TelegramBotsApi added to spring context as well
*/
@Configuration
-public class TelegramBotStarterConfiguration implements CommandLineRunner {
-
-
- private final List longPollingBots;
- private final List webHookBots;
-
- @Autowired
- private TelegramBotsApi telegramBotsApi;
-
- public TelegramBotStarterConfiguration(List longPollingBots,
- List webHookBots) {
- this.longPollingBots = longPollingBots;
- this.webHookBots = webHookBots;
- }
-
- @Override
- public void run(String... args) {
- try {
- for (LongPollingBot bot : longPollingBots) {
- telegramBotsApi.registerBot(bot);
- }
- for (WebhookBot bot : webHookBots) {
- telegramBotsApi.registerBot(bot);
- }
- } catch (TelegramApiException e) {
- e.printStackTrace();
- }
- }
-
+@ConditionalOnProperty(prefix="telegrambots",name = "enabled", havingValue = "true", matchIfMissing = true)
+public class TelegramBotStarterConfiguration {
@Bean
@ConditionalOnMissingBean(TelegramBotsApi.class)
public TelegramBotsApi telegramBotsApi() {
return new TelegramBotsApi();
}
+
+ @Bean
+ @ConditionalOnMissingBean
+ public TelegramBotInitializer telegramBotInitializer(TelegramBotsApi telegramBotsApi,
+ Optional> longPollingBots,
+ Optional> webHookBots) {
+ return new TelegramBotInitializer(telegramBotsApi,
+ longPollingBots.orElseGet(Collections::emptyList),
+ webHookBots.orElseGet(Collections::emptyList));
+ }
}
diff --git a/telegrambots-spring-boot-starter/src/main/resources/META-INF/spring.factories b/telegrambots-spring-boot-starter/src/main/resources/META-INF/spring.factories
new file mode 100644
index 00000000..71b3a84d
--- /dev/null
+++ b/telegrambots-spring-boot-starter/src/main/resources/META-INF/spring.factories
@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.telegram.telegrambots.starter.TelegramBotStarterConfiguration
\ No newline at end of file
diff --git a/telegrambots-spring-boot-starter/src/test/java/org/telegram/telegrambots/starter/TestTelegramBotStarterConfiguration.java b/telegrambots-spring-boot-starter/src/test/java/org/telegram/telegrambots/starter/TestTelegramBotStarterConfiguration.java
new file mode 100644
index 00000000..d8723664
--- /dev/null
+++ b/telegrambots-spring-boot-starter/src/test/java/org/telegram/telegrambots/starter/TestTelegramBotStarterConfiguration.java
@@ -0,0 +1,99 @@
+package org.telegram.telegrambots.starter;
+
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+import static org.mockito.Mockito.*;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.telegram.telegrambots.TelegramBotsApi;
+import org.telegram.telegrambots.generics.LongPollingBot;
+import org.telegram.telegrambots.generics.WebhookBot;
+
+public class TestTelegramBotStarterConfiguration {
+
+ private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(MockTelegramBotsApi.class, TelegramBotStarterConfiguration.class));
+
+ @Test
+ public void createMockTelegramBotsApiWithDefaultSettings() {
+ this.contextRunner.run((context) -> {
+ assertThat(context).hasSingleBean(TelegramBotsApi.class);
+ assertThat(context).hasSingleBean(TelegramBotInitializer.class);
+ assertThat(context).doesNotHaveBean(LongPollingBot.class);
+ assertThat(context).doesNotHaveBean(WebhookBot.class);
+ verifyNoMoreInteractions(context.getBean(TelegramBotsApi.class));
+ });
+ }
+
+ @Test
+ public void createOnlyLongPollingBot() {
+ this.contextRunner.withUserConfiguration(LongPollingBotConfig.class)
+ .run((context) -> {
+ assertThat(context).hasSingleBean(LongPollingBot.class);
+ assertThat(context).doesNotHaveBean(WebhookBot.class);
+
+ TelegramBotsApi telegramBotsApi = context.getBean(TelegramBotsApi.class);
+
+ verify(telegramBotsApi, times(1)).registerBot( context.getBean(LongPollingBot.class) );
+ verifyNoMoreInteractions(telegramBotsApi);
+ });
+ }
+
+ @Test
+ public void createOnlyWebhookBot() {
+ this.contextRunner.withUserConfiguration(WebhookBotConfig.class)
+ .run((context) -> {
+ assertThat(context).hasSingleBean(WebhookBot.class);
+ assertThat(context).doesNotHaveBean(LongPollingBot.class);
+
+ TelegramBotsApi telegramBotsApi = context.getBean(TelegramBotsApi.class);
+
+ verify(telegramBotsApi, times(1)).registerBot( context.getBean(WebhookBot.class) );
+ verifyNoMoreInteractions(telegramBotsApi);
+ });
+ }
+
+ @Test
+ public void createLongPoolingBotAndWebhookBot() {
+ this.contextRunner.withUserConfiguration(LongPollingBotConfig.class, WebhookBotConfig.class)
+ .run((context) -> {
+ assertThat(context).hasSingleBean(LongPollingBot.class);
+ assertThat(context).hasSingleBean(WebhookBot.class);
+
+ TelegramBotsApi telegramBotsApi = context.getBean(TelegramBotsApi.class);
+
+ verify(telegramBotsApi, times(1)).registerBot( context.getBean(LongPollingBot.class) );
+ verify(telegramBotsApi, times(1)).registerBot( context.getBean(WebhookBot.class) );
+ //verifyNoMoreInteractions(telegramBotsApi);
+ });
+ }
+
+ @Configuration
+ static class MockTelegramBotsApi{
+
+ @Bean
+ public TelegramBotsApi telegramBotsApi() {
+ return mock(TelegramBotsApi.class);
+ }
+ }
+
+ @Configuration
+ static class LongPollingBotConfig{
+ @Bean
+ public LongPollingBot longPollingBot() {
+ return mock(LongPollingBot.class);
+ }
+ }
+
+ @Configuration
+ static class WebhookBotConfig{
+ @Bean
+ public WebhookBot webhookBot() {
+ return mock(WebhookBot.class);
+ }
+ }
+}
diff --git a/telegrambots/pom.xml b/telegrambots/pom.xml
index 95d1f3e3..aceeb9d2 100644
--- a/telegrambots/pom.xml
+++ b/telegrambots/pom.xml
@@ -5,7 +5,7 @@
4.0.0
org.telegram
telegrambots
- 3.6.1
+ 3.6.2
jar
Telegram Bots
diff --git a/telegrambots/src/main/java/org/telegram/telegrambots/bots/DefaultAbsSender.java b/telegrambots/src/main/java/org/telegram/telegrambots/bots/DefaultAbsSender.java
index e832e8dd..3b588acc 100644
--- a/telegrambots/src/main/java/org/telegram/telegrambots/bots/DefaultAbsSender.java
+++ b/telegrambots/src/main/java/org/telegram/telegrambots/bots/DefaultAbsSender.java
@@ -31,6 +31,7 @@ import org.telegram.telegrambots.meta.updateshandlers.SentCallback;
import java.io.IOException;
import java.io.Serializable;
+import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
@@ -53,7 +54,7 @@ public abstract class DefaultAbsSender extends AbsSender {
protected final ExecutorService exe;
private final ObjectMapper objectMapper = new ObjectMapper();
private final DefaultBotOptions options;
- private volatile CloseableHttpClient httpclient;
+ private volatile CloseableHttpClient httpClient;
private volatile RequestConfig requestConfig;
protected DefaultAbsSender(DefaultBotOptions options) {
@@ -61,10 +62,10 @@ public abstract class DefaultAbsSender extends AbsSender {
this.exe = Executors.newFixedThreadPool(options.getMaxThreads());
this.options = options;
- httpclient = TelegramHttpClientBuilder.build(options);
+ httpClient = TelegramHttpClientBuilder.build(options);
+ configureHttpContext();
requestConfig = options.getRequestConfig();
-
if (requestConfig == null) {
requestConfig = RequestConfig.copy(RequestConfig.custom().build())
.setSocketTimeout(SOCKET_TIMEOUT)
@@ -73,6 +74,22 @@ public abstract class DefaultAbsSender extends AbsSender {
}
}
+ private void configureHttpContext() {
+
+ if (options.getProxyType() != DefaultBotOptions.ProxyType.NO_PROXY) {
+ InetSocketAddress socksaddr = new InetSocketAddress(options.getProxyHost(), options.getProxyPort());
+ options.getHttpContext().setAttribute("socketAddress", socksaddr);
+ }
+
+ if (options.getProxyType() == DefaultBotOptions.ProxyType.SOCKS4) {
+ options.getHttpContext().setAttribute("socksVersion", 4);
+ }
+ if (options.getProxyType() == DefaultBotOptions.ProxyType.SOCKS5) {
+ options.getHttpContext().setAttribute("socksVersion", 5);
+ }
+
+ }
+
/**
* Returns the token of the bot to be able to perform Telegram Api Requests
* @return Token of the bot
@@ -731,7 +748,7 @@ public abstract class DefaultAbsSender extends AbsSender {
}
private String sendHttpPostRequest(HttpPost httppost) throws IOException {
- try (CloseableHttpResponse response = httpclient.execute(httppost)) {
+ try (CloseableHttpResponse response = httpClient.execute(httppost, options.getHttpContext())) {
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
return EntityUtils.toString(buf, StandardCharsets.UTF_8);
diff --git a/telegrambots/src/main/java/org/telegram/telegrambots/bots/DefaultBotOptions.java b/telegrambots/src/main/java/org/telegram/telegrambots/bots/DefaultBotOptions.java
index 39b14af8..7e2e59af 100644
--- a/telegrambots/src/main/java/org/telegram/telegrambots/bots/DefaultBotOptions.java
+++ b/telegrambots/src/main/java/org/telegram/telegrambots/bots/DefaultBotOptions.java
@@ -1,8 +1,8 @@
package org.telegram.telegrambots.bots;
-import org.apache.http.HttpHost;
-import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.protocol.HttpContext;
import org.telegram.telegrambots.meta.ApiConstants;
import org.telegram.telegrambots.meta.generics.BotOptions;
import org.telegram.telegrambots.updatesreceivers.ExponentialBackOff;
@@ -18,17 +18,27 @@ import java.util.List;
public class DefaultBotOptions implements BotOptions {
private int maxThreads; ///< Max number of threads used for async methods executions (default 1)
private RequestConfig requestConfig;
+ private volatile HttpContext httpContext;
private ExponentialBackOff exponentialBackOff;
private Integer maxWebhookConnections;
private String baseUrl;
private List allowedUpdates;
+ private ProxyType proxyType;
+ private String proxyHost;
+ private int proxyPort;
- private CredentialsProvider credentialsProvider;
- private HttpHost httpProxy;
+ public enum ProxyType {
+ NO_PROXY,
+ HTTP,
+ SOCKS4,
+ SOCKS5
+ }
public DefaultBotOptions() {
maxThreads = 1;
baseUrl = ApiConstants.BASE_URL;
+ httpContext = HttpClientContext.create();
+ proxyType = ProxyType.NO_PROXY;
}
@Override
@@ -56,6 +66,14 @@ public class DefaultBotOptions implements BotOptions {
return maxWebhookConnections;
}
+ public HttpContext getHttpContext() {
+ return httpContext;
+ }
+
+ public void setHttpContext(HttpContext httpContext) {
+ this.httpContext = httpContext;
+ }
+
public void setMaxWebhookConnections(Integer maxWebhookConnections) {
this.maxWebhookConnections = maxWebhookConnections;
}
@@ -88,19 +106,27 @@ public class DefaultBotOptions implements BotOptions {
this.exponentialBackOff = exponentialBackOff;
}
- public CredentialsProvider getCredentialsProvider() {
- return credentialsProvider;
+ public ProxyType getProxyType() {
+ return proxyType;
}
- public void setCredentialsProvider(CredentialsProvider credentialsProvider) {
- this.credentialsProvider = credentialsProvider;
+ public void setProxyType(ProxyType proxyType) {
+ this.proxyType = proxyType;
}
- public HttpHost getHttpProxy() {
- return httpProxy;
+ public String getProxyHost() {
+ return proxyHost;
}
- public void setHttpProxy(HttpHost httpProxy) {
- this.httpProxy = httpProxy;
+ public void setProxyHost(String proxyHost) {
+ this.proxyHost = proxyHost;
+ }
+
+ public int getProxyPort() {
+ return proxyPort;
+ }
+
+ public void setProxyPort(int proxyPort) {
+ this.proxyPort = proxyPort;
}
}
diff --git a/telegrambots/src/main/java/org/telegram/telegrambots/facilities/TelegramHttpClientBuilder.java b/telegrambots/src/main/java/org/telegram/telegrambots/facilities/TelegramHttpClientBuilder.java
index fb911c04..38a3a17a 100644
--- a/telegrambots/src/main/java/org/telegram/telegrambots/facilities/TelegramHttpClientBuilder.java
+++ b/telegrambots/src/main/java/org/telegram/telegrambots/facilities/TelegramHttpClientBuilder.java
@@ -1,10 +1,19 @@
package org.telegram.telegrambots.facilities;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.HttpClientConnectionManager;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.client.ProxyAuthenticationStrategy;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.ssl.SSLContexts;
import org.telegram.telegrambots.bots.DefaultBotOptions;
+import org.telegram.telegrambots.facilities.proxysocketfactorys.HttpConnectionSocketFactory;
+import org.telegram.telegrambots.facilities.proxysocketfactorys.HttpSSLConnectionSocketFactory;
+import org.telegram.telegrambots.facilities.proxysocketfactorys.SocksSSLConnectionSocketFactory;
+import org.telegram.telegrambots.facilities.proxysocketfactorys.SocksConnectionSocketFactory;
import java.util.concurrent.TimeUnit;
@@ -16,22 +25,30 @@ public class TelegramHttpClientBuilder {
public static CloseableHttpClient build(DefaultBotOptions options) {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
.setSSLHostnameVerifier(new NoopHostnameVerifier())
+ .setConnectionManager(createConnectionManager(options))
.setConnectionTimeToLive(70, TimeUnit.SECONDS)
.setMaxConnTotal(100);
-
- if (options.getHttpProxy() != null) {
-
- httpClientBuilder.setProxy(options.getHttpProxy());
-
- if (options.getCredentialsProvider() != null) {
- httpClientBuilder
- .setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy())
- .setDefaultCredentialsProvider(options.getCredentialsProvider());
- }
-
- }
-
return httpClientBuilder.build();
}
+ private static HttpClientConnectionManager createConnectionManager(DefaultBotOptions options) {
+ Registry registry;
+ switch (options.getProxyType()) {
+ case NO_PROXY:
+ return null;
+ case HTTP:
+ registry = RegistryBuilder. create()
+ .register("http", new HttpConnectionSocketFactory())
+ .register("https", new HttpSSLConnectionSocketFactory(SSLContexts.createSystemDefault())).build();
+ return new PoolingHttpClientConnectionManager(registry);
+ case SOCKS4:
+ case SOCKS5:
+ registry = RegistryBuilder. create()
+ .register("http", new SocksConnectionSocketFactory())
+ .register("https", new SocksSSLConnectionSocketFactory(SSLContexts.createSystemDefault())).build();
+ return new PoolingHttpClientConnectionManager(registry);
+ }
+ return null;
+ }
+
}
diff --git a/telegrambots/src/main/java/org/telegram/telegrambots/facilities/proxysocketfactorys/HttpConnectionSocketFactory.java b/telegrambots/src/main/java/org/telegram/telegrambots/facilities/proxysocketfactorys/HttpConnectionSocketFactory.java
new file mode 100644
index 00000000..d06f17ce
--- /dev/null
+++ b/telegrambots/src/main/java/org/telegram/telegrambots/facilities/proxysocketfactorys/HttpConnectionSocketFactory.java
@@ -0,0 +1,33 @@
+package org.telegram.telegrambots.facilities.proxysocketfactorys;
+
+import org.apache.http.HttpHost;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.protocol.HttpContext;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.Socket;
+
+public class HttpConnectionSocketFactory extends PlainConnectionSocketFactory {
+ @Override
+ public Socket createSocket(final HttpContext context) throws IOException {
+ InetSocketAddress socketAddress = (InetSocketAddress) context.getAttribute("socketAddress");
+ Proxy proxy = new Proxy(Proxy.Type.HTTP, socketAddress);
+ return new Socket(proxy);
+ }
+
+ @Override
+ public Socket connectSocket(
+ int connectTimeout,
+ Socket socket,
+ HttpHost host,
+ InetSocketAddress remoteAddress,
+ InetSocketAddress localAddress,
+ HttpContext context) throws IOException {
+ String hostName = host.getHostName();
+ int port = remoteAddress.getPort();
+ InetSocketAddress unresolvedRemote = InetSocketAddress.createUnresolved(hostName, port);
+ return super.connectSocket(connectTimeout, socket, host, unresolvedRemote, localAddress, context);
+ }
+}
diff --git a/telegrambots/src/main/java/org/telegram/telegrambots/facilities/proxysocketfactorys/HttpSSLConnectionSocketFactory.java b/telegrambots/src/main/java/org/telegram/telegrambots/facilities/proxysocketfactorys/HttpSSLConnectionSocketFactory.java
new file mode 100644
index 00000000..2c97e934
--- /dev/null
+++ b/telegrambots/src/main/java/org/telegram/telegrambots/facilities/proxysocketfactorys/HttpSSLConnectionSocketFactory.java
@@ -0,0 +1,40 @@
+package org.telegram.telegrambots.facilities.proxysocketfactorys;
+
+import org.apache.http.HttpHost;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.protocol.HttpContext;
+
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.Socket;
+
+public class HttpSSLConnectionSocketFactory extends SSLConnectionSocketFactory {
+
+ public HttpSSLConnectionSocketFactory(final SSLContext sslContext) {
+ super(sslContext, new NoopHostnameVerifier());
+ }
+
+ @Override
+ public Socket createSocket(final HttpContext context) throws IOException {
+ InetSocketAddress socketAddress = (InetSocketAddress) context.getAttribute("socketAddress");
+ Proxy proxy = new Proxy(Proxy.Type.HTTP, socketAddress);
+ return new Socket(proxy);
+ }
+
+ @Override
+ public Socket connectSocket(
+ int connectTimeout,
+ Socket socket,
+ HttpHost host,
+ InetSocketAddress remoteAddress,
+ InetSocketAddress localAddress,
+ HttpContext context) throws IOException {
+ String hostName = host.getHostName();
+ int port = remoteAddress.getPort();
+ InetSocketAddress unresolvedRemote = InetSocketAddress.createUnresolved(hostName, port);
+ return super.connectSocket(connectTimeout, socket, host, unresolvedRemote, localAddress, context);
+ }
+}
diff --git a/telegrambots/src/main/java/org/telegram/telegrambots/facilities/proxysocketfactorys/SocksConnectionSocketFactory.java b/telegrambots/src/main/java/org/telegram/telegrambots/facilities/proxysocketfactorys/SocksConnectionSocketFactory.java
new file mode 100644
index 00000000..d2b29a5e
--- /dev/null
+++ b/telegrambots/src/main/java/org/telegram/telegrambots/facilities/proxysocketfactorys/SocksConnectionSocketFactory.java
@@ -0,0 +1,37 @@
+package org.telegram.telegrambots.facilities.proxysocketfactorys;
+
+
+import org.apache.http.HttpHost;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.protocol.HttpContext;
+import sun.net.SocksProxy;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.Socket;
+
+public class SocksConnectionSocketFactory extends PlainConnectionSocketFactory {
+
+ @Override
+ public Socket createSocket(final HttpContext context) throws IOException {
+ InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socketAddress");
+ int socksVersion = (Integer) context.getAttribute("socksVersion");
+ Proxy proxy = SocksProxy.create(socksaddr, socksVersion);
+ return new Socket(proxy);
+ }
+
+ @Override
+ public Socket connectSocket(
+ int connectTimeout,
+ Socket socket,
+ HttpHost host,
+ InetSocketAddress remoteAddress,
+ InetSocketAddress localAddress,
+ HttpContext context) throws IOException {
+ String hostName = host.getHostName();
+ int port = remoteAddress.getPort();
+ InetSocketAddress unresolvedRemote = InetSocketAddress.createUnresolved(hostName, port);
+ return super.connectSocket(connectTimeout, socket, host, unresolvedRemote, localAddress, context);
+ }
+}
diff --git a/telegrambots/src/main/java/org/telegram/telegrambots/facilities/proxysocketfactorys/SocksSSLConnectionSocketFactory.java b/telegrambots/src/main/java/org/telegram/telegrambots/facilities/proxysocketfactorys/SocksSSLConnectionSocketFactory.java
new file mode 100644
index 00000000..cbd46b6a
--- /dev/null
+++ b/telegrambots/src/main/java/org/telegram/telegrambots/facilities/proxysocketfactorys/SocksSSLConnectionSocketFactory.java
@@ -0,0 +1,43 @@
+package org.telegram.telegrambots.facilities.proxysocketfactorys;
+
+import org.apache.http.HttpHost;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.protocol.HttpContext;
+import sun.net.SocksProxy;
+
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.Socket;
+
+
+public class SocksSSLConnectionSocketFactory extends SSLConnectionSocketFactory {
+
+ public SocksSSLConnectionSocketFactory(final SSLContext sslContext) {
+ super(sslContext, new NoopHostnameVerifier());
+ }
+
+ @Override
+ public Socket createSocket(final HttpContext context) throws IOException {
+ InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socketAddress");
+ int socksVersion = (Integer) context.getAttribute("socksVersion");
+ Proxy proxy = SocksProxy.create(socksaddr, socksVersion);
+ return new Socket(proxy);
+ }
+
+ @Override
+ public Socket connectSocket(
+ int connectTimeout,
+ Socket socket,
+ HttpHost host,
+ InetSocketAddress remoteAddress,
+ InetSocketAddress localAddress,
+ HttpContext context) throws IOException {
+ String hostName = host.getHostName();
+ int port = remoteAddress.getPort();
+ InetSocketAddress unresolvedRemote = InetSocketAddress.createUnresolved(hostName, port);
+ return super.connectSocket(connectTimeout, socket, host, unresolvedRemote, localAddress, context);
+ }
+}
diff --git a/telegrambots/src/main/java/org/telegram/telegrambots/updatesreceivers/DefaultBotSession.java b/telegrambots/src/main/java/org/telegram/telegrambots/updatesreceivers/DefaultBotSession.java
index 44c92fa6..ed9064a0 100644
--- a/telegrambots/src/main/java/org/telegram/telegrambots/updatesreceivers/DefaultBotSession.java
+++ b/telegrambots/src/main/java/org/telegram/telegrambots/updatesreceivers/DefaultBotSession.java
@@ -241,7 +241,7 @@ public class DefaultBotSession implements BotSession {
httpPost.setConfig(requestConfig);
httpPost.setEntity(new StringEntity(objectMapper.writeValueAsString(request), ContentType.APPLICATION_JSON));
- try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
+ try (CloseableHttpResponse response = httpclient.execute(httpPost, options.getHttpContext())) {
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
String responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8);