diff --git a/Bots.ipr b/Bots.ipr
index 6cbcc842..04178b7e 100644
--- a/Bots.ipr
+++ b/Bots.ipr
@@ -17,6 +17,7 @@
+
@@ -29,11 +30,13 @@
+
+
@@ -261,6 +264,7 @@
+
@@ -834,6 +838,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
index 91d6639c..bbad1838 100644
--- a/README.md
+++ b/README.md
@@ -27,16 +27,16 @@ Just import add the library to your project with one of these options:
org.telegramtelegrambots
- 3.0.1
+ 3.0.2
```
```gradle
- compile "org.telegram:telegrambots:3.0.1"
+ compile "org.telegram:telegrambots:3.0.2"
```
- 2. Using Jitpack from [here](https://jitpack.io/#rubenlagus/TelegramBots/3.0.1)
- 3. Download the jar(including all dependencies) from [here](https://github.com/rubenlagus/TelegramBots/releases/tag/3.0.1)
+ 2. Using Jitpack from [here](https://jitpack.io/#rubenlagus/TelegramBots/3.0.2)
+ 3. Download the jar(including all dependencies) from [here](https://github.com/rubenlagus/TelegramBots/releases/tag/3.0.2)
In order to use Long Polling mode, just create your own bot extending `org.telegram.telegrambots.bots.TelegramLongPollingBot`.
diff --git a/TelegramBots.wiki/Changelog.md b/TelegramBots.wiki/Changelog.md
index c7f54bda..e76e0a06 100644
--- a/TelegramBots.wiki/Changelog.md
+++ b/TelegramBots.wiki/Changelog.md
@@ -58,4 +58,12 @@
### 3.0.1 ###
1. Added `getLevel` to `BotLogger` class.
2. Fix wrong URL when setting webhook
-3. Bug Fixing: #244, #233
\ No newline at end of file
+3. Bug Fixing: #244, #233
+
+### 3.0.2 ###
+1. Bug Fixing: #250
+2. Added new module `telegrambots-extensions` that should contains any extensions of the API such as CommandBot or TimedBot.
+3. `TelegramLongPollingCommandBot` receives now the bot username as constructor parameters, all deprecated constructors will be removed in next mayor release.
+4. `getUsername` method from `TelegramLongPollingCommandBot` can be considered `final` and will be so in next mayor release.
+
+**[[How to update to version 3.0.2|How-To-Update#3.0.2]]**
diff --git a/TelegramBots.wiki/Getting-Started.md b/TelegramBots.wiki/Getting-Started.md
index 8e503c51..e60b719b 100644
--- a/TelegramBots.wiki/Getting-Started.md
+++ b/TelegramBots.wiki/Getting-Started.md
@@ -11,13 +11,13 @@ First you need ot get the library and add it to your project. There are few poss
org.telegramtelegrambots
- 3.0.1
+ 3.0.2
```
* With **Gradle**:
```groovy
- compile group: 'org.telegram', name: 'telegrambots', version: '3.0.1'
+ compile group: 'org.telegram', name: 'telegrambots', version: '3.0.2'
```
2. Don't like **Maven Central Repository**? It can also be taken from [Jitpack](https://jitpack.io/#rubenlagus/TelegramBots).
diff --git a/TelegramBots.wiki/How-To-Update.md b/TelegramBots.wiki/How-To-Update.md
index ca3d4670..a09bfae3 100644
--- a/TelegramBots.wiki/How-To-Update.md
+++ b/TelegramBots.wiki/How-To-Update.md
@@ -23,4 +23,8 @@
2. In `editMessageTextAsync`, `editMessageCaptionAsync` or `editMessageReplyMarkupAsync` in `AbsSender`, second parameter should become `SentCallback` due to new return type.
### To version 3.0 ###
-1. In `Message` object, field `new_chat_member` was replaced by `new_chat_members` that is now an array of users.
\ No newline at end of file
+1. In `Message` object, field `new_chat_member` was replaced by `new_chat_members` that is now an array of users.
+
+### To version 3.0.2 ###
+1. If you were using `TelegramLongPollingCommandBot`, add the new [extensions dependency](https://github.com/rubenlagus/TelegramBots/tree/master/telegrambots-extensions) to your maven and fix import statements in your project.
+2. If you were using `TelegramLongPollingCommandBot`, make sure you start using constructors with username and prevent overriding `getUsername` method.
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 63fb8465..8f92bf11 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,11 +7,12 @@
org.telegramBotspom
- 3.0.1
+ 3.0.2telegrambotstelegrambots-meta
+ telegrambots-extensions
@@ -24,6 +25,6 @@
true
- 3.0.1
+ 3.0.2
\ No newline at end of file
diff --git a/telegrambots-extensions/README.md b/telegrambots-extensions/README.md
new file mode 100644
index 00000000..a117e067
--- /dev/null
+++ b/telegrambots-extensions/README.md
@@ -0,0 +1,27 @@
+# Telegram Bot Extensions
+
+[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.telegram/telegrambotsextensions/badge.svg)](http://mvnrepository.com/artifact/org.telegram/telegrambotsextensions)
+[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/rubenlagus/TelegramBots/blob/master/LICENSE)
+
+Extensions to default bots implementation of Telegram Bots library
+
+
+## Usage
+
+Just import add the library to your project with one of these options:
+
+ 1. Using Maven Central Repository:
+
+```xml
+
+ org.telegram
+ telegrambotsextensions
+ 3.0.2
+
+```
+
+ 2. Using Gradle:
+
+```gradle
+ compile "org.telegram:telegrambotsextensions:3.0.2"
+```
\ No newline at end of file
diff --git a/telegrambots-extensions/pom.xml b/telegrambots-extensions/pom.xml
new file mode 100644
index 00000000..07de16e6
--- /dev/null
+++ b/telegrambots-extensions/pom.xml
@@ -0,0 +1,226 @@
+
+
+ 4.0.0
+ org.telegram
+ telegrambotsextensions
+ 3.0.2
+ jar
+
+ Telegram Bots Extensions
+ https://github.com/rubenlagus/TelegramBots
+ Extensions Bots for Telegram Bots library
+
+
+ https://github.com/rubenlagus/TelegramBots/issues
+ GitHub Issues
+
+
+
+ https://github.com/rubenlagus/TelegramBots
+ scm:git:git://github.com/rubenlagus/TelegramBots.git
+ scm:git:git@github.com:rubenlagus/TelegramBots.git
+
+
+
+ https://travis-ci.org/rubenlagus/TelegramBots
+ Travis
+
+
+
+
+ rberlopez@gmail.com
+ Ruben Bermudez
+ https://github.com/rubenlagus
+ rubenlagus
+
+
+
+
+
+ MIT License
+ http://www.opensource.org/licenses/mit-license.php
+ repo
+
+
+
+
+
+ ossrh
+ https://oss.sonatype.org/content/repositories/snapshots
+
+
+ ossrh
+ https://oss.sonatype.org/service/local/staging/deploy/maven2/
+
+
+
+
+ UTF-8
+ UTF-8
+ 3.0.2
+
+
+
+
+ org.telegram
+ telegrambots
+ ${bots.version}
+
+
+
+
+ ${project.basedir}/target
+ ${project.build.directory}/classes
+ ${project.artifactId}-${project.version}
+ ${project.build.directory}/test-classes
+ ${project.basedir}/src/main/java
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 1.5
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+ org.sonatype.plugins
+ nexus-staging-maven-plugin
+ 1.6.3
+ true
+
+ ossrh
+ https://oss.sonatype.org/
+ true
+
+
+
+ maven-clean-plugin
+ 3.0.0
+
+
+ clean-project
+ clean
+
+ clean
+
+
+
+
+
+ maven-assembly-plugin
+ 2.6
+
+
+ jar-with-dependencies
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.0.0
+
+
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.10.3
+
+
+
+ jar
+
+
+ -Xdoclint:none
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.7.7.201606060606
+
+
+
+ prepare-agent
+
+
+
+ report
+ test
+
+ report
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ 1.4.1
+
+
+ enforce-versions
+
+ enforce
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 2.4
+
+
+ copy
+ package
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 1.8
+ UTF-8
+
+
+
+
+
+
\ No newline at end of file
diff --git a/telegrambots/src/main/java/org/telegram/telegrambots/bots/TelegramLongPollingCommandBot.java b/telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/commandbot/TelegramLongPollingCommandBot.java
similarity index 62%
rename from telegrambots/src/main/java/org/telegram/telegrambots/bots/TelegramLongPollingCommandBot.java
rename to telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/commandbot/TelegramLongPollingCommandBot.java
index 3cf4edea..428e8279 100644
--- a/telegrambots/src/main/java/org/telegram/telegrambots/bots/TelegramLongPollingCommandBot.java
+++ b/telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/commandbot/TelegramLongPollingCommandBot.java
@@ -1,12 +1,15 @@
-package org.telegram.telegrambots.bots;
+package org.telegram.telegrambots.bots.commandbot;
import org.telegram.telegrambots.ApiContext;
import org.telegram.telegrambots.api.objects.Message;
import org.telegram.telegrambots.api.objects.Update;
-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.bots.AbsSender;
+import org.telegram.telegrambots.bots.DefaultBotOptions;
+import org.telegram.telegrambots.bots.TelegramLongPollingBot;
+import org.telegram.telegrambots.bots.commandbot.commands.BotCommand;
+import org.telegram.telegrambots.bots.commandbot.commands.CommandRegistry;
+import org.telegram.telegrambots.bots.commandbot.commands.ICommandRegistry;
import java.util.Collection;
import java.util.Map;
@@ -19,37 +22,82 @@ import java.util.function.BiConsumer;
*/
public abstract class TelegramLongPollingCommandBot extends TelegramLongPollingBot implements ICommandRegistry {
private final CommandRegistry commandRegistry;
+ private String botUsername;
/**
* Creates a TelegramLongPollingCommandBot using default options
* Use ICommandRegistry's methods on this bot to register commands
+ *
+ * @deprecated Uses {@link #TelegramLongPollingCommandBot(String)} instead
*/
+ @Deprecated
public TelegramLongPollingCommandBot() {
this(ApiContext.getInstance(DefaultBotOptions.class));
}
+ /**
+ * Creates a TelegramLongPollingCommandBot using default options
+ * Use ICommandRegistry's methods on this bot to register commands
+ *
+ * @param botUsername Username of the bot
+ */
+ public TelegramLongPollingCommandBot(String botUsername) {
+ this(ApiContext.getInstance(DefaultBotOptions.class), botUsername);
+ }
+
/**
* Creates a TelegramLongPollingCommandBot with custom options and allowing commands with
* usernames
* Use ICommandRegistry's methods on this bot to register commands
* @param options Bot options
+ *
+ * @deprecated Use {@link #TelegramLongPollingCommandBot(DefaultBotOptions, String)} instead
*/
+ @Deprecated
public TelegramLongPollingCommandBot(DefaultBotOptions options) {
this(options, true);
}
+ /**
+ * Creates a TelegramLongPollingCommandBot with custom options and allowing commands with
+ * usernames
+ * Use ICommandRegistry's methods on this bot to register commands
+ * @param options Bot options
+ * @param botUsername Username of the bot
+ */
+ public TelegramLongPollingCommandBot(DefaultBotOptions options, String botUsername) {
+ this(options, true, botUsername);
+ }
+
/**
* Creates a TelegramLongPollingCommandBot
* Use ICommandRegistry's methods on this bot to register commands
* @param options Bot options
* @param allowCommandsWithUsername true to allow commands with parameters (default),
* false otherwise
+ *
+ * @deprecated Use {@link #TelegramLongPollingCommandBot(DefaultBotOptions, boolean, String)} instead
*/
+ @Deprecated
public TelegramLongPollingCommandBot(DefaultBotOptions options, boolean allowCommandsWithUsername) {
super(options);
this.commandRegistry = new CommandRegistry(allowCommandsWithUsername, getBotUsername());
}
+ /**
+ * Creates a TelegramLongPollingCommandBot
+ * Use ICommandRegistry's methods on this bot to register commands
+ * @param options Bot options
+ * @param allowCommandsWithUsername true to allow commands with parameters (default),
+ * false otherwise
+ * @param botUsername bot username of this bot
+ */
+ public TelegramLongPollingCommandBot(DefaultBotOptions options, boolean allowCommandsWithUsername, String botUsername) {
+ super(options);
+ this.botUsername = botUsername;
+ this.commandRegistry = new CommandRegistry(allowCommandsWithUsername, botUsername);
+ }
+
@Override
public final void onUpdateReceived(Update update) {
if (update.hasMessage()) {
@@ -115,6 +163,15 @@ public abstract class TelegramLongPollingCommandBot extends TelegramLongPollingB
return commandRegistry.getRegisteredCommand(commandIdentifier);
}
+ /**
+ * TODO This method will become final in next mayor release, avoid overriding it
+ * @return Bot username
+ */
+ @Override
+ public String getBotUsername() {
+ return botUsername;
+ }
+
/**
* Process all updates, that are not commands.
* @warning Commands that have valid syntax but are not registered on this bot,
diff --git a/telegrambots/src/main/java/org/telegram/telegrambots/bots/commands/BotCommand.java b/telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/commandbot/commands/BotCommand.java
similarity index 97%
rename from telegrambots/src/main/java/org/telegram/telegrambots/bots/commands/BotCommand.java
rename to telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/commandbot/commands/BotCommand.java
index 4b0935fa..02da6ebd 100644
--- a/telegrambots/src/main/java/org/telegram/telegrambots/bots/commands/BotCommand.java
+++ b/telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/commandbot/commands/BotCommand.java
@@ -1,4 +1,4 @@
-package org.telegram.telegrambots.bots.commands;
+package org.telegram.telegrambots.bots.commandbot.commands;
import org.telegram.telegrambots.api.objects.Chat;
import org.telegram.telegrambots.api.objects.User;
diff --git a/telegrambots/src/main/java/org/telegram/telegrambots/bots/commands/CommandRegistry.java b/telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/commandbot/commands/CommandRegistry.java
similarity index 98%
rename from telegrambots/src/main/java/org/telegram/telegrambots/bots/commands/CommandRegistry.java
rename to telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/commandbot/commands/CommandRegistry.java
index e43c273b..17da10d3 100644
--- a/telegrambots/src/main/java/org/telegram/telegrambots/bots/commands/CommandRegistry.java
+++ b/telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/commandbot/commands/CommandRegistry.java
@@ -1,4 +1,4 @@
-package org.telegram.telegrambots.bots.commands;
+package org.telegram.telegrambots.bots.commandbot.commands;
import org.telegram.telegrambots.api.objects.Message;
import org.telegram.telegrambots.bots.AbsSender;
diff --git a/telegrambots/src/main/java/org/telegram/telegrambots/bots/commands/ICommandRegistry.java b/telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/commandbot/commands/ICommandRegistry.java
similarity index 97%
rename from telegrambots/src/main/java/org/telegram/telegrambots/bots/commands/ICommandRegistry.java
rename to telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/commandbot/commands/ICommandRegistry.java
index 56ae4c6c..1f2a4d5f 100644
--- a/telegrambots/src/main/java/org/telegram/telegrambots/bots/commands/ICommandRegistry.java
+++ b/telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/commandbot/commands/ICommandRegistry.java
@@ -1,4 +1,4 @@
-package org.telegram.telegrambots.bots.commands;
+package org.telegram.telegrambots.bots.commandbot.commands;
import org.telegram.telegrambots.api.objects.Message;
import org.telegram.telegrambots.bots.AbsSender;
diff --git a/telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/timedbot/TimedSendLongPollingBot.java b/telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/timedbot/TimedSendLongPollingBot.java
new file mode 100644
index 00000000..734c52a4
--- /dev/null
+++ b/telegrambots-extensions/src/main/java/org/telegram/telegrambots/bots/timedbot/TimedSendLongPollingBot.java
@@ -0,0 +1,218 @@
+package org.telegram.telegrambots.bots.timedbot;
+
+import org.telegram.telegrambots.bots.TelegramLongPollingBot;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Created by Daniil Nikanov aka JetCoder
+ */
+
+public abstract class TimedSendLongPollingBot extends TelegramLongPollingBot
+{
+ private static final long MANY_CHATS_SEND_INTERVAL = 33;
+ private static final long ONE_CHAT_SEND_INTERVAL = 1000;
+ private static final long CHAT_INACTIVE_INTERVAL = 1000 * 60 * 10;
+ private final Timer mSendTimer = new Timer(true);
+ private final ConcurrentHashMap mMessagesMap = new ConcurrentHashMap<>(32, 0.75f, 1);
+ private final ArrayList mSendQueues = new ArrayList<>();
+ private final AtomicBoolean mSendRequested = new AtomicBoolean(false);
+
+ private final class MessageSenderTask extends TimerTask
+ {
+ @Override
+ public void run()
+ {
+ //mSendRequested used for optimisation to not traverse all mMessagesMap 30 times per second all the time
+ if (!mSendRequested.getAndSet(false))
+ return;
+
+ long currentTime = System.currentTimeMillis();
+ mSendQueues.clear();
+ boolean processNext = false;
+
+ //First step - find all chats in which already allowed to send message (passed more than 1000 ms from previuos send)
+ Iterator> it = mMessagesMap.entrySet().iterator();
+ while (it.hasNext())
+ {
+ MessageQueue queue = it.next().getValue();
+ int state = queue.getCurrentState(currentTime); //Actual check here
+ if (state == MessageQueue.GET_MESSAGE)
+ {
+ mSendQueues.add(queue);
+ processNext = true;
+ }
+ else if (state == MessageQueue.WAIT)
+ {
+ processNext = true;
+ }
+ else if (state == MessageQueue.DELETE)
+ {
+ it.remove();
+ }
+ }
+
+ //If any of chats are in state WAIT or GET_MESSAGE, request another iteration
+ if (processNext)
+ mSendRequested.set(true);
+
+ //Second step - find oldest waiting queue and peek it's message
+ MessageQueue sendQueue = null;
+ long oldestPutTime = Long.MAX_VALUE;
+ for (int i = 0; i < mSendQueues.size(); i++)
+ {
+ MessageQueue queue = mSendQueues.get(i);
+ long putTime = queue.getPutTime();
+ if (putTime < oldestPutTime)
+ {
+ oldestPutTime = putTime;
+ sendQueue = queue;
+ }
+ }
+ if (sendQueue == null) //Possible if on first step wasn't found any chats in state GET_MESSAGE
+ return;
+
+ //Invoke the send callback. ChatId is passed for possible additional processing
+ sendMessageCallback(sendQueue.getChatId(), sendQueue.getMessage(currentTime));
+ }
+ }
+
+ private static class MessageQueue
+ {
+ public static final int EMPTY = 0; //Queue is empty
+ public static final int WAIT = 1; //Queue has message(s) but not yet allowed to send
+ public static final int DELETE = 2; //No one message of given queue was sent longer than CHAT_INACTIVE_INTERVAL, delete for optimisation
+ public static final int GET_MESSAGE = 3; //Queue has message(s) and ready to send
+ private final ConcurrentLinkedQueue