Merge pull request #86 from rubenlagus/dev

Update v2.3.3.2
This commit is contained in:
Ruben Bermudez 2016-05-31 01:15:57 +02:00
commit 946b5438ad
29 changed files with 543 additions and 182 deletions

BIN
.DS_Store vendored

Binary file not shown.

17
.gitignore vendored
View File

@ -8,28 +8,33 @@ release.properties
dependency-reduced-pom.xml dependency-reduced-pom.xml
buildNumber.properties buildNumber.properties
.mvn/timing.properties .mvn/timing.properties
### Java template ### Java template
*.class *.class
# Mobile Tools for Java (J2ME) ### Mobile Tools for Java (J2ME)
.mtj.tmp/ .mtj.tmp/
# Package Files # ### Package Files #
*.jar *.jar
*.war *.war
*.ear *.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml ### virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid* hs_err_pid*
# logs files ### logs files
*.log *.log
# Certs ### Certs
*.jks *.jks
*.cer *.cer
*.pem *.pem
# IDE files ### IDE files
.idea/ .idea/
copyright/
*.iml *.iml
#File System specific files
.DS_STORE

8
.travis.yml Normal file
View File

@ -0,0 +1,8 @@
language: java
jdk:
- oraclejdk8
script: mvn clean compile package
notifications:
webhooks:
secure: "jC7dK/x67ONWQoeLZg4HfW0mHhcjDerJjsLLkrbcpltiqAbw2p7XfY8Pk4zHoD72a+5o6WKu5WvYvZ4OdldnjP8Y6ZUbliQ5RG3olg3gFDoe0+sc3geeb4HRYVcdI20O0z4Bup/qO0ZihxPBc0D5IpHmFxlaqlZG0WeST4CicU8PNnBh6aX9/VMrwXhkMb2vfzmjmIhMbx/uK5+93bnk/vR5Uwu00/Yd2cTAAWMaqK1MRdtR0WLbxlUNsprEfCjYiH3n9XZnlKXs6cLC8EOU436Wx7aepiAszW0wWFMe/7nVqOqztrQiKNvL0qXYwlQf0BLechJdt458EopL9QCu687TNDFYvg1yERAmCRiaayYZcX3PbUSMr6H5Q+Odntjs3XKyzfgSqqlkgf/SAND5jny1/1uteVoplZmFXuZFIiK4H8Rl2ezy1/8pnbp+JD3YEfiA2NuRjlou1BZXyMhiqqVXbrJqk/tXF6yZSkDlYJfNsWzRCGfra4B6JjEvUP927chIFm1ii3dgNstXDo1evV46+OQQO4HKvMPdtU2FPvWpPlkTxnmpZRZjB+bjmybluJdWT3E+e1C3wm7YbRe3vporhpfNPlnod6M0G10y9CKzl9Fbcku6X1FtM+IoPO/aqZ8S4/CBZoYEuR/Nk6bcvsYouxtyIl6PSuF9E8YjpJE="
email: false

View File

@ -1,4 +1,5 @@
# Telegram Bot Java Library # Telegram Bot Java Library
[![Build Status](https://travis-ci.org/rubenlagus/TelegramBots.svg?branch=master)](https://travis-ci.org/rubenlagus/TelegramBots)
[![Telegram](http://trellobot.doomdns.org/telegrambadge.svg)](https://telegram.me/JavaBotsApi) [![Telegram](http://trellobot.doomdns.org/telegrambadge.svg)](https://telegram.me/JavaBotsApi)
A simple to use library to create Telegram Bots in Java A simple to use library to create Telegram Bots in Java
@ -9,13 +10,11 @@ Feel free to fork this project, work on it and then make a pull request against
Please, **DO NOT PUSH ANY TOKEN OR API KEY**, I will never accept a pull request with that content. Please, **DO NOT PUSH ANY TOKEN OR API KEY**, I will never accept a pull request with that content.
## Webhooks vs GetUpdates ## Webhooks vs GetUpdates
Both ways are supported (but I still didn't tested webhooks). Both ways are supported, but I recommend long polling method.
I recommend using getUpdates methods.
## Usage ## Usage
Just import add the library to your project using [Maven, Gradly, ...](https://jitpack.io/#rubenlagus/TelegramBots/v2.3.3.1) or download the jar(including all dependencies) from [here](https://github.com/rubenlagus/TelegramBots/releases/tag/v2.3.3.1) Just import add the library to your project using [Maven, Gradly, ...](https://jitpack.io/#rubenlagus/TelegramBots/v2.3.3.2) or download the jar(including all dependencies) from [here](https://github.com/rubenlagus/TelegramBots/releases/tag/v2.3.3.2)
In order to use Long Polling mode, just create your own bot extending `org.telegram.telegrambots.bots.TelegramLongPollingBot`. In order to use Long Polling mode, just create your own bot extending `org.telegram.telegrambots.bots.TelegramLongPollingBot`.
@ -50,15 +49,15 @@ Once done, you just need to creat a `org.telegram.telegrambots.TelegramBotsApi`a
## Example bots ## Example bots
Open them and send them */help* command to get some information about their capabilities: Open them and send them */help* command to get some information about their capabilities:
https://telegram.me/weatherbot https://telegram.me/weatherbot (**Use custom keyboards**)
https://telegram.me/directionsbot https://telegram.me/directionsbot (**Basic messages**)
https://telegram.me/filesbot https://telegram.me/filesbot (**Send files by file_id**)
https://telegram.me/TGlanguagesbot https://telegram.me/TGlanguagesbot (**Send files uploding them**)
https://telegram.me/RaeBot https://telegram.me/RaeBot (**Inline support**)
You can see code for those bots at [TelegramBotsExample](https://github.com/rubenlagus/TelegramBotsExample) project. You can see code for those bots at [TelegramBotsExample](https://github.com/rubenlagus/TelegramBotsExample) project.

View File

@ -1,5 +1,8 @@
# How to use TelegramBots with Eclipse # How to use TelegramBots with Eclipse
If you **don't** need to modify the sources, you can just download the jar file from [here](https://github.com/rubenlagus/TelegramBots/releases) and import it as an external library.
If you need to modify the sources, follow these steps:
### Step 1: Install Maven ### Step 1: Install Maven
To get started, you need to install the Maven-Plugin for Eclipse. Click on Help > Eclipse Marketplace. After it finished loading, search for “Maven”. To get started, you need to install the Maven-Plugin for Eclipse. Click on Help > Eclipse Marketplace. After it finished loading, search for “Maven”.
@ -16,11 +19,9 @@ Now lets setup the project-folder. Go to your Eclipse-Workspace and create a
To import your project into the workspace you have to go to File > Import > (Folder) Maven > Existing Maven Projects > Next. Choose the folder, you have created in Step 3. In my case: **“TelegramBotApi”**. Click on finish and let Maven import the dependencies. To import your project into the workspace you have to go to File > Import > (Folder) Maven > Existing Maven Projects > Next. Choose the folder, you have created in Step 3. In my case: **“TelegramBotApi”**. Click on finish and let Maven import the dependencies.
### Step 5: Setting the compliance level ### Step 5: Setting the compliance level
In this last step you need to change the Compiler compliance level. To do this right-click on your Project (in my case **“TelegramBotApi”**) > Properties > Java Compiler. Uncheck the “Use compliance from…” if necessary and set it to 1.7 In this last step you need to change the Compiler compliance level. To do this right-click on your Project (in my case **“TelegramBotApi”**) > Properties > Java Compiler. Uncheck the “Use compliance from…” if necessary and set it to 1.8
*Now you are done. Everything should work fine. You need to set your Bot-Token in the BotConfig.java, afterwards you can run Main.java to check.* *Now you are done. Everything should work fine.*
**For a better intstruction sheet, visit [Google Drive]**
[Google Drive]:https://goo.gl/5jd40w [Google Drive]:https://goo.gl/5jd40w
[here]:https://github.com/rubenlagus/TelegramBots/archive/master.zip [here]:https://github.com/rubenlagus/TelegramBots/archive/master.zip

148
pom.xml
View File

@ -6,7 +6,7 @@
<packaging>jar</packaging> <packaging>jar</packaging>
<groupId>org.telegram</groupId> <groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId> <artifactId>telegrambots</artifactId>
<version>2.3.3.1</version> <version>2.3.3.2</version>
<name>Telegram Bots</name> <name>Telegram Bots</name>
<url>https://telegram.me/JavaBotsApi</url> <url>https://telegram.me/JavaBotsApi</url>
@ -26,6 +26,7 @@
<jerseybundle.version>1.19.1</jerseybundle.version> <jerseybundle.version>1.19.1</jerseybundle.version>
<httpcompontents.version>4.5.2</httpcompontents.version> <httpcompontents.version>4.5.2</httpcompontents.version>
<json.version>20160212</json.version> <json.version>20160212</json.version>
<jackson.version>2.7.4</jackson.version>
</properties> </properties>
<dependencyManagement> <dependencyManagement>
@ -44,6 +45,7 @@
<dependency> <dependency>
<groupId>org.glassfish.jersey.containers</groupId> <groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId> <artifactId>jersey-container-grizzly2-http</artifactId>
<version>${jersey.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.glassfish.jersey.media</groupId> <groupId>org.glassfish.jersey.media</groupId>
@ -83,91 +85,69 @@
<finalName>${project.artifactId}-${project.version}</finalName> <finalName>${project.artifactId}-${project.version}</finalName>
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory> <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory> <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>clean-project</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<id>attach-javadocs</id>
<phase>site</phase>
<goals>
<goal>javadoc-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement> <pluginManagement>
<plugins> <plugins>
<plugin> <!-- Create sources.jar -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>org.telegram.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>org.telegram.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>

BIN
src/.DS_Store vendored

Binary file not shown.

BIN
src/main/.DS_Store vendored

Binary file not shown.

Binary file not shown.

View File

@ -8,6 +8,7 @@ package org.telegram.telegrambots;
*/ */
public class Constants { public class Constants {
public static final String BASEURL = "https://api.telegram.org/bot"; public static final String BASEURL = "https://api.telegram.org/bot";
public static final int GETUPDATESTIMEOUT = 50;
public static final String RESPONSEFIELDOK = "ok"; public static final String RESPONSEFIELDOK = "ok";
public static final String RESPONSEFIELDRESULT = "result"; public static final String RESPONSEFIELDRESULT = "result";
public static final String ERRORDESCRIPTIONFIELD = "description"; public static final String ERRORDESCRIPTIONFIELD = "description";

View File

@ -21,6 +21,7 @@ import org.telegram.telegrambots.updatesreceivers.Webhook;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import static org.telegram.telegrambots.Constants.ERRORCODEFIELD; import static org.telegram.telegrambots.Constants.ERRORCODEFIELD;
import static org.telegram.telegrambots.Constants.ERRORDESCRIPTIONFIELD; import static org.telegram.telegrambots.Constants.ERRORDESCRIPTIONFIELD;
@ -32,11 +33,11 @@ import static org.telegram.telegrambots.Constants.ERRORDESCRIPTIONFIELD;
* @date 14 of January of 2016 * @date 14 of January of 2016
*/ */
public class TelegramBotsApi { public class TelegramBotsApi {
private static final String webhookUrlFormat = "{0}callback/";
private boolean useWebhook; ///< private boolean useWebhook; ///<
private Webhook webhook; ///< private Webhook webhook; ///<
private String extrenalUrl; ///< private String extrenalUrl; ///<
private String pathToCertificate; ///< private String pathToCertificate; ///<
private String publicCertificateName; ///<
/** /**
* *
@ -52,6 +53,13 @@ public class TelegramBotsApi {
* @param internalUrl * @param internalUrl
*/ */
public TelegramBotsApi(String keyStore, String keyStorePassword, String externalUrl, String internalUrl) throws TelegramApiException { public TelegramBotsApi(String keyStore, String keyStorePassword, String externalUrl, String internalUrl) throws TelegramApiException {
if (externalUrl == null || externalUrl.isEmpty()) {
throw new TelegramApiException("Parameter externalUrl can not be null or empty");
}
if (internalUrl == null || internalUrl.isEmpty()) {
throw new TelegramApiException("Parameter internalUrl can not be null or empty");
}
this.useWebhook = true; this.useWebhook = true;
this.extrenalUrl = fixExternalUrl(externalUrl); this.extrenalUrl = fixExternalUrl(externalUrl);
webhook = new Webhook(keyStore, keyStorePassword, internalUrl); webhook = new Webhook(keyStore, keyStorePassword, internalUrl);
@ -64,14 +72,18 @@ public class TelegramBotsApi {
* @param keyStorePassword * @param keyStorePassword
* @param externalUrl * @param externalUrl
* @param internalUrl * @param internalUrl
* @param pathToCertificate * @param pathToCertificate Full path until .pem public certificate keys
* @param publicCertificateName
*/ */
public TelegramBotsApi(String keyStore, String keyStorePassword, String externalUrl, String internalUrl, String pathToCertificate, String publicCertificateName) throws TelegramApiException { public TelegramBotsApi(String keyStore, String keyStorePassword, String externalUrl, String internalUrl, String pathToCertificate) throws TelegramApiException {
if (externalUrl == null || externalUrl.isEmpty()) {
throw new TelegramApiException("Parameter externalUrl can not be null or empty");
}
if (internalUrl == null || internalUrl.isEmpty()) {
throw new TelegramApiException("Parameter internalUrl can not be null or empty");
}
this.useWebhook = true; this.useWebhook = true;
this.extrenalUrl = fixExternalUrl(externalUrl); this.extrenalUrl = fixExternalUrl(externalUrl);
this.pathToCertificate = pathToCertificate; this.pathToCertificate = pathToCertificate;
this.publicCertificateName = publicCertificateName;
webhook = new Webhook(keyStore, keyStorePassword, internalUrl); webhook = new Webhook(keyStore, keyStorePassword, internalUrl);
webhook.startServer(); webhook.startServer();
} }
@ -85,7 +97,7 @@ public class TelegramBotsApi {
if (externalUrl != null && !externalUrl.endsWith("/")) { if (externalUrl != null && !externalUrl.endsWith("/")) {
externalUrl = externalUrl + "/"; externalUrl = externalUrl + "/";
} }
return externalUrl; return MessageFormat.format(webhookUrlFormat, externalUrl);
} }
/** /**
@ -96,7 +108,7 @@ public class TelegramBotsApi {
* @param publicCertificateName * @param publicCertificateName
* @throws TelegramApiException * @throws TelegramApiException
*/ */
private static void setWebhook(String webHookURL, String botToken, String publicCertificatePath, String publicCertificateName) throws TelegramApiException { private static void setWebhook(String webHookURL, String botToken, String publicCertificatePath) throws TelegramApiException {
try (CloseableHttpClient httpclient = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build()) { try (CloseableHttpClient httpclient = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build()) {
String url = Constants.BASEURL + botToken + "/" + SetWebhook.PATH; String url = Constants.BASEURL + botToken + "/" + SetWebhook.PATH;
@ -104,7 +116,10 @@ public class TelegramBotsApi {
MultipartEntityBuilder builder = MultipartEntityBuilder.create(); MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody(SetWebhook.URL_FIELD, webHookURL); builder.addTextBody(SetWebhook.URL_FIELD, webHookURL);
if (publicCertificatePath != null) { if (publicCertificatePath != null) {
builder.addBinaryBody(SetWebhook.CERTIFICATE_FIELD, new File(publicCertificatePath), ContentType.APPLICATION_OCTET_STREAM, publicCertificateName); File certificate = new File(publicCertificatePath);
if (certificate.exists()) {
builder.addBinaryBody(SetWebhook.CERTIFICATE_FIELD, certificate, ContentType.TEXT_PLAIN, certificate.getName());
}
} }
HttpEntity multipart = builder.build(); HttpEntity multipart = builder.build();
httppost.setEntity(multipart); httppost.setEntity(multipart);
@ -126,10 +141,10 @@ public class TelegramBotsApi {
/** /**
* Register a bot. The Bot Session is started immediately, and may be disconnected by calling close. * Register a bot. The Bot Session is started immediately, and may be disconnected by calling close.
* @param bot * @param bot the bot to register
*/ */
public BotSession registerBot(TelegramLongPollingBot bot) throws TelegramApiException { public BotSession registerBot(TelegramLongPollingBot bot) throws TelegramApiException {
setWebhook(bot.getBotToken()); setWebhook(bot.getBotToken(), null);
return new BotSession(bot.getBotToken(), bot); return new BotSession(bot.getBotToken(), bot);
} }
@ -140,7 +155,7 @@ public class TelegramBotsApi {
public void registerBot(TelegramWebhookBot bot) throws TelegramApiException { public void registerBot(TelegramWebhookBot bot) throws TelegramApiException {
if (useWebhook) { if (useWebhook) {
webhook.registerWebhook(bot); webhook.registerWebhook(bot);
setWebhook(bot.getBotToken()); setWebhook(bot.getBotToken(), bot.getBotPath());
} }
} }
@ -148,10 +163,11 @@ public class TelegramBotsApi {
* *
* @param botToken * @param botToken
*/ */
private void setWebhook(String botToken) throws TelegramApiException { private void setWebhook(String botToken, String urlPath) throws TelegramApiException {
if (botToken == null) { if (botToken == null) {
throw new TelegramApiException("Parameter botToken can not be null"); throw new TelegramApiException("Parameter botToken can not be null");
} }
setWebhook(extrenalUrl == null ? "" : extrenalUrl, botToken, pathToCertificate, publicCertificateName); String completeExternalUrl = urlPath == null ? "" : extrenalUrl + urlPath;
setWebhook(completeExternalUrl, botToken, pathToCertificate);
} }
} }

View File

@ -381,6 +381,18 @@ public class Message implements IBotApiObject {
return text != null && !text.isEmpty(); return text != null && !text.isEmpty();
} }
public boolean isCommand() {
if (hasText() && entities != null) {
for (MessageEntity entity : entities) {
if (entity != null && entity.getOffset() == 0 &&
EntityType.BOTCOMMAND.equals(entity.getType())) {
return true;
}
}
}
return false;
}
public boolean hasDocument() { public boolean hasDocument() {
return this.document != null; return this.document != null;
} }

View File

@ -107,9 +107,9 @@ public class InlineQueryResultVoice implements InlineQueryResult {
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject = new JSONObject();
jsonObject.put(TYPE_FIELD, type); jsonObject.put(TYPE_FIELD, type);
jsonObject.put(ID_FIELD, this.id); jsonObject.put(ID_FIELD, this.id);
jsonObject.put(VOICE_DURATION_FIELD, voiceUrl); jsonObject.put(VOICEURL_FIELD, voiceUrl);
if (title != null) { if (title != null) {
jsonObject.put(TITLE_FIELD, this.title); jsonObject.put(TITLE_FIELD, title);
} }
if (voiceDuration != null) { if (voiceDuration != null) {
jsonObject.put(VOICE_DURATION_FIELD, voiceDuration); jsonObject.put(VOICE_DURATION_FIELD, voiceDuration);
@ -130,7 +130,7 @@ public class InlineQueryResultVoice implements InlineQueryResult {
gen.writeStringField(ID_FIELD, id); gen.writeStringField(ID_FIELD, id);
gen.writeStringField(VOICEURL_FIELD, voiceUrl); gen.writeStringField(VOICEURL_FIELD, voiceUrl);
if (title != null) { if (title != null) {
gen.writeStringField(TITLE_FIELD, this.title); gen.writeStringField(TITLE_FIELD, title);
} }
if (voiceDuration != null) { if (voiceDuration != null) {
gen.writeNumberField(VOICE_DURATION_FIELD, voiceDuration); gen.writeNumberField(VOICE_DURATION_FIELD, voiceDuration);

View File

@ -87,7 +87,7 @@ public class InlineQueryResultCachedAudio implements InlineQueryResult {
jsonObject.put(ID_FIELD, id); jsonObject.put(ID_FIELD, id);
jsonObject.put(AUDIO_FILE_ID_FIELD, audioFileId); jsonObject.put(AUDIO_FILE_ID_FIELD, audioFileId);
if (replyMarkup != null) { if (replyMarkup != null) {
jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup); jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup.toJson());
} }
if (inputMessageContent != null) { if (inputMessageContent != null) {
jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent); jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent);

View File

@ -128,7 +128,7 @@ public class InlineQueryResultCachedDocument implements InlineQueryResult {
jsonObject.put(DESCRIPTION_FIELD, this.description); jsonObject.put(DESCRIPTION_FIELD, this.description);
} }
if (replyMarkup != null) { if (replyMarkup != null) {
jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup); jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup.toJson());
} }
if (inputMessageContent != null) { if (inputMessageContent != null) {
jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent); jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent);

View File

@ -115,7 +115,7 @@ public class InlineQueryResultCachedGif implements InlineQueryResult {
jsonObject.put(CAPTION_FIELD, this.caption); jsonObject.put(CAPTION_FIELD, this.caption);
} }
if (replyMarkup != null) { if (replyMarkup != null) {
jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup); jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup.toJson());
} }
if (inputMessageContent != null) { if (inputMessageContent != null) {
jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent); jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent);

View File

@ -115,7 +115,7 @@ public class InlineQueryResultCachedMpeg4Gif implements InlineQueryResult {
jsonObject.put(CAPTION_FIELD, this.caption); jsonObject.put(CAPTION_FIELD, this.caption);
} }
if (replyMarkup != null) { if (replyMarkup != null) {
jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup); jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup.toJson());
} }
if (inputMessageContent != null) { if (inputMessageContent != null) {
jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent); jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent);

View File

@ -130,7 +130,7 @@ public class InlineQueryResultCachedPhoto implements InlineQueryResult {
jsonObject.put(CAPTION_FIELD, this.caption); jsonObject.put(CAPTION_FIELD, this.caption);
} }
if (replyMarkup != null) { if (replyMarkup != null) {
jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup); jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup.toJson());
} }
if (inputMessageContent != null) { if (inputMessageContent != null) {
jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent); jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent);

View File

@ -87,7 +87,7 @@ public class InlineQueryResultCachedSticker implements InlineQueryResult {
jsonObject.put(ID_FIELD, this.id); jsonObject.put(ID_FIELD, this.id);
jsonObject.put(STICKER_FILE_ID_FIELD, stickerFileId); jsonObject.put(STICKER_FILE_ID_FIELD, stickerFileId);
if (replyMarkup != null) { if (replyMarkup != null) {
jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup); jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup.toJson());
} }
if (inputMessageContent != null) { if (inputMessageContent != null) {
jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent); jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent);

View File

@ -130,7 +130,7 @@ public class InlineQueryResultCachedVideo implements InlineQueryResult {
jsonObject.put(DESCRIPTION_FIELD, this.description); jsonObject.put(DESCRIPTION_FIELD, this.description);
} }
if (replyMarkup != null) { if (replyMarkup != null) {
jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup); jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup.toJson());
} }
if (inputMessageContent != null) { if (inputMessageContent != null) {
jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent); jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent);

View File

@ -102,7 +102,7 @@ public class InlineQueryResultCachedVoice implements InlineQueryResult {
jsonObject.put(TITLE_FIELD, this.title); jsonObject.put(TITLE_FIELD, this.title);
} }
if (replyMarkup != null) { if (replyMarkup != null) {
jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup); jsonObject.put(REPLY_MARKUP_FIELD, replyMarkup.toJson());
} }
if (inputMessageContent != null) { if (inputMessageContent != null) {
jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent); jsonObject.put(INPUTMESSAGECONTENT_FIELD, inputMessageContent);

View File

@ -104,7 +104,7 @@ public abstract class AbsSender {
throw new TelegramApiException("Parameter sendMessage can not be null"); throw new TelegramApiException("Parameter sendMessage can not be null");
} }
return (Message) sendApiMethod(sendMessage); return sendApiMethod(sendMessage);
} }
public Boolean answerInlineQuery(AnswerInlineQuery answerInlineQuery) throws TelegramApiException { public Boolean answerInlineQuery(AnswerInlineQuery answerInlineQuery) throws TelegramApiException {
@ -112,7 +112,7 @@ public abstract class AbsSender {
throw new TelegramApiException("Parameter answerInlineQuery can not be null"); throw new TelegramApiException("Parameter answerInlineQuery can not be null");
} }
return (Boolean) sendApiMethod(answerInlineQuery); return sendApiMethod(answerInlineQuery);
} }
public Boolean sendChatAction(SendChatAction sendChatAction) throws TelegramApiException { public Boolean sendChatAction(SendChatAction sendChatAction) throws TelegramApiException {
@ -120,7 +120,7 @@ public abstract class AbsSender {
throw new TelegramApiException("Parameter sendChatAction can not be null"); throw new TelegramApiException("Parameter sendChatAction can not be null");
} }
return (Boolean) sendApiMethod(sendChatAction); return sendApiMethod(sendChatAction);
} }
public Message forwardMessage(ForwardMessage forwardMessage) throws TelegramApiException { public Message forwardMessage(ForwardMessage forwardMessage) throws TelegramApiException {
@ -128,7 +128,7 @@ public abstract class AbsSender {
throw new TelegramApiException("Parameter forwardMessage can not be null"); throw new TelegramApiException("Parameter forwardMessage can not be null");
} }
return (Message) sendApiMethod(forwardMessage); return sendApiMethod(forwardMessage);
} }
public Message sendLocation(SendLocation sendLocation) throws TelegramApiException { public Message sendLocation(SendLocation sendLocation) throws TelegramApiException {
@ -136,7 +136,7 @@ public abstract class AbsSender {
throw new TelegramApiException("Parameter sendLocation can not be null"); throw new TelegramApiException("Parameter sendLocation can not be null");
} }
return (Message) sendApiMethod(sendLocation); return sendApiMethod(sendLocation);
} }
public Message sendVenue(SendVenue sendVenue) throws TelegramApiException { public Message sendVenue(SendVenue sendVenue) throws TelegramApiException {
@ -144,7 +144,7 @@ public abstract class AbsSender {
throw new TelegramApiException("Parameter sendVenue can not be null"); throw new TelegramApiException("Parameter sendVenue can not be null");
} }
return (Message) sendApiMethod(sendVenue); return sendApiMethod(sendVenue);
} }
public Message sendContact(SendContact sendContact) throws TelegramApiException { public Message sendContact(SendContact sendContact) throws TelegramApiException {
@ -152,84 +152,84 @@ public abstract class AbsSender {
throw new TelegramApiException("Parameter sendContact can not be null"); throw new TelegramApiException("Parameter sendContact can not be null");
} }
return (Message) sendApiMethod(sendContact); return sendApiMethod(sendContact);
} }
public Boolean kickMember(KickChatMember kickChatMember) throws TelegramApiException { public Boolean kickMember(KickChatMember kickChatMember) throws TelegramApiException {
if (kickChatMember == null) { if (kickChatMember == null) {
throw new TelegramApiException("Parameter kickChatMember can not be null"); throw new TelegramApiException("Parameter kickChatMember can not be null");
} }
return (Boolean) sendApiMethod(kickChatMember); return sendApiMethod(kickChatMember);
} }
public Boolean unbanMember(UnbanChatMember unbanChatMember) throws TelegramApiException { public Boolean unbanMember(UnbanChatMember unbanChatMember) throws TelegramApiException {
if (unbanChatMember == null) { if (unbanChatMember == null) {
throw new TelegramApiException("Parameter unbanChatMember can not be null"); throw new TelegramApiException("Parameter unbanChatMember can not be null");
} }
return (Boolean) sendApiMethod(unbanChatMember); return sendApiMethod(unbanChatMember);
} }
public Boolean leaveChat(LeaveChat leaveChat) throws TelegramApiException { public Boolean leaveChat(LeaveChat leaveChat) throws TelegramApiException {
if (leaveChat == null) { if (leaveChat == null) {
throw new TelegramApiException("Parameter leaveChat can not be null"); throw new TelegramApiException("Parameter leaveChat can not be null");
} }
return (Boolean) sendApiMethod(leaveChat); return sendApiMethod(leaveChat);
} }
public Chat getChat(GetChat getChat) throws TelegramApiException { public Chat getChat(GetChat getChat) throws TelegramApiException {
if (getChat == null) { if (getChat == null) {
throw new TelegramApiException("Parameter getChat can not be null"); throw new TelegramApiException("Parameter getChat can not be null");
} }
return (Chat) sendApiMethod(getChat); return sendApiMethod(getChat);
} }
public List<ChatMember> getChatAdministrators(GetChatAdministrators getChatAdministrators) throws TelegramApiException { public List<ChatMember> getChatAdministrators(GetChatAdministrators getChatAdministrators) throws TelegramApiException {
if (getChatAdministrators == null) { if (getChatAdministrators == null) {
throw new TelegramApiException("Parameter getChatAdministrators can not be null"); throw new TelegramApiException("Parameter getChatAdministrators can not be null");
} }
return (ArrayList<ChatMember>) sendApiMethod(getChatAdministrators); return sendApiMethod(getChatAdministrators);
} }
public ChatMember getChatMember(GetChatMember getChatMember) throws TelegramApiException { public ChatMember getChatMember(GetChatMember getChatMember) throws TelegramApiException {
if (getChatMember == null) { if (getChatMember == null) {
throw new TelegramApiException("Parameter getChatMember can not be null"); throw new TelegramApiException("Parameter getChatMember can not be null");
} }
return (ChatMember) sendApiMethod(getChatMember); return sendApiMethod(getChatMember);
} }
public Integer getChatMemberCount(GetChatMemberCount getChatMemberCount) throws TelegramApiException { public Integer getChatMemberCount(GetChatMemberCount getChatMemberCount) throws TelegramApiException {
if (getChatMemberCount == null) { if (getChatMemberCount == null) {
throw new TelegramApiException("Parameter getChatMemberCount can not be null"); throw new TelegramApiException("Parameter getChatMemberCount can not be null");
} }
return (Integer) sendApiMethod(getChatMemberCount); return sendApiMethod(getChatMemberCount);
} }
public Message editMessageText(EditMessageText editMessageText) throws TelegramApiException { public Message editMessageText(EditMessageText editMessageText) throws TelegramApiException {
if (editMessageText == null) { if (editMessageText == null) {
throw new TelegramApiException("Parameter editMessageText can not be null"); throw new TelegramApiException("Parameter editMessageText can not be null");
} }
return (Message) sendApiMethod(editMessageText); return sendApiMethod(editMessageText);
} }
public Message editMessageCaption(EditMessageCaption editMessageCaption) throws TelegramApiException { public Message editMessageCaption(EditMessageCaption editMessageCaption) throws TelegramApiException {
if (editMessageCaption == null) { if (editMessageCaption == null) {
throw new TelegramApiException("Parameter editMessageCaption can not be null"); throw new TelegramApiException("Parameter editMessageCaption can not be null");
} }
return (Message) sendApiMethod(editMessageCaption); return sendApiMethod(editMessageCaption);
} }
public Message editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup) throws TelegramApiException { public Message editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup) throws TelegramApiException {
if (editMessageReplyMarkup == null) { if (editMessageReplyMarkup == null) {
throw new TelegramApiException("Parameter editMessageReplyMarkup can not be null"); throw new TelegramApiException("Parameter editMessageReplyMarkup can not be null");
} }
return (Message) sendApiMethod(editMessageReplyMarkup); return sendApiMethod(editMessageReplyMarkup);
} }
public Boolean answerCallbackQuery(AnswerCallbackQuery answerCallbackQuery) throws TelegramApiException { public Boolean answerCallbackQuery(AnswerCallbackQuery answerCallbackQuery) throws TelegramApiException {
if (answerCallbackQuery == null) { if (answerCallbackQuery == null) {
throw new TelegramApiException("Parameter answerCallbackQuery can not be null"); throw new TelegramApiException("Parameter answerCallbackQuery can not be null");
} }
return (Boolean) sendApiMethod(answerCallbackQuery); return sendApiMethod(answerCallbackQuery);
} }
public UserProfilePhotos getUserProfilePhotos(GetUserProfilePhotos getUserProfilePhotos) throws TelegramApiException { public UserProfilePhotos getUserProfilePhotos(GetUserProfilePhotos getUserProfilePhotos) throws TelegramApiException {
@ -237,7 +237,7 @@ public abstract class AbsSender {
throw new TelegramApiException("Parameter getUserProfilePhotos can not be null"); throw new TelegramApiException("Parameter getUserProfilePhotos can not be null");
} }
return (UserProfilePhotos) sendApiMethod(getUserProfilePhotos); return sendApiMethod(getUserProfilePhotos);
} }
public File getFile(GetFile getFile) throws TelegramApiException{ public File getFile(GetFile getFile) throws TelegramApiException{
@ -247,13 +247,13 @@ public abstract class AbsSender {
else if(getFile.getFileId() == null){ else if(getFile.getFileId() == null){
throw new TelegramApiException("Attribute file_id in parameter getFile can not be null"); throw new TelegramApiException("Attribute file_id in parameter getFile can not be null");
} }
return (File) sendApiMethod(getFile); return sendApiMethod(getFile);
} }
public User getMe() throws TelegramApiException { public User getMe() throws TelegramApiException {
GetMe getMe = new GetMe(); GetMe getMe = new GetMe();
return (User) sendApiMethod(getMe); return sendApiMethod(getMe);
} }
// Send Requests Async // Send Requests Async
@ -928,7 +928,7 @@ public abstract class AbsSender {
}); });
} }
private Serializable sendApiMethod(BotApiMethod method) throws TelegramApiException { private <T extends Serializable> T sendApiMethod(BotApiMethod<T> method) throws TelegramApiException {
String responseContent; String responseContent;
try { try {
String url = getBaseUrl() + method.getPath(); String url = getBaseUrl() + method.getPath();

View File

@ -0,0 +1,82 @@
package org.telegram.telegrambots.bots;
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 java.util.Collection;
import java.util.Map;
import java.util.function.BiConsumer;
/**
* This class adds command functionality to the TelegramLongPollingBot
*
* @author tschulz
*/
public abstract class TelegramLongPollingCommandBot extends TelegramLongPollingBot implements ICommandRegistry {
private final CommandRegistry commandRegistry;
/**
* construct creates CommandRegistry for this bot.
* Use ICommandRegistry's methods on this bot to register commands
*/
public TelegramLongPollingCommandBot() {
super();
this.commandRegistry = new CommandRegistry();
}
@Override
public final void onUpdateReceived(Update update) {
if (update.hasMessage()) {
Message message = update.getMessage();
if (message.isCommand()) {
if (commandRegistry.executeCommand(this, message)) {
return;
}
}
}
processNonCommandUpdate(update);
}
@Override
public final boolean register(BotCommand botCommand) {
return commandRegistry.register(botCommand);
}
@Override
public final Map<BotCommand, Boolean> registerAll(BotCommand... botCommands) {
return commandRegistry.registerAll(botCommands);
}
@Override
public final boolean deregister(BotCommand botCommand) {
return commandRegistry.deregister(botCommand);
}
@Override
public final Map<BotCommand, Boolean> deregisterAll(BotCommand... botCommands) {
return commandRegistry.deregisterAll(botCommands);
}
@Override
public final Collection<BotCommand> getRegisteredCommands() {
return commandRegistry.getRegisteredCommands();
}
@Override
public void registerDefaultAction(BiConsumer<AbsSender, Message> defaultConsumer) {
commandRegistry.registerDefaultAction(defaultConsumer);
}
/**
* Process all updates, that are not commands.
* @warning Commands that have valid syntax but are not registered on this bot,
* won't be forwarded to this method <b>if a default action is present</b>.
*
* @param update the update
*/
public abstract void processNonCommandUpdate(Update update);
}

View File

@ -0,0 +1,76 @@
package org.telegram.telegrambots.bots.commands;
import org.telegram.telegrambots.api.objects.Chat;
import org.telegram.telegrambots.bots.AbsSender;
/**
* Representation of a command, which can be executed
*
* @author tschulz
*/
public abstract class BotCommand {
public final static String COMMAND_INIT_CHARACTER = "/";
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
*
* @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) {
if (commandIdentifier == null || commandIdentifier.isEmpty()) {
throw new IllegalArgumentException("commandIdentifier for command cannot be null or empty");
}
if (commandIdentifier.startsWith(COMMAND_INIT_CHARACTER)) {
commandIdentifier = commandIdentifier.substring(1);
}
if (commandIdentifier.length() + 1 > COMMAND_MAX_LENGTH) {
throw new IllegalArgumentException("commandIdentifier cannot be longer than " + COMMAND_MAX_LENGTH + " (including " + COMMAND_INIT_CHARACTER + ")");
}
this.commandIdentifier = commandIdentifier.toLowerCase();
this.description = description;
}
/**
* Get the identifier of this command
*
* @return the identifier
*/
public final String getCommandIdentifier() {
return commandIdentifier;
}
/**
* Get the description of this command
*
* @return the description as String
*/
public final String getDescription() {
return description;
}
@Override
public String toString() {
return "<b>" + COMMAND_INIT_CHARACTER + getCommandIdentifier() +
"</b>\n" + getDescription();
}
/**
* Execute the command
*
* @param absSender absSender to send messages over
* @param chat the chat, to be able to send replies
* @param arguments passed arguments
*/
public abstract void execute(AbsSender absSender, Chat chat, String[] arguments);
}

View File

@ -0,0 +1,100 @@
package org.telegram.telegrambots.bots.commands;
import org.telegram.telegrambots.api.objects.Message;
import org.telegram.telegrambots.bots.AbsSender;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
/**
* @author tschulz
*/
public final class CommandRegistry implements ICommandRegistry {
private final Map<String, BotCommand> commandRegistryMap = new HashMap<>();
private BiConsumer<AbsSender, Message> defaultConsumer;
public CommandRegistry() {
}
@Override
public void registerDefaultAction(BiConsumer<AbsSender, Message> defaultConsumer) {
this.defaultConsumer = defaultConsumer;
}
@Override
public final boolean register(BotCommand botCommand) {
if (commandRegistryMap.containsKey(botCommand.getCommandIdentifier())) {
return false;
}
commandRegistryMap.put(botCommand.getCommandIdentifier(), botCommand);
return true;
}
@Override
public final Map<BotCommand, Boolean> registerAll(BotCommand... botCommands) {
Map<BotCommand, Boolean> resultMap = new HashMap<>(botCommands.length);
for (BotCommand botCommand : botCommands) {
resultMap.put(botCommand, register(botCommand));
}
return resultMap;
}
@Override
public final boolean deregister(BotCommand botCommand) {
if (commandRegistryMap.containsKey(botCommand.getCommandIdentifier())) {
commandRegistryMap.remove(botCommand.getCommandIdentifier());
return true;
}
return false;
}
@Override
public final Map<BotCommand, Boolean> deregisterAll(BotCommand... botCommands) {
Map<BotCommand, Boolean> resultMap = new HashMap<>(botCommands.length);
for (BotCommand botCommand : botCommands) {
resultMap.put(botCommand, deregister(botCommand));
}
return resultMap;
}
@Override
public final Collection<BotCommand> getRegisteredCommands() {
return commandRegistryMap.values();
}
/**
* 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 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.startsWith(BotCommand.COMMAND_INIT_CHARACTER)) {
String commandMessage = text.substring(1);
String[] commandSplit = commandMessage.split(BotCommand.COMMAND_PARAMETER_SEPARATOR);
String command = commandSplit[0];
if (commandRegistryMap.containsKey(command)) {
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;
}
}
}
return false;
}
}

View File

@ -0,0 +1,63 @@
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<AbsSender, Message> defaultConsumer);
/**
* register a command
*
* @param botCommand the command to register
* @return whether the command could be registered, was not already registered
*/
boolean register(BotCommand botCommand);
/**
* register multiple commands
*
* @param botCommands commands to register
* @return map with results of the command register per command
*/
Map<BotCommand, Boolean> registerAll(BotCommand... botCommands);
/**
* deregister a command
*
* @param botCommand the command to deregister
* @return whether the command could be deregistered, was registered
*/
boolean deregister(BotCommand botCommand);
/**
* deregister multiple commands
*
* @param botCommands commands to deregister
* @return map with results of the command deregistered per command
*/
Map<BotCommand, Boolean> deregisterAll(BotCommand... botCommands);
/**
* get a collection of all registered commands
*
* @return a collection of registered commands
*/
Collection<BotCommand> getRegisteredCommands();
}

View File

@ -14,12 +14,12 @@ import org.apache.http.util.EntityUtils;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.telegram.telegrambots.logging.BotLogger;
import org.telegram.telegrambots.Constants; import org.telegram.telegrambots.Constants;
import org.telegram.telegrambots.TelegramApiException; import org.telegram.telegrambots.TelegramApiException;
import org.telegram.telegrambots.api.methods.updates.GetUpdates; import org.telegram.telegrambots.api.methods.updates.GetUpdates;
import org.telegram.telegrambots.api.objects.Update; import org.telegram.telegrambots.api.objects.Update;
import org.telegram.telegrambots.bots.ITelegramLongPollingBot; import org.telegram.telegrambots.bots.ITelegramLongPollingBot;
import org.telegram.telegrambots.logging.BotLogger;
import java.io.IOException; import java.io.IOException;
import java.io.InvalidObjectException; import java.io.InvalidObjectException;
@ -27,9 +27,6 @@ import java.nio.charset.StandardCharsets;
import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static org.telegram.telegrambots.Constants.ERRORCODEFIELD;
import static org.telegram.telegrambots.Constants.ERRORDESCRIPTIONFIELD;
/** /**
* @author Ruben Bermudez * @author Ruben Bermudez
* @version 1.0 * @version 1.0
@ -54,49 +51,55 @@ public class BotSession {
public BotSession(String token, ITelegramLongPollingBot callback) { public BotSession(String token, ITelegramLongPollingBot callback) {
this.token = token; this.token = token;
this.callback = callback; this.callback = callback;
httpclient = HttpClientBuilder.create() httpclient = HttpClientBuilder.create()
.setSSLHostnameVerifier(new NoopHostnameVerifier()) .setSSLHostnameVerifier(new NoopHostnameVerifier())
.setConnectionTimeToLive(70, TimeUnit.SECONDS) .setConnectionTimeToLive(70, TimeUnit.SECONDS)
.setMaxConnTotal(100) .setMaxConnTotal(100)
.build(); .build();
requestConfig = RequestConfig.copy(RequestConfig.custom().build()) requestConfig = RequestConfig.copy(RequestConfig.custom().build())
.setSocketTimeout(SOCKET_TIMEOUT) .setSocketTimeout(SOCKET_TIMEOUT)
.setConnectTimeout(SOCKET_TIMEOUT) .setConnectTimeout(SOCKET_TIMEOUT)
.setConnectionRequestTimeout(SOCKET_TIMEOUT).build(); .setConnectionRequestTimeout(SOCKET_TIMEOUT).build();
this.readerThread = new ReaderThread();
readerThread = new ReaderThread();
readerThread.setName(callback.getBotUsername() + " Telegram Connection"); readerThread.setName(callback.getBotUsername() + " Telegram Connection");
this.readerThread.start(); readerThread.start();
this.handlerThread = new HandlerThread();
handlerThread.setName(callback.getBotUsername() + " Executor"); handlerThread = new HandlerThread();
this.handlerThread.start(); handlerThread.setName(callback.getBotUsername() + " Telegram Executor");
handlerThread.start();
} }
public void close() public void close() {
{ running = false;
running = false; if (readerThread != null) {
if(httpclient != null) readerThread.interrupt();
{ }
try if (handlerThread != null) {
{ handlerThread.interrupt();
httpclient.close(); }
httpclient = null; if (httpclient != null) {
try {
httpclient.close();
httpclient = null;
} catch (IOException e) { } catch (IOException e) {
BotLogger.severe(LOGTAG, e); BotLogger.severe(LOGTAG, e);
} }
} }
} }
private class ReaderThread extends Thread { private class ReaderThread extends Thread {
@Override @Override
public void run() { public void run() {
setPriority(Thread.MIN_PRIORITY); setPriority(Thread.MIN_PRIORITY);
while(running) { while (running) {
try { try {
GetUpdates request = new GetUpdates(); GetUpdates request = new GetUpdates();
request.setLimit(100); request.setLimit(100);
request.setTimeout(50); request.setTimeout(Constants.GETUPDATESTIMEOUT);
request.setOffset(lastReceivedUpdate + 1); request.setOffset(lastReceivedUpdate + 1);
String url = Constants.BASEURL + token + "/" + GetUpdates.PATH; String url = Constants.BASEURL + token + "/" + GetUpdates.PATH;
//http client //http client
@ -111,7 +114,9 @@ public class BotSession {
String responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8); String responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8);
JSONObject jsonObject = new JSONObject(responseContent); JSONObject jsonObject = new JSONObject(responseContent);
if (!jsonObject.getBoolean(Constants.RESPONSEFIELDOK)) { if (!jsonObject.getBoolean(Constants.RESPONSEFIELDOK)) {
throw new TelegramApiException("Error getting updates", jsonObject.getString(ERRORDESCRIPTIONFIELD), jsonObject.getInt(ERRORCODEFIELD)); throw new TelegramApiException("Error getting updates",
jsonObject.getString(Constants.ERRORDESCRIPTIONFIELD),
jsonObject.getInt(Constants.ERRORCODEFIELD));
} }
JSONArray jsonArray = jsonObject.getJSONArray(Constants.RESPONSEFIELDRESULT); JSONArray jsonArray = jsonObject.getJSONArray(Constants.RESPONSEFIELDRESULT);
if (jsonArray.length() != 0) { if (jsonArray.length() != 0) {
@ -155,7 +160,7 @@ public class BotSession {
@Override @Override
public void run() { public void run() {
setPriority(Thread.MIN_PRIORITY); setPriority(Thread.MIN_PRIORITY);
while(running) { while (running) {
try { try {
Update update = receivedUpdates.pollLast(); Update update = receivedUpdates.pollLast();
if (update == null) { if (update == null) {

View File

@ -3,10 +3,16 @@ package org.telegram.telegrambots.updatesreceivers;
import org.telegram.telegrambots.api.objects.Update; import org.telegram.telegrambots.api.objects.Update;
import org.telegram.telegrambots.bots.ITelegramWebhookBot; import org.telegram.telegrambots.bots.ITelegramWebhookBot;
import javax.ws.rs.*; import java.util.concurrent.ConcurrentHashMap;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* @author Ruben Bermudez * @author Ruben Bermudez
@ -15,7 +21,7 @@ import java.util.concurrent.ConcurrentHashMap;
* @date 20 of June of 2015 * @date 20 of June of 2015
*/ */
@Path("callback") @Path("callback")
class RestApi { public class RestApi {
private final ConcurrentHashMap<String, ITelegramWebhookBot> callbacks = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, ITelegramWebhookBot> callbacks = new ConcurrentHashMap<>();

View File

@ -10,6 +10,7 @@ import org.glassfish.jersey.server.ResourceConfig;
import org.telegram.telegrambots.TelegramApiException; import org.telegram.telegrambots.TelegramApiException;
import org.telegram.telegrambots.bots.ITelegramWebhookBot; import org.telegram.telegrambots.bots.ITelegramWebhookBot;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
@ -20,17 +21,16 @@ import java.net.URI;
* @date 20 of June of 2015 * @date 20 of June of 2015
*/ */
public class Webhook { public class Webhook {
private static final String LOGTAG = "WEBHOOK";
private final String KEYSTORE_SERVER_FILE; private final String KEYSTORE_SERVER_FILE;
private final String KEYSTORE_SERVER_PWD; private final String KEYSTORE_SERVER_PWD;
private final RestApi restApi; private final RestApi restApi;
private final String internalUrl; private final String internalUrl;
public Webhook(String keyStore, String keyStorePassword, String internalUrl) { public Webhook(String keyStore, String keyStorePassword, String internalUrl) throws TelegramApiException {
this.KEYSTORE_SERVER_FILE = keyStore; this.KEYSTORE_SERVER_FILE = keyStore;
this.KEYSTORE_SERVER_PWD = keyStorePassword; this.KEYSTORE_SERVER_PWD = keyStorePassword;
validateServerKeystoreFile(keyStore);
this.internalUrl = internalUrl; this.internalUrl = internalUrl;
this.restApi = new RestApi(); this.restApi = new RestApi();
} }
@ -65,4 +65,11 @@ public class Webhook {
private URI getBaseURI() { private URI getBaseURI() {
return URI.create(internalUrl); return URI.create(internalUrl);
} }
}
private static void validateServerKeystoreFile(String keyStore) throws TelegramApiException {
File file = new File(keyStore);
if (!file.exists() || !file.canRead()) {
throw new TelegramApiException("Can't find or access server keystore file.");
}
}
}