diff --git a/.gitignore b/.gitignore index b8b3cdb3..f2fa92ab 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ hs_err_pid* ### IDE files .idea/ +copyright/ *.iml #File System specific files diff --git a/src/main/java/org/telegram/telegrambots/api/commands/HelpBotCommand.java b/src/main/java/org/telegram/telegrambots/api/commands/HelpBotCommand.java deleted file mode 100644 index 2c02af26..00000000 --- a/src/main/java/org/telegram/telegrambots/api/commands/HelpBotCommand.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.telegram.telegrambots.api.commands; - -import org.telegram.telegrambots.TelegramApiException; -import org.telegram.telegrambots.api.methods.send.SendMessage; -import org.telegram.telegrambots.api.objects.Chat; -import org.telegram.telegrambots.bots.AbsSender; -import org.telegram.telegrambots.logging.BotLogger; - -/** - * standard help command, which gets registered by default, to supply a list of all available commands - * - * @author tschulz - */ -public class HelpBotCommand extends BotCommand { - - private static final String LOGTAG = "HELPCOMMAND"; - private final ICommandRegistry commandRegistry; - - public HelpBotCommand(ICommandRegistry commandRegistry, String botToken) { - super("help", "Gives an overview over all Commands registered for this bot"); - this.commandRegistry = commandRegistry; - } - - @Override - public void execute(AbsSender absSender, Chat chat, String[] arguments) { - - for (BotCommand registeredBotCommand : commandRegistry.getRegisteredCommands()) { - SendMessage sendMessage = new SendMessage(); - sendMessage.setChatId(chat.getId().toString()); - sendMessage.enableHtml(true); - sendMessage.setText("" + COMMAND_INIT_CHARACTER + registeredBotCommand.getCommandIdentifier() + "\n" + registeredBotCommand.getDescription()); - - try { - absSender.sendMessage(sendMessage); - } catch (TelegramApiException e) { - BotLogger.error("Failed to send HelpMessage", LOGTAG, e); - } - } - } -} diff --git a/src/main/java/org/telegram/telegrambots/api/objects/Message.java b/src/main/java/org/telegram/telegrambots/api/objects/Message.java index f32a8c15..f14c2894 100644 --- a/src/main/java/org/telegram/telegrambots/api/objects/Message.java +++ b/src/main/java/org/telegram/telegrambots/api/objects/Message.java @@ -382,10 +382,11 @@ public class Message implements IBotApiObject { } public boolean isCommand() { - if (entities != null) { + if (hasText() && entities != null) { for (MessageEntity entity : entities) { - if (entity != null && "bot_command".equals(entity.getType())) { - return text != null && !text.isEmpty(); + if (entity != null && entity.getOffset() == 0 && + EntityType.BOTCOMMAND.equals(entity.getType())) { + return true; } } } diff --git a/src/main/java/org/telegram/telegrambots/bots/TelegramLongPollingCommandBot.java b/src/main/java/org/telegram/telegrambots/bots/TelegramLongPollingCommandBot.java index 17c0b0a8..fba5b986 100644 --- a/src/main/java/org/telegram/telegrambots/bots/TelegramLongPollingCommandBot.java +++ b/src/main/java/org/telegram/telegrambots/bots/TelegramLongPollingCommandBot.java @@ -1,17 +1,15 @@ package org.telegram.telegrambots.bots; -import org.telegram.telegrambots.TelegramApiException; -import org.telegram.telegrambots.api.commands.BotCommand; -import org.telegram.telegrambots.api.commands.CommandRegistry; -import org.telegram.telegrambots.api.commands.ICommandRegistry; -import org.telegram.telegrambots.api.methods.send.SendMessage; +import org.telegram.telegrambots.bots.commands.BotCommand; +import org.telegram.telegrambots.bots.commands.CommandRegistry; +import org.telegram.telegrambots.bots.commands.ICommandRegistry; import org.telegram.telegrambots.api.objects.Message; import org.telegram.telegrambots.api.objects.Update; -import org.telegram.telegrambots.logging.BotLogger; import java.util.Collection; import java.util.Map; +import java.util.function.BiConsumer; /** * This class adds command functionality to the TelegramLongPollingBot @@ -19,8 +17,6 @@ import java.util.Map; * @author tschulz */ public abstract class TelegramLongPollingCommandBot extends TelegramLongPollingBot implements ICommandRegistry { - - public static final String LOGTAG = "TelegramLongPollingCommandBot"; private final CommandRegistry commandRegistry; /** @@ -28,7 +24,8 @@ public abstract class TelegramLongPollingCommandBot extends TelegramLongPollingB * Use ICommandRegistry's methods on this bot to register commands */ public TelegramLongPollingCommandBot() { - this.commandRegistry = new CommandRegistry(getBotToken()); + super(); + this.commandRegistry = new CommandRegistry(); } @Override @@ -36,17 +33,9 @@ public abstract class TelegramLongPollingCommandBot extends TelegramLongPollingB if (update.hasMessage()) { Message message = update.getMessage(); if (message.isCommand()) { - if (!commandRegistry.executeCommand(this, message)) { - SendMessage sendMessage = new SendMessage(); - sendMessage.setChatId(message.getChatId().toString()); - sendMessage.setText("The command you provided is not registered for this bot"); - try { - sendMessage(sendMessage); - } catch (TelegramApiException e) { - BotLogger.error("Cannot send message", LOGTAG, e); - } + if (commandRegistry.executeCommand(this, message)) { + return; } - return; } } processNonCommandUpdate(update); @@ -77,10 +66,15 @@ public abstract class TelegramLongPollingCommandBot extends TelegramLongPollingB return commandRegistry.getRegisteredCommands(); } + @Override + public void registerDefaultAction(BiConsumer defaultConsumer) { + commandRegistry.registerDefaultAction(defaultConsumer); + } + /** * Process all updates, that are not commands. - * Attention: commands, that have valid syntax but are not registered on this bot, - * won't be forwarded to this method! + * @warning Commands that have valid syntax but are not registered on this bot, + * won't be forwarded to this method if a default action is present. * * @param update the update */ diff --git a/src/main/java/org/telegram/telegrambots/api/commands/BotCommand.java b/src/main/java/org/telegram/telegrambots/bots/commands/BotCommand.java similarity index 78% rename from src/main/java/org/telegram/telegrambots/api/commands/BotCommand.java rename to src/main/java/org/telegram/telegrambots/bots/commands/BotCommand.java index b22bfde6..f46e9a10 100644 --- a/src/main/java/org/telegram/telegrambots/api/commands/BotCommand.java +++ b/src/main/java/org/telegram/telegrambots/bots/commands/BotCommand.java @@ -1,4 +1,4 @@ -package org.telegram.telegrambots.api.commands; +package org.telegram.telegrambots.bots.commands; import org.telegram.telegrambots.api.objects.Chat; import org.telegram.telegrambots.bots.AbsSender; @@ -9,18 +9,18 @@ import org.telegram.telegrambots.bots.AbsSender; * @author tschulz */ public abstract class BotCommand { - public final static String COMMAND_INIT_CHARACTER = "/"; - public final static String COMMAND_PARAMETER_SEPARATOR = " "; + public static final String COMMAND_PARAMETER_SEPARATOR = " "; private final static int COMMAND_MAX_LENGTH = 32; private final String commandIdentifier; private final String description; /** - * construct a command + * Construct a command * - * @param commandIdentifier the unique identifier of this command (e.g. the command string to enter into chat) + * @param commandIdentifier the unique identifier of this command (e.g. the command string to + * enter into chat) * @param description the description of this command */ public BotCommand(String commandIdentifier, String description) { @@ -42,7 +42,7 @@ public abstract class BotCommand { } /** - * get the identifier of this command + * Get the identifier of this command * * @return the identifier */ @@ -51,7 +51,7 @@ public abstract class BotCommand { } /** - * get the description of this command + * Get the description of this command * * @return the description as String */ @@ -59,8 +59,14 @@ public abstract class BotCommand { return description; } + @Override + public String toString() { + return "" + COMMAND_INIT_CHARACTER + getCommandIdentifier() + + "\n" + getDescription(); + } + /** - * execute the command + * Execute the command * * @param absSender absSender to send messages over * @param chat the chat, to be able to send replies diff --git a/src/main/java/org/telegram/telegrambots/api/commands/CommandRegistry.java b/src/main/java/org/telegram/telegrambots/bots/commands/CommandRegistry.java similarity index 75% rename from src/main/java/org/telegram/telegrambots/api/commands/CommandRegistry.java rename to src/main/java/org/telegram/telegrambots/bots/commands/CommandRegistry.java index 8e176508..6d2d3eb7 100644 --- a/src/main/java/org/telegram/telegrambots/api/commands/CommandRegistry.java +++ b/src/main/java/org/telegram/telegrambots/bots/commands/CommandRegistry.java @@ -1,4 +1,4 @@ -package org.telegram.telegrambots.api.commands; +package org.telegram.telegrambots.bots.commands; import org.telegram.telegrambots.api.objects.Message; import org.telegram.telegrambots.bots.AbsSender; @@ -7,6 +7,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.function.BiConsumer; /** * @author tschulz @@ -14,9 +15,14 @@ import java.util.Map; public final class CommandRegistry implements ICommandRegistry { private final Map commandRegistryMap = new HashMap<>(); + private BiConsumer defaultConsumer; - public CommandRegistry(String botToken) { - register(new HelpBotCommand(this, botToken)); + public CommandRegistry() { + } + + @Override + public void registerDefaultAction(BiConsumer defaultConsumer) { + this.defaultConsumer = defaultConsumer; } @Override @@ -61,15 +67,19 @@ public final class CommandRegistry implements ICommandRegistry { } /** - * executes a command if present and replies the success + * Executes a command action if the command is registered. * + * @note If the command is not registered and there is a default consumer, + * that action will be performed + * + * @param absSender absSender * @param message input message - * @return true if success or false otherwise + * @return True if a command or default action is executed, false otherwise */ public final boolean executeCommand(AbsSender absSender, Message message) { if (message.hasText()) { String text = message.getText(); - if (!text.isEmpty() && text.startsWith(BotCommand.COMMAND_INIT_CHARACTER)) { + if (text.startsWith(BotCommand.COMMAND_INIT_CHARACTER)) { String commandMessage = text.substring(1); String[] commandSplit = commandMessage.split(BotCommand.COMMAND_PARAMETER_SEPARATOR); @@ -79,6 +89,9 @@ public final class CommandRegistry implements ICommandRegistry { String[] parameters = Arrays.copyOfRange(commandSplit, 1, commandSplit.length); commandRegistryMap.get(command).execute(absSender, message.getChat(), parameters); return true; + } else if (defaultConsumer != null) { + defaultConsumer.accept(absSender, message); + return true; } } } diff --git a/src/main/java/org/telegram/telegrambots/api/commands/ICommandRegistry.java b/src/main/java/org/telegram/telegrambots/bots/commands/ICommandRegistry.java similarity index 51% rename from src/main/java/org/telegram/telegrambots/api/commands/ICommandRegistry.java rename to src/main/java/org/telegram/telegrambots/bots/commands/ICommandRegistry.java index 06db1d88..676e1f8f 100644 --- a/src/main/java/org/telegram/telegrambots/api/commands/ICommandRegistry.java +++ b/src/main/java/org/telegram/telegrambots/bots/commands/ICommandRegistry.java @@ -1,18 +1,31 @@ -package org.telegram.telegrambots.api.commands; +package org.telegram.telegrambots.bots.commands; + +import org.telegram.telegrambots.api.objects.Message; +import org.telegram.telegrambots.bots.AbsSender; import java.util.Collection; import java.util.Map; +import java.util.function.BiConsumer; /** * */ public interface ICommandRegistry { + /** + * Register a default action when there is no command register that match the message sent + * @param defaultConsumer Consumer to evaluate the message + * + * @note Use this method if you want your bot to execute a default action when the user + * sends a command that is not registered. + */ + void registerDefaultAction(BiConsumer defaultConsumer); + /** * register a command * * @param botCommand the command to register - * @return whether the command could be registered, was not already registered + * @return whether the command could be registered, was not already registered */ boolean register(BotCommand botCommand); @@ -20,7 +33,7 @@ public interface ICommandRegistry { * register multiple commands * * @param botCommands commands to register - * @return map with results of the command register per command + * @return map with results of the command register per command */ Map registerAll(BotCommand... botCommands); @@ -28,7 +41,7 @@ public interface ICommandRegistry { * deregister a command * * @param botCommand the command to deregister - * @return whether the command could be deregistered, was registered + * @return whether the command could be deregistered, was registered */ boolean deregister(BotCommand botCommand); @@ -36,7 +49,7 @@ public interface ICommandRegistry { * deregister multiple commands * * @param botCommands commands to deregister - * @return map with results of the command deregistered per command + * @return map with results of the command deregistered per command */ Map deregisterAll(BotCommand... botCommands);