Merge branch 'dev' into java9-support
# Conflicts: # telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/bot/AbilityBot.java # telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/EndUser.java # telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/MessageContext.java # telegrambots-spring-boot-starter/src/main/java/org/telegram/telegrambots/starter/TelegramBotStarterConfiguration.java # telegrambots/src/main/java/org/telegram/telegrambots/bots/DefaultBotOptions.java
This commit is contained in:
commit
ad3dbfdd58
@ -93,6 +93,12 @@ This library use [Telegram bot API](https://core.telegram.org/bots), you can fin
|
||||
## Questions or Suggestions
|
||||
Feel free to create issues [here](https://github.com/rubenlagus/TelegramBots/issues) as you need or join the [chat](https://telegram.me/JavaBotsApi)
|
||||
|
||||
## Powered by Intellij
|
||||
<p align="center">
|
||||
<a href="https://www.jetbrains.com"><img src="jetbrains.png" width="75"></a>
|
||||
</p>
|
||||
|
||||
|
||||
## License
|
||||
MIT License
|
||||
|
||||
|
@ -31,7 +31,7 @@ public class MyBot extends AbilityBot {
|
||||
|
||||
Now you are able to set up your proxy
|
||||
|
||||
#### without authentication
|
||||
#### Without authentication
|
||||
|
||||
```java
|
||||
public class Main {
|
||||
@ -53,11 +53,10 @@ public class Main {
|
||||
// Set up Http proxy
|
||||
DefaultBotOptions botOptions = ApiContext.getInstance(DefaultBotOptions.class);
|
||||
|
||||
HttpHost httpHost = new HttpHost(PROXY_HOST, PROXY_PORT);
|
||||
|
||||
RequestConfig requestConfig = RequestConfig.custom().setProxy(httpHost).setAuthenticationEnabled(false).build();
|
||||
botOptions.setRequestConfig(requestConfig);
|
||||
botOptions.setHttpProxy(httpHost);
|
||||
botOptions.setProxyHost(PROXY_HOST);
|
||||
botOptions.setProxyPort(PROXY_PORT);
|
||||
// Select proxy type: [HTTP|SOCKS4|SOCKS5] (default: NO_PROXY)
|
||||
botOptions.setProxyType(DefaultBotOptions.ProxyType.SOCKS5);
|
||||
|
||||
// Register your newly created AbilityBot
|
||||
MyBot bot = new MyBot(BOT_TOKEN, BOT_NAME, botOptions);
|
||||
@ -89,6 +88,14 @@ public class Main {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
|
||||
// Create the Authenticator that will return auth's parameters for proxy authentication
|
||||
Authenticator.setDefault(new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(PROXY_USER, PROXY_PASSWORD.toCharArray());
|
||||
}
|
||||
});
|
||||
|
||||
ApiContextInitializer.init();
|
||||
|
||||
// Create the TelegramBotsApi object to register your bots
|
||||
@ -97,17 +104,10 @@ public class Main {
|
||||
// Set up Http proxy
|
||||
DefaultBotOptions botOptions = ApiContext.getInstance(DefaultBotOptions.class);
|
||||
|
||||
CredentialsProvider credsProvider = new BasicCredentialsProvider();
|
||||
credsProvider.setCredentials(
|
||||
new AuthScope(PROXY_HOST, PROXY_PORT),
|
||||
new UsernamePasswordCredentials(PROXY_USER, PROXY_PASSWORD));
|
||||
|
||||
HttpHost httpHost = new HttpHost(PROXY_HOST, PROXY_PORT);
|
||||
|
||||
RequestConfig requestConfig = RequestConfig.custom().setProxy(httpHost).setAuthenticationEnabled(true).build();
|
||||
botOptions.setRequestConfig(requestConfig);
|
||||
botOptions.setCredentialsProvider(credsProvider);
|
||||
botOptions.setHttpProxy(httpHost);
|
||||
botOptions.setProxyHost(PROXY_HOST);
|
||||
botOptions.setProxyPort(PROXY_PORT);
|
||||
// Select proxy type: [HTTP|SOCKS4|SOCKS5] (default: NO_PROXY)
|
||||
botOptions.setProxyType(DefaultBotOptions.ProxyType.SOCKS5);
|
||||
|
||||
// Register your newly created AbilityBot
|
||||
MyBot bot = new MyBot(BOT_TOKEN, BOT_NAME, botOptions);
|
||||
@ -120,3 +120,5 @@ public class Main {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you need something more complex than one proxy, then you can create more complex Authenticator that will check host and other parameters of proxy and return auth values based on them (for more information see code of java.net.Authenticator class)
|
||||
|
@ -102,8 +102,9 @@ If you're in doubt that you're missing some code, the full code example can be i
|
||||
Go ahead and "/hello" to your bot. It should respond back with "Hello World!".
|
||||
|
||||
Since you've implemented an AbilityBot, you get **factory abilities** as well. Try:
|
||||
* /commands - Prints all commands supported by the bot
|
||||
* This will essentially print "hello - says hello world!". Yes! This is the information we supplied to the ability. The bot prints the commands in the format accepted by BotFather. So, whenever you change, add or remove commands, you can simply /commands and forward that message to BotFather.
|
||||
* /report - Prints all user-defined commands supported by the bot
|
||||
* This will essentially print "hello - says hello world!". Yes! This is the information we supplied to the ability. The bot prints the commands in the format accepted by BotFather. So, whenever you change, add or remove commands, you can simply /report and forward that message to BotFather.
|
||||
* /commands - Prints all commands exposed by the bot (factory and user-defined, with and without info)
|
||||
* /claim - Claims this bot
|
||||
* /backup - returns a backup of the bot database
|
||||
* /recover - recovers the database
|
||||
|
BIN
jetbrains.png
Normal file
BIN
jetbrains.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 178 KiB |
2
pom.xml
2
pom.xml
@ -7,7 +7,7 @@
|
||||
<groupId>org.telegram</groupId>
|
||||
<artifactId>Bots</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>3.6.1</version>
|
||||
<version>3.6.2</version>
|
||||
|
||||
<modules>
|
||||
<module>telegrambots</module>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.telegram</groupId>
|
||||
<artifactId>telegrambots-abilities</artifactId>
|
||||
<version>3.6.1</version>
|
||||
<version>3.6.2</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Telegram Ability Bot</name>
|
||||
|
@ -1,6 +1,12 @@
|
||||
package org.telegram.abilitybots.api.bot;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableList.Builder;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.telegram.abilitybots.api.db.DBContext;
|
||||
import org.telegram.abilitybots.api.objects.*;
|
||||
import org.telegram.abilitybots.api.sender.DefaultSender;
|
||||
@ -14,6 +20,7 @@ import org.telegram.telegrambots.meta.api.methods.groupadministration.GetChatAdm
|
||||
import org.telegram.telegrambots.meta.api.methods.send.SendDocument;
|
||||
import org.telegram.telegrambots.meta.api.objects.Message;
|
||||
import org.telegram.telegrambots.meta.api.objects.Update;
|
||||
import org.telegram.telegrambots.meta.api.objects.User;
|
||||
import org.telegram.telegrambots.bots.DefaultBotOptions;
|
||||
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
|
||||
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
|
||||
@ -26,29 +33,31 @@ import java.io.PrintStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static com.google.common.collect.MultimapBuilder.hashKeys;
|
||||
import static java.lang.String.format;
|
||||
import static java.time.ZonedDateTime.now;
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.Comparator.comparing;
|
||||
import static java.util.Objects.nonNull;
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static java.util.function.Function.identity;
|
||||
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||
import static java.util.regex.Pattern.compile;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static jersey.repackaged.com.google.common.base.Throwables.propagate;
|
||||
import static org.apache.commons.lang3.StringUtils.isEmpty;
|
||||
import static org.telegram.abilitybots.api.db.MapDBContext.onlineInstance;
|
||||
import static org.telegram.abilitybots.api.objects.Ability.builder;
|
||||
import static org.telegram.abilitybots.api.objects.EndUser.fromUser;
|
||||
import static org.telegram.abilitybots.api.objects.Flag.*;
|
||||
import static org.telegram.abilitybots.api.objects.Locality.*;
|
||||
import static org.telegram.abilitybots.api.objects.MessageContext.newContext;
|
||||
import static org.telegram.abilitybots.api.objects.Privacy.*;
|
||||
import static org.telegram.abilitybots.api.util.AbilityMessageCodes.*;
|
||||
import static org.telegram.abilitybots.api.util.AbilityUtils.*;
|
||||
|
||||
/**
|
||||
@ -63,10 +72,11 @@ import static org.telegram.abilitybots.api.util.AbilityUtils.*;
|
||||
* <li>Sets the user as the {@link Privacy#CREATOR} of the bot</li>
|
||||
* <li>Only the user with the ID returned by {@link AbilityBot#creatorId()} can genuinely claim the bot</li>
|
||||
* </ul>
|
||||
* <li>/commands - reports all user-defined commands (abilities)</li>
|
||||
* <li>/report - reports all user-defined commands (abilities)</li>
|
||||
* <ul>
|
||||
* <li>The same format acceptable by BotFather</li>
|
||||
* </ul>
|
||||
* <li>/commands - returns a list of all possible bot commands based on the privacy of the requesting user</li>
|
||||
* <li>/backup - returns a backup of the bot database</li>
|
||||
* <li>/recover - recovers the database</li>
|
||||
* <li>/promote <code>@username</code> - promotes user to bot admin</li>
|
||||
@ -101,10 +111,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
|
||||
protected static final String BACKUP = "backup";
|
||||
protected static final String RECOVER = "recover";
|
||||
protected static final String COMMANDS = "commands";
|
||||
|
||||
// Messages
|
||||
protected static final String RECOVERY_MESSAGE = "I am ready to receive the backup file. Please reply to this message with the backup file attached.";
|
||||
protected static final String RECOVER_SUCCESS = "I have successfully recovered.";
|
||||
protected static final String REPORT = "report";
|
||||
|
||||
// DB and sender
|
||||
protected final DBContext db;
|
||||
@ -148,9 +155,9 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the map of ID -> EndUser
|
||||
* @return the map of ID -> User
|
||||
*/
|
||||
protected Map<Integer, EndUser> users() {
|
||||
protected Map<Integer, User> users() {
|
||||
return db.getMap(USERS);
|
||||
}
|
||||
|
||||
@ -175,6 +182,20 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
|
||||
return db.getSet(ADMINS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the immutable map of String -> Ability
|
||||
*/
|
||||
public Map<String, Ability> abilities() {
|
||||
return abilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the immutable list carrying the embedded replies
|
||||
*/
|
||||
public List<Reply> replies() {
|
||||
return replies;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method contains the stream of actions that are applied on any update.
|
||||
* <p>
|
||||
@ -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:
|
||||
* <p>
|
||||
* PUBLIC
|
||||
* <p>
|
||||
* [command1] - [description1]
|
||||
* <p>
|
||||
* [command2] - [description2]
|
||||
* <p>
|
||||
* GROUP_ADMIN
|
||||
* <p>
|
||||
* [command1] - [description1]
|
||||
* <p>
|
||||
* ...
|
||||
*
|
||||
* @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<Privacy, String> 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<Integer> 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<Integer> 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<Integer> 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<Integer> 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<Integer> admins = admins();
|
||||
int id = creatorId();
|
||||
long chatId = ctx.chatId();
|
||||
|
||||
if (admins.contains(id))
|
||||
silent.send("You're already my master.", chatId);
|
||||
send(ABILITY_CLAIM_FAIL, ctx);
|
||||
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()));
|
||||
send(ABILITY_CLAIM_SUCCESS, ctx);
|
||||
}
|
||||
})
|
||||
.post(commitTo(db))
|
||||
.build();
|
||||
}
|
||||
|
||||
private Optional<Message> send(String message, MessageContext ctx, String... args) {
|
||||
return silent.send(getLocalizedMessage(message, ctx.user().getLanguageCode(), args), ctx.chatId());
|
||||
}
|
||||
|
||||
private Optional<Message> sendMd(String message, MessageContext ctx, String... args) {
|
||||
return silent.sendMd(getLocalizedMessage(message, ctx.user().getLanguageCode(), args), ctx.chatId());
|
||||
}
|
||||
|
||||
private Optional<Message> 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.
|
||||
* <p>
|
||||
@ -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::<String, Ability>builder,
|
||||
(b, a) -> b.put(a.name(), a),
|
||||
(b1, b2) -> b1.putAll(b2.build()))
|
||||
.build();
|
||||
|
||||
Stream<Reply> methodReplies = stream(this.getClass().getMethods())
|
||||
.filter(method -> method.getReturnType().equals(Reply.class))
|
||||
@ -547,7 +640,11 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
|
||||
Stream<Reply> abilityReplies = abilities.values().stream()
|
||||
.flatMap(ability -> ability.replies().stream());
|
||||
|
||||
replies = Stream.concat(methodReplies, abilityReplies).collect(toList());
|
||||
replies = Stream.concat(methodReplies, abilityReplies).collect(
|
||||
ImmutableList::<Reply>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<MessageContext, Ability> getContext(Trio<Update, Ability, String[]> 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<Update, Ability, String[]> 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("_", "\\_");
|
||||
}
|
||||
|
@ -39,6 +39,13 @@ public interface DBContext extends Closeable {
|
||||
*/
|
||||
<T> Set<T> getSet(String name);
|
||||
|
||||
/**
|
||||
* @param name the unique name of the {@link Var}
|
||||
* @param <T> the type that the variable holds
|
||||
* @return the variable with the specified name
|
||||
*/
|
||||
<T> Var<T> getVar(String name);
|
||||
|
||||
/**
|
||||
* @return a high-level summary of the database structures (Sets, Lists, Maps, ...) present.
|
||||
*/
|
||||
|
@ -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<T>) db.<T>hashSet(name, JAVA).createOrOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Var<T> getVar(String name) {
|
||||
return new MapDBVar<>((Atomic.Var<T>) db.atomicVar(name).createOrOpen());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String summary() {
|
||||
return stream(db.getAllNames().spliterator(), false)
|
||||
|
@ -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 <T> the type of the inner variable
|
||||
*/
|
||||
public final class MapDBVar<T> implements Var<T> {
|
||||
private Atomic.Var<T> var;
|
||||
|
||||
public MapDBVar(Atomic.Var<T> 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();
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.telegram.abilitybots.api.db;
|
||||
|
||||
/**
|
||||
* The interface governing a variable for abstract getters and setters.
|
||||
* @param <T> the type of the variable
|
||||
*
|
||||
* @author Abbas Abou Daya
|
||||
*/
|
||||
public interface Var<T> {
|
||||
/**
|
||||
* @return the variable contained
|
||||
*/
|
||||
T get();
|
||||
|
||||
/**
|
||||
* @param var the new variable value
|
||||
*/
|
||||
void set(T var);
|
||||
}
|
@ -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}.
|
||||
* <p>
|
||||
* 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:
|
||||
* <ol>
|
||||
* <li>First name</li>
|
||||
* <li>Last name</li>
|
||||
* <li>Username</li>
|
||||
* </ol>
|
||||
* 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();
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ import static java.util.Objects.nonNull;
|
||||
/**
|
||||
* Flags are an conditions that are applied on an {@link Update}.
|
||||
* <p>
|
||||
* 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
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
|
||||
}
|
@ -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<Update> 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:
|
||||
* <ol>
|
||||
* <li>First name</li>
|
||||
* <li>Last name</li>
|
||||
* <li>Username</li>
|
||||
* </ol>
|
||||
* 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();
|
||||
}
|
||||
}
|
@ -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}].
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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<Integer> actual = bot.admins();
|
||||
Set<Integer> expected = newHashSet(MUSER.id());
|
||||
Set<Integer> 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<Integer> actual = bot.blacklist();
|
||||
Set<Integer> expected = newHashSet(MUSER.id());
|
||||
Set<Integer> 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<Integer> actual = bot.blacklist();
|
||||
Set<Integer> expected = newHashSet(MUSER.id());
|
||||
Set<Integer> 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<Integer> actual = bot.admins();
|
||||
Set<Integer> expected = newHashSet(CREATOR.id());
|
||||
Set<Integer> 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<Integer> actual = bot.blacklist();
|
||||
Set<Integer> 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<String, Integer> expectedUserIds = ImmutableMap.of(MUSER.username(), MUSER.id());
|
||||
Map<Integer, EndUser> expectedUsers = ImmutableMap.of(MUSER.id(), MUSER);
|
||||
Map<String, Integer> expectedUserIds = ImmutableMap.of(USER.getUserName(), USER.getId());
|
||||
Map<Integer, User> 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<String, Integer> expectedUserIds = ImmutableMap.of(changedUser.username(), changedUser.id());
|
||||
Map<Integer, EndUser> expectedUsers = ImmutableMap.of(changedUser.id(), changedUser);
|
||||
Map<String, Integer> expectedUserIds = ImmutableMap.of(changedUser.getUserName(), changedUser.getId());
|
||||
Map<Integer, User> 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<Update, Ability, String[]> 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<Update, Ability, String[]> trioOneArg = Trio.of(update, abilityWithOneInput, TEXT);
|
||||
Trio<Update, Ability, String[]> 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<Update, Ability, String[]> 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<Update, Ability, String[]> trio = Trio.of(update, ability, TEXT);
|
||||
|
||||
when(message.getChatId()).thenReturn(GROUP_ID);
|
||||
mockUser(update, message, user);
|
||||
mockUser(update, message, USER);
|
||||
|
||||
Pair<MessageContext, Ability> actualPair = bot.getContext(trio);
|
||||
Pair<MessageContext, Ability> expectedPair = Pair.of(newContext(update, MUSER, GROUP_ID, TEXT), ability);
|
||||
Pair<MessageContext, Ability> 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<Update, Ability, String[]> docTrio = Trio.of(update, documentAbility, TEXT);
|
||||
Trio<Update, Ability, String[]> 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);
|
||||
|
@ -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<Integer, EndUser> users = db.getMap(USERS);
|
||||
Map<Integer, User> users = db.getMap(USERS);
|
||||
Map<String, Integer> 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<Integer, EndUser> originalUsers = newHashMap(users);
|
||||
Map<Integer, User> originalUsers = newHashMap(users);
|
||||
String beforeBackupInfo = db.info(USERS);
|
||||
|
||||
Object jsonBackup = db.backup();
|
||||
db.clear();
|
||||
boolean recovered = db.recover(jsonBackup);
|
||||
|
||||
Map<Integer, EndUser> recoveredUsers = db.getMap(USERS);
|
||||
Map<Integer, User> 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<EndUser> users = db.getSet(USERS);
|
||||
public void canFallbackDBIfRecoveryFails() {
|
||||
Set<User> users = db.getSet(USERS);
|
||||
users.add(CREATOR);
|
||||
users.add(MUSER);
|
||||
users.add(USER);
|
||||
|
||||
Set<EndUser> originalSet = newHashSet(users);
|
||||
Set<User> originalSet = newHashSet(users);
|
||||
Object jsonBackup = db.backup();
|
||||
String corruptBackup = "!@#$" + String.valueOf(jsonBackup);
|
||||
boolean recovered = db.recover(corruptBackup);
|
||||
|
||||
Set<EndUser> recoveredSet = db.getSet(USERS);
|
||||
Set<User> 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<User> var = db.getVar(varName);
|
||||
var.set(CREATOR);
|
||||
db.commit();
|
||||
|
||||
var = db.getVar(varName);
|
||||
assertEquals(var.get(), CREATOR);
|
||||
|
||||
var.set(USER);
|
||||
db.commit();
|
||||
|
||||
Var<User> changedVar = db.getVar(varName);
|
||||
assertEquals(changedVar.get(), USER);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws IOException {
|
||||
db.clear();
|
||||
|
@ -0,0 +1 @@
|
||||
ability.commands.notFound=Non sono presenti comandi disponibile.
|
@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.telegram</groupId>
|
||||
<artifactId>telegrambotsextensions</artifactId>
|
||||
<version>3.6.1</version>
|
||||
<version>3.6.2</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Telegram Bots Extensions</name>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.telegram</groupId>
|
||||
<artifactId>telegrambots-meta</artifactId>
|
||||
<version>3.6.1</version>
|
||||
<version>3.6.2</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Telegram Bots Meta</name>
|
||||
|
@ -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{" +
|
||||
|
@ -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
|
||||
|
@ -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<ChatMember> 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<Message> 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<Boolean> 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<Boolean> 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<Message> 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<Message> 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<Message> 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<Message> 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<Boolean> 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<Boolean> 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<Boolean> 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<Chat> 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<String> 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<ArrayList<ChatMember>> 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<ChatMember> 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<Integer> 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<Serializable> 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<Serializable> 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<Serializable> 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<Boolean> 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<UserProfilePhotos> 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<File> 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<Serializable> 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<ArrayList<GameHighScore>> 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<Message> 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<Boolean> 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<Message> 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<Boolean> 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<Boolean> 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<Boolean> 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<Boolean> 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<Boolean> 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<Boolean> 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<Boolean> 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<Boolean> 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<Boolean> 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<Boolean> sentCallback) throws TelegramApiException {
|
||||
if (setChatTitle == null) {
|
||||
|
@ -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) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.telegram</groupId>
|
||||
<artifactId>telegrambots-spring-boot-starter</artifactId>
|
||||
<version>3.6.1</version>
|
||||
<version>3.6.2</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Telegram Bots Spring Boot Starter</name>
|
||||
@ -60,7 +60,7 @@
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<bots.version>3.6.1</bots.version>
|
||||
<spring-boot.version>1.5.10.RELEASE</spring-boot.version>
|
||||
<spring-boot.version>2.0.2.RELEASE</spring-boot.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -75,11 +75,41 @@
|
||||
<artifactId>spring-boot</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-test</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>3.9.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>2.0.2-beta</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -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 {
|
||||
}
|
@ -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<LongPollingBot> longPollingBots;
|
||||
private final List<WebhookBot> webHookBots;
|
||||
|
||||
public TelegramBotInitializer(TelegramBotsApi telegramBotsApi,
|
||||
List<LongPollingBot> longPollingBots,
|
||||
List<WebhookBot> 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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<LongPollingBot> longPollingBots;
|
||||
private final List<WebhookBot> webHookBots;
|
||||
|
||||
@Autowired
|
||||
private TelegramBotsApi telegramBotsApi;
|
||||
|
||||
public TelegramBotStarterConfiguration(List<LongPollingBot> longPollingBots,
|
||||
List<WebhookBot> 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<List<LongPollingBot>> longPollingBots,
|
||||
Optional<List<WebhookBot>> webHookBots) {
|
||||
return new TelegramBotInitializer(telegramBotsApi,
|
||||
longPollingBots.orElseGet(Collections::emptyList),
|
||||
webHookBots.orElseGet(Collections::emptyList));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.telegram.telegrambots.starter.TelegramBotStarterConfiguration
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.telegram</groupId>
|
||||
<artifactId>telegrambots</artifactId>
|
||||
<version>3.6.1</version>
|
||||
<version>3.6.2</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Telegram Bots</name>
|
||||
|
@ -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);
|
||||
|
@ -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<String> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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<ConnectionSocketFactory> registry;
|
||||
switch (options.getProxyType()) {
|
||||
case NO_PROXY:
|
||||
return null;
|
||||
case HTTP:
|
||||
registry = RegistryBuilder.<ConnectionSocketFactory> create()
|
||||
.register("http", new HttpConnectionSocketFactory())
|
||||
.register("https", new HttpSSLConnectionSocketFactory(SSLContexts.createSystemDefault())).build();
|
||||
return new PoolingHttpClientConnectionManager(registry);
|
||||
case SOCKS4:
|
||||
case SOCKS5:
|
||||
registry = RegistryBuilder.<ConnectionSocketFactory> create()
|
||||
.register("http", new SocksConnectionSocketFactory())
|
||||
.register("https", new SocksSSLConnectionSocketFactory(SSLContexts.createSystemDefault())).build();
|
||||
return new PoolingHttpClientConnectionManager(registry);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user