commit
c45e480d6d
128
Bots.ipr
128
Bots.ipr
@ -17,6 +17,7 @@
|
|||||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||||
<outputRelativeToContentRoot value="true" />
|
<outputRelativeToContentRoot value="true" />
|
||||||
<module name="telegrambots" />
|
<module name="telegrambots" />
|
||||||
|
<module name="telegrambots-abilities" />
|
||||||
<module name="telegrambots-extensions" />
|
<module name="telegrambots-extensions" />
|
||||||
<module name="telegrambots-meta" />
|
<module name="telegrambots-meta" />
|
||||||
</profile>
|
</profile>
|
||||||
@ -30,12 +31,14 @@
|
|||||||
<bytecodeTargetLevel>
|
<bytecodeTargetLevel>
|
||||||
<module name="Bots" target="1.5" />
|
<module name="Bots" target="1.5" />
|
||||||
<module name="telegrambots" target="1.8" />
|
<module name="telegrambots" target="1.8" />
|
||||||
|
<module name="telegrambots-abilities" target="1.8" />
|
||||||
<module name="telegrambots-extensions" target="1.8" />
|
<module name="telegrambots-extensions" target="1.8" />
|
||||||
<module name="telegrambots-meta" target="1.8" />
|
<module name="telegrambots-meta" target="1.8" />
|
||||||
</bytecodeTargetLevel>
|
</bytecodeTargetLevel>
|
||||||
</component>
|
</component>
|
||||||
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
|
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
|
||||||
<file url="file://$PROJECT_DIR$/telegrambots" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/telegrambots" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/telegrambots-abilities" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/telegrambots-extensions" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/telegrambots-extensions" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/telegrambots-meta" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/telegrambots-meta" charset="UTF-8" />
|
||||||
<file url="PROJECT" charset="UTF-8" />
|
<file url="PROJECT" charset="UTF-8" />
|
||||||
@ -126,6 +129,9 @@
|
|||||||
<exe-path>/usr/local/bin/bower</exe-path>
|
<exe-path>/usr/local/bin/bower</exe-path>
|
||||||
<config-path />
|
<config-path />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="KotlinCommonCompilerArguments">
|
||||||
|
<option name="coroutinesWarn" value="false" />
|
||||||
|
</component>
|
||||||
<component name="MavenProjectsManager">
|
<component name="MavenProjectsManager">
|
||||||
<option name="originalFiles">
|
<option name="originalFiles">
|
||||||
<list>
|
<list>
|
||||||
@ -264,6 +270,7 @@
|
|||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://$PROJECT_DIR$/Bots.iml" filepath="$PROJECT_DIR$/Bots.iml" />
|
<module fileurl="file://$PROJECT_DIR$/Bots.iml" filepath="$PROJECT_DIR$/Bots.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/telegrambots/telegrambots.iml" filepath="$PROJECT_DIR$/telegrambots/telegrambots.iml" />
|
<module fileurl="file://$PROJECT_DIR$/telegrambots/telegrambots.iml" filepath="$PROJECT_DIR$/telegrambots/telegrambots.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/telegrambots-abilities/telegrambots-abilities.iml" filepath="$PROJECT_DIR$/telegrambots-abilities/telegrambots-abilities.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/telegrambots-extensions/telegrambots-extensions.iml" filepath="$PROJECT_DIR$/telegrambots-extensions/telegrambots-extensions.iml" />
|
<module fileurl="file://$PROJECT_DIR$/telegrambots-extensions/telegrambots-extensions.iml" filepath="$PROJECT_DIR$/telegrambots-extensions/telegrambots-extensions.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/telegrambots-meta/telegrambots-meta.iml" filepath="$PROJECT_DIR$/telegrambots-meta/telegrambots-meta.iml" />
|
<module fileurl="file://$PROJECT_DIR$/telegrambots-meta/telegrambots-meta.iml" filepath="$PROJECT_DIR$/telegrambots-meta/telegrambots-meta.iml" />
|
||||||
</modules>
|
</modules>
|
||||||
@ -497,6 +504,17 @@
|
|||||||
<root url="jar://$MAVEN_REPOSITORY$/javax/ws/rs/javax.ws.rs-api/2.0.1/javax.ws.rs-api-2.0.1-sources.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/javax/ws/rs/javax.ws.rs-api/2.0.1/javax.ws.rs-api-2.0.1-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
|
<library name="Maven: junit:junit:4.11">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.11/junit-4.11.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.11/junit-4.11-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.11/junit-4.11-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
<library name="Maven: junit:junit:4.12">
|
<library name="Maven: junit:junit:4.12">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.12/junit-4.12.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.12/junit-4.12.jar!/" />
|
||||||
@ -508,6 +526,39 @@
|
|||||||
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.12/junit-4.12-sources.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.12/junit-4.12-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
|
<library name="Maven: net.jcip:jcip-annotations:1.0">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/jcip/jcip-annotations/1.0/jcip-annotations-1.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/jcip/jcip-annotations/1.0/jcip-annotations-1.0-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/jcip/jcip-annotations/1.0/jcip-annotations-1.0-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
<library name="Maven: net.jpountz.lz4:lz4:1.3.0">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/jpountz/lz4/lz4/1.3.0/lz4-1.3.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/jpountz/lz4/lz4/1.3.0/lz4-1.3.0-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/jpountz/lz4/lz4/1.3.0/lz4-1.3.0-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
<library name="Maven: org.apache.commons:commons-lang3:3.5">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
<library name="Maven: org.apache.httpcomponents:httpclient:4.5.3">
|
<library name="Maven: org.apache.httpcomponents:httpclient:4.5.3">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpclient/4.5.3/httpclient-4.5.3.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpclient/4.5.3/httpclient-4.5.3.jar!/" />
|
||||||
@ -541,6 +592,39 @@
|
|||||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpmime/4.5.3/httpmime-4.5.3-sources.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpmime/4.5.3/httpmime-4.5.3-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
|
<library name="Maven: org.eclipse.collections:eclipse-collections-api:7.1.1">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/collections/eclipse-collections-api/7.1.1/eclipse-collections-api-7.1.1.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/collections/eclipse-collections-api/7.1.1/eclipse-collections-api-7.1.1-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/collections/eclipse-collections-api/7.1.1/eclipse-collections-api-7.1.1-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
<library name="Maven: org.eclipse.collections:eclipse-collections-forkjoin:7.1.1">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/collections/eclipse-collections-forkjoin/7.1.1/eclipse-collections-forkjoin-7.1.1.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/collections/eclipse-collections-forkjoin/7.1.1/eclipse-collections-forkjoin-7.1.1-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/collections/eclipse-collections-forkjoin/7.1.1/eclipse-collections-forkjoin-7.1.1-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
<library name="Maven: org.eclipse.collections:eclipse-collections:7.1.1">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/collections/eclipse-collections/7.1.1/eclipse-collections-7.1.1.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/collections/eclipse-collections/7.1.1/eclipse-collections-7.1.1-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/collections/eclipse-collections/7.1.1/eclipse-collections-7.1.1-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
<library name="Maven: org.glassfish.grizzly:grizzly-framework:2.3.28">
|
<library name="Maven: org.glassfish.grizzly:grizzly-framework:2.3.28">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/glassfish/grizzly/grizzly-framework/2.3.28/grizzly-framework-2.3.28.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/glassfish/grizzly/grizzly-framework/2.3.28/grizzly-framework-2.3.28.jar!/" />
|
||||||
@ -816,6 +900,28 @@
|
|||||||
<root url="jar://$MAVEN_REPOSITORY$/org/javassist/javassist/3.20.0-GA/javassist-3.20.0-GA-sources.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/javassist/javassist/3.20.0-GA/javassist-3.20.0-GA-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
|
<library name="Maven: org.jetbrains.kotlin:kotlin-runtime:1.0.7">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-runtime/1.0.7/kotlin-runtime-1.0.7.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-runtime/1.0.7/kotlin-runtime-1.0.7-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-runtime/1.0.7/kotlin-runtime-1.0.7-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
<library name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.0.7">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.0.7/kotlin-stdlib-1.0.7.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.0.7/kotlin-stdlib-1.0.7-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.0.7/kotlin-stdlib-1.0.7-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
<library name="Maven: org.json:json:20160810">
|
<library name="Maven: org.json:json:20160810">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/json/json/20160810/json-20160810.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/json/json/20160810/json-20160810.jar!/" />
|
||||||
@ -827,6 +933,28 @@
|
|||||||
<root url="jar://$MAVEN_REPOSITORY$/org/json/json/20160810/json-20160810-sources.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/json/json/20160810/json-20160810-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
|
<library name="Maven: org.mapdb:elsa:3.0.0-M5">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/mapdb/elsa/3.0.0-M5/elsa-3.0.0-M5.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/mapdb/elsa/3.0.0-M5/elsa-3.0.0-M5-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/mapdb/elsa/3.0.0-M5/elsa-3.0.0-M5-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
<library name="Maven: org.mapdb:mapdb:3.0.4">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/mapdb/mapdb/3.0.4/mapdb-3.0.4.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/mapdb/mapdb/3.0.4/mapdb-3.0.4-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/mapdb/mapdb/3.0.4/mapdb-3.0.4-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
<library name="Maven: org.mockito:mockito-all:2.0.2-beta">
|
<library name="Maven: org.mockito:mockito-all:2.0.2-beta">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/mockito/mockito-all/2.0.2-beta/mockito-all-2.0.2-beta.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/mockito/mockito-all/2.0.2-beta/mockito-all-2.0.2-beta.jar!/" />
|
||||||
|
@ -27,16 +27,16 @@ Just import add the library to your project with one of these options:
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.telegram</groupId>
|
<groupId>org.telegram</groupId>
|
||||||
<artifactId>telegrambots</artifactId>
|
<artifactId>telegrambots</artifactId>
|
||||||
<version>3.1.2</version>
|
<version>3.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
```gradle
|
```gradle
|
||||||
compile "org.telegram:telegrambots:3.1.2"
|
compile "org.telegram:telegrambots:3.2"
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Using Jitpack from [here](https://jitpack.io/#rubenlagus/TelegramBots/3.1.2)
|
2. Using Jitpack from [here](https://jitpack.io/#rubenlagus/TelegramBots/3.2)
|
||||||
3. Download the jar(including all dependencies) from [here](https://github.com/rubenlagus/TelegramBots/releases/tag/v3.1.2)
|
3. Download the jar(including all dependencies) from [here](https://github.com/rubenlagus/TelegramBots/releases/tag/v3.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`.
|
||||||
|
|
||||||
|
@ -82,4 +82,15 @@
|
|||||||
|
|
||||||
|
|
||||||
### <a id="3.1.2"></a>3.1.2 ###
|
### <a id="3.1.2"></a>3.1.2 ###
|
||||||
1. Fix bug #266
|
1. Fix bug #266
|
||||||
|
|
||||||
|
### <a id="3.2"></a>3.2 ###
|
||||||
|
1. Support for Api Version [3.2](https://core.telegram.org/bots/api-changelog#july-21-2017)
|
||||||
|
2. Deprecated all redundant methods in AbsSender, will be removed in next major release
|
||||||
|
3. New Abstract methods `addStickerToSet`, `createNewStickerSet` and `uploadStickerFile` in AbsSender.
|
||||||
|
4. Abilities module
|
||||||
|
5. Removed deprecated methods from previous versions
|
||||||
|
6. Bug fixing: #257, #270
|
||||||
|
7. Simplify code from DefaultAbsSender: #272
|
||||||
|
|
||||||
|
**[[How to update to version 3.2|How-To-Update#3.2]]**
|
@ -11,13 +11,13 @@ First you need ot get the library and add it to your project. There are few poss
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.telegram</groupId>
|
<groupId>org.telegram</groupId>
|
||||||
<artifactId>telegrambots</artifactId>
|
<artifactId>telegrambots</artifactId>
|
||||||
<version>3.1.2</version>
|
<version>3.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
* With **Gradle**:
|
* With **Gradle**:
|
||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
compile group: 'org.telegram', name: 'telegrambots', version: '3.1.2'
|
compile group: 'org.telegram', name: 'telegrambots', version: '3.2'
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Don't like **Maven Central Repository**? It can also be taken from [Jitpack](https://jitpack.io/#rubenlagus/TelegramBots).
|
2. Don't like **Maven Central Repository**? It can also be taken from [Jitpack](https://jitpack.io/#rubenlagus/TelegramBots).
|
||||||
|
@ -27,4 +27,9 @@
|
|||||||
|
|
||||||
### <a id="3.0.2"></a>To version 3.0.2 ###
|
### <a id="3.0.2"></a>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.
|
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.
|
2. If you were using `TelegramLongPollingCommandBot`, make sure you start using constructors with username and prevent overriding `getUsername` method.
|
||||||
|
|
||||||
|
|
||||||
|
### <a id="3.2"></a>To version 3.2 ###
|
||||||
|
1. Replace usage of all deprecated methods from AbsSender with methods `execute` or `executeAsync`.
|
||||||
|
2. If you are extending AbsSender class, implement new added methods.
|
5
pom.xml
5
pom.xml
@ -7,12 +7,13 @@
|
|||||||
<groupId>org.telegram</groupId>
|
<groupId>org.telegram</groupId>
|
||||||
<artifactId>Bots</artifactId>
|
<artifactId>Bots</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>3.1.2</version>
|
<version>3.2</version>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>telegrambots</module>
|
<module>telegrambots</module>
|
||||||
<module>telegrambots-meta</module>
|
<module>telegrambots-meta</module>
|
||||||
<module>telegrambots-extensions</module>
|
<module>telegrambots-extensions</module>
|
||||||
|
<module>telegrambots-abilities</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<licenses>
|
<licenses>
|
||||||
@ -25,6 +26,6 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.deploy.skip>true</maven.deploy.skip>
|
<maven.deploy.skip>true</maven.deploy.skip>
|
||||||
<bots.version>3.1.2</bots.version>
|
<bots.version>3.2</bots.version>
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
170
telegrambots-abilities/README.md
Normal file
170
telegrambots-abilities/README.md
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
<div align="center">
|
||||||
|
<img src="https://github.com/addo37/AbilityBots/blob/gh-pages/images/API%20BOT-03.png?raw=true" alt="abilitybots" width="200" height="200"/>
|
||||||
|
|
||||||
|
[![Build Status](https://travis-ci.org/rubenlagus/TelegramBots.svg?branch=master)](https://travis-ci.org/rubenlagus/TelegramBots)
|
||||||
|
[![Jitpack](https://jitpack.io/v/rubenlagus/TelegramBots.svg)](https://jitpack.io/#rubenlagus/TelegramBots)
|
||||||
|
[![JavaDoc](http://svgur.com/i/1Ex.svg)](https://addo37.github.io/AbilityBots/)
|
||||||
|
[![Telegram](http://trellobot.doomdns.org/telegrambadge.svg)](https://telegram.me/JavaBotsApi)
|
||||||
|
[![ghit.me](https://ghit.me/badge.svg?repo=rubenlagus/TelegramBots)](https://ghit.me/repo/rubenlagus/TelegramBots)
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
**Maven**
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.telegram</groupId>
|
||||||
|
<artifactId>telegrambots-abilities</artifactId>
|
||||||
|
<version>3.2</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Gradle**
|
||||||
|
|
||||||
|
```gradle
|
||||||
|
compile "org.telegram:telegrambots-abilities:3.2"
|
||||||
|
```
|
||||||
|
|
||||||
|
**JitPack** - [JitPack](https://jitpack.io/#rubenlagus/TelegramBots/v3.2)
|
||||||
|
|
||||||
|
**Plain imports** - [Here](https://github.com/rubenlagus/TelegramBots/releases/tag/v3.2)
|
||||||
|
|
||||||
|
Motivation
|
||||||
|
----------
|
||||||
|
Ever since I've started programming bots for Telegram, I've been using the Telegram Bot Java API. It's a basic and nicely done API that is a 1-to-1 translation of the HTTP API exposed by Telegram.
|
||||||
|
|
||||||
|
Dealing with a basic API has its advantages and disadvantages. Obviously, there's nothing hidden. If it's there on Telegram, it's here in the Java API.
|
||||||
|
When you want to implement a feature in your bot, you start asking these questions:
|
||||||
|
|
||||||
|
* The **WHO**?
|
||||||
|
* Who is going to use this feature? Should they be allowed to use all the features?
|
||||||
|
* The **WHAT**?
|
||||||
|
* Under what conditions should I allow this feature?
|
||||||
|
* Should the message have a photo? A document? Oh, maybe a callback query?
|
||||||
|
* The **HOW**?
|
||||||
|
* If my bot crashes, how can I resume my operation?
|
||||||
|
* Should I utilize a DB?
|
||||||
|
* How can I separate logic execution of different features?
|
||||||
|
* How can I unit-test my feature outside of Telegram?
|
||||||
|
|
||||||
|
Every time you write a command or a feature, you will need to answer these questions and ensure that your feature logic works.
|
||||||
|
|
||||||
|
Ability Bot Abstraction
|
||||||
|
-----------------------
|
||||||
|
After implementing my fifth bot using that API, I had had it with the amount of **boilerplate code** that was needed for every added feature. Methods were getting overly-complex and readability became subpar.
|
||||||
|
That is where the notion of another layer of abstraction (AbilityBot) began taking shape.
|
||||||
|
|
||||||
|
The AbilityBot abstraction defines a new object, named **Ability**. An ability combines conditions, flags, action, post-action and replies.
|
||||||
|
As an example, here is a code-snippet of an ability that creates a ***/hello*** command:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public Ability sayHelloWorld() {
|
||||||
|
return Ability
|
||||||
|
.builder()
|
||||||
|
.name("hello")
|
||||||
|
.info("says hello world!")
|
||||||
|
.input(0)
|
||||||
|
.locality(USER)
|
||||||
|
.privacy(ADMIN)
|
||||||
|
.action(ctx -> sender.send("Hello world!", ctx.chatId()))
|
||||||
|
.post(ctx -> sender.send("Bye world!", ctx.chatId()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Here is a breakdown of the above code snippet:
|
||||||
|
* *.name()* - the name of the ability (essentially, this is the command)
|
||||||
|
* *.info()* - provides information for the command
|
||||||
|
* More on this later, but it basically centralizes command information in-code.
|
||||||
|
* *.input()* - the number of input arguments needed, 0 is for do-not-care
|
||||||
|
* *.locality()* - this answers where you want the ability to be available
|
||||||
|
* In GROUP, USER private chats or ALL (both)
|
||||||
|
* *.privacy()* - this answers who you want to access your ability
|
||||||
|
* CREATOR, ADMIN, or everyone as PUBLIC
|
||||||
|
* *.action()* - the feature logic resides here (a lambda function that takes a *MessageContext*)
|
||||||
|
* *MessageContext* provides fast accessors for the **chatId**, **user** and the underlying **update**. It also conforms to the specifications of the basic API.
|
||||||
|
* *.post()* - the logic executed **after** your main action finishes execution
|
||||||
|
|
||||||
|
The following is a snippet of how this would look like with the plain basic API.
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Override
|
||||||
|
public void onUpdateReceived(Update update) {
|
||||||
|
// Global checks...
|
||||||
|
// Switch, if, logic to route to hello world method
|
||||||
|
// Execute method
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sayHelloWorld(Update update) {
|
||||||
|
if (!update.hasMessage() || !update.getMessage().isUserMessage() || !update.getMessage().hasText() || update.getMessage.getText().isEmpty())
|
||||||
|
return;
|
||||||
|
User maybeAdmin = update.getMessage().getFrom();
|
||||||
|
/* Query DB for if the user is an admin, can be SQL, Reddis, Ignite, etc...
|
||||||
|
If user is not an admin, then return here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
SendMessage snd = new SendMessage();
|
||||||
|
snd.setChatId(update.getMessage().getChatId());
|
||||||
|
snd.setText("Hello world!");
|
||||||
|
|
||||||
|
try {
|
||||||
|
sendMessage(snd);
|
||||||
|
} catch (TelegramApiException e) {
|
||||||
|
BotLogger.error("Could not send message", TAG, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
I will leave you the choice to decide between the two snippets as to which is more **readable**, **writable** and **testable**.
|
||||||
|
|
||||||
|
***You can do so much more with abilities, besides plain commands. Head over to our [examples](#examples) to check out all of its features!***
|
||||||
|
|
||||||
|
Objective
|
||||||
|
---------
|
||||||
|
The AbilityBot abstraction intends to provide the following:
|
||||||
|
* New feature is a new **Ability**, a new method - no fuss, zero overhead, no cross-code with other features
|
||||||
|
* Argument length on a command is as easy as changing a single integer
|
||||||
|
* Privacy settings per Ability - access levels to Abilities! User | Admin | Creator
|
||||||
|
* Embedded database - available for every declared ability
|
||||||
|
* Proxy sender interface - enhances testability; accurate results pre-release
|
||||||
|
|
||||||
|
Alongside these exciting core features of the AbilityBot, the following have been introduced:
|
||||||
|
* The bot automatically maintains an up-to-date set of all the users who have contacted the bot
|
||||||
|
* up-to-date: if a user changes their Username, First Name or Last Name, the bot updates the respective field in the embedded-DB
|
||||||
|
* Backup and recovery for the DB
|
||||||
|
* Default implementation relies on JSON/Jackson
|
||||||
|
* Ban and unban users from accessing your bots
|
||||||
|
* The bot will execute the shortest path to discard the update the next time they try to spam
|
||||||
|
* Promote and demote users as bot administrators
|
||||||
|
* Allows admins to execute admin abilities
|
||||||
|
|
||||||
|
What's next?
|
||||||
|
------------
|
||||||
|
I am looking forward to:
|
||||||
|
* Provide a trigger to record metrics per ability
|
||||||
|
* Implement AsyncAbility
|
||||||
|
* Maintain integration with the latest updates on the basic API
|
||||||
|
* Enrich the bot with features requested by the community
|
||||||
|
|
||||||
|
Examples
|
||||||
|
-------------------
|
||||||
|
* [Example Bots](https://github.com/addo37/ExampleBots)
|
||||||
|
|
||||||
|
Do you have a project that uses **AbilityBots**? Let us know!
|
||||||
|
|
||||||
|
Support
|
||||||
|
-------
|
||||||
|
For issues and features, please use GitHub's [issues](https://github.com/rubenlagus/TelegramBots/issues) tab.
|
||||||
|
|
||||||
|
For quick feedback, chatting or just having fun, please come and join us in our Telegram Supergroup.
|
||||||
|
|
||||||
|
[![Telegram](http://trellobot.doomdns.org/telegrambadge.svg)](https://telegram.me/JavaBotsApi)
|
||||||
|
|
||||||
|
Credits
|
||||||
|
-------
|
||||||
|
This project would not have been made possible had it not been for [Ruben](https://github.com/rubenlagus)'s work with the [Telegram Bot Java API](https://github.com/rubenlagus/TelegramBots).
|
||||||
|
I strongly urge you to check out that project and implement a bot to have a sense of how the basic API feels like.
|
||||||
|
Ruben has done a great job in supplying a clear and straightforward API that conforms to Telegram's HTTP API.
|
||||||
|
There is also a chat for that API.
|
263
telegrambots-abilities/pom.xml
Normal file
263
telegrambots-abilities/pom.xml
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.telegram</groupId>
|
||||||
|
<artifactId>telegrambots-abilities</artifactId>
|
||||||
|
<version>3.2</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Telegram Ability Bot</name>
|
||||||
|
<url>https://github.com/rubenlagus/TelegramBots</url>
|
||||||
|
<description>AbilityBot Extension and Abstraction</description>
|
||||||
|
|
||||||
|
<issueManagement>
|
||||||
|
<url>https://github.com/rubenlagus/TelegramBots/issues</url>
|
||||||
|
<system>GitHub Issues</system>
|
||||||
|
</issueManagement>
|
||||||
|
|
||||||
|
<scm>
|
||||||
|
<url>https://github.com/rubenlagus/TelegramBots</url>
|
||||||
|
<connection>scm:git:git://github.com/rubenlagus/TelegramBots.git</connection>
|
||||||
|
<developerConnection>scm:git:git@github.com:rubenlagus/TelegramBots.git</developerConnection>
|
||||||
|
</scm>
|
||||||
|
|
||||||
|
<ciManagement>
|
||||||
|
<url>https://travis-ci.org/rubenlagus/TelegramBots</url>
|
||||||
|
<system>Travis</system>
|
||||||
|
</ciManagement>
|
||||||
|
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<email>abbas.aboudayya@gmail.com</email>
|
||||||
|
<name>Abbas Abou Daya</name>
|
||||||
|
<url>https://github.com/addo37</url>
|
||||||
|
<id>addo37</id>
|
||||||
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<email>rberlopez@gmail.com</email>
|
||||||
|
<name>Ruben Bermudez</name>
|
||||||
|
<url>https://github.com/rubenlagus</url>
|
||||||
|
<id>rubenlagus</id>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
|
||||||
|
<licenses>
|
||||||
|
<license>
|
||||||
|
<name>MIT License</name>
|
||||||
|
<url>http://www.opensource.org/licenses/mit-license.php</url>
|
||||||
|
<distribution>repo</distribution>
|
||||||
|
</license>
|
||||||
|
</licenses>
|
||||||
|
|
||||||
|
<distributionManagement>
|
||||||
|
<snapshotRepository>
|
||||||
|
<id>ossrh</id>
|
||||||
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
|
</snapshotRepository>
|
||||||
|
<repository>
|
||||||
|
<id>ossrh</id>
|
||||||
|
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||||
|
</repository>
|
||||||
|
</distributionManagement>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<bots.version>3.2</bots.version>
|
||||||
|
<commonslang.version>3.5</commonslang.version>
|
||||||
|
<mapdb.version>3.0.4</mapdb.version>
|
||||||
|
<guava.version>19.0</guava.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.telegram</groupId>
|
||||||
|
<artifactId>telegrambots</artifactId>
|
||||||
|
<version>${bots.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commonslang.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapdb</groupId>
|
||||||
|
<artifactId>mapdb</artifactId>
|
||||||
|
<version>${mapdb.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>${guava.version}</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>
|
||||||
|
<directory>${project.basedir}/target</directory>
|
||||||
|
<outputDirectory>${project.build.directory}/classes</outputDirectory>
|
||||||
|
<finalName>${project.artifactId}-${project.version}</finalName>
|
||||||
|
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
|
||||||
|
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
|
<version>1.5</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>sign-artifacts</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>sign</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.sonatype.plugins</groupId>
|
||||||
|
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||||
|
<version>1.6.3</version>
|
||||||
|
<extensions>true</extensions>
|
||||||
|
<configuration>
|
||||||
|
<serverId>ossrh</serverId>
|
||||||
|
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
|
||||||
|
<autoReleaseAfterClose>true</autoReleaseAfterClose>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<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>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>2.10.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<additionalparam>-Xdoclint:none</additionalparam>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
<version>0.7.7.201606060606</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>prepare-agent</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>report</id>
|
||||||
|
<phase>test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>report</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
|
<version>1.4.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>enforce-versions</id>
|
||||||
|
<goals>
|
||||||
|
<goal>enforce</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<rules>
|
||||||
|
<DependencyConvergence />
|
||||||
|
</rules>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<version>2.4</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,743 @@
|
|||||||
|
package org.telegram.abilitybots.api.bot;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.telegram.abilitybots.api.db.DBContext;
|
||||||
|
import org.telegram.abilitybots.api.objects.*;
|
||||||
|
import org.telegram.abilitybots.api.sender.DefaultMessageSender;
|
||||||
|
import org.telegram.abilitybots.api.sender.MessageSender;
|
||||||
|
import org.telegram.abilitybots.api.util.AbilityUtils;
|
||||||
|
import org.telegram.abilitybots.api.util.Pair;
|
||||||
|
import org.telegram.abilitybots.api.util.Trio;
|
||||||
|
import org.telegram.telegrambots.api.methods.GetFile;
|
||||||
|
import org.telegram.telegrambots.api.methods.send.SendDocument;
|
||||||
|
import org.telegram.telegrambots.api.objects.Message;
|
||||||
|
import org.telegram.telegrambots.api.objects.Update;
|
||||||
|
import org.telegram.telegrambots.bots.DefaultBotOptions;
|
||||||
|
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiException;
|
||||||
|
import org.telegram.telegrambots.logging.BotLogger;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
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 java.lang.String.format;
|
||||||
|
import static java.time.ZonedDateTime.now;
|
||||||
|
import static java.util.Arrays.stream;
|
||||||
|
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 jersey.repackaged.com.google.common.base.Throwables.propagate;
|
||||||
|
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.AbilityUtils.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <b>father</b> of all ability bots. Bots that need to utilize abilities need to extend this bot.
|
||||||
|
* <p>
|
||||||
|
* It's important to note that this bot strictly extends {@link TelegramLongPollingBot}.
|
||||||
|
* <p>
|
||||||
|
* All bots extending the {@link AbilityBot} get implicit abilities:
|
||||||
|
* <ul>
|
||||||
|
* <li>/claim - Claims this bot</li>
|
||||||
|
* <ul>
|
||||||
|
* <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>
|
||||||
|
* <ul>
|
||||||
|
* <li>The same format acceptable by BotFather</li>
|
||||||
|
* </ul>
|
||||||
|
* <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>
|
||||||
|
* <li>/demote <code>@username</code> - demotes bot admin to user</li>
|
||||||
|
* <li>/ban <code>@username</code> - bans the user from accessing your bot commands and features</li>
|
||||||
|
* <li>/unban <code>@username</code> - lifts the ban from the user</li>
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* Additional information of the implicit abilities are present in the methods that declare them.
|
||||||
|
* <p>
|
||||||
|
* The two most important handles in the AbilityBot are the {@link DBContext} <b><code>db</code></b> and the {@link MessageSender} <b><code>sender</code></b>.
|
||||||
|
* All bots extending AbilityBot can use both handles in their update consumers.
|
||||||
|
*
|
||||||
|
* @author Abbas Abou Daya
|
||||||
|
*/
|
||||||
|
public abstract class AbilityBot extends TelegramLongPollingBot {
|
||||||
|
private static final String TAG = AbilityBot.class.getSimpleName();
|
||||||
|
|
||||||
|
// DB objects
|
||||||
|
public static final String ADMINS = "ADMINS";
|
||||||
|
public static final String USERS = "USERS";
|
||||||
|
public static final String USER_ID = "USER_ID";
|
||||||
|
public static final String BLACKLIST = "BLACKLIST";
|
||||||
|
|
||||||
|
// Factory commands
|
||||||
|
protected static final String DEFAULT = "default";
|
||||||
|
protected static final String CLAIM = "claim";
|
||||||
|
protected static final String BAN = "ban";
|
||||||
|
protected static final String PROMOTE = "promote";
|
||||||
|
protected static final String DEMOTE = "demote";
|
||||||
|
protected static final String UNBAN = "unban";
|
||||||
|
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.";
|
||||||
|
|
||||||
|
// DB and sender
|
||||||
|
protected final DBContext db;
|
||||||
|
protected MessageSender sender;
|
||||||
|
|
||||||
|
// Bot token and username
|
||||||
|
private final String botToken;
|
||||||
|
private final String botUsername;
|
||||||
|
|
||||||
|
// Ability registry
|
||||||
|
private Map<String, Ability> abilities;
|
||||||
|
|
||||||
|
// Reply registry
|
||||||
|
private List<Reply> replies;
|
||||||
|
|
||||||
|
protected AbilityBot(String botToken, String botUsername, DBContext db, DefaultBotOptions botOptions) {
|
||||||
|
super(botOptions);
|
||||||
|
|
||||||
|
this.botToken = botToken;
|
||||||
|
this.botUsername = botUsername;
|
||||||
|
this.db = db;
|
||||||
|
this.sender = new DefaultMessageSender(this);
|
||||||
|
|
||||||
|
registerAbilities();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AbilityBot(String botToken, String botUsername, DBContext db) {
|
||||||
|
this(botToken, botUsername, db, new DefaultBotOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AbilityBot(String botToken, String botUsername, DefaultBotOptions botOptions) {
|
||||||
|
this(botToken, botUsername, onlineInstance(botUsername), botOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AbilityBot(String botToken, String botUsername) {
|
||||||
|
this(botToken, botUsername, onlineInstance(botUsername));
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract int creatorId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the map of ID -> EndUser
|
||||||
|
*/
|
||||||
|
protected Map<Integer, EndUser> users() {
|
||||||
|
return db.getMap(USERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the map of Username -> ID
|
||||||
|
*/
|
||||||
|
protected Map<String, Integer> userIds() {
|
||||||
|
return db.getMap(USER_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a blacklist containing all the IDs of the banned users
|
||||||
|
*/
|
||||||
|
protected Set<Integer> blacklist() {
|
||||||
|
return db.getSet(BLACKLIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return an admin set of all the IDs of bot administrators
|
||||||
|
*/
|
||||||
|
protected Set<Integer> admins() {
|
||||||
|
return db.getSet(ADMINS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method contains the stream of actions that are applied on any update.
|
||||||
|
* <p>
|
||||||
|
* It will correctly handle addition of users into the DB and the execution of abilities and replies.
|
||||||
|
*
|
||||||
|
* @param update the update received by Telegram's API
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onUpdateReceived(Update update) {
|
||||||
|
BotLogger.info(format("New update [%s] received at %s", update.getUpdateId(), now()), format("%s - %s", TAG, botUsername));
|
||||||
|
BotLogger.info(update.toString(), TAG);
|
||||||
|
long millisStarted = System.currentTimeMillis();
|
||||||
|
|
||||||
|
Stream.of(update)
|
||||||
|
.filter(this::checkGlobalFlags)
|
||||||
|
.filter(this::checkBlacklist)
|
||||||
|
.map(this::addUser)
|
||||||
|
.filter(this::filterReply)
|
||||||
|
.map(this::getAbility)
|
||||||
|
.filter(this::validateAbility)
|
||||||
|
.filter(this::checkPrivacy)
|
||||||
|
.filter(this::checkLocality)
|
||||||
|
.filter(this::checkInput)
|
||||||
|
.filter(this::checkMessageFlags)
|
||||||
|
.map(this::getContext)
|
||||||
|
.map(this::consumeUpdate)
|
||||||
|
.forEach(this::postConsumption);
|
||||||
|
|
||||||
|
long processingTime = System.currentTimeMillis() - millisStarted;
|
||||||
|
BotLogger.info(format("Processing of update [%s] ended at %s%n---> Processing time: [%d ms] <---%n", update.getUpdateId(), now(), processingTime), format("%s - %s", TAG, botUsername));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBotToken() {
|
||||||
|
return botToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBotUsername() {
|
||||||
|
return botUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the update against the provided global flags. The default implementation requires a {@link Flag#MESSAGE}.
|
||||||
|
* <p>
|
||||||
|
* This method should be <b>overridden</b> if the user wants updates that don't require a MESSAGE to pass through.
|
||||||
|
*
|
||||||
|
* @param update a Telegram {@link Update}
|
||||||
|
* @return <tt>true</tt> if the update satisfies the global flags
|
||||||
|
*/
|
||||||
|
protected boolean checkGlobalFlags(Update update) {
|
||||||
|
return MESSAGE.test(update);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user with the specified username.
|
||||||
|
*
|
||||||
|
* @param username the username of the required user
|
||||||
|
* @return the user
|
||||||
|
*/
|
||||||
|
protected EndUser 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
return getUser(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user with the specified ID.
|
||||||
|
*
|
||||||
|
* @param id the id of the required user
|
||||||
|
* @return the user
|
||||||
|
*/
|
||||||
|
protected EndUser getUser(int id) {
|
||||||
|
EndUser endUser = users().get(id);
|
||||||
|
if (endUser == null) {
|
||||||
|
throw new IllegalStateException(format("Could not find user corresponding to id [%d]", id));
|
||||||
|
}
|
||||||
|
|
||||||
|
return endUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* @return the id of the user
|
||||||
|
*/
|
||||||
|
protected int getUserIdSendError(String username, long chatId) {
|
||||||
|
try {
|
||||||
|
return getUser(username).id();
|
||||||
|
} catch (IllegalStateException ex) {
|
||||||
|
sender.send(format("Sorry, I could not find the user [%s].", username), chatId);
|
||||||
|
throw propagate(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Format of the report:
|
||||||
|
* <p>
|
||||||
|
* [command1] - [description1]
|
||||||
|
* <p>
|
||||||
|
* [command2] - [description2]
|
||||||
|
* <p>
|
||||||
|
* ...
|
||||||
|
* <p>
|
||||||
|
* Once you invoke it, the bot will send the available commands to the chat. This is a public ability so anyone can invoke it.
|
||||||
|
* <p>
|
||||||
|
* Usage: <code>/commands</code>
|
||||||
|
*
|
||||||
|
* @return the ability to report commands defined by the child bot.
|
||||||
|
*/
|
||||||
|
public Ability reportCommands() {
|
||||||
|
return builder()
|
||||||
|
.name(COMMANDS)
|
||||||
|
.locality(ALL)
|
||||||
|
.privacy(PUBLIC)
|
||||||
|
.input(0)
|
||||||
|
.action(ctx -> {
|
||||||
|
String commands = abilities.entrySet().stream()
|
||||||
|
.filter(entry -> nonNull(entry.getValue().info()))
|
||||||
|
.map(entry -> {
|
||||||
|
String name = entry.getValue().name();
|
||||||
|
String info = entry.getValue().info();
|
||||||
|
return format("%s - %s", name, info);
|
||||||
|
})
|
||||||
|
.sorted()
|
||||||
|
.reduce((a, b) -> format("%s%n%s", a, b))
|
||||||
|
.orElse("No public commands found.");
|
||||||
|
|
||||||
|
sender.send(commands, ctx.chatId());
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This backup ability returns the object defined by {@link DBContext#backup()} as a message document.
|
||||||
|
* <p>
|
||||||
|
* This is a high-profile ability and is restricted to the CREATOR only.
|
||||||
|
* <p>
|
||||||
|
* Usage: <code>/backup</code>
|
||||||
|
*
|
||||||
|
* @return the ability to back-up the database of the bot
|
||||||
|
*/
|
||||||
|
public Ability backupDB() {
|
||||||
|
return builder()
|
||||||
|
.name(BACKUP)
|
||||||
|
.locality(USER)
|
||||||
|
.privacy(CREATOR)
|
||||||
|
.input(0)
|
||||||
|
.action(ctx -> {
|
||||||
|
File backup = new File("backup.json");
|
||||||
|
|
||||||
|
try (PrintStream printStream = new PrintStream(backup)) {
|
||||||
|
printStream.print(db.backup());
|
||||||
|
sender.sendDocument(new SendDocument()
|
||||||
|
.setNewDocument(backup)
|
||||||
|
.setChatId(ctx.chatId())
|
||||||
|
);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
BotLogger.error("Error while fetching backup", TAG, e);
|
||||||
|
} catch (TelegramApiException e) {
|
||||||
|
BotLogger.error("Error while sending document/backup file", TAG, e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recovers the bot database using {@link DBContext#recover(Object)}.
|
||||||
|
* <p>
|
||||||
|
* The bot recovery process hugely depends on the implementation of the recovery method of {@link DBContext}.
|
||||||
|
* <p>
|
||||||
|
* Usage: <code>/recover</code>
|
||||||
|
*
|
||||||
|
* @return the ability to recover the database of the bot
|
||||||
|
*/
|
||||||
|
public Ability recoverDB() {
|
||||||
|
return builder()
|
||||||
|
.name(RECOVER)
|
||||||
|
.locality(USER)
|
||||||
|
.privacy(CREATOR)
|
||||||
|
.input(0)
|
||||||
|
.action(ctx -> sender.forceReply(RECOVERY_MESSAGE, ctx.chatId()))
|
||||||
|
.reply(update -> {
|
||||||
|
Long chatId = update.getMessage().getChatId();
|
||||||
|
String fileId = update.getMessage().getDocument().getFileId();
|
||||||
|
|
||||||
|
try (FileReader reader = new FileReader(downloadFileWithId(fileId))) {
|
||||||
|
String backupData = IOUtils.toString(reader);
|
||||||
|
if (db.recover(backupData)) {
|
||||||
|
sender.send(RECOVER_SUCCESS, chatId);
|
||||||
|
} else {
|
||||||
|
sender.send("Oops, something went wrong during recovery.", chatId);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
BotLogger.error("Could not recover DB from backup", TAG, e);
|
||||||
|
sender.send("I have failed to recover.", chatId);
|
||||||
|
}
|
||||||
|
}, MESSAGE, DOCUMENT, REPLY, isReplyTo(RECOVERY_MESSAGE))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Banned users are accumulated in the blacklist. Use {@link DBContext#getSet(String)} with name specified by {@link AbilityBot#BLACKLIST}.
|
||||||
|
* <p>
|
||||||
|
* Usage: <code>/ban @username</code>
|
||||||
|
* <p>
|
||||||
|
* <u>Note that admins who try to ban the creator, get banned.</u>
|
||||||
|
*
|
||||||
|
* @return the ability to ban the user from any kind of <b>bot interaction</b>
|
||||||
|
*/
|
||||||
|
public Ability banUser() {
|
||||||
|
return builder()
|
||||||
|
.name(BAN)
|
||||||
|
.locality(ALL)
|
||||||
|
.privacy(ADMIN)
|
||||||
|
.input(1)
|
||||||
|
.action(ctx -> {
|
||||||
|
String username = stripTag(ctx.firstArg());
|
||||||
|
int userId = getUserIdSendError(username, ctx.chatId());
|
||||||
|
String bannedUser;
|
||||||
|
|
||||||
|
// Protection from abuse
|
||||||
|
if (userId == creatorId()) {
|
||||||
|
userId = ctx.user().id();
|
||||||
|
bannedUser = isNullOrEmpty(ctx.user().username()) ? addTag(ctx.user().username()) : ctx.user().shortName();
|
||||||
|
} else {
|
||||||
|
bannedUser = addTag(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Integer> blacklist = blacklist();
|
||||||
|
if (blacklist.contains(userId))
|
||||||
|
sender.sendMd(format("%s is already *banned*.", bannedUser), ctx.chatId());
|
||||||
|
else {
|
||||||
|
blacklist.add(userId);
|
||||||
|
sender.sendMd(format("%s is now *banned*.", bannedUser), ctx.chatId());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.post(commitTo(db))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usage: <code>/unban @username</code>
|
||||||
|
*
|
||||||
|
* @return the ability to unban a user
|
||||||
|
*/
|
||||||
|
public Ability unbanUser() {
|
||||||
|
return builder()
|
||||||
|
.name(UNBAN)
|
||||||
|
.locality(ALL)
|
||||||
|
.privacy(ADMIN)
|
||||||
|
.input(1)
|
||||||
|
.action(ctx -> {
|
||||||
|
String username = stripTag(ctx.firstArg());
|
||||||
|
Integer userId = getUserIdSendError(username, ctx.chatId());
|
||||||
|
|
||||||
|
Set<Integer> blacklist = blacklist();
|
||||||
|
|
||||||
|
if (!blacklist.remove(userId))
|
||||||
|
sender.sendMd(format("@%s is *not* on the *blacklist*.", username), ctx.chatId());
|
||||||
|
else {
|
||||||
|
sender.sendMd(format("@%s, your ban has been *lifted*.", username), ctx.chatId());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.post(commitTo(db))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the ability to promote a user to a bot admin
|
||||||
|
*/
|
||||||
|
public Ability promoteAdmin() {
|
||||||
|
return builder()
|
||||||
|
.name(PROMOTE)
|
||||||
|
.locality(ALL)
|
||||||
|
.privacy(ADMIN)
|
||||||
|
.input(1)
|
||||||
|
.action(ctx -> {
|
||||||
|
String username = stripTag(ctx.firstArg());
|
||||||
|
Integer userId = getUserIdSendError(username, ctx.chatId());
|
||||||
|
|
||||||
|
Set<Integer> admins = admins();
|
||||||
|
if (admins.contains(userId))
|
||||||
|
sender.sendMd(format("@%s is already an *admin*.", username), ctx.chatId());
|
||||||
|
else {
|
||||||
|
admins.add(userId);
|
||||||
|
sender.sendMd(format("@%s has been *promoted*.", username), ctx.chatId());
|
||||||
|
}
|
||||||
|
}).post(commitTo(db))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the ability to demote an admin to a user
|
||||||
|
*/
|
||||||
|
public Ability demoteAdmin() {
|
||||||
|
return builder()
|
||||||
|
.name(DEMOTE)
|
||||||
|
.locality(ALL)
|
||||||
|
.privacy(ADMIN)
|
||||||
|
.input(1)
|
||||||
|
.action(ctx -> {
|
||||||
|
String username = stripTag(ctx.firstArg());
|
||||||
|
Integer userId = getUserIdSendError(username, ctx.chatId());
|
||||||
|
|
||||||
|
Set<Integer> admins = admins();
|
||||||
|
if (admins.remove(userId)) {
|
||||||
|
sender.sendMd(format("@%s has been *demoted*.", username), ctx.chatId());
|
||||||
|
} else {
|
||||||
|
sender.sendMd(format("@%s is *not* an *admin*.", username), ctx.chatId());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.post(commitTo(db))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regular users and admins who try to claim the bot will get <b>banned</b>.
|
||||||
|
*
|
||||||
|
* @return the ability to claim yourself as the master and creator of the bot
|
||||||
|
*/
|
||||||
|
public Ability claimCreator() {
|
||||||
|
return builder()
|
||||||
|
.name(CLAIM)
|
||||||
|
.locality(ALL)
|
||||||
|
.privacy(PUBLIC)
|
||||||
|
.input(0)
|
||||||
|
.action(ctx -> {
|
||||||
|
if (ctx.user().id() == creatorId()) {
|
||||||
|
Set<Integer> admins = admins();
|
||||||
|
int id = creatorId();
|
||||||
|
long chatId = ctx.chatId();
|
||||||
|
|
||||||
|
if (admins.contains(id))
|
||||||
|
sender.send("You're already my master.", chatId);
|
||||||
|
else {
|
||||||
|
admins.add(id);
|
||||||
|
sender.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()));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.post(commitTo(db))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the declared abilities using method reflection. Also, replies are accumulated using the built abilities and standalone methods that return a Reply.
|
||||||
|
* <p>
|
||||||
|
* <b>Only abilities and replies with the <u>public</u> accessor are registered!</b>
|
||||||
|
*/
|
||||||
|
private void registerAbilities() {
|
||||||
|
try {
|
||||||
|
abilities = stream(this.getClass().getMethods())
|
||||||
|
.filter(method -> method.getReturnType().equals(Ability.class))
|
||||||
|
.map(this::returnAbility)
|
||||||
|
.collect(toMap(Ability::name, identity()));
|
||||||
|
|
||||||
|
Stream<Reply> methodReplies = stream(this.getClass().getMethods())
|
||||||
|
.filter(method -> method.getReturnType().equals(Reply.class))
|
||||||
|
.map(this::returnReply);
|
||||||
|
|
||||||
|
Stream<Reply> abilityReplies = abilities.values().stream()
|
||||||
|
.flatMap(ability -> ability.replies().stream());
|
||||||
|
|
||||||
|
replies = Stream.concat(methodReplies, abilityReplies).collect(toList());
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes the method and retrieves its return {@link Ability}.
|
||||||
|
*
|
||||||
|
* @param method a method that returns an ability
|
||||||
|
* @return the ability returned by the method
|
||||||
|
*/
|
||||||
|
private Ability returnAbility(Method method) {
|
||||||
|
try {
|
||||||
|
return (Ability) method.invoke(this);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
BotLogger.error("Could not add ability", TAG, e);
|
||||||
|
throw propagate(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes the method and retrieves its returned Reply.
|
||||||
|
*
|
||||||
|
* @param method a method that returns a reply
|
||||||
|
* @return the reply returned by the method
|
||||||
|
*/
|
||||||
|
private Reply returnReply(Method method) {
|
||||||
|
try {
|
||||||
|
return (Reply) method.invoke(this);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
BotLogger.error("Could not add reply", TAG, e);
|
||||||
|
throw propagate(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postConsumption(Pair<MessageContext, Ability> pair) {
|
||||||
|
ofNullable(pair.b().postAction())
|
||||||
|
.ifPresent(consumer -> consumer.accept(pair.a()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair<MessageContext, Ability> consumeUpdate(Pair<MessageContext, Ability> pair) {
|
||||||
|
pair.b().action().accept(pair.a());
|
||||||
|
return pair;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair<MessageContext, Ability> getContext(Trio<Update, Ability, String[]> trio) {
|
||||||
|
Update update = trio.a();
|
||||||
|
EndUser user = fromUser(AbilityUtils.getUser(update));
|
||||||
|
|
||||||
|
return Pair.of(newContext(update, user, getChatId(update), trio.c()), trio.b());
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean checkBlacklist(Update update) {
|
||||||
|
Integer id = AbilityUtils.getUser(update).getId();
|
||||||
|
|
||||||
|
return id == creatorId() || !blacklist().contains(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean checkInput(Trio<Update, Ability, String[]> trio) {
|
||||||
|
String[] tokens = trio.c();
|
||||||
|
int abilityTokens = trio.b().tokens();
|
||||||
|
|
||||||
|
boolean isOk = abilityTokens == 0 || (tokens.length > 0 && tokens.length == abilityTokens);
|
||||||
|
|
||||||
|
if (!isOk)
|
||||||
|
sender.send(String.format("Sorry, this feature requires %d additional %s.", abilityTokens, abilityTokens == 1 ? "input" : "inputs"), getChatId(trio.a()));
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean checkLocality(Trio<Update, Ability, String[]> trio) {
|
||||||
|
Update update = trio.a();
|
||||||
|
Locality locality = isUserMessage(update) ? USER : GROUP;
|
||||||
|
Locality abilityLocality = trio.b().locality();
|
||||||
|
|
||||||
|
boolean isOk = abilityLocality == ALL || locality == abilityLocality;
|
||||||
|
|
||||||
|
if (!isOk)
|
||||||
|
sender.send(String.format("Sorry, %s-only feature.", 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));
|
||||||
|
Privacy privacy;
|
||||||
|
int id = user.id();
|
||||||
|
|
||||||
|
privacy = isCreator(id) ? CREATOR : isAdmin(id) ? ADMIN : PUBLIC;
|
||||||
|
|
||||||
|
boolean isOk = privacy.compareTo(trio.b().privacy()) >= 0;
|
||||||
|
|
||||||
|
if (!isOk)
|
||||||
|
sender.send(String.format("Sorry, %s-only feature.", trio.b().privacy().toString().toLowerCase()), getChatId(trio.a()));
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isCreator(int id) {
|
||||||
|
return id == creatorId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAdmin(Integer id) {
|
||||||
|
return admins().contains(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean validateAbility(Trio<Update, Ability, String[]> trio) {
|
||||||
|
return trio.b() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Trio<Update, Ability, String[]> getAbility(Update update) {
|
||||||
|
// Handle updates without messages
|
||||||
|
// Passing through this function means that the global flags have passed
|
||||||
|
Message msg = update.getMessage();
|
||||||
|
if (!update.hasMessage() || !msg.hasText())
|
||||||
|
return Trio.of(update, abilities.get(DEFAULT), new String[]{});
|
||||||
|
|
||||||
|
// Priority goes to text before captions
|
||||||
|
String[] tokens = msg.getText().split(" ");
|
||||||
|
|
||||||
|
if (tokens[0].startsWith("/")) {
|
||||||
|
String abilityToken = stripBotUsername(tokens[0].substring(1));
|
||||||
|
Ability ability = abilities.get(abilityToken);
|
||||||
|
tokens = Arrays.copyOfRange(tokens, 1, tokens.length);
|
||||||
|
return Trio.of(update, ability, tokens);
|
||||||
|
} else {
|
||||||
|
Ability ability = abilities.get(DEFAULT);
|
||||||
|
return Trio.of(update, ability, tokens);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String stripBotUsername(String token) {
|
||||||
|
return compile(format("@%s", botUsername), CASE_INSENSITIVE)
|
||||||
|
.matcher(token)
|
||||||
|
.replaceAll("");
|
||||||
|
}
|
||||||
|
|
||||||
|
Update addUser(Update update) {
|
||||||
|
EndUser endUser = fromUser(AbilityUtils.getUser(update));
|
||||||
|
|
||||||
|
users().compute(endUser.id(), (id, user) -> {
|
||||||
|
if (user == null) {
|
||||||
|
updateUserId(user, endUser);
|
||||||
|
return endUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user.equals(endUser)) {
|
||||||
|
updateUserId(user, endUser);
|
||||||
|
return endUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
return user;
|
||||||
|
});
|
||||||
|
|
||||||
|
db.commit();
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateUserId(EndUser oldUser, EndUser newUser) {
|
||||||
|
if (oldUser != null && oldUser.username() != null) {
|
||||||
|
// Remove old username -> ID
|
||||||
|
userIds().remove(oldUser.username());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newUser.username() != null) {
|
||||||
|
// Add new mapping with the new username
|
||||||
|
userIds().put(newUser.username().toLowerCase(), newUser.id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean filterReply(Update update) {
|
||||||
|
return replies.stream()
|
||||||
|
.filter(reply -> reply.isOkFor(update))
|
||||||
|
.map(reply -> {
|
||||||
|
reply.actOn(update);
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
.reduce(true, Boolean::logicalAnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean checkMessageFlags(Trio<Update, Ability, String[]> trio) {
|
||||||
|
Ability ability = trio.b();
|
||||||
|
Update update = trio.a();
|
||||||
|
|
||||||
|
// The following variable is required to avoid bug #JDK-8044546
|
||||||
|
BiFunction<Boolean, Predicate<Update>, Boolean> flagAnd = (flag, nextFlag) -> flag && nextFlag.test(update);
|
||||||
|
return ability.flags().stream()
|
||||||
|
.reduce(true, flagAnd, Boolean::logicalAnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
private File downloadFileWithId(String fileId) throws TelegramApiException {
|
||||||
|
return sender.downloadFile(sender.getFile(new GetFile().setFileId(fileId)));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
package org.telegram.abilitybots.api.db;
|
||||||
|
|
||||||
|
import org.telegram.abilitybots.api.bot.AbilityBot;
|
||||||
|
import org.telegram.telegrambots.api.objects.Update;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface represents the high-level methods exposed to the user when handling an {@link Update}.
|
||||||
|
* Example usage:
|
||||||
|
* <p><code>Ability.builder().action(ctx -> {db.getSet(USERS); doSomething();})* </code></p>
|
||||||
|
* {@link AbilityBot} contains a handle on the <code>db</code> that the user can use inside his declared abilities.
|
||||||
|
*
|
||||||
|
* @author Abbas Abou Daya
|
||||||
|
*/
|
||||||
|
public interface DBContext extends Closeable {
|
||||||
|
/**
|
||||||
|
* @param name the unique name of the {@link List}
|
||||||
|
* @param <T> the type that the List holds
|
||||||
|
* @return the List with the specified name
|
||||||
|
*/
|
||||||
|
<T> List<T> getList(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the unique name of the {@link Map}
|
||||||
|
* @param <K> the type of the Map keys
|
||||||
|
* @param <V> the type of the Map values
|
||||||
|
* @return the Map with the specified name
|
||||||
|
*/
|
||||||
|
<K, V> Map<K, V> getMap(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the unique name of the {@link Set}
|
||||||
|
* @param <T> the type that the Set holds
|
||||||
|
* @return the Set with the specified name
|
||||||
|
*/
|
||||||
|
<T> Set<T> getSet(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a high-level summary of the database structures (Sets, Lists, Maps, ...) present.
|
||||||
|
*/
|
||||||
|
String summary();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementations of this method are free to return any object such as XML, JSON, etc...
|
||||||
|
*
|
||||||
|
* @return a backup of the DB
|
||||||
|
*/
|
||||||
|
Object backup();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The object passed to this method need to conform to the implementation of the {@link DBContext#backup()} method.
|
||||||
|
*
|
||||||
|
* @param backup the backup of the database containing all the structures
|
||||||
|
* @return <tt>true</tt> if the database successfully recovered
|
||||||
|
*/
|
||||||
|
boolean recover(Object backup);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name of the data structure
|
||||||
|
* @return the high-level information of the structure
|
||||||
|
*/
|
||||||
|
String info(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commits the database to its persistent layer. Implementations are free to not implement this method as it is not compulsory.
|
||||||
|
*/
|
||||||
|
void commit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the data structures present in the database.
|
||||||
|
* <p>
|
||||||
|
* This method does not delete the data-structure themselves, but leaves them empty.
|
||||||
|
*/
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name of the data structure
|
||||||
|
* @return <tt>true</tt> if this database contains the specified structure name
|
||||||
|
*/
|
||||||
|
boolean contains(String name);
|
||||||
|
}
|
@ -0,0 +1,224 @@
|
|||||||
|
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.DB;
|
||||||
|
import org.mapdb.DBMaker;
|
||||||
|
import org.mapdb.Serializer;
|
||||||
|
import org.telegram.abilitybots.api.util.Pair;
|
||||||
|
import org.telegram.telegrambots.logging.BotLogger;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static com.google.common.collect.Lists.newArrayList;
|
||||||
|
import static com.google.common.collect.Maps.newHashMap;
|
||||||
|
import static com.google.common.collect.Sets.newHashSet;
|
||||||
|
import static java.lang.String.format;
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
import static java.util.stream.Collectors.toMap;
|
||||||
|
import static java.util.stream.StreamSupport.stream;
|
||||||
|
import static org.mapdb.Serializer.JAVA;
|
||||||
|
import static org.telegram.abilitybots.api.bot.AbilityBot.USERS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of {@link DBContext} that relies on a {@link DB}.
|
||||||
|
*
|
||||||
|
* @author Abbas Abou Daya
|
||||||
|
* @see <a href="https://github.com/jankotek/mapdb">MapDB project</a>
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public class MapDBContext implements DBContext {
|
||||||
|
private static final String TAG = DBContext.class.getSimpleName();
|
||||||
|
|
||||||
|
private final DB db;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
public MapDBContext(DB db) {
|
||||||
|
this.db = db;
|
||||||
|
|
||||||
|
objectMapper = new ObjectMapper();
|
||||||
|
objectMapper.enableDefaultTyping();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DB returned by this method does not trigger deletion on JVM shutdown.
|
||||||
|
*
|
||||||
|
* @param name name of the DB file
|
||||||
|
* @return an online instance of {@link MapDBContext}
|
||||||
|
*/
|
||||||
|
public static DBContext onlineInstance(String name) {
|
||||||
|
DB db = DBMaker
|
||||||
|
.fileDB(name)
|
||||||
|
.fileMmapEnableIfSupported()
|
||||||
|
.closeOnJvmShutdown()
|
||||||
|
.transactionEnable()
|
||||||
|
.make();
|
||||||
|
|
||||||
|
return new MapDBContext(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This DB returned by this method gets deleted on JVM shutdown.
|
||||||
|
*
|
||||||
|
* @param name name of the DB file
|
||||||
|
* @return an offline instance of {@link MapDBContext}
|
||||||
|
*/
|
||||||
|
public static DBContext offlineInstance(String name) {
|
||||||
|
DB db = DBMaker
|
||||||
|
.fileDB(name)
|
||||||
|
.fileMmapEnableIfSupported()
|
||||||
|
.closeOnJvmShutdown()
|
||||||
|
.cleanerHackEnable()
|
||||||
|
.transactionEnable()
|
||||||
|
.fileDeleteAfterClose()
|
||||||
|
.make();
|
||||||
|
|
||||||
|
return new MapDBContext(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> List<T> getList(String name) {
|
||||||
|
return (List<T>) db.<T>indexTreeList(name, Serializer.JAVA).createOrOpen();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <K, V> Map<K, V> getMap(String name) {
|
||||||
|
return db.<K, V>hashMap(name, JAVA, JAVA).createOrOpen();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Set<T> getSet(String name) {
|
||||||
|
return (Set<T>) db.<T>hashSet(name, JAVA).createOrOpen();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String summary() {
|
||||||
|
return stream(db.getAllNames().spliterator(), false)
|
||||||
|
.map(this::info)
|
||||||
|
.reduce(new StringJoiner("\n"), StringJoiner::add, StringJoiner::merge)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object backup() {
|
||||||
|
Map<String, Object> collectedMap = localCopy();
|
||||||
|
return writeAsString(collectedMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean recover(Object backup) {
|
||||||
|
Map<String, Object> snapshot = localCopy();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Map<String, Object> backupData = objectMapper.readValue(backup.toString(), new TypeReference<HashMap<String, Object>>() {
|
||||||
|
});
|
||||||
|
doRecover(backupData);
|
||||||
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
BotLogger.error(format("Could not recover DB data from file with String representation %s", backup), TAG, e);
|
||||||
|
// Attempt to fallback to data snapshot before recovery
|
||||||
|
doRecover(snapshot);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String info(String name) {
|
||||||
|
Object struct = db.get(name);
|
||||||
|
if (isNull(struct))
|
||||||
|
throw new IllegalStateException(format("DB structure with name [%s] does not exist", name));
|
||||||
|
|
||||||
|
if (struct instanceof Set)
|
||||||
|
return format("%s - Set - %d", name, ((Set) struct).size());
|
||||||
|
else if (struct instanceof List)
|
||||||
|
return format("%s - List - %d", name, ((List) struct).size());
|
||||||
|
else if (struct instanceof Map)
|
||||||
|
return format("%s - Map - %d", name, ((Map) struct).size());
|
||||||
|
else
|
||||||
|
return format("%s - %s", name, struct.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void commit() {
|
||||||
|
db.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
db.getAllNames().forEach(name -> {
|
||||||
|
Object struct = db.get(name);
|
||||||
|
if (struct instanceof Collection)
|
||||||
|
((Collection) struct).clear();
|
||||||
|
else if (struct instanceof Map)
|
||||||
|
((Map) struct).clear();
|
||||||
|
});
|
||||||
|
commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(String name) {
|
||||||
|
return db.exists(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a local non-thread safe copy of the database
|
||||||
|
*/
|
||||||
|
private Map<String, Object> localCopy() {
|
||||||
|
return db.getAll().entrySet().stream().map(entry -> {
|
||||||
|
Object struct = entry.getValue();
|
||||||
|
if (struct instanceof Set)
|
||||||
|
return Pair.of(entry.getKey(), newHashSet((Set) struct));
|
||||||
|
else if (struct instanceof List)
|
||||||
|
return Pair.of(entry.getKey(), newArrayList((List) struct));
|
||||||
|
else if (struct instanceof Map)
|
||||||
|
return Pair.of(entry.getKey(), newHashMap((Map) struct));
|
||||||
|
else
|
||||||
|
return Pair.of(entry.getKey(), struct);
|
||||||
|
}).collect(toMap(pair -> (String) pair.a(), Pair::b));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doRecover(Map<String, Object> backupData) {
|
||||||
|
clear();
|
||||||
|
backupData.forEach((name, value) -> {
|
||||||
|
|
||||||
|
if (value instanceof Set) {
|
||||||
|
Set entrySet = (Set) value;
|
||||||
|
getSet(name).addAll(entrySet);
|
||||||
|
} else if (value instanceof Map) {
|
||||||
|
Map<Object, Object> entryMap = (Map) value;
|
||||||
|
|
||||||
|
// TODO: This is ugly
|
||||||
|
// Special handling of USERS since the key is an integer. JSON by default considers a map a JSONObject.
|
||||||
|
// Keys are serialized and deserialized as String
|
||||||
|
if (name.equals(USERS))
|
||||||
|
entryMap = entryMap.entrySet().stream()
|
||||||
|
.map(entry -> Pair.of(Integer.parseInt(entry.getKey().toString()), entry.getValue()))
|
||||||
|
.collect(toMap(Pair::a, Pair::b));
|
||||||
|
|
||||||
|
getMap(name).putAll(entryMap);
|
||||||
|
} else if (value instanceof List) {
|
||||||
|
List entryList = (List) value;
|
||||||
|
getList(name).addAll(entryList);
|
||||||
|
} else {
|
||||||
|
BotLogger.error(TAG, format("Unable to identify object type during DB recovery, entry name: %s", name));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String writeAsString(Object obj) {
|
||||||
|
try {
|
||||||
|
return objectMapper.writeValueAsString(obj);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
BotLogger.info(format("Failed to read the JSON representation of object: %s", obj), TAG, e);
|
||||||
|
return "Error reading required data...";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,208 @@
|
|||||||
|
package org.telegram.abilitybots.api.objects;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import org.telegram.telegrambots.api.objects.Update;
|
||||||
|
import org.telegram.telegrambots.logging.BotLogger;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.collect.Lists.newArrayList;
|
||||||
|
import static java.lang.String.format;
|
||||||
|
import static java.util.Objects.hash;
|
||||||
|
import static java.util.Optional.ofNullable;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ability is a fully-fledged bot action that contains all the necessary information to process:
|
||||||
|
* <ol>
|
||||||
|
* <li>A response to a command</li>
|
||||||
|
* <li>A post-response to a command</li>
|
||||||
|
* <li>A reply to a sequence of actions</li>
|
||||||
|
* </ol>
|
||||||
|
* <p>
|
||||||
|
* In-order to instantiate an ability, you can call {@link Ability#builder()} to get the {@link AbilityBuilder}.
|
||||||
|
* Once you're done setting your ability, you'll call {@link AbilityBuilder#build()} to get your constructed ability.
|
||||||
|
* <p>
|
||||||
|
* The only optional fields in an ability are {@link Ability#info}, {@link Ability#postAction}, {@link Ability#flags} and {@link Ability#replies}.
|
||||||
|
*
|
||||||
|
* @author Abbas Abou Daya
|
||||||
|
*/
|
||||||
|
public final class Ability {
|
||||||
|
private static final String TAG = Ability.class.getSimpleName();
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final String info;
|
||||||
|
private final Locality locality;
|
||||||
|
private final Privacy privacy;
|
||||||
|
private final int argNum;
|
||||||
|
private final Consumer<MessageContext> action;
|
||||||
|
private final Consumer<MessageContext> postAction;
|
||||||
|
private final List<Reply> replies;
|
||||||
|
private final List<Predicate<Update>> flags;
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
private Ability(String name, String info, Locality locality, Privacy privacy, int argNum, Consumer<MessageContext> action, Consumer<MessageContext> postAction, List<Reply> replies, Predicate<Update>... flags) {
|
||||||
|
checkArgument(!isEmpty(name), "Method name cannot be empty");
|
||||||
|
checkArgument(!containsWhitespace(name), "Method name cannot contain spaces");
|
||||||
|
checkArgument(isAlphanumeric(name), "Method name can only be alpha-numeric", name);
|
||||||
|
this.name = name;
|
||||||
|
this.info = info;
|
||||||
|
|
||||||
|
this.locality = checkNotNull(locality, "Please specify a valid locality setting. Use the Locality enum class");
|
||||||
|
this.privacy = checkNotNull(privacy, "Please specify a valid privacy setting. Use the Privacy enum class");
|
||||||
|
|
||||||
|
checkArgument(argNum >= 0, "The number of arguments the method can handle CANNOT be negative. " +
|
||||||
|
"Use the number 0 if the method ignores the arguments OR uses as many as appended");
|
||||||
|
this.argNum = argNum;
|
||||||
|
|
||||||
|
this.action = checkNotNull(action, "Method action can't be empty. Please assign a function by using .action() method");
|
||||||
|
if (postAction == null)
|
||||||
|
BotLogger.info(TAG, format("No post action was detected for method with name [%s]", name));
|
||||||
|
|
||||||
|
this.flags = ofNullable(flags).map(Arrays::asList).orElse(newArrayList());
|
||||||
|
|
||||||
|
this.postAction = postAction;
|
||||||
|
this.replies = replies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AbilityBuilder builder() {
|
||||||
|
return new AbilityBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String info() {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Locality locality() {
|
||||||
|
return locality;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Privacy privacy() {
|
||||||
|
return privacy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int tokens() {
|
||||||
|
return argNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Consumer<MessageContext> action() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Consumer<MessageContext> postAction() {
|
||||||
|
return postAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Reply> replies() {
|
||||||
|
return replies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Predicate<Update>> flags() {
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("name", name)
|
||||||
|
.add("locality", locality)
|
||||||
|
.add("privacy", privacy)
|
||||||
|
.add("argNum", argNum)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Ability ability = (Ability) o;
|
||||||
|
return argNum == ability.argNum &&
|
||||||
|
Objects.equal(name, ability.name) &&
|
||||||
|
locality == ability.locality &&
|
||||||
|
privacy == ability.privacy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return hash(name, info, locality, privacy, argNum, action, postAction, replies, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AbilityBuilder {
|
||||||
|
private String name;
|
||||||
|
private String info;
|
||||||
|
private Privacy privacy;
|
||||||
|
private Locality locality;
|
||||||
|
private int argNum;
|
||||||
|
private Consumer<MessageContext> consumer;
|
||||||
|
private Consumer<MessageContext> postConsumer;
|
||||||
|
private List<Reply> replies;
|
||||||
|
private Flag[] flags;
|
||||||
|
|
||||||
|
private AbilityBuilder() {
|
||||||
|
replies = newArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbilityBuilder action(Consumer<MessageContext> consumer) {
|
||||||
|
this.consumer = consumer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbilityBuilder name(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbilityBuilder info(String info) {
|
||||||
|
this.info = info;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbilityBuilder flag(Flag... flags) {
|
||||||
|
this.flags = flags;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbilityBuilder locality(Locality type) {
|
||||||
|
this.locality = type;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbilityBuilder input(int argNum) {
|
||||||
|
this.argNum = argNum;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbilityBuilder privacy(Privacy privacy) {
|
||||||
|
this.privacy = privacy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbilityBuilder post(Consumer<MessageContext> postConsumer) {
|
||||||
|
this.postConsumer = postConsumer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final AbilityBuilder reply(Consumer<Update> action, Predicate<Update>... conditions) {
|
||||||
|
replies.add(Reply.of(action, conditions));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ability build() {
|
||||||
|
return new Ability(name, info, locality, privacy, argNum, consumer, postConsumer, replies, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
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.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();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package org.telegram.abilitybots.api.objects;
|
||||||
|
|
||||||
|
import org.telegram.abilitybots.api.objects.Ability.AbilityBuilder;
|
||||||
|
import org.telegram.telegrambots.api.objects.Update;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
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[])}.
|
||||||
|
*
|
||||||
|
* @author Abbas Abou Daya
|
||||||
|
*/
|
||||||
|
public enum Flag implements Predicate<Update> {
|
||||||
|
// Update Flags
|
||||||
|
NONE(update -> true),
|
||||||
|
MESSAGE(Update::hasMessage),
|
||||||
|
CALLBACK_QUERY(Update::hasCallbackQuery),
|
||||||
|
CHANNEL_POST(Update::hasChannelPost),
|
||||||
|
EDITED_CHANNEL_POST(Update::hasEditedChannelPost),
|
||||||
|
EDITED_MESSAGE(Update::hasEditedMessage),
|
||||||
|
INLINE_QUERY(Update::hasInlineQuery),
|
||||||
|
CHOSEN_INLINE_QUERY(Update::hasChosenInlineQuery),
|
||||||
|
|
||||||
|
// Message Flags
|
||||||
|
REPLY(update -> update.getMessage().isReply()),
|
||||||
|
DOCUMENT(upd -> upd.getMessage().hasDocument()),
|
||||||
|
TEXT(upd -> upd.getMessage().hasText()),
|
||||||
|
PHOTO(upd -> upd.getMessage().hasPhoto()),
|
||||||
|
LOCATION(upd -> upd.getMessage().hasLocation()),
|
||||||
|
CAPTION(upd -> nonNull(upd.getMessage().getCaption()));
|
||||||
|
|
||||||
|
private final Predicate<Update> predicate;
|
||||||
|
|
||||||
|
Flag(Predicate<Update> predicate) {
|
||||||
|
this.predicate = predicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean test(Update update) {
|
||||||
|
return nonNull(update) && predicate.test(update);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package org.telegram.abilitybots.api.objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locality identifies the location in which you want your message to be accessed.
|
||||||
|
* <p>
|
||||||
|
* If locality of your message is set to <code>USER</code>, then the ability will only be executed if its being called in a user private chat.
|
||||||
|
*
|
||||||
|
* @author Abbas Abou Daya
|
||||||
|
*/
|
||||||
|
public enum Locality {
|
||||||
|
/**
|
||||||
|
* Ability would be valid for groups and private user chats
|
||||||
|
*/
|
||||||
|
ALL,
|
||||||
|
/**
|
||||||
|
* Only user chats
|
||||||
|
*/
|
||||||
|
USER,
|
||||||
|
/**
|
||||||
|
* Only group chats
|
||||||
|
*/
|
||||||
|
GROUP
|
||||||
|
}
|
@ -0,0 +1,123 @@
|
|||||||
|
package org.telegram.abilitybots.api.objects;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import org.telegram.telegrambots.api.objects.Update;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageContext is a wrapper class to the {@link Update}, originating end-user and the arguments present in its message (if any).
|
||||||
|
* <p>
|
||||||
|
* A user is not bound to the usage of this higher level context as it's possible to fetch the underlying {@link Update} using {@link MessageContext#update()}.
|
||||||
|
*
|
||||||
|
* @author Abbas Abou Daya
|
||||||
|
*/
|
||||||
|
public class MessageContext {
|
||||||
|
private final EndUser user;
|
||||||
|
private final Long chatId;
|
||||||
|
private final String[] arguments;
|
||||||
|
private final Update update;
|
||||||
|
|
||||||
|
private MessageContext(Update update, EndUser 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) {
|
||||||
|
return new MessageContext(update, user, chatId, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the originating Telegram user of this update
|
||||||
|
*/
|
||||||
|
public EndUser user() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the originating chatId, maps correctly to both group and user-private chats
|
||||||
|
*/
|
||||||
|
public Long chatId() {
|
||||||
|
return chatId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If there's no message in the update, then this will an empty array.
|
||||||
|
*
|
||||||
|
* @return the text sent by the user message.
|
||||||
|
*/
|
||||||
|
public String[] arguments() {
|
||||||
|
return arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the first argument directly after the command
|
||||||
|
* @throws IllegalStateException if message has no arguments
|
||||||
|
*/
|
||||||
|
public String firstArg() {
|
||||||
|
checkLength();
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the second argument directly after the command
|
||||||
|
* @throws IllegalStateException if message has no arguments
|
||||||
|
*/
|
||||||
|
public String secondArg() {
|
||||||
|
checkLength();
|
||||||
|
return arguments[1 % arguments.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the third argument directly after the command
|
||||||
|
* @throws IllegalStateException if message has no arguments
|
||||||
|
*/
|
||||||
|
public String thirdArg() {
|
||||||
|
checkLength();
|
||||||
|
return arguments[2 % arguments.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the actual update behind this context
|
||||||
|
*/
|
||||||
|
public Update update() {
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkLength() {
|
||||||
|
if (arguments.length == 0)
|
||||||
|
throw new IllegalStateException("This message has no arguments");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("user", user)
|
||||||
|
.add("chatId", chatId)
|
||||||
|
.add("arguments", arguments)
|
||||||
|
.add("update", update)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MessageContext that = (MessageContext) o;
|
||||||
|
return Objects.equal(user, that.user) &&
|
||||||
|
Objects.equal(chatId, that.chatId) &&
|
||||||
|
Arrays.equals(arguments, that.arguments) &&
|
||||||
|
Objects.equal(update, that.update);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(user, chatId, Arrays.hashCode(arguments), update);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package org.telegram.abilitybots.api.objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Privacy represents a restriction on <b>who</b> can use the ability.
|
||||||
|
*
|
||||||
|
* @author Abbas Abou Daya
|
||||||
|
*/
|
||||||
|
public enum Privacy {
|
||||||
|
/**
|
||||||
|
* Anybody who is not a bot admin or its creator will be considered as a public user.
|
||||||
|
*/
|
||||||
|
PUBLIC,
|
||||||
|
/**
|
||||||
|
* A global admin of the bot, regardless of the group the bot is in.
|
||||||
|
*/
|
||||||
|
ADMIN,
|
||||||
|
/**
|
||||||
|
* The creator of the bot.
|
||||||
|
*/
|
||||||
|
CREATOR
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package org.telegram.abilitybots.api.objects;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import org.telegram.telegrambots.api.objects.Update;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reply consists of update conditionals and an action to be applied on the update.
|
||||||
|
* <p>
|
||||||
|
* If an update satisfies the {@link Reply#conditions}set by the reply, then it's safe to {@link Reply#actOn(Update)}.
|
||||||
|
*
|
||||||
|
* @author Abbas Abou Daya
|
||||||
|
*/
|
||||||
|
public final class Reply {
|
||||||
|
public final List<Predicate<Update>> conditions;
|
||||||
|
public final Consumer<Update> action;
|
||||||
|
|
||||||
|
private Reply(List<Predicate<Update>> conditions, Consumer<Update> action) {
|
||||||
|
this.conditions = conditions;
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public static Reply of(Consumer<Update> action, Predicate<Update>... conditions) {
|
||||||
|
return new Reply(asList(conditions), action);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOkFor(Update update) {
|
||||||
|
// The following variable is required to avoid bug #JDK-8044546
|
||||||
|
BiFunction<Boolean, Predicate<Update>, Boolean> stateAnd = (state, cond) -> state && cond.test(update);
|
||||||
|
return conditions.stream().reduce(true, stateAnd, Boolean::logicalAnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void actOn(Update update) {
|
||||||
|
action.accept(update);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Reply reply = (Reply) o;
|
||||||
|
return Objects.equals(conditions, reply.conditions) &&
|
||||||
|
Objects.equals(action, reply.action);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(conditions, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("conditions", conditions)
|
||||||
|
.add("action", action)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,493 @@
|
|||||||
|
package org.telegram.abilitybots.api.sender;
|
||||||
|
|
||||||
|
import org.telegram.telegrambots.api.methods.*;
|
||||||
|
import org.telegram.telegrambots.api.methods.games.GetGameHighScores;
|
||||||
|
import org.telegram.telegrambots.api.methods.games.SetGameScore;
|
||||||
|
import org.telegram.telegrambots.api.methods.groupadministration.*;
|
||||||
|
import org.telegram.telegrambots.api.methods.pinnedmessages.PinChatMessage;
|
||||||
|
import org.telegram.telegrambots.api.methods.pinnedmessages.UnpinChatMessage;
|
||||||
|
import org.telegram.telegrambots.api.methods.send.*;
|
||||||
|
import org.telegram.telegrambots.api.methods.updates.DeleteWebhook;
|
||||||
|
import org.telegram.telegrambots.api.methods.updatingmessages.DeleteMessage;
|
||||||
|
import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageCaption;
|
||||||
|
import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageReplyMarkup;
|
||||||
|
import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageText;
|
||||||
|
import org.telegram.telegrambots.api.objects.*;
|
||||||
|
import org.telegram.telegrambots.api.objects.games.GameHighScore;
|
||||||
|
import org.telegram.telegrambots.api.objects.replykeyboard.ForceReplyKeyboard;
|
||||||
|
import org.telegram.telegrambots.bots.DefaultAbsSender;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiException;
|
||||||
|
import org.telegram.telegrambots.logging.BotLogger;
|
||||||
|
import org.telegram.telegrambots.updateshandlers.DownloadFileCallback;
|
||||||
|
import org.telegram.telegrambots.updateshandlers.SentCallback;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static java.util.Optional.empty;
|
||||||
|
import static java.util.Optional.ofNullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default implementation of the {@link MessageSender}. This serves as a proxy to the {@link DefaultAbsSender} methods.
|
||||||
|
* <p>Most of the methods below will be directly calling the bot's similar functions. However, there are some methods introduced to ease sending messages such as:</p>
|
||||||
|
* <ol>
|
||||||
|
* <li>{@link DefaultMessageSender#sendMd(String, long)} - with markdown</li>
|
||||||
|
* <li>{@link DefaultMessageSender#send(String, long)} - without markdown</li>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* @author Abbas Abou Daya
|
||||||
|
*/
|
||||||
|
public class DefaultMessageSender implements MessageSender {
|
||||||
|
private static final String TAG = MessageSender.class.getName();
|
||||||
|
|
||||||
|
private DefaultAbsSender bot;
|
||||||
|
|
||||||
|
public DefaultMessageSender(DefaultAbsSender bot) {
|
||||||
|
this.bot = bot;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Message> send(String message, long id) {
|
||||||
|
return doSendMessage(message, id, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Message> sendMd(String message, long id) {
|
||||||
|
return doSendMessage(message, id, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Message> forceReply(String message, long id) {
|
||||||
|
SendMessage msg = new SendMessage();
|
||||||
|
msg.setText(message);
|
||||||
|
msg.setChatId(id);
|
||||||
|
msg.setReplyMarkup(new ForceReplyKeyboard());
|
||||||
|
|
||||||
|
return optionalSendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean answerInlineQuery(AnswerInlineQuery answerInlineQuery) throws TelegramApiException {
|
||||||
|
return bot.execute(answerInlineQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean sendChatAction(SendChatAction sendChatAction) throws TelegramApiException {
|
||||||
|
return bot.execute(sendChatAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message forwardMessage(ForwardMessage forwardMessage) throws TelegramApiException {
|
||||||
|
return bot.execute(forwardMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message sendLocation(SendLocation sendLocation) throws TelegramApiException {
|
||||||
|
return bot.execute(sendLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message sendVenue(SendVenue sendVenue) throws TelegramApiException {
|
||||||
|
return bot.execute(sendVenue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message sendContact(SendContact sendContact) throws TelegramApiException {
|
||||||
|
return bot.execute(sendContact);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean kickMember(KickChatMember kickChatMember) throws TelegramApiException {
|
||||||
|
return bot.execute(kickChatMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean unbanMember(UnbanChatMember unbanChatMember) throws TelegramApiException {
|
||||||
|
return bot.execute(unbanChatMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean leaveChat(LeaveChat leaveChat) throws TelegramApiException {
|
||||||
|
return bot.execute(leaveChat);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Chat getChat(GetChat getChat) throws TelegramApiException {
|
||||||
|
return bot.execute(getChat);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ChatMember> getChatAdministrators(GetChatAdministrators getChatAdministrators) throws TelegramApiException {
|
||||||
|
return bot.execute(getChatAdministrators);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChatMember getChatMember(GetChatMember getChatMember) throws TelegramApiException {
|
||||||
|
return bot.execute(getChatMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getChatMemberCount(GetChatMemberCount getChatMemberCount) throws TelegramApiException {
|
||||||
|
return bot.execute(getChatMemberCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean setChatPhoto(SetChatPhoto setChatPhoto) throws TelegramApiException {
|
||||||
|
return bot.setChatPhoto(setChatPhoto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean deleteChatPhoto(DeleteChatPhoto deleteChatPhoto) throws TelegramApiException {
|
||||||
|
return bot.execute(deleteChatPhoto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteChatPhoto(DeleteChatPhoto deleteChatPhoto, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(deleteChatPhoto, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean pinChatMessage(PinChatMessage pinChatMessage) throws TelegramApiException {
|
||||||
|
return bot.execute(pinChatMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pinChatMessage(PinChatMessage pinChatMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(pinChatMessage, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean unpinChatMessage(UnpinChatMessage unpinChatMessage) throws TelegramApiException {
|
||||||
|
return bot.execute(unpinChatMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unpinChatMessage(UnpinChatMessage unpinChatMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(unpinChatMessage, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean promoteChatMember(PromoteChatMember promoteChatMember) throws TelegramApiException {
|
||||||
|
return bot.execute(promoteChatMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void promoteChatMember(PromoteChatMember promoteChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(promoteChatMember, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean restrictChatMember(RestrictChatMember restrictChatMember) throws TelegramApiException {
|
||||||
|
return bot.execute(restrictChatMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restrictChatMember(RestrictChatMember restrictChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(restrictChatMember, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean setChatDescription(SetChatDescription setChatDescription) throws TelegramApiException {
|
||||||
|
return bot.execute(setChatDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setChatDescription(SetChatDescription setChatDescription, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(setChatDescription, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean setChatTite(SetChatTitle setChatTitle) throws TelegramApiException {
|
||||||
|
return bot.execute(setChatTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setChatTite(SetChatTitle setChatTitle, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(setChatTitle, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String exportChatInviteLink(ExportChatInviteLink exportChatInviteLink) throws TelegramApiException {
|
||||||
|
return bot.execute(exportChatInviteLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exportChatInviteLinkAsync(ExportChatInviteLink exportChatInviteLink, SentCallback<String> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(exportChatInviteLink, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean deleteMessage(DeleteMessage deleteMessage) throws TelegramApiException {
|
||||||
|
return bot.execute(deleteMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteMessageAsync(DeleteMessage deleteMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(deleteMessage, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializable editMessageText(EditMessageText editMessageText) throws TelegramApiException {
|
||||||
|
return bot.execute(editMessageText);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializable editMessageCaption(EditMessageCaption editMessageCaption) throws TelegramApiException {
|
||||||
|
return bot.execute(editMessageCaption);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializable editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup) throws TelegramApiException {
|
||||||
|
return bot.execute(editMessageReplyMarkup);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean answerCallbackQuery(AnswerCallbackQuery answerCallbackQuery) throws TelegramApiException {
|
||||||
|
return bot.execute(answerCallbackQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserProfilePhotos getUserProfilePhotos(GetUserProfilePhotos getUserProfilePhotos) throws TelegramApiException {
|
||||||
|
return bot.execute(getUserProfilePhotos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.io.File downloadFile(String path) throws TelegramApiException {
|
||||||
|
return bot.downloadFile(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void downloadFileAsync(String path, DownloadFileCallback<String> callback) throws TelegramApiException {
|
||||||
|
bot.downloadFileAsync(path, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.io.File downloadFile(File file) throws TelegramApiException {
|
||||||
|
return bot.downloadFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void downloadFileAsync(File file, DownloadFileCallback<File> callback) throws TelegramApiException {
|
||||||
|
bot.downloadFileAsync(file, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getFile(GetFile getFile) throws TelegramApiException {
|
||||||
|
return bot.execute(getFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User getMe() throws TelegramApiException {
|
||||||
|
return bot.getMe();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WebhookInfo getWebhookInfo() throws TelegramApiException {
|
||||||
|
return bot.getWebhookInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializable setGameScore(SetGameScore setGameScore) throws TelegramApiException {
|
||||||
|
return bot.execute(setGameScore);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializable getGameHighScores(GetGameHighScores getGameHighScores) throws TelegramApiException {
|
||||||
|
return bot.execute(getGameHighScores);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message sendGame(SendGame sendGame) throws TelegramApiException {
|
||||||
|
return bot.execute(sendGame);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean deleteWebhook(DeleteWebhook deleteWebhook) throws TelegramApiException {
|
||||||
|
return bot.execute(deleteWebhook);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message sendMessage(SendMessage sendMessage) throws TelegramApiException {
|
||||||
|
return bot.execute(sendMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessageAsync(SendMessage sendMessage, SentCallback<Message> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(sendMessage, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void answerInlineQueryAsync(AnswerInlineQuery answerInlineQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(answerInlineQuery, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChatActionAsync(SendChatAction sendChatAction, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(sendChatAction, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forwardMessageAsync(ForwardMessage forwardMessage, SentCallback<Message> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(forwardMessage, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendLocationAsync(SendLocation sendLocation, SentCallback<Message> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(sendLocation, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendVenueAsync(SendVenue sendVenue, SentCallback<Message> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(sendVenue, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContactAsync(SendContact sendContact, SentCallback<Message> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(sendContact, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void kickMemberAsync(KickChatMember kickChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(kickChatMember, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unbanMemberAsync(UnbanChatMember unbanChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(unbanChatMember, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void leaveChatAsync(LeaveChat leaveChat, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(leaveChat, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getChatAsync(GetChat getChat, SentCallback<Chat> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(getChat, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getChatAdministratorsAsync(GetChatAdministrators getChatAdministrators, SentCallback<ArrayList<ChatMember>> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(getChatAdministrators, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getChatMemberAsync(GetChatMember getChatMember, SentCallback<ChatMember> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(getChatMember, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getChatMemberCountAsync(GetChatMemberCount getChatMemberCount, SentCallback<Integer> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(getChatMemberCount, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void editMessageTextAsync(EditMessageText editMessageText, SentCallback<Serializable> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(editMessageText, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void editMessageCaptionAsync(EditMessageCaption editMessageCaption, SentCallback<Serializable> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(editMessageCaption, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup, SentCallback<Serializable> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(editMessageReplyMarkup, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void answerCallbackQueryAsync(AnswerCallbackQuery answerCallbackQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(answerCallbackQuery, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getUserProfilePhotosAsync(GetUserProfilePhotos getUserProfilePhotos, SentCallback<UserProfilePhotos> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(getUserProfilePhotos, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getFileAsync(GetFile getFile, SentCallback<File> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(getFile, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getMeAsync(SentCallback<User> sentCallback) throws TelegramApiException {
|
||||||
|
bot.getMeAsync(sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getWebhookInfoAsync(SentCallback<WebhookInfo> sentCallback) throws TelegramApiException {
|
||||||
|
bot.getWebhookInfoAsync(sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setGameScoreAsync(SetGameScore setGameScore, SentCallback<Serializable> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(setGameScore, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getGameHighScoresAsync(GetGameHighScores getGameHighScores, SentCallback<ArrayList<GameHighScore>> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(getGameHighScores, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendGameAsync(SendGame sendGame, SentCallback<Message> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(sendGame, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteWebhook(DeleteWebhook deleteWebhook, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
|
bot.executeAsync(deleteWebhook, sentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message sendDocument(SendDocument sendDocument) throws TelegramApiException {
|
||||||
|
return bot.sendDocument(sendDocument);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message sendPhoto(SendPhoto sendPhoto) throws TelegramApiException {
|
||||||
|
return bot.sendPhoto(sendPhoto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message sendVideo(SendVideo sendVideo) throws TelegramApiException {
|
||||||
|
return bot.sendVideo(sendVideo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message sendSticker(SendSticker sendSticker) throws TelegramApiException {
|
||||||
|
return bot.sendSticker(sendSticker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message sendAudio(SendAudio sendAudio) throws TelegramApiException {
|
||||||
|
return bot.sendAudio(sendAudio);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message sendVoice(SendVoice sendVoice) throws TelegramApiException {
|
||||||
|
return bot.sendVoice(sendVoice);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<Message> doSendMessage(String txt, long groupId, boolean format) {
|
||||||
|
SendMessage smsg = new SendMessage();
|
||||||
|
smsg.setChatId(groupId);
|
||||||
|
smsg.setText(txt);
|
||||||
|
smsg.enableMarkdown(format);
|
||||||
|
|
||||||
|
return optionalSendMessage(smsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<Message> optionalSendMessage(SendMessage smsg) {
|
||||||
|
try {
|
||||||
|
return ofNullable(sendMessage(smsg));
|
||||||
|
} catch (TelegramApiException e) {
|
||||||
|
BotLogger.error("Could not send message", TAG, e);
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,200 @@
|
|||||||
|
package org.telegram.abilitybots.api.sender;
|
||||||
|
|
||||||
|
import org.telegram.telegrambots.api.methods.*;
|
||||||
|
import org.telegram.telegrambots.api.methods.games.GetGameHighScores;
|
||||||
|
import org.telegram.telegrambots.api.methods.games.SetGameScore;
|
||||||
|
import org.telegram.telegrambots.api.methods.groupadministration.*;
|
||||||
|
import org.telegram.telegrambots.api.methods.pinnedmessages.PinChatMessage;
|
||||||
|
import org.telegram.telegrambots.api.methods.pinnedmessages.UnpinChatMessage;
|
||||||
|
import org.telegram.telegrambots.api.methods.send.*;
|
||||||
|
import org.telegram.telegrambots.api.methods.updates.DeleteWebhook;
|
||||||
|
import org.telegram.telegrambots.api.methods.updatingmessages.DeleteMessage;
|
||||||
|
import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageCaption;
|
||||||
|
import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageReplyMarkup;
|
||||||
|
import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageText;
|
||||||
|
import org.telegram.telegrambots.api.objects.*;
|
||||||
|
import org.telegram.telegrambots.api.objects.games.GameHighScore;
|
||||||
|
import org.telegram.telegrambots.bots.DefaultAbsSender;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiException;
|
||||||
|
import org.telegram.telegrambots.updateshandlers.DownloadFileCallback;
|
||||||
|
import org.telegram.telegrambots.updateshandlers.SentCallback;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A sender interface that replicates {@link DefaultAbsSender} methods.
|
||||||
|
*
|
||||||
|
* @author Abbas Abou Daya
|
||||||
|
*/
|
||||||
|
public interface MessageSender {
|
||||||
|
Optional<Message> send(String message, long id);
|
||||||
|
|
||||||
|
Optional<Message> sendMd(String message, long id);
|
||||||
|
|
||||||
|
Optional<Message> forceReply(String message, long id);
|
||||||
|
|
||||||
|
Boolean answerInlineQuery(AnswerInlineQuery answerInlineQuery) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean sendChatAction(SendChatAction sendChatAction) throws TelegramApiException;
|
||||||
|
|
||||||
|
Message forwardMessage(ForwardMessage forwardMessage) throws TelegramApiException;
|
||||||
|
|
||||||
|
Message sendLocation(SendLocation sendLocation) throws TelegramApiException;
|
||||||
|
|
||||||
|
Message sendVenue(SendVenue sendVenue) throws TelegramApiException;
|
||||||
|
|
||||||
|
Message sendContact(SendContact sendContact) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean kickMember(KickChatMember kickChatMember) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean unbanMember(UnbanChatMember unbanChatMember) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean leaveChat(LeaveChat leaveChat) throws TelegramApiException;
|
||||||
|
|
||||||
|
Chat getChat(GetChat getChat) throws TelegramApiException;
|
||||||
|
|
||||||
|
List<ChatMember> getChatAdministrators(GetChatAdministrators getChatAdministrators) throws TelegramApiException;
|
||||||
|
|
||||||
|
ChatMember getChatMember(GetChatMember getChatMember) throws TelegramApiException;
|
||||||
|
|
||||||
|
Integer getChatMemberCount(GetChatMemberCount getChatMemberCount) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean setChatPhoto(SetChatPhoto setChatPhoto) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean deleteChatPhoto(DeleteChatPhoto deleteChatPhoto) throws TelegramApiException;
|
||||||
|
|
||||||
|
void deleteChatPhoto(DeleteChatPhoto deleteChatPhoto, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean pinChatMessage(PinChatMessage pinChatMessage) throws TelegramApiException;
|
||||||
|
|
||||||
|
void pinChatMessage(PinChatMessage pinChatMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean unpinChatMessage(UnpinChatMessage unpinChatMessage) throws TelegramApiException;
|
||||||
|
|
||||||
|
void unpinChatMessage(UnpinChatMessage unpinChatMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean promoteChatMember(PromoteChatMember promoteChatMember) throws TelegramApiException;
|
||||||
|
|
||||||
|
void promoteChatMember(PromoteChatMember promoteChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean restrictChatMember(RestrictChatMember restrictChatMember) throws TelegramApiException;
|
||||||
|
|
||||||
|
void restrictChatMember(RestrictChatMember restrictChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean setChatDescription(SetChatDescription setChatDescription) throws TelegramApiException;
|
||||||
|
|
||||||
|
void setChatDescription(SetChatDescription setChatDescription, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean setChatTite(SetChatTitle setChatTitle) throws TelegramApiException;
|
||||||
|
|
||||||
|
void setChatTite(SetChatTitle setChatTitle, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
String exportChatInviteLink(ExportChatInviteLink exportChatInviteLink) throws TelegramApiException;
|
||||||
|
|
||||||
|
void exportChatInviteLinkAsync(ExportChatInviteLink exportChatInviteLink, SentCallback<String> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean deleteMessage(DeleteMessage deleteMessage) throws TelegramApiException;
|
||||||
|
|
||||||
|
void deleteMessageAsync(DeleteMessage deleteMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
Serializable editMessageText(EditMessageText editMessageText) throws TelegramApiException;
|
||||||
|
|
||||||
|
Serializable editMessageCaption(EditMessageCaption editMessageCaption) throws TelegramApiException;
|
||||||
|
|
||||||
|
Serializable editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean answerCallbackQuery(AnswerCallbackQuery answerCallbackQuery) throws TelegramApiException;
|
||||||
|
|
||||||
|
UserProfilePhotos getUserProfilePhotos(GetUserProfilePhotos getUserProfilePhotos) throws TelegramApiException;
|
||||||
|
|
||||||
|
java.io.File downloadFile(String path) throws TelegramApiException;
|
||||||
|
|
||||||
|
void downloadFileAsync(String path, DownloadFileCallback<String> callback) throws TelegramApiException;
|
||||||
|
|
||||||
|
java.io.File downloadFile(File file) throws TelegramApiException;
|
||||||
|
|
||||||
|
void downloadFileAsync(File file, DownloadFileCallback<File> callback) throws TelegramApiException;
|
||||||
|
|
||||||
|
File getFile(GetFile getFile) throws TelegramApiException;
|
||||||
|
|
||||||
|
User getMe() throws TelegramApiException;
|
||||||
|
|
||||||
|
WebhookInfo getWebhookInfo() throws TelegramApiException;
|
||||||
|
|
||||||
|
Serializable setGameScore(SetGameScore setGameScore) throws TelegramApiException;
|
||||||
|
|
||||||
|
Serializable getGameHighScores(GetGameHighScores getGameHighScores) throws TelegramApiException;
|
||||||
|
|
||||||
|
Message sendGame(SendGame sendGame) throws TelegramApiException;
|
||||||
|
|
||||||
|
Boolean deleteWebhook(DeleteWebhook deleteWebhook) throws TelegramApiException;
|
||||||
|
|
||||||
|
Message sendMessage(SendMessage sendMessage) throws TelegramApiException;
|
||||||
|
|
||||||
|
void sendMessageAsync(SendMessage sendMessage, SentCallback<Message> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void answerInlineQueryAsync(AnswerInlineQuery answerInlineQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void sendChatActionAsync(SendChatAction sendChatAction, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void forwardMessageAsync(ForwardMessage forwardMessage, SentCallback<Message> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void sendLocationAsync(SendLocation sendLocation, SentCallback<Message> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void sendVenueAsync(SendVenue sendVenue, SentCallback<Message> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void sendContactAsync(SendContact sendContact, SentCallback<Message> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void kickMemberAsync(KickChatMember kickChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void unbanMemberAsync(UnbanChatMember unbanChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void leaveChatAsync(LeaveChat leaveChat, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void getChatAsync(GetChat getChat, SentCallback<Chat> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void getChatAdministratorsAsync(GetChatAdministrators getChatAdministrators, SentCallback<ArrayList<ChatMember>> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void getChatMemberAsync(GetChatMember getChatMember, SentCallback<ChatMember> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void getChatMemberCountAsync(GetChatMemberCount getChatMemberCount, SentCallback<Integer> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void editMessageTextAsync(EditMessageText editMessageText, SentCallback<Serializable> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void editMessageCaptionAsync(EditMessageCaption editMessageCaption, SentCallback<Serializable> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup, SentCallback<Serializable> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void answerCallbackQueryAsync(AnswerCallbackQuery answerCallbackQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void getUserProfilePhotosAsync(GetUserProfilePhotos getUserProfilePhotos, SentCallback<UserProfilePhotos> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void getFileAsync(GetFile getFile, SentCallback<File> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void getMeAsync(SentCallback<User> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void getWebhookInfoAsync(SentCallback<WebhookInfo> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void setGameScoreAsync(SetGameScore setGameScore, SentCallback<Serializable> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void getGameHighScoresAsync(GetGameHighScores getGameHighScores, SentCallback<ArrayList<GameHighScore>> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void sendGameAsync(SendGame sendGame, SentCallback<Message> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
void deleteWebhook(DeleteWebhook deleteWebhook, SentCallback<Boolean> sentCallback) throws TelegramApiException;
|
||||||
|
|
||||||
|
Message sendDocument(SendDocument sendDocument) throws TelegramApiException;
|
||||||
|
|
||||||
|
Message sendPhoto(SendPhoto sendPhoto) throws TelegramApiException;
|
||||||
|
|
||||||
|
Message sendVideo(SendVideo sendVideo) throws TelegramApiException;
|
||||||
|
|
||||||
|
Message sendSticker(SendSticker sendSticker) throws TelegramApiException;
|
||||||
|
|
||||||
|
Message sendAudio(SendAudio sendAudio) throws TelegramApiException;
|
||||||
|
|
||||||
|
Message sendVoice(SendVoice sendVoice) throws TelegramApiException;
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
package org.telegram.abilitybots.api.util;
|
||||||
|
|
||||||
|
import org.telegram.abilitybots.api.db.DBContext;
|
||||||
|
import org.telegram.abilitybots.api.objects.MessageContext;
|
||||||
|
import org.telegram.telegrambots.api.objects.Update;
|
||||||
|
import org.telegram.telegrambots.api.objects.User;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import static org.telegram.abilitybots.api.objects.Flag.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper and utility methods
|
||||||
|
*/
|
||||||
|
public final class AbilityUtils {
|
||||||
|
private AbilityUtils() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param username any username
|
||||||
|
* @return the username with the preceding "@" stripped off
|
||||||
|
*/
|
||||||
|
public static String stripTag(String username) {
|
||||||
|
String lowerCase = username.toLowerCase();
|
||||||
|
return lowerCase.startsWith("@") ? lowerCase.substring(1, lowerCase.length()) : lowerCase;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commits to DB.
|
||||||
|
*
|
||||||
|
* @param db the database to commit on
|
||||||
|
* @return a lambda consumer that takes in a {@link MessageContext}, used in post actions for abilities
|
||||||
|
*/
|
||||||
|
public static Consumer<MessageContext> commitTo(DBContext db) {
|
||||||
|
return ctx -> db.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the user who caused the update.
|
||||||
|
*
|
||||||
|
* @param update a Telegram {@link Update}
|
||||||
|
* @return the originating user
|
||||||
|
* @throws IllegalStateException if the user could not be found
|
||||||
|
*/
|
||||||
|
public static User getUser(Update update) {
|
||||||
|
if (MESSAGE.test(update)) {
|
||||||
|
return update.getMessage().getFrom();
|
||||||
|
} else if (CALLBACK_QUERY.test(update)) {
|
||||||
|
return update.getCallbackQuery().getFrom();
|
||||||
|
} else if (INLINE_QUERY.test(update)) {
|
||||||
|
return update.getInlineQuery().getFrom();
|
||||||
|
} else if (CHANNEL_POST.test(update)) {
|
||||||
|
return update.getChannelPost().getFrom();
|
||||||
|
} else if (EDITED_CHANNEL_POST.test(update)) {
|
||||||
|
return update.getEditedChannelPost().getFrom();
|
||||||
|
} else if (EDITED_MESSAGE.test(update)) {
|
||||||
|
return update.getEditedMessage().getFrom();
|
||||||
|
} else if (CHOSEN_INLINE_QUERY.test(update)) {
|
||||||
|
return update.getChosenInlineQuery().getFrom();
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Could not retrieve originating user from update");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the direct chat ID of the specified update.
|
||||||
|
*
|
||||||
|
* @param update a Telegram {@link Update}
|
||||||
|
* @return the originating chat ID
|
||||||
|
* @throws IllegalStateException if the chat ID could not be found
|
||||||
|
*/
|
||||||
|
public static Long getChatId(Update update) {
|
||||||
|
if (MESSAGE.test(update)) {
|
||||||
|
return update.getMessage().getChatId();
|
||||||
|
} else if (CALLBACK_QUERY.test(update)) {
|
||||||
|
return update.getCallbackQuery().getMessage().getChatId();
|
||||||
|
} else if (INLINE_QUERY.test(update)) {
|
||||||
|
return (long) update.getInlineQuery().getFrom().getId();
|
||||||
|
} else if (CHANNEL_POST.test(update)) {
|
||||||
|
return update.getChannelPost().getChatId();
|
||||||
|
} else if (EDITED_CHANNEL_POST.test(update)) {
|
||||||
|
return update.getEditedChannelPost().getChatId();
|
||||||
|
} else if (EDITED_MESSAGE.test(update)) {
|
||||||
|
return update.getEditedMessage().getChatId();
|
||||||
|
} else if (CHOSEN_INLINE_QUERY.test(update)) {
|
||||||
|
return (long) update.getChosenInlineQuery().getFrom().getId();
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Could not retrieve originating chat ID from update");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param update a Telegram {@link Update}
|
||||||
|
* @return <tt>true</tt> if the update contains contains a private user message
|
||||||
|
*/
|
||||||
|
public static boolean isUserMessage(Update update) {
|
||||||
|
if (MESSAGE.test(update)) {
|
||||||
|
return update.getMessage().isUserMessage();
|
||||||
|
} else if (CALLBACK_QUERY.test(update)) {
|
||||||
|
return update.getCallbackQuery().getMessage().isUserMessage();
|
||||||
|
} else if (CHANNEL_POST.test(update)) {
|
||||||
|
return update.getChannelPost().isUserMessage();
|
||||||
|
} else if (EDITED_CHANNEL_POST.test(update)) {
|
||||||
|
return update.getEditedChannelPost().isUserMessage();
|
||||||
|
} else if (EDITED_MESSAGE.test(update)) {
|
||||||
|
return update.getEditedMessage().isUserMessage();
|
||||||
|
} else if (CHOSEN_INLINE_QUERY.test(update) || INLINE_QUERY.test(update)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Could not retrieve update context origin (user/group)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param username the username to add the tag to
|
||||||
|
* @return the username prefixed with the "@" tag.
|
||||||
|
*/
|
||||||
|
public static String addTag(String username) {
|
||||||
|
return "@" + username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param msg the message to be replied to
|
||||||
|
* @return a predicate that asserts that the update is a reply to the specified message.
|
||||||
|
*/
|
||||||
|
public static Predicate<Update> isReplyTo(String msg) {
|
||||||
|
return update -> update.getMessage().getReplyToMessage().getText().equals(msg);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package org.telegram.abilitybots.api.util;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public final class Pair<A, B> {
|
||||||
|
@JsonProperty("a")
|
||||||
|
private final A a;
|
||||||
|
@JsonProperty("b")
|
||||||
|
private final B b;
|
||||||
|
|
||||||
|
private Pair(A a, B b) {
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public static <A, B> Pair<A, B> of(@JsonProperty("a") A a, @JsonProperty("b") B b) {
|
||||||
|
return new Pair<>(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public A a() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public B b() {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Pair<?, ?> pair = (Pair<?, ?>) o;
|
||||||
|
return Objects.equals(a, pair.a) &&
|
||||||
|
Objects.equals(b, pair.b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("a", a)
|
||||||
|
.add("b", b)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package org.telegram.abilitybots.api.util;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class Trio<A, B, C> {
|
||||||
|
@JsonProperty("a")
|
||||||
|
private final A a;
|
||||||
|
@JsonProperty("b")
|
||||||
|
private final B b;
|
||||||
|
@JsonProperty("c")
|
||||||
|
private final C c;
|
||||||
|
|
||||||
|
private Trio(A a, B b, C c) {
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
this.c = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public static <A, B, C> Trio<A, B, C> of(@JsonProperty("a") A a, @JsonProperty("b") B b, @JsonProperty("c") C c) {
|
||||||
|
return new Trio<>(a, b, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public A a() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public B b() {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public C c() {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Trio<?, ?, ?> trio = (Trio<?, ?, ?>) o;
|
||||||
|
return Objects.equals(a, trio.a) &&
|
||||||
|
Objects.equals(b, trio.b) &&
|
||||||
|
Objects.equals(c, trio.c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(a, b, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("a", a)
|
||||||
|
.add("b", b)
|
||||||
|
.add("c", c)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,588 @@
|
|||||||
|
package org.telegram.abilitybots.api.bot;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Matchers;
|
||||||
|
import org.telegram.abilitybots.api.db.DBContext;
|
||||||
|
import org.telegram.abilitybots.api.objects.*;
|
||||||
|
import org.telegram.abilitybots.api.sender.MessageSender;
|
||||||
|
import org.telegram.abilitybots.api.util.Pair;
|
||||||
|
import org.telegram.abilitybots.api.util.Trio;
|
||||||
|
import org.telegram.telegrambots.api.objects.*;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiException;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static com.google.common.collect.Sets.newHashSet;
|
||||||
|
import static java.lang.String.format;
|
||||||
|
import static java.util.Collections.emptySet;
|
||||||
|
import static org.apache.commons.lang3.ArrayUtils.addAll;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.EMPTY;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
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;
|
||||||
|
import static org.telegram.abilitybots.api.objects.Locality.GROUP;
|
||||||
|
import static org.telegram.abilitybots.api.objects.MessageContext.newContext;
|
||||||
|
import static org.telegram.abilitybots.api.objects.Privacy.ADMIN;
|
||||||
|
import static org.telegram.abilitybots.api.objects.Privacy.PUBLIC;
|
||||||
|
|
||||||
|
public class AbilityBotTest {
|
||||||
|
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");
|
||||||
|
|
||||||
|
private DefaultBot bot;
|
||||||
|
private DBContext db;
|
||||||
|
private MessageSender sender;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
db = offlineInstance("db");
|
||||||
|
bot = new DefaultBot(EMPTY, EMPTY, db);
|
||||||
|
sender = mock(MessageSender.class);
|
||||||
|
bot.setSender(sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sendsPrivacyViolation() {
|
||||||
|
Update update = mockFullUpdate(MUSER, "/admin");
|
||||||
|
|
||||||
|
bot.onUpdateReceived(update);
|
||||||
|
|
||||||
|
verify(sender, times(1)).send(format("Sorry, %s-only feature.", "admin"), MUSER.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sendsLocalityViolation() {
|
||||||
|
Update update = mockFullUpdate(MUSER, "/group");
|
||||||
|
|
||||||
|
bot.onUpdateReceived(update);
|
||||||
|
|
||||||
|
verify(sender, times(1)).send(format("Sorry, %s-only feature.", "group"), MUSER.id());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sendsInputArgsViolation() {
|
||||||
|
Update update = mockFullUpdate(MUSER, "/count 1 2 3");
|
||||||
|
|
||||||
|
bot.onUpdateReceived(update);
|
||||||
|
|
||||||
|
verify(sender, times(1)).send(format("Sorry, this feature requires %d additional inputs.", 4), MUSER.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canProcessRepliesIfSatisfyRequirements() {
|
||||||
|
Update update = mockFullUpdate(MUSER, "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(sender, times(1)).send("reply", MUSER.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canBackupDB() throws TelegramApiException {
|
||||||
|
MessageContext context = defaultContext();
|
||||||
|
|
||||||
|
bot.backupDB().action().accept(context);
|
||||||
|
|
||||||
|
verify(sender, times(1)).sendDocument(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canRecoverDB() throws TelegramApiException, IOException {
|
||||||
|
Update update = mockBackupUpdate();
|
||||||
|
Object backup = getDbBackup();
|
||||||
|
java.io.File backupFile = createBackupFile(backup);
|
||||||
|
|
||||||
|
when(sender.downloadFile(Matchers.any(File.class))).thenReturn(backupFile);
|
||||||
|
bot.recoverDB().replies().get(0).actOn(update);
|
||||||
|
|
||||||
|
verify(sender, times(1)).send(RECOVER_SUCCESS, GROUP_ID);
|
||||||
|
assertEquals("Bot recovered but the DB is still not in sync", db.getSet(TEST), newHashSet(TEST));
|
||||||
|
assertTrue("Could not delete backup file", backupFile.delete());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canFilterOutReplies() {
|
||||||
|
Update update = mock(Update.class);
|
||||||
|
when(update.hasMessage()).thenReturn(false);
|
||||||
|
|
||||||
|
assertTrue(bot.filterReply(update));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canDemote() {
|
||||||
|
addUsers(MUSER);
|
||||||
|
bot.admins().add(MUSER.id());
|
||||||
|
|
||||||
|
MessageContext context = defaultContext();
|
||||||
|
|
||||||
|
bot.demoteAdmin().action().accept(context);
|
||||||
|
|
||||||
|
Set<Integer> actual = bot.admins();
|
||||||
|
Set<Integer> expected = emptySet();
|
||||||
|
assertEquals("Could not sudont super-admin", expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canPromote() {
|
||||||
|
addUsers(MUSER);
|
||||||
|
|
||||||
|
MessageContext context = defaultContext();
|
||||||
|
|
||||||
|
bot.promoteAdmin().action().accept(context);
|
||||||
|
|
||||||
|
Set<Integer> actual = bot.admins();
|
||||||
|
Set<Integer> expected = newHashSet(MUSER.id());
|
||||||
|
assertEquals("Could not sudo user", expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canBanUser() {
|
||||||
|
addUsers(MUSER);
|
||||||
|
MessageContext context = defaultContext();
|
||||||
|
|
||||||
|
bot.banUser().action().accept(context);
|
||||||
|
|
||||||
|
Set<Integer> actual = bot.blacklist();
|
||||||
|
Set<Integer> expected = newHashSet(MUSER.id());
|
||||||
|
assertEquals("The ban was not emplaced", expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canUnbanUser() {
|
||||||
|
addUsers(MUSER);
|
||||||
|
bot.blacklist().add(MUSER.id());
|
||||||
|
|
||||||
|
MessageContext context = defaultContext();
|
||||||
|
|
||||||
|
bot.unbanUser().action().accept(context);
|
||||||
|
|
||||||
|
Set<Integer> actual = bot.blacklist();
|
||||||
|
Set<Integer> expected = newHashSet();
|
||||||
|
assertEquals("The ban was not lifted", expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private MessageContext defaultContext() {
|
||||||
|
MessageContext context = mock(MessageContext.class);
|
||||||
|
when(context.user()).thenReturn(CREATOR);
|
||||||
|
when(context.firstArg()).thenReturn(MUSER.username());
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cannotBanCreator() {
|
||||||
|
addUsers(MUSER, CREATOR);
|
||||||
|
MessageContext context = mock(MessageContext.class);
|
||||||
|
when(context.user()).thenReturn(MUSER);
|
||||||
|
when(context.firstArg()).thenReturn(CREATOR.username());
|
||||||
|
|
||||||
|
bot.banUser().action().accept(context);
|
||||||
|
|
||||||
|
Set<Integer> actual = bot.blacklist();
|
||||||
|
Set<Integer> expected = newHashSet(MUSER.id());
|
||||||
|
assertEquals("Impostor was not added to the blacklist", expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addUsers(EndUser... users) {
|
||||||
|
Arrays.stream(users).forEach(user -> {
|
||||||
|
bot.users().put(user.id(), user);
|
||||||
|
bot.userIds().put(user.username().toLowerCase(), user.id());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void creatorCanClaimBot() {
|
||||||
|
MessageContext context = mock(MessageContext.class);
|
||||||
|
when(context.user()).thenReturn(CREATOR);
|
||||||
|
|
||||||
|
bot.claimCreator().action().accept(context);
|
||||||
|
|
||||||
|
Set<Integer> actual = bot.admins();
|
||||||
|
Set<Integer> expected = newHashSet(CREATOR.id());
|
||||||
|
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());
|
||||||
|
Update update = mock(Update.class);
|
||||||
|
Message message = mock(Message.class);
|
||||||
|
User user = mock(User.class);
|
||||||
|
|
||||||
|
mockUser(update, message, user);
|
||||||
|
|
||||||
|
boolean notBanned = bot.checkBlacklist(update);
|
||||||
|
assertTrue("Creator is banned", notBanned);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canAddUser() {
|
||||||
|
Update update = mock(Update.class);
|
||||||
|
Message message = mock(Message.class);
|
||||||
|
User user = mock(User.class);
|
||||||
|
|
||||||
|
mockAlternateUser(update, message, user, MUSER);
|
||||||
|
|
||||||
|
bot.addUser(update);
|
||||||
|
|
||||||
|
Map<String, Integer> expectedUserIds = ImmutableMap.of(MUSER.username(), MUSER.id());
|
||||||
|
Map<Integer, EndUser> expectedUsers = ImmutableMap.of(MUSER.id(), MUSER);
|
||||||
|
assertEquals("User was not added", expectedUserIds, bot.userIds());
|
||||||
|
assertEquals("User was not added", expectedUsers, bot.users());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canEditUser() {
|
||||||
|
addUsers(MUSER);
|
||||||
|
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);
|
||||||
|
|
||||||
|
mockAlternateUser(update, message, user, changedUser);
|
||||||
|
|
||||||
|
bot.addUser(update);
|
||||||
|
|
||||||
|
Map<String, Integer> expectedUserIds = ImmutableMap.of(changedUser.username(), changedUser.id());
|
||||||
|
Map<Integer, EndUser> expectedUsers = ImmutableMap.of(changedUser.id(), changedUser);
|
||||||
|
assertEquals("User was not properly edited", bot.userIds(), expectedUserIds);
|
||||||
|
assertEquals("User was not properly edited", expectedUsers, expectedUsers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canValidateAbility() {
|
||||||
|
Trio<Update, Ability, String[]> invalidPair = Trio.of(null, null, null);
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canCheckInput() {
|
||||||
|
Update update = mockFullUpdate(MUSER, "/something");
|
||||||
|
Ability abilityWithOneInput = getDefaultBuilder()
|
||||||
|
.build();
|
||||||
|
Ability abilityWithZeroInput = getDefaultBuilder()
|
||||||
|
.input(0)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
trioOneArg = Trio.of(update, abilityWithOneInput, addAll(TEXT, TEXT));
|
||||||
|
assertEquals("Unexpected result when applying token filter", false, bot.checkInput(trioOneArg));
|
||||||
|
|
||||||
|
assertEquals("Unexpected result when applying token filter", true, bot.checkInput(trioZeroArg));
|
||||||
|
|
||||||
|
trioZeroArg = Trio.of(update, abilityWithZeroInput, EMPTY_ARRAY);
|
||||||
|
assertEquals("Unexpected result when applying token filter", true, bot.checkInput(trioZeroArg));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canCheckPrivacy() {
|
||||||
|
Update update = mock(Update.class);
|
||||||
|
Message message = mock(Message.class);
|
||||||
|
org.telegram.telegrambots.api.objects.User user = mock(User.class);
|
||||||
|
Ability publicAbility = getDefaultBuilder().privacy(PUBLIC).build();
|
||||||
|
Ability adminAbility = getDefaultBuilder().privacy(ADMIN).build();
|
||||||
|
Ability creatorAbility = getDefaultBuilder().privacy(Privacy.CREATOR).build();
|
||||||
|
|
||||||
|
Trio<Update, Ability, String[]> publicTrio = Trio.of(update, publicAbility, TEXT);
|
||||||
|
Trio<Update, Ability, String[]> adminTrio = Trio.of(update, adminAbility, TEXT);
|
||||||
|
Trio<Update, Ability, String[]> creatorTrio = Trio.of(update, creatorAbility, TEXT);
|
||||||
|
|
||||||
|
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(adminTrio));
|
||||||
|
assertEquals("Unexpected result when checking for privacy", false, bot.checkPrivacy(creatorTrio));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canBlockAdminsFromCreatorAbilities() {
|
||||||
|
Update update = mock(Update.class);
|
||||||
|
Message message = mock(Message.class);
|
||||||
|
org.telegram.telegrambots.api.objects.User user = mock(User.class);
|
||||||
|
Ability creatorAbility = getDefaultBuilder().privacy(Privacy.CREATOR).build();
|
||||||
|
|
||||||
|
Trio<Update, Ability, String[]> creatorTrio = Trio.of(update, creatorAbility, TEXT);
|
||||||
|
|
||||||
|
bot.admins().add(MUSER.id());
|
||||||
|
mockUser(update, message, user);
|
||||||
|
|
||||||
|
assertEquals("Unexpected result when checking for privacy", false, bot.checkPrivacy(creatorTrio));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canCheckLocality() {
|
||||||
|
Update update = mock(Update.class);
|
||||||
|
Message message = mock(Message.class);
|
||||||
|
User user = mock(User.class);
|
||||||
|
Ability allAbility = getDefaultBuilder().locality(ALL).build();
|
||||||
|
Ability userAbility = getDefaultBuilder().locality(Locality.USER).build();
|
||||||
|
Ability groupAbility = getDefaultBuilder().locality(GROUP).build();
|
||||||
|
|
||||||
|
Trio<Update, Ability, String[]> publicTrio = Trio.of(update, allAbility, TEXT);
|
||||||
|
Trio<Update, Ability, String[]> userTrio = Trio.of(update, userAbility, TEXT);
|
||||||
|
Trio<Update, Ability, String[]> groupTrio = Trio.of(update, groupAbility, TEXT);
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
|
|
||||||
|
Pair<MessageContext, Ability> actualPair = bot.getContext(trio);
|
||||||
|
Pair<MessageContext, Ability> expectedPair = Pair.of(newContext(update, MUSER, GROUP_ID, TEXT), ability);
|
||||||
|
|
||||||
|
assertEquals("Unexpected result when fetching for context", expectedPair, actualPair);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canCheckGlobalFlags() {
|
||||||
|
Update update = mock(Update.class);
|
||||||
|
Message message = mock(Message.class);
|
||||||
|
|
||||||
|
when(update.hasMessage()).thenReturn(true);
|
||||||
|
when(update.getMessage()).thenReturn(message);
|
||||||
|
assertEquals("Unexpected result when checking for locality", true, bot.checkGlobalFlags(update));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ArithmeticException.class)
|
||||||
|
public void canConsumeUpdate() {
|
||||||
|
Ability ability = getDefaultBuilder()
|
||||||
|
.action((context) -> {
|
||||||
|
int x = 1 / 0;
|
||||||
|
}).build();
|
||||||
|
MessageContext context = mock(MessageContext.class);
|
||||||
|
|
||||||
|
Pair<MessageContext, Ability> pair = Pair.of(context, ability);
|
||||||
|
|
||||||
|
bot.consumeUpdate(pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canFetchAbility() {
|
||||||
|
Update update = mock(Update.class);
|
||||||
|
Message message = mock(Message.class);
|
||||||
|
|
||||||
|
String text = "/test";
|
||||||
|
when(update.hasMessage()).thenReturn(true);
|
||||||
|
when(update.getMessage()).thenReturn(message);
|
||||||
|
when(update.getMessage().hasText()).thenReturn(true);
|
||||||
|
when(message.getText()).thenReturn(text);
|
||||||
|
|
||||||
|
Trio<Update, Ability, String[]> trio = bot.getAbility(update);
|
||||||
|
|
||||||
|
Ability expected = bot.testAbility();
|
||||||
|
Ability actual = trio.b();
|
||||||
|
|
||||||
|
assertEquals("Wrong ability was fetched", expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canFetchDefaultAbility() {
|
||||||
|
Update update = mock(Update.class);
|
||||||
|
Message message = mock(Message.class);
|
||||||
|
|
||||||
|
String text = "test tags";
|
||||||
|
when(update.getMessage()).thenReturn(message);
|
||||||
|
when(message.getText()).thenReturn(text);
|
||||||
|
|
||||||
|
Trio<Update, Ability, String[]> trio = bot.getAbility(update);
|
||||||
|
|
||||||
|
Ability expected = bot.defaultAbility();
|
||||||
|
Ability actual = trio.b();
|
||||||
|
|
||||||
|
assertEquals("Wrong ability was fetched", expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canCheckAbilityFlags() {
|
||||||
|
Update update = mock(Update.class);
|
||||||
|
Message message = mock(Message.class);
|
||||||
|
|
||||||
|
when(update.hasMessage()).thenReturn(true);
|
||||||
|
when(update.getMessage()).thenReturn(message);
|
||||||
|
when(message.hasDocument()).thenReturn(false);
|
||||||
|
when(message.hasText()).thenReturn(true);
|
||||||
|
|
||||||
|
Ability documentAbility = getDefaultBuilder().flag(DOCUMENT, MESSAGE).build();
|
||||||
|
Ability textAbility = getDefaultBuilder().flag(Flag.TEXT, MESSAGE).build();
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canReportCommands() {
|
||||||
|
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);
|
||||||
|
|
||||||
|
bot.reportCommands().action().accept(context);
|
||||||
|
|
||||||
|
verify(sender, times(1)).send("default - dis iz default command", GROUP_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws IOException {
|
||||||
|
db.clear();
|
||||||
|
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());
|
||||||
|
|
||||||
|
bot.admins().add(CREATOR.id());
|
||||||
|
|
||||||
|
User user = mockUser(fromUser);
|
||||||
|
|
||||||
|
Update update = mock(Update.class);
|
||||||
|
when(update.hasMessage()).thenReturn(true);
|
||||||
|
Message message = mock(Message.class);
|
||||||
|
when(message.getFrom()).thenReturn(user);
|
||||||
|
when(message.getText()).thenReturn(args);
|
||||||
|
when(message.hasText()).thenReturn(true);
|
||||||
|
when(message.isUserMessage()).thenReturn(true);
|
||||||
|
when(message.getChatId()).thenReturn((long) fromUser.id());
|
||||||
|
when(update.getMessage()).thenReturn(message);
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mockUser(Update update, Message message, User user) {
|
||||||
|
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());
|
||||||
|
when(message.getFrom()).thenReturn(user);
|
||||||
|
when(update.hasMessage()).thenReturn(true);
|
||||||
|
when(update.getMessage()).thenReturn(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Update mockBackupUpdate() {
|
||||||
|
Update update = mock(Update.class);
|
||||||
|
Message message = mock(Message.class);
|
||||||
|
Message botMessage = mock(Message.class);
|
||||||
|
Document document = mock(Document.class);
|
||||||
|
|
||||||
|
when(update.getMessage()).thenReturn(message);
|
||||||
|
when(message.getDocument()).thenReturn(document);
|
||||||
|
when(botMessage.getText()).thenReturn(RECOVERY_MESSAGE);
|
||||||
|
when(message.isReply()).thenReturn(true);
|
||||||
|
when(message.hasDocument()).thenReturn(true);
|
||||||
|
when(message.getReplyToMessage()).thenReturn(botMessage);
|
||||||
|
when(message.getChatId()).thenReturn(GROUP_ID);
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getDbBackup() {
|
||||||
|
db.getSet(TEST).add(TEST);
|
||||||
|
Object backup = db.backup();
|
||||||
|
db.clear();
|
||||||
|
return backup;
|
||||||
|
}
|
||||||
|
|
||||||
|
private java.io.File createBackupFile(Object backup) throws IOException {
|
||||||
|
java.io.File backupFile = new java.io.File(TEST);
|
||||||
|
BufferedWriter writer = Files.newWriter(backupFile, Charset.defaultCharset());
|
||||||
|
writer.write(backup.toString());
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
return backupFile;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package org.telegram.abilitybots.api.bot;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import org.telegram.abilitybots.api.db.DBContext;
|
||||||
|
import org.telegram.abilitybots.api.objects.Ability;
|
||||||
|
import org.telegram.abilitybots.api.objects.Ability.AbilityBuilder;
|
||||||
|
import org.telegram.abilitybots.api.sender.MessageSender;
|
||||||
|
|
||||||
|
import static org.telegram.abilitybots.api.objects.Ability.builder;
|
||||||
|
import static org.telegram.abilitybots.api.objects.Flag.CALLBACK_QUERY;
|
||||||
|
import static org.telegram.abilitybots.api.objects.Flag.MESSAGE;
|
||||||
|
import static org.telegram.abilitybots.api.objects.Locality.*;
|
||||||
|
import static org.telegram.abilitybots.api.objects.Privacy.ADMIN;
|
||||||
|
import static org.telegram.abilitybots.api.objects.Privacy.PUBLIC;
|
||||||
|
|
||||||
|
public class DefaultBot extends AbilityBot {
|
||||||
|
|
||||||
|
public DefaultBot(String token, String username, DBContext db) {
|
||||||
|
super(token, username, db);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AbilityBuilder getDefaultBuilder() {
|
||||||
|
return builder()
|
||||||
|
.name("test")
|
||||||
|
.privacy(PUBLIC)
|
||||||
|
.locality(ALL)
|
||||||
|
.input(1)
|
||||||
|
.action(ctx -> {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int creatorId() {
|
||||||
|
return 1337;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ability defaultAbility() {
|
||||||
|
return getDefaultBuilder()
|
||||||
|
.name(DEFAULT)
|
||||||
|
.info("dis iz default command")
|
||||||
|
.reply(upd -> sender.send("reply", upd.getMessage().getChatId()), MESSAGE, update -> update.getMessage().getText().equals("must reply"))
|
||||||
|
.reply(upd -> sender.send("reply", upd.getCallbackQuery().getMessage().getChatId()), CALLBACK_QUERY)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ability adminAbility() {
|
||||||
|
return getDefaultBuilder()
|
||||||
|
.name("admin")
|
||||||
|
.privacy(ADMIN)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ability groupAbility() {
|
||||||
|
return getDefaultBuilder()
|
||||||
|
.name("group")
|
||||||
|
.privacy(PUBLIC)
|
||||||
|
.locality(GROUP)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ability multipleInputAbility() {
|
||||||
|
return getDefaultBuilder()
|
||||||
|
.name("count")
|
||||||
|
.privacy(PUBLIC)
|
||||||
|
.locality(USER)
|
||||||
|
.input(4)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ability testAbility() {
|
||||||
|
return getDefaultBuilder().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void setSender(MessageSender sender) {
|
||||||
|
this.sender = sender;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,109 @@
|
|||||||
|
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 java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
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.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.db.MapDBContext.offlineInstance;
|
||||||
|
|
||||||
|
public class MapDBContextTest {
|
||||||
|
|
||||||
|
private static final String TEST = "TEST";
|
||||||
|
private DBContext db;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
db = offlineInstance("db");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canRecoverDB() throws IOException {
|
||||||
|
Map<Integer, EndUser> 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());
|
||||||
|
|
||||||
|
db.getSet("AYRE").add(123123);
|
||||||
|
Map<Integer, EndUser> 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);
|
||||||
|
String afterRecoveryInfo = db.info(USERS);
|
||||||
|
|
||||||
|
assertTrue("Could not recover database successfully", recovered);
|
||||||
|
assertEquals("Map info before and after recovery is different", beforeBackupInfo, afterRecoveryInfo);
|
||||||
|
assertEquals("Map before and after recovery are not equal", originalUsers, recoveredUsers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canFallbackDBIfRecoveryFails() throws IOException {
|
||||||
|
Set<EndUser> users = db.getSet(USERS);
|
||||||
|
users.add(CREATOR);
|
||||||
|
users.add(MUSER);
|
||||||
|
|
||||||
|
Set<EndUser> originalSet = newHashSet(users);
|
||||||
|
Object jsonBackup = db.backup();
|
||||||
|
String corruptBackup = "!@#$" + String.valueOf(jsonBackup);
|
||||||
|
boolean recovered = db.recover(corruptBackup);
|
||||||
|
|
||||||
|
Set<EndUser> recoveredSet = db.getSet(USERS);
|
||||||
|
|
||||||
|
assertEquals("Recovery was successful from a CORRUPT backup", false, recovered);
|
||||||
|
assertEquals("Set before and after corrupt recovery are not equal", originalSet, recoveredSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canGetSummary() throws IOException {
|
||||||
|
String anotherTest = TEST + 1;
|
||||||
|
db.getSet(TEST).add(TEST);
|
||||||
|
db.getSet(anotherTest).add(anotherTest);
|
||||||
|
|
||||||
|
String actualSummary = db.summary();
|
||||||
|
// Name - Type - Number of "rows"
|
||||||
|
String expectedSummary = format("%s - Set - 1\n%s - Set - 1", TEST, anotherTest);
|
||||||
|
|
||||||
|
assertEquals("Actual DB summary does not match that of the expected", expectedSummary, actualSummary);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canGetInfo() throws IOException {
|
||||||
|
db.getSet(TEST).add(TEST);
|
||||||
|
|
||||||
|
String actualInfo = db.info(TEST);
|
||||||
|
// JSON
|
||||||
|
String expectedInfo = "TEST - Set - 1";
|
||||||
|
|
||||||
|
assertEquals("Actual DB structure info does not match that of the expected", expectedInfo, actualInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void cantGetInfoFromNonexistentDBStructureName() throws IOException {
|
||||||
|
db.info(TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws IOException {
|
||||||
|
db.clear();
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package org.telegram.abilitybots.api.objects;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
import static org.telegram.abilitybots.api.bot.DefaultBot.getDefaultBuilder;
|
||||||
|
|
||||||
|
public class AbilityTest {
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void argumentsCannotBeNegative() {
|
||||||
|
getDefaultBuilder().input(-4).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void nameCannotBeEmpty() {
|
||||||
|
getDefaultBuilder().name("").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void nameCannotBeNull() {
|
||||||
|
getDefaultBuilder().name(null).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void consumerCannotBeNull() {
|
||||||
|
getDefaultBuilder().action(null).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void localityCannotBeNull() {
|
||||||
|
getDefaultBuilder().locality(null).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void privacyCannotBeNull() {
|
||||||
|
getDefaultBuilder().privacy(null).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void nameCannotContainSpaces() {
|
||||||
|
getDefaultBuilder().name("test test").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void abilityEqualsMethod() {
|
||||||
|
Ability ability1 = getDefaultBuilder().build();
|
||||||
|
Ability ability2 = getDefaultBuilder().build();
|
||||||
|
Ability ability3 = getDefaultBuilder().name("anotherconsumer").build();
|
||||||
|
Ability ability4 = getDefaultBuilder().action((context) -> {
|
||||||
|
}).build();
|
||||||
|
|
||||||
|
assertEquals("Abilities should not be equal", ability1, ability2);
|
||||||
|
assertEquals("Abilities should not be equal", ability1, ability4);
|
||||||
|
assertNotEquals("Abilities should be equal", ability1, ability3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,12 +16,12 @@ Just import add the library to your project with one of these options:
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.telegram</groupId>
|
<groupId>org.telegram</groupId>
|
||||||
<artifactId>telegrambotsextensions</artifactId>
|
<artifactId>telegrambotsextensions</artifactId>
|
||||||
<version>3.1.2</version>
|
<version>3.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Using Gradle:
|
2. Using Gradle:
|
||||||
|
|
||||||
```gradle
|
```gradle
|
||||||
compile "org.telegram:telegrambotsextensions:3.1.2"
|
compile "org.telegram:telegrambotsextensions:3.2"
|
||||||
```
|
```
|
@ -5,7 +5,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.telegram</groupId>
|
<groupId>org.telegram</groupId>
|
||||||
<artifactId>telegrambotsextensions</artifactId>
|
<artifactId>telegrambotsextensions</artifactId>
|
||||||
<version>3.1.2</version>
|
<version>3.2</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Telegram Bots Extensions</name>
|
<name>Telegram Bots Extensions</name>
|
||||||
@ -59,7 +59,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<bots.version>3.1.2</bots.version>
|
<bots.version>3.2</bots.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -24,17 +24,6 @@ public abstract class TelegramLongPollingCommandBot extends TelegramLongPollingB
|
|||||||
private final CommandRegistry commandRegistry;
|
private final CommandRegistry commandRegistry;
|
||||||
private String botUsername;
|
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
|
* Creates a TelegramLongPollingCommandBot using default options
|
||||||
* Use ICommandRegistry's methods on this bot to register commands
|
* Use ICommandRegistry's methods on this bot to register commands
|
||||||
@ -45,19 +34,6 @@ public abstract class TelegramLongPollingCommandBot extends TelegramLongPollingB
|
|||||||
this(ApiContext.getInstance(DefaultBotOptions.class), 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
|
* Creates a TelegramLongPollingCommandBot with custom options and allowing commands with
|
||||||
* usernames
|
* usernames
|
||||||
@ -69,21 +45,6 @@ public abstract class TelegramLongPollingCommandBot extends TelegramLongPollingB
|
|||||||
this(options, true, 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
|
* Creates a TelegramLongPollingCommandBot
|
||||||
* Use ICommandRegistry's methods on this bot to register commands
|
* Use ICommandRegistry's methods on this bot to register commands
|
||||||
@ -164,11 +125,10 @@ public abstract class TelegramLongPollingCommandBot extends TelegramLongPollingB
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO This method will become final in next mayor release, avoid overriding it
|
|
||||||
* @return Bot username
|
* @return Bot username
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getBotUsername() {
|
public final String getBotUsername() {
|
||||||
return botUsername;
|
return botUsername;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.telegram</groupId>
|
<groupId>org.telegram</groupId>
|
||||||
<artifactId>telegrambots-meta</artifactId>
|
<artifactId>telegrambots-meta</artifactId>
|
||||||
<version>3.1.2</version>
|
<version>3.2</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Telegram Bots Meta</name>
|
<name>Telegram Bots Meta</name>
|
||||||
|
@ -50,6 +50,7 @@ public class ApiContext {
|
|||||||
return INJECTOR;
|
return INJECTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private static class ApiModule extends AbstractModule {
|
private static class ApiModule extends AbstractModule {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
|
@ -0,0 +1,190 @@
|
|||||||
|
package org.telegram.telegrambots.api.methods.stickers;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import org.telegram.telegrambots.api.methods.PartialBotApiMethod;
|
||||||
|
import org.telegram.telegrambots.api.objects.replykeyboard.ApiResponse;
|
||||||
|
import org.telegram.telegrambots.api.objects.stickers.MaskPosition;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiRequestException;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiValidationException;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Ruben Bermudez
|
||||||
|
* @version 1.0
|
||||||
|
* Use this method to add a new sticker to a set created by the bot. Returns True on success.
|
||||||
|
*/
|
||||||
|
public class AddStickerToSet extends PartialBotApiMethod<Boolean> {
|
||||||
|
public static final String PATH = "addStickerToSet";
|
||||||
|
|
||||||
|
public static final String USERID_FIELD = "user_id";
|
||||||
|
public static final String NAME_FIELD = "name";
|
||||||
|
public static final String PNGSTICKER_FIELD = "png_sticker";
|
||||||
|
public static final String EMOJIS_FIELD = "emojis";
|
||||||
|
public static final String MASKPOSITION_FIELD = "mask_position";
|
||||||
|
|
||||||
|
private Integer userId; ///< User identifier of sticker set owner
|
||||||
|
private String name; ///< Sticker set name
|
||||||
|
private String emojis; ///< One or more emoji corresponding to the sticker
|
||||||
|
private MaskPosition maskPosition; ///< Position where the mask should be placed on faces
|
||||||
|
/**
|
||||||
|
* Png image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px,
|
||||||
|
* and either width or height must be exactly 512px. Pass a file_id as a String to send a file
|
||||||
|
* that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram
|
||||||
|
* to get a file from the Internet, or upload a new one using multipart/form-data.
|
||||||
|
*/
|
||||||
|
private Boolean isNewPngSticker;
|
||||||
|
private String pngSticker;
|
||||||
|
private File pngStickerFile; ///< New sticker file
|
||||||
|
private InputStream pngStickerStream; ///< New sticker stream
|
||||||
|
private String pngStickerName; ///< New sticker stream name
|
||||||
|
|
||||||
|
public AddStickerToSet() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AddStickerToSet(Integer userId, String name, String emojis) {
|
||||||
|
this.userId = checkNotNull(userId);
|
||||||
|
this.name = checkNotNull(name);
|
||||||
|
this.emojis = checkNotNull(emojis);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AddStickerToSet setUserId(Integer userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPngSticker() {
|
||||||
|
return pngSticker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AddStickerToSet setPngSticker(String pngSticker) {
|
||||||
|
this.pngSticker = pngSticker;
|
||||||
|
this.isNewPngSticker = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getPngStickerFile() {
|
||||||
|
return pngStickerFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AddStickerToSet setPngStickerFile(File pngStickerFile) {
|
||||||
|
Objects.requireNonNull(pngStickerFile, "pngStickerFile cannot be null!");
|
||||||
|
this.pngStickerFile = pngStickerFile;
|
||||||
|
this.isNewPngSticker = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getPngStickerStream() {
|
||||||
|
return pngStickerStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AddStickerToSet setPngStickerStream(String pngStickerName, InputStream pngStickerStream) {
|
||||||
|
Objects.requireNonNull(pngStickerName, "pngStickerName cannot be null!");
|
||||||
|
Objects.requireNonNull(pngStickerStream, "pngStickerStream cannot be null!");
|
||||||
|
this.pngStickerStream = pngStickerStream;
|
||||||
|
this.pngStickerName = pngStickerName;
|
||||||
|
this.isNewPngSticker = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPngStickerName() {
|
||||||
|
return pngStickerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isNewPngSticker() {
|
||||||
|
return isNewPngSticker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AddStickerToSet setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmojis() {
|
||||||
|
return emojis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AddStickerToSet setEmojis(String emojis) {
|
||||||
|
this.emojis = emojis;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaskPosition getMaskPosition() {
|
||||||
|
return maskPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AddStickerToSet setMaskPosition(MaskPosition maskPosition) {
|
||||||
|
this.maskPosition = maskPosition;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean deserializeResponse(String answer) throws TelegramApiRequestException {
|
||||||
|
try {
|
||||||
|
ApiResponse<Boolean> result = OBJECT_MAPPER.readValue(answer,
|
||||||
|
new TypeReference<ApiResponse<Boolean>>(){});
|
||||||
|
if (result.getOk()) {
|
||||||
|
return result.getResult();
|
||||||
|
} else {
|
||||||
|
throw new TelegramApiRequestException("Error creating new sticker set", result);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new TelegramApiRequestException("Unable to deserialize response", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate() throws TelegramApiValidationException {
|
||||||
|
if (userId == null || userId <= 0) {
|
||||||
|
throw new TelegramApiValidationException("userId can't be empty", this);
|
||||||
|
}
|
||||||
|
if (name == null || name.isEmpty()) {
|
||||||
|
throw new TelegramApiValidationException("name can't be empty", this);
|
||||||
|
}
|
||||||
|
if (emojis == null || emojis.isEmpty()) {
|
||||||
|
throw new TelegramApiValidationException("emojis can't be empty", this);
|
||||||
|
}
|
||||||
|
if (isNewPngSticker) {
|
||||||
|
if (pngStickerFile == null && pngStickerStream == null) {
|
||||||
|
throw new TelegramApiValidationException("PngSticker can't be empty", this);
|
||||||
|
}
|
||||||
|
if (pngStickerStream != null && (pngStickerName == null || pngStickerName.isEmpty())) {
|
||||||
|
throw new TelegramApiValidationException("PngSticker name can't be empty", this);
|
||||||
|
}
|
||||||
|
} else if (pngSticker == null) {
|
||||||
|
throw new TelegramApiValidationException("PngSticker can't be empty", this);
|
||||||
|
}
|
||||||
|
if (maskPosition != null) {
|
||||||
|
maskPosition.validate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "AddStickerToSet{" +
|
||||||
|
"userId=" + userId +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", emojis='" + emojis + '\'' +
|
||||||
|
", maskPosition=" + maskPosition +
|
||||||
|
", isNewPngSticker=" + isNewPngSticker +
|
||||||
|
", pngSticker='" + pngSticker + '\'' +
|
||||||
|
", pngStickerFile=" + pngStickerFile +
|
||||||
|
", pngStickerStream=" + pngStickerStream +
|
||||||
|
", pngStickerName='" + pngStickerName + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,220 @@
|
|||||||
|
package org.telegram.telegrambots.api.methods.stickers;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import org.telegram.telegrambots.api.methods.PartialBotApiMethod;
|
||||||
|
import org.telegram.telegrambots.api.objects.replykeyboard.ApiResponse;
|
||||||
|
import org.telegram.telegrambots.api.objects.stickers.MaskPosition;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiRequestException;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiValidationException;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Ruben Bermudez
|
||||||
|
* @version 1.0
|
||||||
|
* Use this method to create new sticker set owned by a user. The bot will be able to edit the created sticker set.
|
||||||
|
* Returns True on success.
|
||||||
|
*/
|
||||||
|
public class CreateNewStickerSet extends PartialBotApiMethod<Boolean> {
|
||||||
|
public static final String PATH = "createNewStickerSet";
|
||||||
|
|
||||||
|
public static final String USERID_FIELD = "user_id";
|
||||||
|
public static final String NAME_FIELD = "name";
|
||||||
|
public static final String TITLE_FIELD = "title";
|
||||||
|
public static final String PNGSTICKER_FIELD = "png_sticker";
|
||||||
|
public static final String EMOJIS_FIELD = "emojis";
|
||||||
|
public static final String CONTAINSMASKS_FIELD = "contains_masks";
|
||||||
|
public static final String MASKPOSITION_FIELD = "mask_position";
|
||||||
|
|
||||||
|
private Integer userId; ///< User identifier of created sticker set owner
|
||||||
|
/**
|
||||||
|
* Name of sticker set, to be used in t.me/addstickers/<name> URLs.
|
||||||
|
* Can contain only english letters, digits and underscores.
|
||||||
|
* Must begin with a letter, can't contain consecutive underscores and must end in “_by_<bot username>”.
|
||||||
|
* <bot_username> is case insensitive. 7-64 characters.
|
||||||
|
*/
|
||||||
|
private String name; ///< Sticker set title, 1-64 characters
|
||||||
|
private String title; ///< User identifier of created sticker set owner
|
||||||
|
private String emojis; ///< One or more emoji corresponding to the sticker
|
||||||
|
private Boolean containsMasks; ///< Pass True, if a set of mask stickers should be created
|
||||||
|
private MaskPosition maskPosition; ///< Position where the mask should be placed on faces
|
||||||
|
/**
|
||||||
|
* Png image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px,
|
||||||
|
* and either width or height must be exactly 512px.
|
||||||
|
* Pass a file_id as a String to send a file that already exists on the Telegram servers,
|
||||||
|
* pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one
|
||||||
|
* using multipart/form-data. More info on Sending Files »
|
||||||
|
*/
|
||||||
|
private Boolean isNewPngSticker;
|
||||||
|
private String pngSticker;
|
||||||
|
private java.io.File pngStickerFile; ///< New sticker file
|
||||||
|
private InputStream pngStickerStream; ///< New sticker stream
|
||||||
|
private String pngStickerName; ///< New sticker stream name
|
||||||
|
|
||||||
|
public CreateNewStickerSet() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateNewStickerSet(Integer userId, String name, String title, String emojis) {
|
||||||
|
this.userId = checkNotNull(userId);
|
||||||
|
this.name = checkNotNull(name);
|
||||||
|
this.title = checkNotNull(title);
|
||||||
|
this.emojis = checkNotNull(emojis);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserId(Integer userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPngSticker() {
|
||||||
|
return pngSticker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateNewStickerSet setPngSticker(String pngSticker) {
|
||||||
|
this.pngSticker = pngSticker;
|
||||||
|
this.isNewPngSticker = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getPngStickerFile() {
|
||||||
|
return pngStickerFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateNewStickerSet setPngStickerFile(File pngStickerFile) {
|
||||||
|
Objects.requireNonNull(pngStickerFile, "pngStickerFile cannot be null!");
|
||||||
|
this.pngStickerFile = pngStickerFile;
|
||||||
|
this.isNewPngSticker = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getPngStickerStream() {
|
||||||
|
return pngStickerStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateNewStickerSet setPngStickerStream(String pngStickerName, InputStream pngStickerStream) {
|
||||||
|
Objects.requireNonNull(pngStickerName, "pngStickerName cannot be null!");
|
||||||
|
Objects.requireNonNull(pngStickerStream, "pngStickerStream cannot be null!");
|
||||||
|
this.pngStickerStream = pngStickerStream;
|
||||||
|
this.pngStickerName = pngStickerName;
|
||||||
|
this.isNewPngSticker = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPngStickerName() {
|
||||||
|
return pngStickerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isNewPngSticker() {
|
||||||
|
return isNewPngSticker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmojis() {
|
||||||
|
return emojis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmojis(String emojis) {
|
||||||
|
this.emojis = emojis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getContainsMasks() {
|
||||||
|
return containsMasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContainsMasks(Boolean containsMasks) {
|
||||||
|
this.containsMasks = containsMasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaskPosition getMaskPosition() {
|
||||||
|
return maskPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaskPosition(MaskPosition maskPosition) {
|
||||||
|
this.maskPosition = maskPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean deserializeResponse(String answer) throws TelegramApiRequestException {
|
||||||
|
try {
|
||||||
|
ApiResponse<Boolean> result = OBJECT_MAPPER.readValue(answer,
|
||||||
|
new TypeReference<ApiResponse<Boolean>>(){});
|
||||||
|
if (result.getOk()) {
|
||||||
|
return result.getResult();
|
||||||
|
} else {
|
||||||
|
throw new TelegramApiRequestException("Error creating new sticker set", result);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new TelegramApiRequestException("Unable to deserialize response", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate() throws TelegramApiValidationException {
|
||||||
|
if (userId == null || userId <= 0) {
|
||||||
|
throw new TelegramApiValidationException("userId can't be empty", this);
|
||||||
|
}
|
||||||
|
if (name == null || name.isEmpty()) {
|
||||||
|
throw new TelegramApiValidationException("name can't be empty", this);
|
||||||
|
}
|
||||||
|
if (title == null || title.isEmpty()) {
|
||||||
|
throw new TelegramApiValidationException("userId can't be empty", this);
|
||||||
|
}
|
||||||
|
if (emojis == null || emojis.isEmpty()) {
|
||||||
|
throw new TelegramApiValidationException("emojis can't be empty", this);
|
||||||
|
}
|
||||||
|
if (isNewPngSticker) {
|
||||||
|
if (pngStickerFile == null && pngStickerStream == null) {
|
||||||
|
throw new TelegramApiValidationException("PngSticker can't be empty", this);
|
||||||
|
}
|
||||||
|
if (pngStickerStream != null && (pngStickerName == null || pngStickerName.isEmpty())) {
|
||||||
|
throw new TelegramApiValidationException("PngSticker name can't be empty", this);
|
||||||
|
}
|
||||||
|
} else if (pngSticker == null) {
|
||||||
|
throw new TelegramApiValidationException("PngSticker can't be empty", this);
|
||||||
|
}
|
||||||
|
if (maskPosition != null) {
|
||||||
|
maskPosition.validate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CreateNewStickerSet{" +
|
||||||
|
"userId=" + userId +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", title='" + title + '\'' +
|
||||||
|
", emojis='" + emojis + '\'' +
|
||||||
|
", containsMasks=" + containsMasks +
|
||||||
|
", maskPosition=" + maskPosition +
|
||||||
|
", isNewPngSticker=" + isNewPngSticker +
|
||||||
|
", pngSticker='" + pngSticker + '\'' +
|
||||||
|
", pngStickerFile=" + pngStickerFile +
|
||||||
|
", pngStickerStream=" + pngStickerStream +
|
||||||
|
", pngStickerName='" + pngStickerName + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package org.telegram.telegrambots.api.methods.stickers;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import org.telegram.telegrambots.api.methods.BotApiMethod;
|
||||||
|
import org.telegram.telegrambots.api.objects.replykeyboard.ApiResponse;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiRequestException;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiValidationException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Ruben Bermudez
|
||||||
|
* @version 1.0
|
||||||
|
* Use this method to delete a sticker from a set created by the bot. Returns True on success.
|
||||||
|
*/
|
||||||
|
public class DeleteStickerFromSet extends BotApiMethod<Boolean> {
|
||||||
|
private static final String PATH = "deleteStickerFromSet";
|
||||||
|
|
||||||
|
private static final String STICKER_FIELD = "sticker";
|
||||||
|
|
||||||
|
@JsonProperty(STICKER_FIELD)
|
||||||
|
private String sticker; ///< File identifier of the sticker
|
||||||
|
|
||||||
|
public DeleteStickerFromSet() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeleteStickerFromSet(String sticker) {
|
||||||
|
super();
|
||||||
|
this.sticker = checkNotNull(sticker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMethod() {
|
||||||
|
return PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean deserializeResponse(String answer) throws TelegramApiRequestException {
|
||||||
|
try {
|
||||||
|
ApiResponse<Boolean> result = OBJECT_MAPPER.readValue(answer,
|
||||||
|
new TypeReference<ApiResponse<Boolean>>(){});
|
||||||
|
if (result.getOk()) {
|
||||||
|
return result.getResult();
|
||||||
|
} else {
|
||||||
|
throw new TelegramApiRequestException("Error deleting sticker from set", result);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new TelegramApiRequestException("Unable to deserialize response", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate() throws TelegramApiValidationException {
|
||||||
|
if (sticker == null || sticker.isEmpty()) {
|
||||||
|
throw new TelegramApiValidationException("sticker can't be null", this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSticker() {
|
||||||
|
return sticker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeleteStickerFromSet setSticker(String sticker) {
|
||||||
|
this.sticker = sticker;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DeleteStickerFromSet{" +
|
||||||
|
"sticker='" + sticker + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package org.telegram.telegrambots.api.methods.stickers;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import org.telegram.telegrambots.api.methods.BotApiMethod;
|
||||||
|
import org.telegram.telegrambots.api.objects.replykeyboard.ApiResponse;
|
||||||
|
import org.telegram.telegrambots.api.objects.stickers.StickerSet;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiRequestException;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiValidationException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Ruben Bermudez
|
||||||
|
* @version 1.0
|
||||||
|
* Use this method to get a sticker set. On success, a StickerSet object is returned.
|
||||||
|
*/
|
||||||
|
public class GetStickerSet extends BotApiMethod<StickerSet> {
|
||||||
|
private static final String PATH = "getStickerSet";
|
||||||
|
|
||||||
|
private static final String NAME_FIELD = "name";
|
||||||
|
|
||||||
|
@JsonProperty(NAME_FIELD)
|
||||||
|
private String name; ///< Name of the sticker set
|
||||||
|
|
||||||
|
public GetStickerSet(String name) {
|
||||||
|
super();
|
||||||
|
this.name = checkNotNull(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GetStickerSet() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMethod() {
|
||||||
|
return PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StickerSet deserializeResponse(String answer) throws TelegramApiRequestException {
|
||||||
|
try {
|
||||||
|
ApiResponse<StickerSet> result = OBJECT_MAPPER.readValue(answer,
|
||||||
|
new TypeReference<ApiResponse<StickerSet>>(){});
|
||||||
|
if (result.getOk()) {
|
||||||
|
return result.getResult();
|
||||||
|
} else {
|
||||||
|
throw new TelegramApiRequestException("Error getting sticker set", result);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new TelegramApiRequestException("Unable to deserialize response", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate() throws TelegramApiValidationException {
|
||||||
|
if (name == null || name.isEmpty()) {
|
||||||
|
throw new TelegramApiValidationException("Name can't be null", this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GetStickerSet setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GetStickerSet{" +
|
||||||
|
"name='" + name + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
package org.telegram.telegrambots.api.methods.stickers;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import org.telegram.telegrambots.api.methods.BotApiMethod;
|
||||||
|
import org.telegram.telegrambots.api.objects.replykeyboard.ApiResponse;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiRequestException;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiValidationException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Ruben Bermudez
|
||||||
|
* @version 1.0
|
||||||
|
* Use this method to move a sticker in a set created by the bot to a specific position. Returns True on success.
|
||||||
|
*/
|
||||||
|
public class SetStickerPositionInSet extends BotApiMethod<Boolean> {
|
||||||
|
private static final String PATH = "getStickerSet";
|
||||||
|
|
||||||
|
private static final String STICKER_FIELD = "sticker";
|
||||||
|
private static final String POSITION_FIELD = "position";
|
||||||
|
|
||||||
|
@JsonProperty(STICKER_FIELD)
|
||||||
|
private String sticker; ///< File identifier of the sticker
|
||||||
|
@JsonProperty(STICKER_FIELD)
|
||||||
|
private Integer position; ///< New sticker position in the set, zero-based
|
||||||
|
|
||||||
|
public SetStickerPositionInSet(String sticker, Integer position) {
|
||||||
|
this.sticker = checkNotNull(sticker);
|
||||||
|
this.position = checkNotNull(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SetStickerPositionInSet() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMethod() {
|
||||||
|
return PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean deserializeResponse(String answer) throws TelegramApiRequestException {
|
||||||
|
try {
|
||||||
|
ApiResponse<Boolean> result = OBJECT_MAPPER.readValue(answer,
|
||||||
|
new TypeReference<ApiResponse<Boolean>>(){});
|
||||||
|
if (result.getOk()) {
|
||||||
|
return result.getResult();
|
||||||
|
} else {
|
||||||
|
throw new TelegramApiRequestException("Error setting sticker position in set", result);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new TelegramApiRequestException("Unable to deserialize response", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate() throws TelegramApiValidationException {
|
||||||
|
if (sticker == null || sticker.isEmpty()) {
|
||||||
|
throw new TelegramApiValidationException("sticker can't be null", this);
|
||||||
|
}
|
||||||
|
if (position == null || position > 0) {
|
||||||
|
throw new TelegramApiValidationException("position can't be null", this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSticker() {
|
||||||
|
return sticker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SetStickerPositionInSet setSticker(String sticker) {
|
||||||
|
this.sticker = sticker;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SetStickerPositionInSet setPosition(Integer position) {
|
||||||
|
this.position = position;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SetStickerPositionInSet{" +
|
||||||
|
"sticker='" + sticker + '\'' +
|
||||||
|
", position=" + position +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,114 @@
|
|||||||
|
package org.telegram.telegrambots.api.methods.stickers;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import org.telegram.telegrambots.api.methods.PartialBotApiMethod;
|
||||||
|
import org.telegram.telegrambots.api.objects.File;
|
||||||
|
import org.telegram.telegrambots.api.objects.replykeyboard.ApiResponse;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiRequestException;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiValidationException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Ruben Bermudez
|
||||||
|
* @version 1.0
|
||||||
|
* Use this method to upload a .png file with a sticker for later use in createNewStickerSet and addStickerToSet
|
||||||
|
* methods (can be used multiple times). Returns the uploaded File on success.
|
||||||
|
*/
|
||||||
|
public class UploadStickerFile extends PartialBotApiMethod<File> {
|
||||||
|
public static final String PATH = "uploadStickerFile";
|
||||||
|
|
||||||
|
public static final String USERID_FIELD = "name";
|
||||||
|
public static final String PNGSTICKER_FIELD = "png_sticker";
|
||||||
|
|
||||||
|
private Integer userId; ///< User identifier of sticker file owner
|
||||||
|
/**
|
||||||
|
* Png image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px,
|
||||||
|
* and either width or height must be exactly 512px. More info on Sending Files »
|
||||||
|
*/
|
||||||
|
private java.io.File newPngStickerFile; ///< New sticker file
|
||||||
|
private InputStream newPngStickerStream; ///< New sticker stream
|
||||||
|
private String newPngStickerName; ///< New sticker stream name
|
||||||
|
|
||||||
|
public UploadStickerFile() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UploadStickerFile(Integer userId) {
|
||||||
|
super();
|
||||||
|
this.userId = checkNotNull(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File deserializeResponse(String answer) throws TelegramApiRequestException {
|
||||||
|
try {
|
||||||
|
ApiResponse<File> result = OBJECT_MAPPER.readValue(answer,
|
||||||
|
new TypeReference<ApiResponse<File>>(){});
|
||||||
|
if (result.getOk()) {
|
||||||
|
return result.getResult();
|
||||||
|
} else {
|
||||||
|
throw new TelegramApiRequestException("Error uploading sticker set", result);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new TelegramApiRequestException("Unable to deserialize response", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate() throws TelegramApiValidationException {
|
||||||
|
if (userId == null || userId <= 0) {
|
||||||
|
throw new TelegramApiValidationException("userId can't be empty", this);
|
||||||
|
}
|
||||||
|
if (newPngStickerFile == null && newPngStickerStream == null) {
|
||||||
|
throw new TelegramApiValidationException("file or stream must be present", this);
|
||||||
|
}
|
||||||
|
if (newPngStickerStream != null && (newPngStickerName == null || newPngStickerName.isEmpty())) {
|
||||||
|
throw new TelegramApiValidationException("Stream name must be present", this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UploadStickerFile setUserId(Integer userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public java.io.File getNewPngStickerFile() {
|
||||||
|
return newPngStickerFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UploadStickerFile setNewPngSticker(java.io.File newPngStickerFile) {
|
||||||
|
this.newPngStickerFile = newPngStickerFile;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getNewPngStickerStream() {
|
||||||
|
return newPngStickerStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UploadStickerFile setNewPngSticker(String newPngStickerName, InputStream newPngStickerStream) {
|
||||||
|
this.newPngStickerName = newPngStickerName;
|
||||||
|
this.newPngStickerStream = newPngStickerStream;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNewPngStickerName() {
|
||||||
|
return newPngStickerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "UploadStickerFile{" +
|
||||||
|
"userId=" + userId +
|
||||||
|
", newPngStickerFile=" + newPngStickerFile +
|
||||||
|
", newPngStickerStream=" + newPngStickerStream +
|
||||||
|
", newPngStickerName='" + newPngStickerName + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ import org.telegram.telegrambots.api.interfaces.BotApiObject;
|
|||||||
import org.telegram.telegrambots.api.objects.games.Game;
|
import org.telegram.telegrambots.api.objects.games.Game;
|
||||||
import org.telegram.telegrambots.api.objects.payments.Invoice;
|
import org.telegram.telegrambots.api.objects.payments.Invoice;
|
||||||
import org.telegram.telegrambots.api.objects.payments.SuccessfulPayment;
|
import org.telegram.telegrambots.api.objects.payments.SuccessfulPayment;
|
||||||
|
import org.telegram.telegrambots.api.objects.stickers.Sticker;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -0,0 +1,89 @@
|
|||||||
|
package org.telegram.telegrambots.api.objects.stickers;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import org.telegram.telegrambots.api.interfaces.InputBotApiObject;
|
||||||
|
import org.telegram.telegrambots.api.interfaces.Validable;
|
||||||
|
import org.telegram.telegrambots.exceptions.TelegramApiValidationException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Ruben Bermudez
|
||||||
|
* @version 3.2
|
||||||
|
* This object describes the position on faces where a mask should be placed by default.
|
||||||
|
*/
|
||||||
|
public class MaskPosition implements InputBotApiObject, Validable {
|
||||||
|
private static final String POINT_FIELD = "point";
|
||||||
|
private static final String XSHIFT_FIELD = "x_shift";
|
||||||
|
private static final String YSHIFT_FIELD = "y_shift";
|
||||||
|
private static final String SCALE_FIELD = "scale";
|
||||||
|
|
||||||
|
@JsonProperty(POINT_FIELD)
|
||||||
|
private String point; ///< The part of the face relative to which the mask should be placed. One of “forehead”, “eyes”, “mouth”, or “chin”.
|
||||||
|
@JsonProperty(XSHIFT_FIELD)
|
||||||
|
private Float xShift; ///< Shift by X-axis measured in widths of the mask scaled to the face size, from left to right. For example, choosing -1.0 will place mask just to the left of the default mask position.
|
||||||
|
@JsonProperty(YSHIFT_FIELD)
|
||||||
|
private Float yShift; ///< Shift by Y-axis measured in heights of the mask scaled to the face size, from top to bottom. For example, 1.0 will place the mask just below the default mask position.
|
||||||
|
@JsonProperty(SCALE_FIELD)
|
||||||
|
private Float scale; ///< Mask scaling coefficient. For example, 2.0 means double size.
|
||||||
|
|
||||||
|
public MaskPosition() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPoint() {
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Float getxShift() {
|
||||||
|
return xShift;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Float getyShift() {
|
||||||
|
return yShift;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Float getScale() {
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPoint(String point) {
|
||||||
|
this.point = point;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setxShift(Float xShift) {
|
||||||
|
this.xShift = xShift;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setyShift(Float yShift) {
|
||||||
|
this.yShift = yShift;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScale(Float scale) {
|
||||||
|
this.scale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "MaskPosition{" +
|
||||||
|
"point='" + point + '\'' +
|
||||||
|
", xShift=" + xShift +
|
||||||
|
", yShift=" + yShift +
|
||||||
|
", scale=" + scale +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate() throws TelegramApiValidationException {
|
||||||
|
if (point == null || point.isEmpty()) {
|
||||||
|
throw new TelegramApiValidationException("point can't be empty", this);
|
||||||
|
}
|
||||||
|
if (xShift == null) {
|
||||||
|
throw new TelegramApiValidationException("xShift can't be empty", this);
|
||||||
|
}
|
||||||
|
if (yShift == null) {
|
||||||
|
throw new TelegramApiValidationException("yShift can't be empty", this);
|
||||||
|
}
|
||||||
|
if (scale == null) {
|
||||||
|
throw new TelegramApiValidationException("scale can't be empty", this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,14 @@
|
|||||||
package org.telegram.telegrambots.api.objects;
|
package org.telegram.telegrambots.api.objects.stickers;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
import org.telegram.telegrambots.api.interfaces.BotApiObject;
|
import org.telegram.telegrambots.api.interfaces.BotApiObject;
|
||||||
|
import org.telegram.telegrambots.api.objects.PhotoSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Ruben Bermudez
|
* @author Ruben Bermudez
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @brief This object represents a sticker.
|
* @brief This object represents a sticker.
|
||||||
* @date 20 of June of 2015
|
|
||||||
*/
|
*/
|
||||||
public class Sticker implements BotApiObject {
|
public class Sticker implements BotApiObject {
|
||||||
|
|
||||||
@ -18,6 +18,8 @@ public class Sticker implements BotApiObject {
|
|||||||
private static final String THUMB_FIELD = "thumb";
|
private static final String THUMB_FIELD = "thumb";
|
||||||
private static final String FILESIZE_FIELD = "file_size";
|
private static final String FILESIZE_FIELD = "file_size";
|
||||||
private static final String EMOJI_FIELD = "emoji";
|
private static final String EMOJI_FIELD = "emoji";
|
||||||
|
private static final String SETNAME_FIELD = "set_name";
|
||||||
|
private static final String MASKPOSITON_FIELD = "mask_position";
|
||||||
|
|
||||||
@JsonProperty(FILEID_FIELD)
|
@JsonProperty(FILEID_FIELD)
|
||||||
private String fileId; ///< Unique identifier for this file
|
private String fileId; ///< Unique identifier for this file
|
||||||
@ -31,6 +33,10 @@ public class Sticker implements BotApiObject {
|
|||||||
private Integer fileSize; ///< Optional. File size
|
private Integer fileSize; ///< Optional. File size
|
||||||
@JsonProperty(EMOJI_FIELD)
|
@JsonProperty(EMOJI_FIELD)
|
||||||
private String emoji; ///< Optional. Emoji associated with the sticker
|
private String emoji; ///< Optional. Emoji associated with the sticker
|
||||||
|
@JsonProperty(SETNAME_FIELD)
|
||||||
|
private String setName; ///< Optional. Name of the sticker set to which the sticker belongs
|
||||||
|
@JsonProperty(MASKPOSITON_FIELD)
|
||||||
|
private String maskPosition; ///< Optional. For mask stickers, the position where the mask should be placed
|
||||||
|
|
||||||
public Sticker() {
|
public Sticker() {
|
||||||
super();
|
super();
|
||||||
@ -60,6 +66,14 @@ public class Sticker implements BotApiObject {
|
|||||||
return emoji;
|
return emoji;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSetName() {
|
||||||
|
return setName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMaskPosition() {
|
||||||
|
return maskPosition;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Sticker{" +
|
return "Sticker{" +
|
||||||
@ -68,7 +82,9 @@ public class Sticker implements BotApiObject {
|
|||||||
", height=" + height +
|
", height=" + height +
|
||||||
", thumb=" + thumb +
|
", thumb=" + thumb +
|
||||||
", fileSize=" + fileSize +
|
", fileSize=" + fileSize +
|
||||||
", emoji=" + emoji +
|
", emoji='" + emoji + '\'' +
|
||||||
|
", setName='" + setName + '\'' +
|
||||||
|
", maskPosition='" + maskPosition + '\'' +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package org.telegram.telegrambots.api.objects.stickers;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import org.telegram.telegrambots.api.interfaces.BotApiObject;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Ruben Bermudez
|
||||||
|
* @version 1.0
|
||||||
|
* This object represents a sticker set.
|
||||||
|
*/
|
||||||
|
public class StickerSet implements BotApiObject {
|
||||||
|
private static final String NAME_FIELD = "name";
|
||||||
|
private static final String TITLE_FIELD = "title";
|
||||||
|
private static final String CONTAINSMASKS_FIELD = "contains_masks";
|
||||||
|
private static final String STICKERS_FIELD = "stickers";
|
||||||
|
|
||||||
|
@JsonProperty(NAME_FIELD)
|
||||||
|
private String name;
|
||||||
|
@JsonProperty(TITLE_FIELD)
|
||||||
|
private String title;
|
||||||
|
@JsonProperty(CONTAINSMASKS_FIELD)
|
||||||
|
private Boolean containsMasks;
|
||||||
|
@JsonProperty(STICKERS_FIELD)
|
||||||
|
private List<Sticker> stickers;
|
||||||
|
|
||||||
|
public StickerSet() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getContainsMasks() {
|
||||||
|
return containsMasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Sticker> getStickers() {
|
||||||
|
return stickers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "StickerSet{" +
|
||||||
|
"name='" + name + '\'' +
|
||||||
|
", title='" + title + '\'' +
|
||||||
|
", containsMasks=" + containsMasks +
|
||||||
|
", stickers=" + stickers +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,9 @@ import org.telegram.telegrambots.api.methods.groupadministration.*;
|
|||||||
import org.telegram.telegrambots.api.methods.pinnedmessages.PinChatMessage;
|
import org.telegram.telegrambots.api.methods.pinnedmessages.PinChatMessage;
|
||||||
import org.telegram.telegrambots.api.methods.pinnedmessages.UnpinChatMessage;
|
import org.telegram.telegrambots.api.methods.pinnedmessages.UnpinChatMessage;
|
||||||
import org.telegram.telegrambots.api.methods.send.*;
|
import org.telegram.telegrambots.api.methods.send.*;
|
||||||
|
import org.telegram.telegrambots.api.methods.stickers.AddStickerToSet;
|
||||||
|
import org.telegram.telegrambots.api.methods.stickers.CreateNewStickerSet;
|
||||||
|
import org.telegram.telegrambots.api.methods.stickers.UploadStickerFile;
|
||||||
import org.telegram.telegrambots.api.methods.updates.DeleteWebhook;
|
import org.telegram.telegrambots.api.methods.updates.DeleteWebhook;
|
||||||
import org.telegram.telegrambots.api.methods.updates.GetWebhookInfo;
|
import org.telegram.telegrambots.api.methods.updates.GetWebhookInfo;
|
||||||
import org.telegram.telegrambots.api.methods.updatingmessages.DeleteMessage;
|
import org.telegram.telegrambots.api.methods.updatingmessages.DeleteMessage;
|
||||||
@ -52,6 +55,7 @@ public abstract class AbsSender {
|
|||||||
|
|
||||||
// Send Requests
|
// Send Requests
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Message sendMessage(SendMessage sendMessage) throws TelegramApiException {
|
public final Message sendMessage(SendMessage sendMessage) throws TelegramApiException {
|
||||||
if (sendMessage == null) {
|
if (sendMessage == null) {
|
||||||
throw new TelegramApiException("Parameter sendMessage can not be null");
|
throw new TelegramApiException("Parameter sendMessage can not be null");
|
||||||
@ -60,6 +64,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(sendMessage);
|
return sendApiMethod(sendMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean answerInlineQuery(AnswerInlineQuery answerInlineQuery) throws TelegramApiException {
|
public final Boolean answerInlineQuery(AnswerInlineQuery answerInlineQuery) throws TelegramApiException {
|
||||||
if (answerInlineQuery == null) {
|
if (answerInlineQuery == null) {
|
||||||
throw new TelegramApiException("Parameter answerInlineQuery can not be null");
|
throw new TelegramApiException("Parameter answerInlineQuery can not be null");
|
||||||
@ -68,6 +73,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(answerInlineQuery);
|
return sendApiMethod(answerInlineQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean sendChatAction(SendChatAction sendChatAction) throws TelegramApiException {
|
public final Boolean sendChatAction(SendChatAction sendChatAction) throws TelegramApiException {
|
||||||
if (sendChatAction == null) {
|
if (sendChatAction == null) {
|
||||||
throw new TelegramApiException("Parameter sendChatAction can not be null");
|
throw new TelegramApiException("Parameter sendChatAction can not be null");
|
||||||
@ -76,6 +82,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(sendChatAction);
|
return sendApiMethod(sendChatAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Message forwardMessage(ForwardMessage forwardMessage) throws TelegramApiException {
|
public final Message forwardMessage(ForwardMessage forwardMessage) throws TelegramApiException {
|
||||||
if (forwardMessage == null) {
|
if (forwardMessage == null) {
|
||||||
throw new TelegramApiException("Parameter forwardMessage can not be null");
|
throw new TelegramApiException("Parameter forwardMessage can not be null");
|
||||||
@ -84,6 +91,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(forwardMessage);
|
return sendApiMethod(forwardMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Message sendLocation(SendLocation sendLocation) throws TelegramApiException {
|
public final Message sendLocation(SendLocation sendLocation) throws TelegramApiException {
|
||||||
if (sendLocation == null) {
|
if (sendLocation == null) {
|
||||||
throw new TelegramApiException("Parameter sendLocation can not be null");
|
throw new TelegramApiException("Parameter sendLocation can not be null");
|
||||||
@ -92,6 +100,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(sendLocation);
|
return sendApiMethod(sendLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Message sendVenue(SendVenue sendVenue) throws TelegramApiException {
|
public final Message sendVenue(SendVenue sendVenue) throws TelegramApiException {
|
||||||
if (sendVenue == null) {
|
if (sendVenue == null) {
|
||||||
throw new TelegramApiException("Parameter sendVenue can not be null");
|
throw new TelegramApiException("Parameter sendVenue can not be null");
|
||||||
@ -100,6 +109,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(sendVenue);
|
return sendApiMethod(sendVenue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Message sendContact(SendContact sendContact) throws TelegramApiException {
|
public final Message sendContact(SendContact sendContact) throws TelegramApiException {
|
||||||
if (sendContact == null) {
|
if (sendContact == null) {
|
||||||
throw new TelegramApiException("Parameter sendContact can not be null");
|
throw new TelegramApiException("Parameter sendContact can not be null");
|
||||||
@ -108,6 +118,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(sendContact);
|
return sendApiMethod(sendContact);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean kickMember(KickChatMember kickChatMember) throws TelegramApiException {
|
public final 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");
|
||||||
@ -115,6 +126,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(kickChatMember);
|
return sendApiMethod(kickChatMember);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean unbanMember(UnbanChatMember unbanChatMember) throws TelegramApiException {
|
public final 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");
|
||||||
@ -122,6 +134,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(unbanChatMember);
|
return sendApiMethod(unbanChatMember);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean leaveChat(LeaveChat leaveChat) throws TelegramApiException {
|
public final 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");
|
||||||
@ -129,6 +142,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(leaveChat);
|
return sendApiMethod(leaveChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Chat getChat(GetChat getChat) throws TelegramApiException {
|
public final 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");
|
||||||
@ -136,6 +150,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(getChat);
|
return sendApiMethod(getChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final String exportChatInviteLink(ExportChatInviteLink exportChatInviteLink) throws TelegramApiException {
|
public final String exportChatInviteLink(ExportChatInviteLink exportChatInviteLink) throws TelegramApiException {
|
||||||
if (exportChatInviteLink == null) {
|
if (exportChatInviteLink == null) {
|
||||||
throw new TelegramApiException("Parameter exportChatInviteLink can not be null");
|
throw new TelegramApiException("Parameter exportChatInviteLink can not be null");
|
||||||
@ -143,6 +158,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(exportChatInviteLink);
|
return sendApiMethod(exportChatInviteLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final List<ChatMember> getChatAdministrators(GetChatAdministrators getChatAdministrators) throws TelegramApiException {
|
public final 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");
|
||||||
@ -150,6 +166,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(getChatAdministrators);
|
return sendApiMethod(getChatAdministrators);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final ChatMember getChatMember(GetChatMember getChatMember) throws TelegramApiException {
|
public final 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");
|
||||||
@ -157,6 +174,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(getChatMember);
|
return sendApiMethod(getChatMember);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Integer getChatMemberCount(GetChatMemberCount getChatMemberCount) throws TelegramApiException {
|
public final 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");
|
||||||
@ -164,6 +182,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(getChatMemberCount);
|
return sendApiMethod(getChatMemberCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Serializable editMessageText(EditMessageText editMessageText) throws TelegramApiException {
|
public final Serializable 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");
|
||||||
@ -171,6 +190,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(editMessageText);
|
return sendApiMethod(editMessageText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Serializable editMessageCaption(EditMessageCaption editMessageCaption) throws TelegramApiException {
|
public final Serializable 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");
|
||||||
@ -178,6 +198,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(editMessageCaption);
|
return sendApiMethod(editMessageCaption);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Serializable editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup) throws TelegramApiException {
|
public final Serializable 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");
|
||||||
@ -185,6 +206,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(editMessageReplyMarkup);
|
return sendApiMethod(editMessageReplyMarkup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean answerCallbackQuery(AnswerCallbackQuery answerCallbackQuery) throws TelegramApiException {
|
public final 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");
|
||||||
@ -192,6 +214,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(answerCallbackQuery);
|
return sendApiMethod(answerCallbackQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final UserProfilePhotos getUserProfilePhotos(GetUserProfilePhotos getUserProfilePhotos) throws TelegramApiException {
|
public final UserProfilePhotos getUserProfilePhotos(GetUserProfilePhotos getUserProfilePhotos) throws TelegramApiException {
|
||||||
if (getUserProfilePhotos == null) {
|
if (getUserProfilePhotos == null) {
|
||||||
throw new TelegramApiException("Parameter getUserProfilePhotos can not be null");
|
throw new TelegramApiException("Parameter getUserProfilePhotos can not be null");
|
||||||
@ -200,6 +223,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(getUserProfilePhotos);
|
return sendApiMethod(getUserProfilePhotos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final File getFile(GetFile getFile) throws TelegramApiException {
|
public final File getFile(GetFile getFile) throws TelegramApiException {
|
||||||
if(getFile == null){
|
if(getFile == null){
|
||||||
throw new TelegramApiException("Parameter getFile can not be null");
|
throw new TelegramApiException("Parameter getFile can not be null");
|
||||||
@ -211,9 +235,7 @@ public abstract class AbsSender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final User getMe() throws TelegramApiException {
|
public final User getMe() throws TelegramApiException {
|
||||||
GetMe getMe = new GetMe();
|
return sendApiMethod(new GetMe());
|
||||||
|
|
||||||
return sendApiMethod(getMe);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final WebhookInfo getWebhookInfo() throws TelegramApiException {
|
public final WebhookInfo getWebhookInfo() throws TelegramApiException {
|
||||||
@ -221,6 +243,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(getWebhookInfo);
|
return sendApiMethod(getWebhookInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Serializable setGameScore(SetGameScore setGameScore) throws TelegramApiException {
|
public final Serializable setGameScore(SetGameScore setGameScore) throws TelegramApiException {
|
||||||
if(setGameScore == null){
|
if(setGameScore == null){
|
||||||
throw new TelegramApiException("Parameter setGameScore can not be null");
|
throw new TelegramApiException("Parameter setGameScore can not be null");
|
||||||
@ -228,6 +251,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(setGameScore);
|
return sendApiMethod(setGameScore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Serializable getGameHighScores(GetGameHighScores getGameHighScores) throws TelegramApiException {
|
public final Serializable getGameHighScores(GetGameHighScores getGameHighScores) throws TelegramApiException {
|
||||||
if(getGameHighScores == null){
|
if(getGameHighScores == null){
|
||||||
throw new TelegramApiException("Parameter getGameHighScores can not be null");
|
throw new TelegramApiException("Parameter getGameHighScores can not be null");
|
||||||
@ -235,6 +259,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(getGameHighScores);
|
return sendApiMethod(getGameHighScores);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Message sendGame(SendGame sendGame) throws TelegramApiException {
|
public final Message sendGame(SendGame sendGame) throws TelegramApiException {
|
||||||
if(sendGame == null){
|
if(sendGame == null){
|
||||||
throw new TelegramApiException("Parameter sendGame can not be null");
|
throw new TelegramApiException("Parameter sendGame can not be null");
|
||||||
@ -242,6 +267,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(sendGame);
|
return sendApiMethod(sendGame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean deleteWebhook(DeleteWebhook deleteWebhook) throws TelegramApiException {
|
public final Boolean deleteWebhook(DeleteWebhook deleteWebhook) throws TelegramApiException {
|
||||||
if(deleteWebhook == null){
|
if(deleteWebhook == null){
|
||||||
throw new TelegramApiException("Parameter deleteWebhook can not be null");
|
throw new TelegramApiException("Parameter deleteWebhook can not be null");
|
||||||
@ -249,6 +275,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(deleteWebhook);
|
return sendApiMethod(deleteWebhook);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Message sendInvoice(SendInvoice sendInvoice) throws TelegramApiException {
|
public final Message sendInvoice(SendInvoice sendInvoice) throws TelegramApiException {
|
||||||
if(sendInvoice == null){
|
if(sendInvoice == null){
|
||||||
throw new TelegramApiException("Parameter sendInvoice can not be null");
|
throw new TelegramApiException("Parameter sendInvoice can not be null");
|
||||||
@ -256,6 +283,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(sendInvoice);
|
return sendApiMethod(sendInvoice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean answerShippingQuery(AnswerShippingQuery answerShippingQuery) throws TelegramApiException {
|
public final Boolean answerShippingQuery(AnswerShippingQuery answerShippingQuery) throws TelegramApiException {
|
||||||
if(answerShippingQuery == null){
|
if(answerShippingQuery == null){
|
||||||
throw new TelegramApiException("Parameter answerShippingQuery can not be null");
|
throw new TelegramApiException("Parameter answerShippingQuery can not be null");
|
||||||
@ -263,6 +291,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(answerShippingQuery);
|
return sendApiMethod(answerShippingQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean answerPreCheckoutQuery(AnswerPreCheckoutQuery answerPreCheckoutQuery) throws TelegramApiException {
|
public final Boolean answerPreCheckoutQuery(AnswerPreCheckoutQuery answerPreCheckoutQuery) throws TelegramApiException {
|
||||||
if(answerPreCheckoutQuery == null){
|
if(answerPreCheckoutQuery == null){
|
||||||
throw new TelegramApiException("Parameter answerPreCheckoutQuery can not be null");
|
throw new TelegramApiException("Parameter answerPreCheckoutQuery can not be null");
|
||||||
@ -270,6 +299,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(answerPreCheckoutQuery);
|
return sendApiMethod(answerPreCheckoutQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean deleteMessage(DeleteMessage deleteMessage) throws TelegramApiException {
|
public final Boolean deleteMessage(DeleteMessage deleteMessage) throws TelegramApiException {
|
||||||
if(deleteMessage == null){
|
if(deleteMessage == null){
|
||||||
throw new TelegramApiException("Parameter deleteMessage can not be null");
|
throw new TelegramApiException("Parameter deleteMessage can not be null");
|
||||||
@ -277,6 +307,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(deleteMessage);
|
return sendApiMethod(deleteMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean deleteChatPhoto(DeleteChatPhoto deleteChatPhoto) throws TelegramApiException {
|
public final Boolean deleteChatPhoto(DeleteChatPhoto deleteChatPhoto) throws TelegramApiException {
|
||||||
if(deleteChatPhoto == null){
|
if(deleteChatPhoto == null){
|
||||||
throw new TelegramApiException("Parameter deleteChatPhoto can not be null");
|
throw new TelegramApiException("Parameter deleteChatPhoto can not be null");
|
||||||
@ -284,6 +315,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(deleteChatPhoto);
|
return sendApiMethod(deleteChatPhoto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean pinChatMessage(PinChatMessage pinChatMessage) throws TelegramApiException {
|
public final Boolean pinChatMessage(PinChatMessage pinChatMessage) throws TelegramApiException {
|
||||||
if(pinChatMessage == null){
|
if(pinChatMessage == null){
|
||||||
throw new TelegramApiException("Parameter pinChatMessage can not be null");
|
throw new TelegramApiException("Parameter pinChatMessage can not be null");
|
||||||
@ -291,6 +323,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(pinChatMessage);
|
return sendApiMethod(pinChatMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean unpinChatMessage(UnpinChatMessage unpinChatMessage) throws TelegramApiException {
|
public final Boolean unpinChatMessage(UnpinChatMessage unpinChatMessage) throws TelegramApiException {
|
||||||
if(unpinChatMessage == null){
|
if(unpinChatMessage == null){
|
||||||
throw new TelegramApiException("Parameter unpinChatMessage can not be null");
|
throw new TelegramApiException("Parameter unpinChatMessage can not be null");
|
||||||
@ -298,6 +331,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(unpinChatMessage);
|
return sendApiMethod(unpinChatMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean promoteChatMember(PromoteChatMember promoteChatMember) throws TelegramApiException {
|
public final Boolean promoteChatMember(PromoteChatMember promoteChatMember) throws TelegramApiException {
|
||||||
if(promoteChatMember == null){
|
if(promoteChatMember == null){
|
||||||
throw new TelegramApiException("Parameter promoteChatMember can not be null");
|
throw new TelegramApiException("Parameter promoteChatMember can not be null");
|
||||||
@ -305,6 +339,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(promoteChatMember);
|
return sendApiMethod(promoteChatMember);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean restrictChatMember(RestrictChatMember restrictChatMember) throws TelegramApiException {
|
public final Boolean restrictChatMember(RestrictChatMember restrictChatMember) throws TelegramApiException {
|
||||||
if(restrictChatMember == null){
|
if(restrictChatMember == null){
|
||||||
throw new TelegramApiException("Parameter restrictChatMember can not be null");
|
throw new TelegramApiException("Parameter restrictChatMember can not be null");
|
||||||
@ -312,6 +347,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(restrictChatMember);
|
return sendApiMethod(restrictChatMember);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean setChatDescription(SetChatDescription setChatDescription) throws TelegramApiException {
|
public final Boolean setChatDescription(SetChatDescription setChatDescription) throws TelegramApiException {
|
||||||
if(setChatDescription == null){
|
if(setChatDescription == null){
|
||||||
throw new TelegramApiException("Parameter setChatDescription can not be null");
|
throw new TelegramApiException("Parameter setChatDescription can not be null");
|
||||||
@ -319,6 +355,7 @@ public abstract class AbsSender {
|
|||||||
return sendApiMethod(setChatDescription);
|
return sendApiMethod(setChatDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final Boolean setChatTitle(SetChatTitle setChatTitle) throws TelegramApiException {
|
public final Boolean setChatTitle(SetChatTitle setChatTitle) throws TelegramApiException {
|
||||||
if(setChatTitle == null){
|
if(setChatTitle == null){
|
||||||
throw new TelegramApiException("Parameter setChatTitle can not be null");
|
throw new TelegramApiException("Parameter setChatTitle can not be null");
|
||||||
@ -328,6 +365,7 @@ public abstract class AbsSender {
|
|||||||
|
|
||||||
// Send Requests Async
|
// Send Requests Async
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void sendMessageAsync(SendMessage sendMessage, SentCallback<Message> sentCallback) throws TelegramApiException {
|
public final void sendMessageAsync(SendMessage sendMessage, SentCallback<Message> sentCallback) throws TelegramApiException {
|
||||||
if (sendMessage == null) {
|
if (sendMessage == null) {
|
||||||
throw new TelegramApiException("Parameter sendMessage can not be null");
|
throw new TelegramApiException("Parameter sendMessage can not be null");
|
||||||
@ -340,6 +378,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(sendMessage, sentCallback);
|
sendApiMethodAsync(sendMessage, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void answerInlineQueryAsync(AnswerInlineQuery answerInlineQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void answerInlineQueryAsync(AnswerInlineQuery answerInlineQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
if (answerInlineQuery == null) {
|
if (answerInlineQuery == null) {
|
||||||
throw new TelegramApiException("Parameter answerInlineQuery can not be null");
|
throw new TelegramApiException("Parameter answerInlineQuery can not be null");
|
||||||
@ -352,6 +391,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(answerInlineQuery, sentCallback);
|
sendApiMethodAsync(answerInlineQuery, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void sendChatActionAsync(SendChatAction sendChatAction, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void sendChatActionAsync(SendChatAction sendChatAction, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
if (sendChatAction == null) {
|
if (sendChatAction == null) {
|
||||||
throw new TelegramApiException("Parameter sendChatAction can not be null");
|
throw new TelegramApiException("Parameter sendChatAction can not be null");
|
||||||
@ -364,6 +404,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(sendChatAction, sentCallback);
|
sendApiMethodAsync(sendChatAction, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void forwardMessageAsync(ForwardMessage forwardMessage, SentCallback<Message> sentCallback) throws TelegramApiException {
|
public final void forwardMessageAsync(ForwardMessage forwardMessage, SentCallback<Message> sentCallback) throws TelegramApiException {
|
||||||
if (forwardMessage == null) {
|
if (forwardMessage == null) {
|
||||||
throw new TelegramApiException("Parameter forwardMessage can not be null");
|
throw new TelegramApiException("Parameter forwardMessage can not be null");
|
||||||
@ -376,6 +417,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(forwardMessage, sentCallback);
|
sendApiMethodAsync(forwardMessage, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void sendLocationAsync(SendLocation sendLocation, SentCallback<Message> sentCallback) throws TelegramApiException {
|
public final void sendLocationAsync(SendLocation sendLocation, SentCallback<Message> sentCallback) throws TelegramApiException {
|
||||||
if (sendLocation == null) {
|
if (sendLocation == null) {
|
||||||
throw new TelegramApiException("Parameter sendLocation can not be null");
|
throw new TelegramApiException("Parameter sendLocation can not be null");
|
||||||
@ -388,6 +430,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(sendLocation, sentCallback);
|
sendApiMethodAsync(sendLocation, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void sendVenueAsync(SendVenue sendVenue, SentCallback<Message> sentCallback) throws TelegramApiException {
|
public final void sendVenueAsync(SendVenue sendVenue, SentCallback<Message> sentCallback) throws TelegramApiException {
|
||||||
if (sendVenue == null) {
|
if (sendVenue == null) {
|
||||||
throw new TelegramApiException("Parameter sendVenue can not be null");
|
throw new TelegramApiException("Parameter sendVenue can not be null");
|
||||||
@ -400,6 +443,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(sendVenue, sentCallback);
|
sendApiMethodAsync(sendVenue, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void sendContactAsync(SendContact sendContact, SentCallback<Message> sentCallback) throws TelegramApiException {
|
public final void sendContactAsync(SendContact sendContact, SentCallback<Message> sentCallback) throws TelegramApiException {
|
||||||
if (sendContact == null) {
|
if (sendContact == null) {
|
||||||
throw new TelegramApiException("Parameter sendContact can not be null");
|
throw new TelegramApiException("Parameter sendContact can not be null");
|
||||||
@ -411,6 +455,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(sendContact, sentCallback);
|
sendApiMethodAsync(sendContact, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void kickMemberAsync(KickChatMember kickChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void kickMemberAsync(KickChatMember kickChatMember, SentCallback<Boolean> sentCallback) 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");
|
||||||
@ -422,6 +467,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(kickChatMember, sentCallback);
|
sendApiMethodAsync(kickChatMember, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void unbanMemberAsync(UnbanChatMember unbanChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void unbanMemberAsync(UnbanChatMember unbanChatMember, SentCallback<Boolean> sentCallback) 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");
|
||||||
@ -433,6 +479,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(unbanChatMember, sentCallback);
|
sendApiMethodAsync(unbanChatMember, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void leaveChatAsync(LeaveChat leaveChat, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void leaveChatAsync(LeaveChat leaveChat, SentCallback<Boolean> sentCallback) 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");
|
||||||
@ -443,6 +490,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(leaveChat, sentCallback);
|
sendApiMethodAsync(leaveChat, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void getChatAsync(GetChat getChat, SentCallback<Chat> sentCallback) throws TelegramApiException {
|
public final void getChatAsync(GetChat getChat, SentCallback<Chat> sentCallback) 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");
|
||||||
@ -453,6 +501,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(getChat, sentCallback);
|
sendApiMethodAsync(getChat, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void exportChatInviteLinkAsync(ExportChatInviteLink exportChatInviteLink, SentCallback<String> sentCallback) throws TelegramApiException {
|
public final void exportChatInviteLinkAsync(ExportChatInviteLink exportChatInviteLink, SentCallback<String> sentCallback) throws TelegramApiException {
|
||||||
if (exportChatInviteLink == null) {
|
if (exportChatInviteLink == null) {
|
||||||
throw new TelegramApiException("Parameter exportChatInviteLink can not be null");
|
throw new TelegramApiException("Parameter exportChatInviteLink can not be null");
|
||||||
@ -463,6 +512,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(exportChatInviteLink, sentCallback);
|
sendApiMethodAsync(exportChatInviteLink, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void getChatAdministratorsAsync(GetChatAdministrators getChatAdministrators, SentCallback<ArrayList<ChatMember>> sentCallback) throws TelegramApiException {
|
public final void getChatAdministratorsAsync(GetChatAdministrators getChatAdministrators, SentCallback<ArrayList<ChatMember>> sentCallback) 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");
|
||||||
@ -473,6 +523,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(getChatAdministrators, sentCallback);
|
sendApiMethodAsync(getChatAdministrators, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void getChatMemberAsync(GetChatMember getChatMember, SentCallback<ChatMember> sentCallback) throws TelegramApiException {
|
public final void getChatMemberAsync(GetChatMember getChatMember, SentCallback<ChatMember> sentCallback) 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");
|
||||||
@ -483,6 +534,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(getChatMember, sentCallback);
|
sendApiMethodAsync(getChatMember, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void getChatMemberCountAsync(GetChatMemberCount getChatMemberCount, SentCallback<Integer> sentCallback) throws TelegramApiException {
|
public final void getChatMemberCountAsync(GetChatMemberCount getChatMemberCount, SentCallback<Integer> sentCallback) 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");
|
||||||
@ -494,6 +546,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(getChatMemberCount, sentCallback);
|
sendApiMethodAsync(getChatMemberCount, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void editMessageTextAsync(EditMessageText editMessageText, SentCallback<Serializable> sentCallback) throws TelegramApiException {
|
public final void editMessageTextAsync(EditMessageText editMessageText, SentCallback<Serializable> sentCallback) 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");
|
||||||
@ -505,6 +558,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(editMessageText, sentCallback);
|
sendApiMethodAsync(editMessageText, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void editMessageCaptionAsync(EditMessageCaption editMessageCaption, SentCallback<Serializable> sentCallback) throws TelegramApiException {
|
public final void editMessageCaptionAsync(EditMessageCaption editMessageCaption, SentCallback<Serializable> sentCallback) 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");
|
||||||
@ -516,6 +570,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(editMessageCaption, sentCallback);
|
sendApiMethodAsync(editMessageCaption, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup, SentCallback<Serializable> sentCallback) throws TelegramApiException {
|
public final void editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup, SentCallback<Serializable> sentCallback) 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");
|
||||||
@ -527,6 +582,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(editMessageReplyMarkup, sentCallback);
|
sendApiMethodAsync(editMessageReplyMarkup, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void answerCallbackQueryAsync(AnswerCallbackQuery answerCallbackQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void answerCallbackQueryAsync(AnswerCallbackQuery answerCallbackQuery, SentCallback<Boolean> sentCallback) 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");
|
||||||
@ -538,6 +594,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(answerCallbackQuery, sentCallback);
|
sendApiMethodAsync(answerCallbackQuery, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void getUserProfilePhotosAsync(GetUserProfilePhotos getUserProfilePhotos, SentCallback<UserProfilePhotos> sentCallback) throws TelegramApiException {
|
public final void getUserProfilePhotosAsync(GetUserProfilePhotos getUserProfilePhotos, SentCallback<UserProfilePhotos> sentCallback) throws TelegramApiException {
|
||||||
if (getUserProfilePhotos == null) {
|
if (getUserProfilePhotos == null) {
|
||||||
throw new TelegramApiException("Parameter getUserProfilePhotos can not be null");
|
throw new TelegramApiException("Parameter getUserProfilePhotos can not be null");
|
||||||
@ -549,6 +606,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(getUserProfilePhotos, sentCallback);
|
sendApiMethodAsync(getUserProfilePhotos, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void getFileAsync(GetFile getFile, SentCallback<File> sentCallback) throws TelegramApiException {
|
public final void getFileAsync(GetFile getFile, SentCallback<File> sentCallback) throws TelegramApiException {
|
||||||
if (getFile == null) {
|
if (getFile == null) {
|
||||||
throw new TelegramApiException("Parameter getFile can not be null");
|
throw new TelegramApiException("Parameter getFile can not be null");
|
||||||
@ -564,19 +622,17 @@ public abstract class AbsSender {
|
|||||||
if (sentCallback == null) {
|
if (sentCallback == null) {
|
||||||
throw new TelegramApiException("Parameter sentCallback can not be null");
|
throw new TelegramApiException("Parameter sentCallback can not be null");
|
||||||
}
|
}
|
||||||
GetMe getMe = new GetMe();
|
sendApiMethodAsync(new GetMe(), sentCallback);
|
||||||
sendApiMethodAsync(getMe, sentCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void getWebhookInfoAsync(SentCallback<WebhookInfo> sentCallback) throws TelegramApiException {
|
public final void getWebhookInfoAsync(SentCallback<WebhookInfo> sentCallback) throws TelegramApiException {
|
||||||
if (sentCallback == null) {
|
if (sentCallback == null) {
|
||||||
throw new TelegramApiException("Parameter sentCallback can not be null");
|
throw new TelegramApiException("Parameter sentCallback can not be null");
|
||||||
}
|
}
|
||||||
|
sendApiMethodAsync(new GetWebhookInfo(), sentCallback);
|
||||||
GetWebhookInfo getWebhookInfo = new GetWebhookInfo();
|
|
||||||
sendApiMethodAsync(getWebhookInfo, sentCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void setGameScoreAsync(SetGameScore setGameScore, SentCallback<Serializable> sentCallback) throws TelegramApiException {
|
public final void setGameScoreAsync(SetGameScore setGameScore, SentCallback<Serializable> sentCallback) throws TelegramApiException {
|
||||||
if (setGameScore == null) {
|
if (setGameScore == null) {
|
||||||
throw new TelegramApiException("Parameter setGameScore can not be null");
|
throw new TelegramApiException("Parameter setGameScore can not be null");
|
||||||
@ -587,6 +643,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(setGameScore, sentCallback);
|
sendApiMethodAsync(setGameScore, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void getGameHighScoresAsync(GetGameHighScores getGameHighScores, SentCallback<ArrayList<GameHighScore>> sentCallback) throws TelegramApiException {
|
public final void getGameHighScoresAsync(GetGameHighScores getGameHighScores, SentCallback<ArrayList<GameHighScore>> sentCallback) throws TelegramApiException {
|
||||||
if (getGameHighScores == null) {
|
if (getGameHighScores == null) {
|
||||||
throw new TelegramApiException("Parameter getGameHighScores can not be null");
|
throw new TelegramApiException("Parameter getGameHighScores can not be null");
|
||||||
@ -597,6 +654,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(getGameHighScores, sentCallback);
|
sendApiMethodAsync(getGameHighScores, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void sendGameAsync(SendGame sendGame, SentCallback<Message> sentCallback) throws TelegramApiException {
|
public final void sendGameAsync(SendGame sendGame, SentCallback<Message> sentCallback) throws TelegramApiException {
|
||||||
if (sendGame == null) {
|
if (sendGame == null) {
|
||||||
throw new TelegramApiException("Parameter sendGame can not be null");
|
throw new TelegramApiException("Parameter sendGame can not be null");
|
||||||
@ -607,6 +665,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(sendGame, sentCallback);
|
sendApiMethodAsync(sendGame, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void deleteWebhook(DeleteWebhook deleteWebhook, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void deleteWebhook(DeleteWebhook deleteWebhook, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
if (deleteWebhook == null) {
|
if (deleteWebhook == null) {
|
||||||
throw new TelegramApiException("Parameter deleteWebhook can not be null");
|
throw new TelegramApiException("Parameter deleteWebhook can not be null");
|
||||||
@ -617,6 +676,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(deleteWebhook, sentCallback);
|
sendApiMethodAsync(deleteWebhook, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void sendInvoice(SendInvoice sendInvoice, SentCallback<Message> sentCallback) throws TelegramApiException {
|
public final void sendInvoice(SendInvoice sendInvoice, SentCallback<Message> sentCallback) throws TelegramApiException {
|
||||||
if (sendInvoice == null) {
|
if (sendInvoice == null) {
|
||||||
throw new TelegramApiException("Parameter sendInvoice can not be null");
|
throw new TelegramApiException("Parameter sendInvoice can not be null");
|
||||||
@ -627,6 +687,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(sendInvoice, sentCallback);
|
sendApiMethodAsync(sendInvoice, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void answerShippingQuery(AnswerShippingQuery answerShippingQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void answerShippingQuery(AnswerShippingQuery answerShippingQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
if (answerShippingQuery == null) {
|
if (answerShippingQuery == null) {
|
||||||
throw new TelegramApiException("Parameter answerShippingQuery can not be null");
|
throw new TelegramApiException("Parameter answerShippingQuery can not be null");
|
||||||
@ -637,6 +698,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(answerShippingQuery, sentCallback);
|
sendApiMethodAsync(answerShippingQuery, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void answerPreCheckoutQuery(AnswerPreCheckoutQuery answerPreCheckoutQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void answerPreCheckoutQuery(AnswerPreCheckoutQuery answerPreCheckoutQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
if (answerPreCheckoutQuery == null) {
|
if (answerPreCheckoutQuery == null) {
|
||||||
throw new TelegramApiException("Parameter answerPreCheckoutQuery can not be null");
|
throw new TelegramApiException("Parameter answerPreCheckoutQuery can not be null");
|
||||||
@ -647,6 +709,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(answerPreCheckoutQuery, sentCallback);
|
sendApiMethodAsync(answerPreCheckoutQuery, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void deleteMessage(DeleteMessage deleteMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void deleteMessage(DeleteMessage deleteMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
if (deleteMessage == null) {
|
if (deleteMessage == null) {
|
||||||
throw new TelegramApiException("Parameter deleteMessage can not be null");
|
throw new TelegramApiException("Parameter deleteMessage can not be null");
|
||||||
@ -657,6 +720,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(deleteMessage, sentCallback);
|
sendApiMethodAsync(deleteMessage, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void deleteChatPhoto(DeleteChatPhoto deleteChatPhoto, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void deleteChatPhoto(DeleteChatPhoto deleteChatPhoto, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
if (deleteChatPhoto == null) {
|
if (deleteChatPhoto == null) {
|
||||||
throw new TelegramApiException("Parameter deleteChatPhoto can not be null");
|
throw new TelegramApiException("Parameter deleteChatPhoto can not be null");
|
||||||
@ -667,6 +731,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(deleteChatPhoto, sentCallback);
|
sendApiMethodAsync(deleteChatPhoto, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void pinChatMessage(PinChatMessage pinChatMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void pinChatMessage(PinChatMessage pinChatMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
if (pinChatMessage == null) {
|
if (pinChatMessage == null) {
|
||||||
throw new TelegramApiException("Parameter pinChatMessage can not be null");
|
throw new TelegramApiException("Parameter pinChatMessage can not be null");
|
||||||
@ -677,6 +742,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(pinChatMessage, sentCallback);
|
sendApiMethodAsync(pinChatMessage, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void unpinChatMessage(UnpinChatMessage unpinChatMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void unpinChatMessage(UnpinChatMessage unpinChatMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
if (unpinChatMessage == null) {
|
if (unpinChatMessage == null) {
|
||||||
throw new TelegramApiException("Parameter unpinChatMessage can not be null");
|
throw new TelegramApiException("Parameter unpinChatMessage can not be null");
|
||||||
@ -687,6 +753,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(unpinChatMessage, sentCallback);
|
sendApiMethodAsync(unpinChatMessage, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void promoteChatMember(PromoteChatMember promoteChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void promoteChatMember(PromoteChatMember promoteChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
if (promoteChatMember == null) {
|
if (promoteChatMember == null) {
|
||||||
throw new TelegramApiException("Parameter promoteChatMember can not be null");
|
throw new TelegramApiException("Parameter promoteChatMember can not be null");
|
||||||
@ -697,6 +764,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(promoteChatMember, sentCallback);
|
sendApiMethodAsync(promoteChatMember, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void restrictChatMember(RestrictChatMember restrictChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void restrictChatMember(RestrictChatMember restrictChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
if (restrictChatMember == null) {
|
if (restrictChatMember == null) {
|
||||||
throw new TelegramApiException("Parameter restrictChatMember can not be null");
|
throw new TelegramApiException("Parameter restrictChatMember can not be null");
|
||||||
@ -707,6 +775,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(restrictChatMember, sentCallback);
|
sendApiMethodAsync(restrictChatMember, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void setChatDescription(SetChatDescription setChatDescription, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void setChatDescription(SetChatDescription setChatDescription, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
if (setChatDescription == null) {
|
if (setChatDescription == null) {
|
||||||
throw new TelegramApiException("Parameter setChatDescription can not be null");
|
throw new TelegramApiException("Parameter setChatDescription can not be null");
|
||||||
@ -717,6 +786,7 @@ public abstract class AbsSender {
|
|||||||
sendApiMethodAsync(setChatDescription, sentCallback);
|
sendApiMethodAsync(setChatDescription, sentCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final void setChatTitle(SetChatTitle setChatTitle, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
public final void setChatTitle(SetChatTitle setChatTitle, SentCallback<Boolean> sentCallback) throws TelegramApiException {
|
||||||
if (setChatTitle == null) {
|
if (setChatTitle == null) {
|
||||||
throw new TelegramApiException("Parameter setChatTitle can not be null");
|
throw new TelegramApiException("Parameter setChatTitle can not be null");
|
||||||
@ -763,6 +833,30 @@ public abstract class AbsSender {
|
|||||||
*/
|
*/
|
||||||
public abstract Boolean setChatPhoto(SetChatPhoto setChatPhoto) throws TelegramApiException;
|
public abstract Boolean setChatPhoto(SetChatPhoto setChatPhoto) throws TelegramApiException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new sticker to a set (https://core.telegram.org/bots/api#addStickerToSet)
|
||||||
|
* @param addStickerToSet Information of the sticker to set
|
||||||
|
* @return If success, true is returned
|
||||||
|
* @throws TelegramApiException If there is any error adding the sticker to the set
|
||||||
|
*/
|
||||||
|
public abstract Boolean addStickerToSet(AddStickerToSet addStickerToSet) throws TelegramApiException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new sticker set (https://core.telegram.org/bots/api#createNewStickerSet)
|
||||||
|
* @param createNewStickerSet Information of the sticker set to create
|
||||||
|
* @return If success, true is returned
|
||||||
|
* @throws TelegramApiException If there is any error creating the new sticker set
|
||||||
|
*/
|
||||||
|
public abstract Boolean createNewStickerSet(CreateNewStickerSet createNewStickerSet) throws TelegramApiException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload a new file as sticker (https://core.telegram.org/bots/api#uploadStickerFile)
|
||||||
|
* @param uploadStickerFile Information of the file to upload as sticker
|
||||||
|
* @return If success, true is returned
|
||||||
|
* @throws TelegramApiException If there is any error uploading the new file
|
||||||
|
*/
|
||||||
|
public abstract File uploadStickerFile(UploadStickerFile uploadStickerFile) throws TelegramApiException;
|
||||||
|
|
||||||
// Simplified methods
|
// Simplified methods
|
||||||
|
|
||||||
protected abstract <T extends Serializable, Method extends BotApiMethod<T>, Callback extends SentCallback<T>> void sendApiMethodAsync(Method method, Callback callback);
|
protected abstract <T extends Serializable, Method extends BotApiMethod<T>, Callback extends SentCallback<T>> void sendApiMethodAsync(Method method, Callback callback);
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.telegram</groupId>
|
<groupId>org.telegram</groupId>
|
||||||
<artifactId>telegrambots</artifactId>
|
<artifactId>telegrambots</artifactId>
|
||||||
<version>3.1.2</version>
|
<version>3.2</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Telegram Bots</name>
|
<name>Telegram Bots</name>
|
||||||
@ -66,7 +66,7 @@
|
|||||||
<jackson.version>2.8.7</jackson.version>
|
<jackson.version>2.8.7</jackson.version>
|
||||||
<jacksonanotation.version>2.8.0</jacksonanotation.version>
|
<jacksonanotation.version>2.8.0</jacksonanotation.version>
|
||||||
<commonio.version>2.5</commonio.version>
|
<commonio.version>2.5</commonio.version>
|
||||||
<bots.version>3.1.2</bots.version>
|
<bots.version>3.2</bots.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
|
@ -17,6 +17,9 @@ import org.apache.http.util.EntityUtils;
|
|||||||
import org.telegram.telegrambots.api.methods.BotApiMethod;
|
import org.telegram.telegrambots.api.methods.BotApiMethod;
|
||||||
import org.telegram.telegrambots.api.methods.groupadministration.SetChatPhoto;
|
import org.telegram.telegrambots.api.methods.groupadministration.SetChatPhoto;
|
||||||
import org.telegram.telegrambots.api.methods.send.*;
|
import org.telegram.telegrambots.api.methods.send.*;
|
||||||
|
import org.telegram.telegrambots.api.methods.stickers.AddStickerToSet;
|
||||||
|
import org.telegram.telegrambots.api.methods.stickers.CreateNewStickerSet;
|
||||||
|
import org.telegram.telegrambots.api.methods.stickers.UploadStickerFile;
|
||||||
import org.telegram.telegrambots.api.objects.File;
|
import org.telegram.telegrambots.api.objects.File;
|
||||||
import org.telegram.telegrambots.api.objects.Message;
|
import org.telegram.telegrambots.api.objects.Message;
|
||||||
import org.telegram.telegrambots.exceptions.TelegramApiException;
|
import org.telegram.telegrambots.exceptions.TelegramApiException;
|
||||||
@ -89,105 +92,48 @@ public abstract class DefaultAbsSender extends AbsSender {
|
|||||||
throw new TelegramApiException("Parameter file can not be null");
|
throw new TelegramApiException("Parameter file can not be null");
|
||||||
}
|
}
|
||||||
String url = File.getFileUrl(getBotToken(), filePath);
|
String url = File.getFileUrl(getBotToken(), filePath);
|
||||||
java.io.File output;
|
String tempFileName = Long.toString(System.currentTimeMillis());
|
||||||
try {
|
return downloadToTemporaryFileWrappingExceptions(url, tempFileName);
|
||||||
output = java.io.File.createTempFile(Long.toString(System.currentTimeMillis()), ".tmp");
|
|
||||||
FileUtils.copyURLToFile(new URL(url), output);
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
throw new TelegramApiException("Wrong url for file: " + url);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new TelegramApiRequestException("Error downloading the file", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final java.io.File downloadFile(File file) throws TelegramApiException {
|
public final java.io.File downloadFile(File file) throws TelegramApiException {
|
||||||
if(file == null){
|
assertParamNotNull(file, "file");
|
||||||
throw new TelegramApiException("Parameter file can not be null");
|
|
||||||
}
|
|
||||||
String url = file.getFileUrl(getBotToken());
|
String url = file.getFileUrl(getBotToken());
|
||||||
java.io.File output;
|
String tempFileName = file.getFileId();
|
||||||
try {
|
return downloadToTemporaryFileWrappingExceptions(url, tempFileName);
|
||||||
output = java.io.File.createTempFile(file.getFileId(), ".tmp");
|
|
||||||
FileUtils.copyURLToFile(new URL(url), output);
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
throw new TelegramApiException("Wrong url for file: " + url);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new TelegramApiRequestException("Error downloading the file", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void downloadFileAsync(String filePath, DownloadFileCallback<String> callback) throws TelegramApiException {
|
public final void downloadFileAsync(String filePath, DownloadFileCallback<String> callback) throws TelegramApiException {
|
||||||
if(filePath == null || filePath.isEmpty()){
|
if(filePath == null || filePath.isEmpty()){
|
||||||
throw new TelegramApiException("Parameter filePath can not be null");
|
throw new TelegramApiException("Parameter filePath can not be null");
|
||||||
}
|
}
|
||||||
if (callback == null) {
|
assertParamNotNull(callback, "callback");
|
||||||
throw new TelegramApiException("Parameter callback can not be null");
|
String url = File.getFileUrl(getBotToken(), filePath);
|
||||||
}
|
String tempFileName = Long.toString(System.currentTimeMillis());
|
||||||
|
exe.submit(getDownloadFileAsyncJob(filePath, callback, url, tempFileName));
|
||||||
exe.submit(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
String url = File.getFileUrl(getBotToken(), filePath);
|
|
||||||
try {
|
|
||||||
java.io.File output = java.io.File.createTempFile(Long.toString(System.currentTimeMillis()), ".tmp");
|
|
||||||
FileUtils.copyURLToFile(new URL(url), output);
|
|
||||||
callback.onResult(filePath, output);
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
callback.onException(filePath, new TelegramApiException("Wrong url for file: " + url));
|
|
||||||
} catch (IOException e) {
|
|
||||||
callback.onException(filePath, new TelegramApiRequestException("Error downloading the file", e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void downloadFileAsync(File file, DownloadFileCallback<File> callback) throws TelegramApiException {
|
public final void downloadFileAsync(File file, DownloadFileCallback<File> callback) throws TelegramApiException {
|
||||||
if(file == null){
|
assertParamNotNull(file, "file");
|
||||||
throw new TelegramApiException("Parameter file can not be null");
|
assertParamNotNull(callback, "callback");
|
||||||
}
|
String url = file.getFileUrl(getBotToken());
|
||||||
if (callback == null) {
|
String tempFileName = file.getFileId();
|
||||||
throw new TelegramApiException("Parameter callback can not be null");
|
exe.submit(getDownloadFileAsyncJob(file, callback, url, tempFileName));
|
||||||
}
|
|
||||||
|
|
||||||
exe.submit(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
String url = file.getFileUrl(getBotToken());
|
|
||||||
try {
|
|
||||||
java.io.File output = java.io.File.createTempFile(file.getFileId(), ".tmp");
|
|
||||||
FileUtils.copyURLToFile(new URL(url), output);
|
|
||||||
callback.onResult(file, output);
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
callback.onException(file, new TelegramApiException("Wrong url for file: " + url));
|
|
||||||
} catch (IOException e) {
|
|
||||||
callback.onException(file, new TelegramApiRequestException("Error downloading the file", e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specific Send Requests
|
// Specific Send Requests
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Message sendDocument(SendDocument sendDocument) throws TelegramApiException {
|
public final Message sendDocument(SendDocument sendDocument) throws TelegramApiException {
|
||||||
if(sendDocument == null){
|
assertParamNotNull(sendDocument, "sendDocument");
|
||||||
throw new TelegramApiException("Parameter sendDocument can not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
sendDocument.validate();
|
sendDocument.validate();
|
||||||
String responseContent;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String url = getBaseUrl() + SendDocument.PATH;
|
String url = getBaseUrl() + SendDocument.PATH;
|
||||||
HttpPost httppost = new HttpPost(url);
|
HttpPost httppost = configuredHttpPost(url);
|
||||||
httppost.setConfig(requestConfig);
|
|
||||||
|
|
||||||
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||||
builder.addTextBody(SendDocument.CHATID_FIELD, sendDocument.getChatId());
|
builder.addTextBody(SendDocument.CHATID_FIELD, sendDocument.getChatId(), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
if (sendDocument.isNewDocument()) {
|
if (sendDocument.isNewDocument()) {
|
||||||
if (sendDocument.getNewDocumentFile() != null) {
|
if (sendDocument.getNewDocumentFile() != null) {
|
||||||
builder.addBinaryBody(SendDocument.DOCUMENT_FIELD, sendDocument.getNewDocumentFile());
|
builder.addBinaryBody(SendDocument.DOCUMENT_FIELD, sendDocument.getNewDocumentFile());
|
||||||
@ -197,47 +143,37 @@ public abstract class DefaultAbsSender extends AbsSender {
|
|||||||
builder.addBinaryBody(SendDocument.DOCUMENT_FIELD, new java.io.File(sendDocument.getDocument()), ContentType.APPLICATION_OCTET_STREAM, sendDocument.getDocumentName());
|
builder.addBinaryBody(SendDocument.DOCUMENT_FIELD, new java.io.File(sendDocument.getDocument()), ContentType.APPLICATION_OCTET_STREAM, sendDocument.getDocumentName());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
builder.addTextBody(SendDocument.DOCUMENT_FIELD, sendDocument.getDocument());
|
builder.addTextBody(SendDocument.DOCUMENT_FIELD, sendDocument.getDocument(), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
if (sendDocument.getReplyMarkup() != null) {
|
if (sendDocument.getReplyMarkup() != null) {
|
||||||
builder.addTextBody(SendDocument.REPLYMARKUP_FIELD, objectMapper.writeValueAsString(sendDocument.getReplyMarkup()), TEXT_PLAIN_CONTENT_TYPE);
|
builder.addTextBody(SendDocument.REPLYMARKUP_FIELD, objectMapper.writeValueAsString(sendDocument.getReplyMarkup()), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
if (sendDocument.getReplyToMessageId() != null) {
|
if (sendDocument.getReplyToMessageId() != null) {
|
||||||
builder.addTextBody(SendDocument.REPLYTOMESSAGEID_FIELD, sendDocument.getReplyToMessageId().toString());
|
builder.addTextBody(SendDocument.REPLYTOMESSAGEID_FIELD, sendDocument.getReplyToMessageId().toString(), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
if (sendDocument.getCaption() != null) {
|
if (sendDocument.getCaption() != null) {
|
||||||
builder.addTextBody(SendDocument.CAPTION_FIELD, sendDocument.getCaption(), TEXT_PLAIN_CONTENT_TYPE);
|
builder.addTextBody(SendDocument.CAPTION_FIELD, sendDocument.getCaption(), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
if (sendDocument.getDisableNotification() != null) {
|
if (sendDocument.getDisableNotification() != null) {
|
||||||
builder.addTextBody(SendDocument.DISABLENOTIFICATION_FIELD, sendDocument.getDisableNotification().toString());
|
builder.addTextBody(SendDocument.DISABLENOTIFICATION_FIELD, sendDocument.getDisableNotification().toString(), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
HttpEntity multipart = builder.build();
|
HttpEntity multipart = builder.build();
|
||||||
httppost.setEntity(multipart);
|
httppost.setEntity(multipart);
|
||||||
|
|
||||||
try (CloseableHttpResponse response = httpclient.execute(httppost)) {
|
return sendDocument.deserializeResponse(sendHttpPostRequest(httppost));
|
||||||
HttpEntity ht = response.getEntity();
|
|
||||||
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
|
|
||||||
responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new TelegramApiException("Unable to send document", e);
|
throw new TelegramApiException("Unable to send document", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sendDocument.deserializeResponse(responseContent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Message sendPhoto(SendPhoto sendPhoto) throws TelegramApiException {
|
public final Message sendPhoto(SendPhoto sendPhoto) throws TelegramApiException {
|
||||||
if(sendPhoto == null){
|
assertParamNotNull(sendPhoto, "sendPhoto");
|
||||||
throw new TelegramApiException("Parameter sendPhoto can not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
sendPhoto.validate();
|
sendPhoto.validate();
|
||||||
String responseContent;
|
|
||||||
try {
|
try {
|
||||||
String url = getBaseUrl() + SendPhoto.PATH;
|
String url = getBaseUrl() + SendPhoto.PATH;
|
||||||
HttpPost httppost = new HttpPost(url);
|
HttpPost httppost = configuredHttpPost(url);
|
||||||
httppost.setConfig(requestConfig);
|
|
||||||
|
|
||||||
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||||
builder.addTextBody(SendPhoto.CHATID_FIELD, sendPhoto.getChatId());
|
builder.addTextBody(SendPhoto.CHATID_FIELD, sendPhoto.getChatId());
|
||||||
@ -267,30 +203,20 @@ public abstract class DefaultAbsSender extends AbsSender {
|
|||||||
HttpEntity multipart = builder.build();
|
HttpEntity multipart = builder.build();
|
||||||
httppost.setEntity(multipart);
|
httppost.setEntity(multipart);
|
||||||
|
|
||||||
try (CloseableHttpResponse response = httpclient.execute(httppost)) {
|
return sendPhoto.deserializeResponse(sendHttpPostRequest(httppost));
|
||||||
HttpEntity ht = response.getEntity();
|
|
||||||
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
|
|
||||||
responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new TelegramApiException("Unable to send photo", e);
|
throw new TelegramApiException("Unable to send photo", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sendPhoto.deserializeResponse(responseContent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Message sendVideo(SendVideo sendVideo) throws TelegramApiException {
|
public final Message sendVideo(SendVideo sendVideo) throws TelegramApiException {
|
||||||
if(sendVideo == null){
|
assertParamNotNull(sendVideo, "sendVideo");
|
||||||
throw new TelegramApiException("Parameter sendVideo can not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
sendVideo.validate();
|
sendVideo.validate();
|
||||||
String responseContent;
|
|
||||||
try {
|
try {
|
||||||
String url = getBaseUrl() + SendVideo.PATH;
|
String url = getBaseUrl() + SendVideo.PATH;
|
||||||
HttpPost httppost = new HttpPost(url);
|
HttpPost httppost = configuredHttpPost(url);
|
||||||
httppost.setConfig(requestConfig);
|
|
||||||
|
|
||||||
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||||
builder.addTextBody(SendVideo.CHATID_FIELD, sendVideo.getChatId());
|
builder.addTextBody(SendVideo.CHATID_FIELD, sendVideo.getChatId());
|
||||||
@ -329,30 +255,20 @@ public abstract class DefaultAbsSender extends AbsSender {
|
|||||||
HttpEntity multipart = builder.build();
|
HttpEntity multipart = builder.build();
|
||||||
httppost.setEntity(multipart);
|
httppost.setEntity(multipart);
|
||||||
|
|
||||||
try (CloseableHttpResponse response = httpclient.execute(httppost)) {
|
return sendVideo.deserializeResponse(sendHttpPostRequest(httppost));
|
||||||
HttpEntity ht = response.getEntity();
|
|
||||||
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
|
|
||||||
responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new TelegramApiException("Unable to send video", e);
|
throw new TelegramApiException("Unable to send video", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sendVideo.deserializeResponse(responseContent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Message sendVideoNote(SendVideoNote sendVideoNote) throws TelegramApiException {
|
public final Message sendVideoNote(SendVideoNote sendVideoNote) throws TelegramApiException {
|
||||||
if(sendVideoNote == null){
|
assertParamNotNull(sendVideoNote, "sendVideoNote");
|
||||||
throw new TelegramApiException("Parameter sendVideoNote can not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
sendVideoNote.validate();
|
sendVideoNote.validate();
|
||||||
String responseContent;
|
|
||||||
try {
|
try {
|
||||||
String url = getBaseUrl() + SendVideoNote.PATH;
|
String url = getBaseUrl() + SendVideoNote.PATH;
|
||||||
HttpPost httppost = new HttpPost(url);
|
HttpPost httppost = configuredHttpPost(url);
|
||||||
httppost.setConfig(requestConfig);
|
|
||||||
|
|
||||||
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||||
builder.addTextBody(SendVideoNote.CHATID_FIELD, sendVideoNote.getChatId());
|
builder.addTextBody(SendVideoNote.CHATID_FIELD, sendVideoNote.getChatId());
|
||||||
@ -386,30 +302,20 @@ public abstract class DefaultAbsSender extends AbsSender {
|
|||||||
httppost.setEntity(multipart);
|
httppost.setEntity(multipart);
|
||||||
|
|
||||||
|
|
||||||
try (CloseableHttpResponse response = httpclient.execute(httppost)) {
|
return sendVideoNote.deserializeResponse(sendHttpPostRequest(httppost));
|
||||||
HttpEntity ht = response.getEntity();
|
|
||||||
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
|
|
||||||
responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new TelegramApiException("Unable to send video note", e);
|
throw new TelegramApiException("Unable to send video note", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sendVideoNote.deserializeResponse(responseContent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Message sendSticker(SendSticker sendSticker) throws TelegramApiException {
|
public final Message sendSticker(SendSticker sendSticker) throws TelegramApiException {
|
||||||
if(sendSticker == null){
|
assertParamNotNull(sendSticker, "sendSticker");
|
||||||
throw new TelegramApiException("Parameter sendSticker can not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
sendSticker.validate();
|
sendSticker.validate();
|
||||||
String responseContent;
|
|
||||||
try {
|
try {
|
||||||
String url = getBaseUrl() + SendSticker.PATH;
|
String url = getBaseUrl() + SendSticker.PATH;
|
||||||
HttpPost httppost = new HttpPost(url);
|
HttpPost httppost = configuredHttpPost(url);
|
||||||
httppost.setConfig(requestConfig);
|
|
||||||
|
|
||||||
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||||
builder.addTextBody(SendSticker.CHATID_FIELD, sendSticker.getChatId());
|
builder.addTextBody(SendSticker.CHATID_FIELD, sendSticker.getChatId());
|
||||||
@ -436,16 +342,10 @@ public abstract class DefaultAbsSender extends AbsSender {
|
|||||||
HttpEntity multipart = builder.build();
|
HttpEntity multipart = builder.build();
|
||||||
httppost.setEntity(multipart);
|
httppost.setEntity(multipart);
|
||||||
|
|
||||||
try (CloseableHttpResponse response = httpclient.execute(httppost)) {
|
return sendSticker.deserializeResponse(sendHttpPostRequest(httppost));
|
||||||
HttpEntity ht = response.getEntity();
|
|
||||||
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
|
|
||||||
responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new TelegramApiException("Unable to send sticker", e);
|
throw new TelegramApiException("Unable to send sticker", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sendSticker.deserializeResponse(responseContent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -456,16 +356,11 @@ public abstract class DefaultAbsSender extends AbsSender {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final Message sendAudio(SendAudio sendAudio) throws TelegramApiException {
|
public final Message sendAudio(SendAudio sendAudio) throws TelegramApiException {
|
||||||
if(sendAudio == null){
|
assertParamNotNull(sendAudio, "sendAudio");
|
||||||
throw new TelegramApiException("Parameter sendAudio can not be null");
|
|
||||||
}
|
|
||||||
sendAudio.validate();
|
sendAudio.validate();
|
||||||
String responseContent;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String url = getBaseUrl() + SendAudio.PATH;
|
String url = getBaseUrl() + SendAudio.PATH;
|
||||||
HttpPost httppost = new HttpPost(url);
|
HttpPost httppost = configuredHttpPost(url);
|
||||||
httppost.setConfig(requestConfig);
|
|
||||||
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||||
builder.addTextBody(SendAudio.CHATID_FIELD, sendAudio.getChatId());
|
builder.addTextBody(SendAudio.CHATID_FIELD, sendAudio.getChatId());
|
||||||
if (sendAudio.isNewAudio()) {
|
if (sendAudio.isNewAudio()) {
|
||||||
@ -504,16 +399,10 @@ public abstract class DefaultAbsSender extends AbsSender {
|
|||||||
httppost.setEntity(multipart);
|
httppost.setEntity(multipart);
|
||||||
|
|
||||||
|
|
||||||
try (CloseableHttpResponse response = httpclient.execute(httppost)) {
|
return sendAudio.deserializeResponse(sendHttpPostRequest(httppost));
|
||||||
HttpEntity ht = response.getEntity();
|
|
||||||
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
|
|
||||||
responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new TelegramApiException("Unable to send sticker", e);
|
throw new TelegramApiException("Unable to send sticker", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sendAudio.deserializeResponse(responseContent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -525,16 +414,11 @@ public abstract class DefaultAbsSender extends AbsSender {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final Message sendVoice(SendVoice sendVoice) throws TelegramApiException {
|
public final Message sendVoice(SendVoice sendVoice) throws TelegramApiException {
|
||||||
if(sendVoice == null){
|
assertParamNotNull(sendVoice, "sendVoice");
|
||||||
throw new TelegramApiException("Parameter sendVoice can not be null");
|
|
||||||
}
|
|
||||||
sendVoice.validate();
|
sendVoice.validate();
|
||||||
String responseContent;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String url = getBaseUrl() + SendVoice.PATH;
|
String url = getBaseUrl() + SendVoice.PATH;
|
||||||
HttpPost httppost = new HttpPost(url);
|
HttpPost httppost = configuredHttpPost(url);
|
||||||
httppost.setConfig(requestConfig);
|
|
||||||
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||||
builder.addTextBody(SendVoice.CHATID_FIELD, sendVoice.getChatId());
|
builder.addTextBody(SendVoice.CHATID_FIELD, sendVoice.getChatId());
|
||||||
if (sendVoice.isNewVoice()) {
|
if (sendVoice.isNewVoice()) {
|
||||||
@ -566,30 +450,20 @@ public abstract class DefaultAbsSender extends AbsSender {
|
|||||||
HttpEntity multipart = builder.build();
|
HttpEntity multipart = builder.build();
|
||||||
httppost.setEntity(multipart);
|
httppost.setEntity(multipart);
|
||||||
|
|
||||||
try (CloseableHttpResponse response = httpclient.execute(httppost)) {
|
return sendVoice.deserializeResponse(sendHttpPostRequest(httppost));
|
||||||
HttpEntity ht = response.getEntity();
|
|
||||||
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
|
|
||||||
responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new TelegramApiException("Unable to send voice", e);
|
throw new TelegramApiException("Unable to send voice", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sendVoice.deserializeResponse(responseContent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean setChatPhoto(SetChatPhoto setChatPhoto) throws TelegramApiException {
|
public Boolean setChatPhoto(SetChatPhoto setChatPhoto) throws TelegramApiException {
|
||||||
if(setChatPhoto == null){
|
assertParamNotNull(setChatPhoto, "setChatPhoto");
|
||||||
throw new TelegramApiException("Parameter setChatPhoto can not be null");
|
|
||||||
}
|
|
||||||
setChatPhoto.validate();
|
setChatPhoto.validate();
|
||||||
String responseContent;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String url = getBaseUrl() + SetChatPhoto.PATH;
|
String url = getBaseUrl() + SetChatPhoto.PATH;
|
||||||
HttpPost httppost = new HttpPost(url);
|
HttpPost httppost = configuredHttpPost(url);
|
||||||
httppost.setConfig(requestConfig);
|
|
||||||
|
|
||||||
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||||
builder.addTextBody(SetChatPhoto.CHATID_FIELD, setChatPhoto.getChatId());
|
builder.addTextBody(SetChatPhoto.CHATID_FIELD, setChatPhoto.getChatId());
|
||||||
@ -601,16 +475,104 @@ public abstract class DefaultAbsSender extends AbsSender {
|
|||||||
HttpEntity multipart = builder.build();
|
HttpEntity multipart = builder.build();
|
||||||
httppost.setEntity(multipart);
|
httppost.setEntity(multipart);
|
||||||
|
|
||||||
try (CloseableHttpResponse response = httpclient.execute(httppost)) {
|
return setChatPhoto.deserializeResponse(sendHttpPostRequest(httppost));
|
||||||
HttpEntity ht = response.getEntity();
|
|
||||||
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
|
|
||||||
responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new TelegramApiException("Unable to set chat photo", e);
|
throw new TelegramApiException("Unable to set chat photo", e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return setChatPhoto.deserializeResponse(responseContent);
|
|
||||||
|
@Override
|
||||||
|
public Boolean addStickerToSet(AddStickerToSet addStickerToSet) throws TelegramApiException {
|
||||||
|
assertParamNotNull(addStickerToSet, "addStickerToSet");
|
||||||
|
addStickerToSet.validate();
|
||||||
|
try {
|
||||||
|
String url = getBaseUrl() + AddStickerToSet.PATH;
|
||||||
|
HttpPost httppost = configuredHttpPost(url);
|
||||||
|
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||||
|
builder.addTextBody(AddStickerToSet.USERID_FIELD, addStickerToSet.getUserId().toString(), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
|
builder.addTextBody(AddStickerToSet.NAME_FIELD, addStickerToSet.getName(), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
|
builder.addTextBody(AddStickerToSet.EMOJIS_FIELD, addStickerToSet.getEmojis(), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
|
if (addStickerToSet.isNewPngSticker()) {
|
||||||
|
if (addStickerToSet.getPngStickerFile() != null) {
|
||||||
|
builder.addBinaryBody(AddStickerToSet.PNGSTICKER_FIELD, addStickerToSet.getPngStickerFile());
|
||||||
|
} else if (addStickerToSet.getPngStickerStream() != null) {
|
||||||
|
builder.addBinaryBody(AddStickerToSet.PNGSTICKER_FIELD, addStickerToSet.getPngStickerStream(), ContentType.APPLICATION_OCTET_STREAM, addStickerToSet.getPngStickerName());
|
||||||
|
} else {
|
||||||
|
builder.addBinaryBody(AddStickerToSet.PNGSTICKER_FIELD, new java.io.File(addStickerToSet.getPngSticker()), ContentType.create("image/png"), addStickerToSet.getPngStickerName());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.addTextBody(AddStickerToSet.PNGSTICKER_FIELD, addStickerToSet.getPngSticker());
|
||||||
|
}
|
||||||
|
if (addStickerToSet.getMaskPosition() != null) {
|
||||||
|
builder.addTextBody(AddStickerToSet.MASKPOSITION_FIELD, objectMapper.writeValueAsString(addStickerToSet.getMaskPosition()), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
|
}
|
||||||
|
HttpEntity multipart = builder.build();
|
||||||
|
httppost.setEntity(multipart);
|
||||||
|
|
||||||
|
return addStickerToSet.deserializeResponse(sendHttpPostRequest(httppost));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new TelegramApiException("Unable to add sticker to set", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean createNewStickerSet(CreateNewStickerSet createNewStickerSet) throws TelegramApiException {
|
||||||
|
assertParamNotNull(createNewStickerSet, "createNewStickerSet");
|
||||||
|
createNewStickerSet.validate();
|
||||||
|
try {
|
||||||
|
String url = getBaseUrl() + CreateNewStickerSet.PATH;
|
||||||
|
HttpPost httppost = configuredHttpPost(url);
|
||||||
|
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||||
|
builder.addTextBody(CreateNewStickerSet.USERID_FIELD, createNewStickerSet.getUserId().toString(), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
|
builder.addTextBody(CreateNewStickerSet.NAME_FIELD, createNewStickerSet.getName(), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
|
builder.addTextBody(CreateNewStickerSet.TITLE_FIELD, createNewStickerSet.getTitle(), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
|
builder.addTextBody(CreateNewStickerSet.EMOJIS_FIELD, createNewStickerSet.getEmojis(), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
|
builder.addTextBody(CreateNewStickerSet.CONTAINSMASKS_FIELD, createNewStickerSet.getContainsMasks().toString());
|
||||||
|
if (createNewStickerSet.isNewPngSticker()) {
|
||||||
|
if (createNewStickerSet.getPngStickerFile() != null) {
|
||||||
|
builder.addBinaryBody(CreateNewStickerSet.PNGSTICKER_FIELD, createNewStickerSet.getPngStickerFile());
|
||||||
|
} else if (createNewStickerSet.getPngStickerStream() != null) {
|
||||||
|
builder.addBinaryBody(CreateNewStickerSet.PNGSTICKER_FIELD, createNewStickerSet.getPngStickerStream(), ContentType.APPLICATION_OCTET_STREAM, createNewStickerSet.getPngStickerName());
|
||||||
|
} else {
|
||||||
|
builder.addBinaryBody(CreateNewStickerSet.PNGSTICKER_FIELD, new java.io.File(createNewStickerSet.getPngSticker()), ContentType.create("image/png"), createNewStickerSet.getPngStickerName());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.addTextBody(CreateNewStickerSet.PNGSTICKER_FIELD, createNewStickerSet.getPngSticker());
|
||||||
|
}
|
||||||
|
if (createNewStickerSet.getMaskPosition() != null) {
|
||||||
|
builder.addTextBody(CreateNewStickerSet.MASKPOSITION_FIELD, objectMapper.writeValueAsString(createNewStickerSet.getMaskPosition()), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
|
}
|
||||||
|
HttpEntity multipart = builder.build();
|
||||||
|
httppost.setEntity(multipart);
|
||||||
|
|
||||||
|
return createNewStickerSet.deserializeResponse(sendHttpPostRequest(httppost));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new TelegramApiException("Unable to create new sticker set", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File uploadStickerFile(UploadStickerFile uploadStickerFile) throws TelegramApiException {
|
||||||
|
assertParamNotNull(uploadStickerFile, "uploadStickerFile");
|
||||||
|
uploadStickerFile.validate();
|
||||||
|
try {
|
||||||
|
String url = getBaseUrl() + UploadStickerFile.PATH;
|
||||||
|
HttpPost httppost = configuredHttpPost(url);
|
||||||
|
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||||
|
builder.addTextBody(UploadStickerFile.USERID_FIELD, uploadStickerFile.getUserId().toString(), TEXT_PLAIN_CONTENT_TYPE);
|
||||||
|
if (uploadStickerFile.getNewPngStickerFile() != null) {
|
||||||
|
builder.addBinaryBody(UploadStickerFile.PNGSTICKER_FIELD, uploadStickerFile.getNewPngStickerFile());
|
||||||
|
} else if (uploadStickerFile.getNewPngStickerStream() != null) {
|
||||||
|
builder.addBinaryBody(UploadStickerFile.PNGSTICKER_FIELD, uploadStickerFile.getNewPngStickerStream(), ContentType.APPLICATION_OCTET_STREAM, uploadStickerFile.getNewPngStickerName());
|
||||||
|
}
|
||||||
|
HttpEntity multipart = builder.build();
|
||||||
|
httppost.setEntity(multipart);
|
||||||
|
|
||||||
|
return uploadStickerFile.deserializeResponse(sendHttpPostRequest(httppost));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new TelegramApiException("Unable to upload new sticker file", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simplified methods
|
// Simplified methods
|
||||||
@ -622,21 +584,11 @@ public abstract class DefaultAbsSender extends AbsSender {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
method.validate();
|
String responseContent = sendMethodRequest(method);
|
||||||
String url = getBaseUrl() + method.getMethod();
|
try {
|
||||||
HttpPost httppost = new HttpPost(url);
|
callback.onResult(method, method.deserializeResponse(responseContent));
|
||||||
httppost.setConfig(requestConfig);
|
} catch (TelegramApiRequestException e) {
|
||||||
httppost.addHeader("charset", StandardCharsets.UTF_8.name());
|
callback.onError(method, e);
|
||||||
httppost.setEntity(new StringEntity(objectMapper.writeValueAsString(method), ContentType.APPLICATION_JSON));
|
|
||||||
try (CloseableHttpResponse response = httpclient.execute(httppost)) {
|
|
||||||
HttpEntity ht = response.getEntity();
|
|
||||||
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
|
|
||||||
String responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8);
|
|
||||||
try {
|
|
||||||
callback.onResult(method, method.deserializeResponse(responseContent));
|
|
||||||
} catch (TelegramApiRequestException e) {
|
|
||||||
callback.onError(method, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (IOException | TelegramApiValidationException e) {
|
} catch (IOException | TelegramApiValidationException e) {
|
||||||
callback.onException(method, e);
|
callback.onException(method, e);
|
||||||
@ -648,27 +600,76 @@ public abstract class DefaultAbsSender extends AbsSender {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final <T extends Serializable, Method extends BotApiMethod<T>> T sendApiMethod(Method method) throws TelegramApiException {
|
protected final <T extends Serializable, Method extends BotApiMethod<T>> T sendApiMethod(Method method) throws TelegramApiException {
|
||||||
method.validate();
|
|
||||||
String responseContent;
|
|
||||||
try {
|
try {
|
||||||
String url = getBaseUrl() + method.getMethod();
|
String responseContent = sendMethodRequest(method);
|
||||||
HttpPost httppost = new HttpPost(url);
|
return method.deserializeResponse(responseContent);
|
||||||
httppost.setConfig(requestConfig);
|
|
||||||
httppost.addHeader("charset", StandardCharsets.UTF_8.name());
|
|
||||||
httppost.setEntity(new StringEntity(objectMapper.writeValueAsString(method), ContentType.APPLICATION_JSON));
|
|
||||||
try (CloseableHttpResponse response = httpclient.execute(httppost)) {
|
|
||||||
HttpEntity ht = response.getEntity();
|
|
||||||
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
|
|
||||||
responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new TelegramApiException("Unable to execute " + method.getMethod() + " method", e);
|
throw new TelegramApiException("Unable to execute " + method.getMethod() + " method", e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return method.deserializeResponse(responseContent);
|
private <T> Runnable getDownloadFileAsyncJob(T fileIdentifier, DownloadFileCallback<T> callback, String url, String tempFileName) {
|
||||||
|
//noinspection Convert2Lambda
|
||||||
|
return new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
callback.onResult(fileIdentifier, downloadToTemporaryFile(url, tempFileName));
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
callback.onException(fileIdentifier, new TelegramApiException("Wrong url for file: " + url));
|
||||||
|
} catch (IOException e) {
|
||||||
|
callback.onException(fileIdentifier, new TelegramApiRequestException("Error downloading the file", e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private java.io.File downloadToTemporaryFileWrappingExceptions(String url, String tempFileName) throws TelegramApiException {
|
||||||
|
try {
|
||||||
|
return downloadToTemporaryFile(url, tempFileName);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
throw new TelegramApiException("Wrong url for file: " + url);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new TelegramApiRequestException("Error downloading the file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private java.io.File downloadToTemporaryFile(String url, String tempFileName) throws IOException {
|
||||||
|
java.io.File output = java.io.File.createTempFile(tempFileName, ".tmp");
|
||||||
|
FileUtils.copyURLToFile(new URL(url), output);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends Serializable, Method extends BotApiMethod<T>> String sendMethodRequest(Method method) throws TelegramApiValidationException, IOException {
|
||||||
|
method.validate();
|
||||||
|
String url = getBaseUrl() + method.getMethod();
|
||||||
|
HttpPost httppost = configuredHttpPost(url);
|
||||||
|
httppost.addHeader("charset", StandardCharsets.UTF_8.name());
|
||||||
|
httppost.setEntity(new StringEntity(objectMapper.writeValueAsString(method), ContentType.APPLICATION_JSON));
|
||||||
|
return sendHttpPostRequest(httppost);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String sendHttpPostRequest(HttpPost httppost) throws IOException {
|
||||||
|
try (CloseableHttpResponse response = httpclient.execute(httppost)) {
|
||||||
|
HttpEntity ht = response.getEntity();
|
||||||
|
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
|
||||||
|
return EntityUtils.toString(buf, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpPost configuredHttpPost(String url) {
|
||||||
|
HttpPost httppost = new HttpPost(url);
|
||||||
|
httppost.setConfig(requestConfig);
|
||||||
|
return httppost;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getBaseUrl() {
|
protected String getBaseUrl() {
|
||||||
return options.getBaseUrl() + getBotToken() + "/";
|
return options.getBaseUrl() + getBotToken() + "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void assertParamNotNull(Object param, String paramName) throws TelegramApiException {
|
||||||
|
if (param == null) {
|
||||||
|
throw new TelegramApiException("Parameter " + paramName + " can not be null");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package org.telegram.telegrambots.updatesreceivers;
|
package org.telegram.telegrambots.updatesreceivers;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.google.inject.Inject;
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.client.config.RequestConfig;
|
import org.apache.http.client.config.RequestConfig;
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
@ -21,15 +19,12 @@ 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.DefaultBotOptions;
|
import org.telegram.telegrambots.bots.DefaultBotOptions;
|
||||||
import org.telegram.telegrambots.exceptions.TelegramApiRequestException;
|
import org.telegram.telegrambots.exceptions.TelegramApiRequestException;
|
||||||
import org.telegram.telegrambots.generics.BotOptions;
|
import org.telegram.telegrambots.generics.*;
|
||||||
import org.telegram.telegrambots.generics.BotSession;
|
|
||||||
import org.telegram.telegrambots.generics.LongPollingBot;
|
|
||||||
import org.telegram.telegrambots.generics.UpdatesHandler;
|
|
||||||
import org.telegram.telegrambots.generics.UpdatesReader;
|
|
||||||
import org.telegram.telegrambots.logging.BotLogger;
|
import org.telegram.telegrambots.logging.BotLogger;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InvalidObjectException;
|
import java.io.InvalidObjectException;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.InvalidParameterException;
|
import java.security.InvalidParameterException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -229,6 +224,8 @@ public class DefaultBotSession implements BotSession {
|
|||||||
BotLogger.severe(responseContent, LOGTAG, e);
|
BotLogger.severe(responseContent, LOGTAG, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (SocketTimeoutException e) {
|
||||||
|
BotLogger.fine(LOGTAG, e);
|
||||||
} catch (InvalidObjectException | TelegramApiRequestException e) {
|
} catch (InvalidObjectException | TelegramApiRequestException e) {
|
||||||
BotLogger.severe(LOGTAG, e);
|
BotLogger.severe(LOGTAG, e);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user