initial commit
This commit is contained in:
19
.gitignore
vendored
Normal file
19
.gitignore
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
17
README.MD
Normal file
17
README.MD
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
## Простой фреймворк\фасад для Telegram-бота
|
||||||
|
|
||||||
|
### Цели
|
||||||
|
|
||||||
|
* Предоставить удобные абстракции
|
||||||
|
* Предоставить инструменты для тестирования
|
||||||
|
* Отделить логику бота от конкретной реализации
|
||||||
|
|
||||||
|
### Основная идея
|
||||||
|
|
||||||
|
Цепочка из `Command` принимает `BotRequest` и `BotResponse`, и после обработки вызывает следующий `Command`.
|
||||||
|
|
||||||
|
`BotRequest` содержит информации о действии пользователя.
|
||||||
|
|
||||||
|
`BotResponse` позволяет отправить ответ в виде `Screen`.
|
||||||
|
|
||||||
|
`Screen` содержит отображаемый текст и действия -- кнопки для клавиатуры или inline-кнопки с данными.
|
||||||
57
pom.xml
Normal file
57
pom.xml
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<groupId>ru.penkrat.stbf</groupId>
|
||||||
|
<artifactId>stbf-parent</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>stbf-parent</name>
|
||||||
|
|
||||||
|
<description>Simple Telegram Bot Facade</description>
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<lombok.version>1.18.6</lombok.version>
|
||||||
|
<slf4j.version>1.7.25</slf4j.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>stbf-api</module>
|
||||||
|
<module>stbf-pengrad</module>
|
||||||
|
<module>stbf-test</module>
|
||||||
|
<module>stbf-common</module>
|
||||||
|
<module>stbf-rubenlagus</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>${slf4j.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
30
stbf-api/pom.xml
Normal file
30
stbf-api/pom.xml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>ru.penkrat.stbf</groupId>
|
||||||
|
<artifactId>stbf-parent</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>stbf-api</artifactId>
|
||||||
|
<name>stbf-api</name>
|
||||||
|
<description>Simple Telegram Bot Facade API Module</description>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
57
stbf-api/src/main/java/ru/penkrat/stbf/api/Action.java
Normal file
57
stbf-api/src/main/java/ru/penkrat/stbf/api/Action.java
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package ru.penkrat.stbf.api;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@ToString(of = "text")
|
||||||
|
public class Action {
|
||||||
|
|
||||||
|
public static Action simple(String text) {
|
||||||
|
return builder().text(text).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Action simple(String text, String cmd) {
|
||||||
|
validateCmd(cmd);
|
||||||
|
return builder().text(text).cmd(cmd).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Action callback(String text, String callbackData) {
|
||||||
|
return builder().inline(true).text(text).callbackData(callbackData).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Action requestContact(String text) {
|
||||||
|
return builder().text(text).requestContact(true).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean inline;
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
private String cmd;
|
||||||
|
|
||||||
|
// in-line
|
||||||
|
private String callbackData;
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
// keyboard
|
||||||
|
private boolean requestContact;
|
||||||
|
private boolean requestLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Text of the command, 1-32 characters. Can contain only lowercase English
|
||||||
|
* letters, digits and underscores.
|
||||||
|
*/
|
||||||
|
private static void validateCmd(@NonNull String cmd) {
|
||||||
|
if (cmd.length() > 32) {
|
||||||
|
throw new IllegalArgumentException("Max length - 32 characters");
|
||||||
|
}
|
||||||
|
if (!cmd.startsWith("/")) {
|
||||||
|
throw new IllegalArgumentException("Command must start / character");
|
||||||
|
}
|
||||||
|
// TODO validate lowercase etc
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package ru.penkrat.stbf.api;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class BotCommandChain implements CommandChain {
|
||||||
|
|
||||||
|
private final List<Command> commands;
|
||||||
|
|
||||||
|
public BotCommandChain() {
|
||||||
|
this(new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processCommand(BotRequest botRequest, BotResponse botResponse) {
|
||||||
|
if (!commands.isEmpty()) {
|
||||||
|
try {
|
||||||
|
Command command = commands.get(0);
|
||||||
|
log.debug("Run command {}", command.getClass().getSimpleName());
|
||||||
|
command.process(botRequest, botResponse,
|
||||||
|
new BotCommandChain(commands.subList(1, commands.size())));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error in command:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BotCommandChain add(Command cmd) {
|
||||||
|
commands.add(cmd);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
17
stbf-api/src/main/java/ru/penkrat/stbf/api/BotRequest.java
Normal file
17
stbf-api/src/main/java/ru/penkrat/stbf/api/BotRequest.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package ru.penkrat.stbf.api;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface BotRequest {
|
||||||
|
|
||||||
|
Optional<String> getMessageText();
|
||||||
|
|
||||||
|
Optional<String> getPhoneNumber();
|
||||||
|
|
||||||
|
Optional<String> getCallbackData();
|
||||||
|
|
||||||
|
Optional<String> getCallbackMessageText();
|
||||||
|
|
||||||
|
Long getChatId();
|
||||||
|
|
||||||
|
}
|
||||||
15
stbf-api/src/main/java/ru/penkrat/stbf/api/BotResponse.java
Normal file
15
stbf-api/src/main/java/ru/penkrat/stbf/api/BotResponse.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package ru.penkrat.stbf.api;
|
||||||
|
|
||||||
|
public interface BotResponse {
|
||||||
|
|
||||||
|
void send(Screen screen);
|
||||||
|
|
||||||
|
void sendFile(String filename, byte[] data);
|
||||||
|
|
||||||
|
void editMessage(String text);
|
||||||
|
|
||||||
|
void deleteMessage();
|
||||||
|
|
||||||
|
void edit(Screen screen);
|
||||||
|
|
||||||
|
}
|
||||||
7
stbf-api/src/main/java/ru/penkrat/stbf/api/Command.java
Normal file
7
stbf-api/src/main/java/ru/penkrat/stbf/api/Command.java
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package ru.penkrat.stbf.api;
|
||||||
|
|
||||||
|
public interface Command {
|
||||||
|
|
||||||
|
void process(BotRequest botRequest, BotResponse botResponse, CommandChain chain);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package ru.penkrat.stbf.api;
|
||||||
|
|
||||||
|
public interface CommandChain {
|
||||||
|
|
||||||
|
void processCommand(BotRequest botRequest, BotResponse botResponse);
|
||||||
|
|
||||||
|
}
|
||||||
5
stbf-api/src/main/java/ru/penkrat/stbf/api/Keyboard.java
Normal file
5
stbf-api/src/main/java/ru/penkrat/stbf/api/Keyboard.java
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package ru.penkrat.stbf.api;
|
||||||
|
|
||||||
|
public interface Keyboard {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package ru.penkrat.stbf.api;
|
||||||
|
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
|
||||||
|
public interface KeyboardBuilder {
|
||||||
|
|
||||||
|
ServiceLoader<KeyboardBuilder> keyboardBuilderLoader = ServiceLoader.load(KeyboardBuilder.class);
|
||||||
|
|
||||||
|
public static KeyboardBuilder newKeyboard() {
|
||||||
|
for (KeyboardBuilder kb : keyboardBuilderLoader) {
|
||||||
|
return kb.newInstance();
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("No service KeyboardBuilder found");
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardBuilder newInstance();
|
||||||
|
|
||||||
|
public static Keyboard singleKey(Action action) {
|
||||||
|
return newKeyboard().add(action).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
default KeyboardBuilder add(String text, String callbackData) {
|
||||||
|
return add(Action.callback(text, callbackData));
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardBuilder add(Action action);
|
||||||
|
|
||||||
|
KeyboardBuilder row(Action... buttons);
|
||||||
|
|
||||||
|
KeyboardBuilder column(Action... buttons);
|
||||||
|
|
||||||
|
Keyboard build();
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package ru.penkrat.stbf.api;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface RequestMatcher {
|
||||||
|
|
||||||
|
boolean match(BotRequest botRequest);
|
||||||
|
|
||||||
|
}
|
||||||
14
stbf-api/src/main/java/ru/penkrat/stbf/api/Screen.java
Normal file
14
stbf-api/src/main/java/ru/penkrat/stbf/api/Screen.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package ru.penkrat.stbf.api;
|
||||||
|
|
||||||
|
public interface Screen {
|
||||||
|
|
||||||
|
String getText();
|
||||||
|
|
||||||
|
default Keyboard getKeyboard() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
default ScreenProperties getScreenProperties() {
|
||||||
|
return ScreenProperties.DEFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package ru.penkrat.stbf.api;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class ScreenProperties {
|
||||||
|
|
||||||
|
public static final ScreenProperties DEFAULT = new ScreenProperties()
|
||||||
|
.setDisableWebPagePreview(true)
|
||||||
|
.setDisableNotification(true)
|
||||||
|
.setParseModeHtml(true);
|
||||||
|
|
||||||
|
private boolean disableWebPagePreview;
|
||||||
|
|
||||||
|
private boolean disableNotification;
|
||||||
|
|
||||||
|
private boolean parseModeHtml;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
ru.penkrat.stbf.impl.pengrad.PengradKeyboardBuilder
|
||||||
41
stbf-common/pom.xml
Normal file
41
stbf-common/pom.xml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
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>
|
||||||
|
<parent>
|
||||||
|
<artifactId>stbf-parent</artifactId>
|
||||||
|
<groupId>ru.penkrat.stbf</groupId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>stbf-common</artifactId>
|
||||||
|
<name>stbf-common</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.penkrat.stbf</groupId>
|
||||||
|
<artifactId>stbf-api</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.11</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package ru.penkrat.stbf.common.command;
|
||||||
|
|
||||||
|
import ru.penkrat.stbf.api.Action;
|
||||||
|
import ru.penkrat.stbf.api.BotRequest;
|
||||||
|
import ru.penkrat.stbf.api.BotResponse;
|
||||||
|
import ru.penkrat.stbf.api.Command;
|
||||||
|
import ru.penkrat.stbf.api.CommandChain;
|
||||||
|
import ru.penkrat.stbf.api.RequestMatcher;
|
||||||
|
import ru.penkrat.stbf.tools.RequestMatchers;
|
||||||
|
|
||||||
|
public abstract class AbstractActionCommand implements Command {
|
||||||
|
|
||||||
|
private RequestMatcher matcher;
|
||||||
|
|
||||||
|
public AbstractActionCommand(Action action) {
|
||||||
|
matcher = RequestMatchers.action(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(BotRequest botRequest, BotResponse botResponse, CommandChain chain) {
|
||||||
|
if (matcher.match(botRequest)) {
|
||||||
|
doProcess(botRequest, botResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
chain.processCommand(botRequest, botResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void doProcess(BotRequest botRequest, BotResponse botResponse);
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package ru.penkrat.stbf.common.command;
|
||||||
|
|
||||||
|
import ru.penkrat.stbf.api.Action;
|
||||||
|
import ru.penkrat.stbf.api.BotRequest;
|
||||||
|
import ru.penkrat.stbf.api.BotResponse;
|
||||||
|
import ru.penkrat.stbf.api.Command;
|
||||||
|
import ru.penkrat.stbf.api.CommandChain;
|
||||||
|
import ru.penkrat.stbf.api.RequestMatcher;
|
||||||
|
import ru.penkrat.stbf.api.Screen;
|
||||||
|
import ru.penkrat.stbf.common.screen.TextScreen;
|
||||||
|
import ru.penkrat.stbf.tools.RequestMatchers;
|
||||||
|
|
||||||
|
public class SimpleCommand implements Command {
|
||||||
|
|
||||||
|
private final RequestMatcher matcher;
|
||||||
|
private final Screen screen;
|
||||||
|
|
||||||
|
public SimpleCommand(String input, String output) {
|
||||||
|
this(Action.simple(input), new TextScreen(output));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleCommand(Action action, Screen screen) {
|
||||||
|
this.screen = screen;
|
||||||
|
matcher = RequestMatchers.action(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(BotRequest botRequest, BotResponse botResponse, CommandChain chain) {
|
||||||
|
if (matcher.match(botRequest)) {
|
||||||
|
botResponse.send(screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
chain.processCommand(botRequest, botResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package ru.penkrat.stbf.common.screen;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import ru.penkrat.stbf.api.Action;
|
||||||
|
import ru.penkrat.stbf.api.Keyboard;
|
||||||
|
import ru.penkrat.stbf.api.Screen;
|
||||||
|
import ru.penkrat.stbf.api.KeyboardBuilder;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class TextScreen implements Screen {
|
||||||
|
|
||||||
|
private final String text;
|
||||||
|
|
||||||
|
private final Keyboard keyboard;
|
||||||
|
|
||||||
|
public TextScreen(String text) {
|
||||||
|
this.text = text;
|
||||||
|
this.keyboard = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextScreen(String text, Keyboard keyboard) {
|
||||||
|
this.text = text;
|
||||||
|
this.keyboard = keyboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextScreen(String text, Action btn) {
|
||||||
|
this(text, KeyboardBuilder.singleKey(btn));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextScreen(String text, Action btn1, Action btn2) {
|
||||||
|
this(text, KeyboardBuilder.newKeyboard().add(btn1).add(btn2).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package ru.penkrat.stbf.tools;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import ru.penkrat.stbf.api.Action;
|
||||||
|
import ru.penkrat.stbf.api.RequestMatcher;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class RequestMatchers {
|
||||||
|
|
||||||
|
public RequestMatcher action(Action action) {
|
||||||
|
return request -> request.getMessageText()
|
||||||
|
.filter(text -> matchText(action, text))
|
||||||
|
.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean matchText(Action action, String inputText) {
|
||||||
|
return inputText.equalsIgnoreCase(action.getText())
|
||||||
|
|| (action.getCmd() != null && inputText.equalsIgnoreCase(action.getCmd()));
|
||||||
|
}
|
||||||
|
}
|
||||||
20
stbf-common/src/test/java/ru/penkrat/stbf/AppTest.java
Normal file
20
stbf-common/src/test/java/ru/penkrat/stbf/AppTest.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package ru.penkrat.stbf;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for simple App.
|
||||||
|
*/
|
||||||
|
public class AppTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Rigorous Test :-)
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void shouldAnswerWithTrue()
|
||||||
|
{
|
||||||
|
assertTrue( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
43
stbf-pengrad/pom.xml
Normal file
43
stbf-pengrad/pom.xml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>ru.penkrat.stbf</groupId>
|
||||||
|
<artifactId>stbf-parent</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>stbf-pengrad</artifactId>
|
||||||
|
<name>stbf-pengrad</name>
|
||||||
|
<description>Simple Telegram Bot Facade with com.github.pengrad implementation</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.penkrat.stbf</groupId>
|
||||||
|
<artifactId>stbf-api</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.pengrad</groupId>
|
||||||
|
<artifactId>java-telegram-bot-api</artifactId>
|
||||||
|
<version>[4.9.0,5.2.0]</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package ru.penkrat.stbf.impl.pengrad;
|
||||||
|
|
||||||
|
import static lombok.AccessLevel.PROTECTED;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import com.pengrad.telegrambot.model.CallbackQuery;
|
||||||
|
import com.pengrad.telegrambot.model.Contact;
|
||||||
|
import com.pengrad.telegrambot.model.Message;
|
||||||
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import ru.penkrat.stbf.api.BotRequest;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class BotRequestImpl implements BotRequest {
|
||||||
|
|
||||||
|
@Getter(PROTECTED)
|
||||||
|
private final Update update;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getMessageText() {
|
||||||
|
if (update.message() != null) {
|
||||||
|
return Optional.ofNullable(update.message().text());
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getPhoneNumber() {
|
||||||
|
return Optional.of(update)
|
||||||
|
.map(Update::message)
|
||||||
|
.map(Message::contact)
|
||||||
|
.map(Contact::phoneNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getCallbackData() {
|
||||||
|
return Optional.of(update)
|
||||||
|
.map(Update::callbackQuery)
|
||||||
|
.map(CallbackQuery::data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getCallbackMessageText() {
|
||||||
|
return Optional.of(update)
|
||||||
|
.map(Update::callbackQuery)
|
||||||
|
.map(CallbackQuery::message)
|
||||||
|
.map(Message::text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getChatId() {
|
||||||
|
return Optional.of(update)
|
||||||
|
.map(Update::callbackQuery)
|
||||||
|
.map(CallbackQuery::message)
|
||||||
|
.orElseGet(() -> update.message()).chat().id();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
package ru.penkrat.stbf.impl.pengrad;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import com.google.gson.internal.reflect.ReflectionAccessor;
|
||||||
|
import com.pengrad.telegrambot.TelegramBot;
|
||||||
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
import com.pengrad.telegrambot.model.request.InlineKeyboardButton;
|
||||||
|
import com.pengrad.telegrambot.model.request.InlineKeyboardMarkup;
|
||||||
|
import com.pengrad.telegrambot.model.request.KeyboardButton;
|
||||||
|
import com.pengrad.telegrambot.model.request.ParseMode;
|
||||||
|
import com.pengrad.telegrambot.model.request.ReplyKeyboardMarkup;
|
||||||
|
import com.pengrad.telegrambot.request.DeleteMessage;
|
||||||
|
import com.pengrad.telegrambot.request.EditMessageText;
|
||||||
|
import com.pengrad.telegrambot.request.SendDocument;
|
||||||
|
import com.pengrad.telegrambot.request.SendMessage;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import ru.penkrat.stbf.api.BotResponse;
|
||||||
|
import ru.penkrat.stbf.api.Screen;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class BotResponseImpl implements BotResponse {
|
||||||
|
|
||||||
|
private final Update update;
|
||||||
|
|
||||||
|
private final TelegramBot telegramBot;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(Screen screen) {
|
||||||
|
log.debug("Send message: \n============\n{}\n============", screen.getText().trim());
|
||||||
|
|
||||||
|
SendMessage sendMessage = new SendMessage(chatId(), screen.getText().trim())
|
||||||
|
.parseMode(screen.getScreenProperties().isParseModeHtml() ? ParseMode.HTML : ParseMode.MarkdownV2)
|
||||||
|
.disableWebPagePreview(screen.getScreenProperties().isDisableWebPagePreview())
|
||||||
|
.disableNotification(screen.getScreenProperties().isDisableNotification());
|
||||||
|
|
||||||
|
if (screen.getKeyboard() instanceof KeyboardImpl) {
|
||||||
|
KeyboardImpl kk = (KeyboardImpl) screen.getKeyboard();
|
||||||
|
KeyboardButton[][] keyboard = kk.getKeyboard();
|
||||||
|
InlineKeyboardButton[][] inlineKeyboard = kk.getInlineKeyboard();
|
||||||
|
|
||||||
|
if (inlineKeyboard != null && inlineKeyboard.length > 0) {
|
||||||
|
logKeyboard(inlineKeyboard);
|
||||||
|
sendMessage = sendMessage.replyMarkup(new InlineKeyboardMarkup(inlineKeyboard));
|
||||||
|
} else if (keyboard != null && keyboard.length > 0) {
|
||||||
|
logKeyboard(keyboard);
|
||||||
|
sendMessage = sendMessage.replyMarkup(new ReplyKeyboardMarkup(keyboard));
|
||||||
|
} else {
|
||||||
|
log.debug("No keyboard");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
telegramBot.execute(sendMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendFile(String filename, byte[] data) {
|
||||||
|
telegramBot.execute(new SendDocument(chatId(), data).fileName(filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public void editMessage(String text) {
|
||||||
|
telegramBot.execute(new EditMessageText(chatId(), messageId(), text)
|
||||||
|
.parseMode(ParseMode.HTML)
|
||||||
|
.disableWebPagePreview(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void edit(Screen screen) {
|
||||||
|
EditMessageText editMessage = new EditMessageText(chatId(), messageId(), screen.getText())
|
||||||
|
.parseMode(screen.getScreenProperties().isParseModeHtml() ? ParseMode.HTML : ParseMode.MarkdownV2)
|
||||||
|
.disableWebPagePreview(screen.getScreenProperties().isDisableWebPagePreview());
|
||||||
|
|
||||||
|
if (screen.getKeyboard() instanceof KeyboardImpl) {
|
||||||
|
KeyboardImpl kk = (KeyboardImpl) screen.getKeyboard();
|
||||||
|
InlineKeyboardButton[][] inlineKeyboard = kk.getInlineKeyboard();
|
||||||
|
|
||||||
|
if (inlineKeyboard != null && inlineKeyboard.length > 0) {
|
||||||
|
logKeyboard(inlineKeyboard);
|
||||||
|
editMessage = editMessage.replyMarkup(new InlineKeyboardMarkup(inlineKeyboard));
|
||||||
|
} else {
|
||||||
|
log.debug("No keyboard");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
telegramBot.execute(editMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteMessage() {
|
||||||
|
telegramBot.execute(new DeleteMessage(chatId(), messageId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long chatId() {
|
||||||
|
if (update.callbackQuery() != null) {
|
||||||
|
return update.callbackQuery().message().chat().id();
|
||||||
|
}
|
||||||
|
return update.message().chat().id();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer messageId() {
|
||||||
|
if (update.callbackQuery() != null) {
|
||||||
|
return update.callbackQuery().message().messageId();
|
||||||
|
}
|
||||||
|
return update.message().messageId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logKeyboard(KeyboardButton[][] keyboard) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
for (int i = 0; i < keyboard.length; i++) {
|
||||||
|
if (keyboard[i].length > 0) {
|
||||||
|
String row = Stream.of(keyboard[i]).map(this::getText).collect(Collectors.joining(" | "));
|
||||||
|
log.debug("Keyboard: {}", row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logKeyboard(InlineKeyboardButton[][] keyboard) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
for (int i = 0; i < keyboard.length; i++) {
|
||||||
|
if (keyboard[i].length > 0) {
|
||||||
|
String row = Stream.of(keyboard[i]).map(this::getText).collect(Collectors.joining(" | "));
|
||||||
|
log.debug("Inline keyboard: {}", row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
private String getText(KeyboardButton btn) {
|
||||||
|
Field text = KeyboardButton.class.getDeclaredField("text");
|
||||||
|
ReflectionAccessor.getInstance().makeAccessible(text);
|
||||||
|
return String.valueOf(text.get(btn));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
private String getText(InlineKeyboardButton btn) {
|
||||||
|
Field text = InlineKeyboardButton.class.getDeclaredField("text");
|
||||||
|
ReflectionAccessor.getInstance().makeAccessible(text);
|
||||||
|
return String.valueOf(text.get(btn));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package ru.penkrat.stbf.impl.pengrad;
|
||||||
|
|
||||||
|
import com.pengrad.telegrambot.model.request.InlineKeyboardButton;
|
||||||
|
import com.pengrad.telegrambot.model.request.KeyboardButton;
|
||||||
|
|
||||||
|
import lombok.Value;
|
||||||
|
import ru.penkrat.stbf.api.Keyboard;
|
||||||
|
|
||||||
|
@Value
|
||||||
|
class KeyboardImpl implements Keyboard {
|
||||||
|
|
||||||
|
private KeyboardButton[][] keyboard;
|
||||||
|
|
||||||
|
private InlineKeyboardButton[][] inlineKeyboard;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
package ru.penkrat.stbf.impl.pengrad;
|
||||||
|
|
||||||
|
import com.pengrad.telegrambot.model.request.InlineKeyboardButton;
|
||||||
|
import com.pengrad.telegrambot.model.request.KeyboardButton;
|
||||||
|
|
||||||
|
import ru.penkrat.stbf.api.Action;
|
||||||
|
import ru.penkrat.stbf.api.Keyboard;
|
||||||
|
import ru.penkrat.stbf.api.KeyboardBuilder;
|
||||||
|
|
||||||
|
public class PengradKeyboardBuilder implements KeyboardBuilder {
|
||||||
|
|
||||||
|
private KeyboardButton[][] keyboard;
|
||||||
|
|
||||||
|
private InlineKeyboardButton[][] inlineKeyboard;
|
||||||
|
|
||||||
|
public static Keyboard singleKey(Action action) {
|
||||||
|
return KeyboardBuilder.newKeyboard().add(action).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Keyboard build() {
|
||||||
|
return new KeyboardImpl(keyboard, inlineKeyboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyboardBuilder addGetContact(String text) {
|
||||||
|
put(new KeyboardButton(text).requestContact(true));
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyboardBuilder add(String text) {
|
||||||
|
put(new KeyboardButton(text));
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyboardBuilder add(Action action) {
|
||||||
|
put(action);
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyboardBuilder row(KeyboardButton... buttons) {
|
||||||
|
for (int i = 0; i < buttons.length; i++) {
|
||||||
|
put(buttons[i]);
|
||||||
|
}
|
||||||
|
nextRow();
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyboardBuilder row(Action... buttons) {
|
||||||
|
for (int i = 0; i < buttons.length; i++) {
|
||||||
|
put(buttons[i]);
|
||||||
|
}
|
||||||
|
nextRow();
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyboardBuilder column(Action... buttons) {
|
||||||
|
for (int i = 0; i < buttons.length; i++) {
|
||||||
|
put(buttons[i]);
|
||||||
|
if (buttons[i].isInline()) {
|
||||||
|
nextRowI();
|
||||||
|
} else {
|
||||||
|
nextRow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyboardBuilder addNl(String text) {
|
||||||
|
add(text);
|
||||||
|
nextRow();
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PengradKeyboardBuilder add(String text, String data) {
|
||||||
|
put(new InlineKeyboardButton(text).callbackData(data));
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyboardBuilder addNl(String text, String data) {
|
||||||
|
add(text, data);
|
||||||
|
nextRowI();
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void nextRow() {
|
||||||
|
KeyboardButton[][] n = new KeyboardButton[keyboard.length + 1][];
|
||||||
|
System.arraycopy(keyboard, 0, n, 0, keyboard.length);
|
||||||
|
keyboard = n;
|
||||||
|
keyboard[keyboard.length - 1] = new KeyboardButton[] {};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void nextRowI() {
|
||||||
|
InlineKeyboardButton[][] n = new InlineKeyboardButton[inlineKeyboard.length + 1][];
|
||||||
|
System.arraycopy(inlineKeyboard, 0, n, 0, inlineKeyboard.length);
|
||||||
|
inlineKeyboard = n;
|
||||||
|
inlineKeyboard[inlineKeyboard.length - 1] = new InlineKeyboardButton[] {};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PengradKeyboardBuilder self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void put(Action action) {
|
||||||
|
if (action.isInline()) {
|
||||||
|
put(new InlineKeyboardButton(action.getText()).callbackData(action.getCallbackData()));
|
||||||
|
} else {
|
||||||
|
put(new KeyboardButton(action.getText()).requestContact(action.isRequestContact()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void put(KeyboardButton btn) {
|
||||||
|
if (keyboard == null) {
|
||||||
|
keyboard = new KeyboardButton[][] {
|
||||||
|
new KeyboardButton[] { btn }
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
KeyboardButton[] k = keyboard[keyboard.length - 1];
|
||||||
|
KeyboardButton[] n = new KeyboardButton[k.length + 1];
|
||||||
|
System.arraycopy(k, 0, n, 0, k.length);
|
||||||
|
n[k.length] = btn;
|
||||||
|
keyboard[keyboard.length - 1] = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void put(InlineKeyboardButton btn) {
|
||||||
|
if (inlineKeyboard == null) {
|
||||||
|
inlineKeyboard = new InlineKeyboardButton[][] {
|
||||||
|
new InlineKeyboardButton[] { btn }
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
InlineKeyboardButton[] k = inlineKeyboard[inlineKeyboard.length - 1];
|
||||||
|
InlineKeyboardButton[] n = new InlineKeyboardButton[k.length + 1];
|
||||||
|
System.arraycopy(k, 0, n, 0, k.length);
|
||||||
|
n[k.length] = btn;
|
||||||
|
inlineKeyboard[inlineKeyboard.length - 1] = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyboardBuilder newInstance() {
|
||||||
|
return new PengradKeyboardBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package ru.penkrat.stbf.impl.pengrad;
|
||||||
|
|
||||||
|
import com.pengrad.telegrambot.TelegramBot;
|
||||||
|
import com.pengrad.telegrambot.UpdatesListener;
|
||||||
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import ru.penkrat.stbf.api.CommandChain;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class PengradTelegramBot extends TelegramBot implements AutoCloseable {
|
||||||
|
|
||||||
|
public PengradTelegramBot(String botToken, CommandChain commandChain) {
|
||||||
|
super(botToken);
|
||||||
|
this.setUpdatesListener(updates -> {
|
||||||
|
for (Update update : updates) {
|
||||||
|
try {
|
||||||
|
commandChain.processCommand(
|
||||||
|
new BotRequestImpl(update),
|
||||||
|
new BotResponseImpl(update, this));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Bot Error:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return UpdatesListener.CONFIRMED_UPDATES_ALL;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws Exception {
|
||||||
|
removeGetUpdatesListener();
|
||||||
|
log.debug("Bot closed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
ru.penkrat.stbf.impl.pengrad.PengradKeyboardBuilder
|
||||||
41
stbf-rubenlagus/pom.xml
Normal file
41
stbf-rubenlagus/pom.xml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
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>
|
||||||
|
<parent>
|
||||||
|
<artifactId>stbf-parent</artifactId>
|
||||||
|
<groupId>ru.penkrat.stbf</groupId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>stbf-rubenlagus</artifactId>
|
||||||
|
<name>stbf-rubenlagus</name>
|
||||||
|
<description>Simple Telegram Bot Facade with https://github.com/rubenlagus/TelegramBots implementation</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.penkrat.stbf</groupId>
|
||||||
|
<artifactId>stbf-api</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.telegram</groupId>
|
||||||
|
<artifactId>telegrambots</artifactId>
|
||||||
|
<version>5.3.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package ru.penkrat.stbf.impl.rubenlagus;
|
||||||
|
|
||||||
|
import static lombok.AccessLevel.PROTECTED;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.CallbackQuery;
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.Contact;
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.Message;
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.Update;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import ru.penkrat.stbf.api.BotRequest;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
class BotRequestImpl implements BotRequest {
|
||||||
|
|
||||||
|
@Getter(PROTECTED)
|
||||||
|
private final Update update;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getMessageText() {
|
||||||
|
if (update.hasMessage()) {
|
||||||
|
return Optional.ofNullable(update.getMessage().getText());
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getPhoneNumber() {
|
||||||
|
return Optional.of(update)
|
||||||
|
.map(Update::getMessage)
|
||||||
|
.map(Message::getContact)
|
||||||
|
.map(Contact::getPhoneNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getCallbackData() {
|
||||||
|
return Optional.of(update)
|
||||||
|
.map(Update::getCallbackQuery)
|
||||||
|
.map(CallbackQuery::getData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getCallbackMessageText() {
|
||||||
|
return Optional.of(update)
|
||||||
|
.map(Update::getCallbackQuery)
|
||||||
|
.map(CallbackQuery::getMessage)
|
||||||
|
.map(Message::getText);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getChatId() {
|
||||||
|
return update.getMessage().getChatId();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package ru.penkrat.stbf.impl.rubenlagus;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
|
||||||
|
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
|
||||||
|
import org.telegram.telegrambots.meta.api.methods.updatingmessages.DeleteMessage;
|
||||||
|
import org.telegram.telegrambots.meta.api.methods.updatingmessages.EditMessageText;
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.Update;
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup;
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.replykeyboard.ReplyKeyboardMarkup;
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton;
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.KeyboardRow;
|
||||||
|
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import ru.penkrat.stbf.api.BotResponse;
|
||||||
|
import ru.penkrat.stbf.api.Screen;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
class BotResponseImpl implements BotResponse {
|
||||||
|
|
||||||
|
private final Update update;
|
||||||
|
|
||||||
|
private final TelegramLongPollingBot bot;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(Screen screen) {
|
||||||
|
SendMessage send = new SendMessage(chatId(), screen.getText());
|
||||||
|
|
||||||
|
if (screen.getKeyboard() instanceof KeyboardImpl) {
|
||||||
|
KeyboardImpl kk = (KeyboardImpl) screen.getKeyboard();
|
||||||
|
List<KeyboardRow> keyboard = kk.getKeyboard();
|
||||||
|
List<List<InlineKeyboardButton>> inlineKeyboard = kk.getInlineKeyboard();
|
||||||
|
|
||||||
|
if (inlineKeyboard != null && !inlineKeyboard.isEmpty()) {
|
||||||
|
send.setReplyMarkup(new InlineKeyboardMarkup(inlineKeyboard));
|
||||||
|
} else if (keyboard != null && !keyboard.isEmpty()) {
|
||||||
|
send.setReplyMarkup(new ReplyKeyboardMarkup(keyboard));
|
||||||
|
} else {
|
||||||
|
log.debug("No keyboard");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
bot.execute(send);
|
||||||
|
} catch (TelegramApiException e) {
|
||||||
|
log.error("Send error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendFile(String filename, byte[] data) {
|
||||||
|
throw new IllegalStateException("Not inplemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void editMessage(String text) {
|
||||||
|
EditMessageText send = new EditMessageText(text);
|
||||||
|
send.setChatId(chatId());
|
||||||
|
send.setMessageId(messageId());
|
||||||
|
if (update.hasCallbackQuery()) {
|
||||||
|
send.setInlineMessageId(update.getCallbackQuery().getInlineMessageId());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
bot.execute(send);
|
||||||
|
} catch (TelegramApiException e) {
|
||||||
|
log.error("Send error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteMessage() {
|
||||||
|
DeleteMessage send = new DeleteMessage(chatId(), messageId());
|
||||||
|
try {
|
||||||
|
bot.execute(send);
|
||||||
|
} catch (TelegramApiException e) {
|
||||||
|
log.error("Send error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void edit(Screen screen) {
|
||||||
|
EditMessageText send = new EditMessageText(screen.getText());
|
||||||
|
send.setChatId(chatId());
|
||||||
|
send.setMessageId(messageId());
|
||||||
|
if (update.hasCallbackQuery()) {
|
||||||
|
send.setInlineMessageId(update.getCallbackQuery().getInlineMessageId());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
bot.execute(send);
|
||||||
|
} catch (TelegramApiException e) {
|
||||||
|
log.error("Send error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String chatId() {
|
||||||
|
if (update.hasCallbackQuery()) {
|
||||||
|
return Long.toString(update.getCallbackQuery().getMessage().getChatId());
|
||||||
|
}
|
||||||
|
return Long.toString(update.getMessage().getChatId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer messageId() {
|
||||||
|
if (update.hasCallbackQuery()) {
|
||||||
|
return Integer.parseInt(update.getCallbackQuery().getInlineMessageId());
|
||||||
|
}
|
||||||
|
return update.getMessage().getMessageId();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package ru.penkrat.stbf.impl.rubenlagus;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton;
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.KeyboardRow;
|
||||||
|
|
||||||
|
import lombok.Value;
|
||||||
|
import ru.penkrat.stbf.api.Keyboard;
|
||||||
|
|
||||||
|
@Value
|
||||||
|
class KeyboardImpl implements Keyboard {
|
||||||
|
|
||||||
|
private List<KeyboardRow> keyboard;
|
||||||
|
|
||||||
|
private List<List<InlineKeyboardButton>> inlineKeyboard;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
package ru.penkrat.stbf.impl.rubenlagus;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton;
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.KeyboardButton;
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.KeyboardRow;
|
||||||
|
|
||||||
|
import ru.penkrat.stbf.api.Action;
|
||||||
|
import ru.penkrat.stbf.api.Keyboard;
|
||||||
|
import ru.penkrat.stbf.api.KeyboardBuilder;
|
||||||
|
|
||||||
|
public class RubenlagusKeyboardBuilder implements KeyboardBuilder {
|
||||||
|
|
||||||
|
private List<KeyboardRow> keyboard;
|
||||||
|
|
||||||
|
private List<List<InlineKeyboardButton>> inlineKeyboard;
|
||||||
|
|
||||||
|
public static Keyboard singleKey(Action action) {
|
||||||
|
return KeyboardBuilder.newKeyboard().add(action).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Keyboard build() {
|
||||||
|
return new KeyboardImpl(keyboard, inlineKeyboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyboardBuilder addGetContact(String text) {
|
||||||
|
KeyboardButton keyboardButton = new KeyboardButton(text);
|
||||||
|
keyboardButton.setRequestContact(true);
|
||||||
|
put(keyboardButton);
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyboardBuilder add(String text) {
|
||||||
|
put(new KeyboardButton(text));
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyboardBuilder add(Action action) {
|
||||||
|
put(action);
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyboardBuilder row(KeyboardButton... buttons) {
|
||||||
|
for (int i = 0; i < buttons.length; i++) {
|
||||||
|
put(buttons[i]);
|
||||||
|
}
|
||||||
|
nextRow();
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyboardBuilder row(Action... buttons) {
|
||||||
|
for (int i = 0; i < buttons.length; i++) {
|
||||||
|
put(buttons[i]);
|
||||||
|
}
|
||||||
|
nextRow();
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyboardBuilder column(Action... buttons) {
|
||||||
|
for (int i = 0; i < buttons.length; i++) {
|
||||||
|
put(buttons[i]);
|
||||||
|
if (buttons[i].isInline()) {
|
||||||
|
nextRowI();
|
||||||
|
} else {
|
||||||
|
nextRow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyboardBuilder addNl(String text) {
|
||||||
|
add(text);
|
||||||
|
nextRow();
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RubenlagusKeyboardBuilder add(String text, String data) {
|
||||||
|
InlineKeyboardButton inlineKeyboardButton = new InlineKeyboardButton(text);
|
||||||
|
inlineKeyboardButton.setCallbackData(data);
|
||||||
|
put(inlineKeyboardButton);
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyboardBuilder addNl(String text, String data) {
|
||||||
|
add(text, data);
|
||||||
|
nextRowI();
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void nextRow() {
|
||||||
|
KeyboardRow row = new KeyboardRow();
|
||||||
|
keyboard.add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void nextRowI() {
|
||||||
|
List<InlineKeyboardButton> row = new ArrayList<>();
|
||||||
|
inlineKeyboard.add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RubenlagusKeyboardBuilder self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void put(Action action) {
|
||||||
|
if (action.isInline()) {
|
||||||
|
InlineKeyboardButton inlineKeyboardButton = new InlineKeyboardButton(action.getText());
|
||||||
|
inlineKeyboardButton.setCallbackData(action.getCallbackData());
|
||||||
|
put(inlineKeyboardButton);
|
||||||
|
} else {
|
||||||
|
KeyboardButton keyboardButton = new KeyboardButton(action.getText());
|
||||||
|
keyboardButton.setRequestContact(action.isRequestContact());
|
||||||
|
put(keyboardButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void put(KeyboardButton btn) {
|
||||||
|
if (keyboard == null) {
|
||||||
|
keyboard = new ArrayList<KeyboardRow>();
|
||||||
|
KeyboardRow row = new KeyboardRow();
|
||||||
|
keyboard.add(row);
|
||||||
|
row.add(btn);
|
||||||
|
} else {
|
||||||
|
keyboard.get(keyboard.size() - 1).add(btn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void put(InlineKeyboardButton btn) {
|
||||||
|
if (inlineKeyboard == null) {
|
||||||
|
inlineKeyboard = new ArrayList<List<InlineKeyboardButton>>();
|
||||||
|
List<InlineKeyboardButton> row = new ArrayList<>();
|
||||||
|
inlineKeyboard.add(row);
|
||||||
|
row.add(btn);
|
||||||
|
} else {
|
||||||
|
inlineKeyboard.get(inlineKeyboard.size() - 1).add(btn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyboardBuilder newInstance() {
|
||||||
|
return new RubenlagusKeyboardBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package ru.penkrat.stbf.impl.rubenlagus;
|
||||||
|
|
||||||
|
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
|
||||||
|
import org.telegram.telegrambots.meta.TelegramBotsApi;
|
||||||
|
import org.telegram.telegrambots.meta.api.objects.Update;
|
||||||
|
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
|
||||||
|
import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import ru.penkrat.stbf.api.BotCommandChain;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class RubenlagusTelegramBot extends TelegramLongPollingBot {
|
||||||
|
|
||||||
|
private final String botUsername;
|
||||||
|
private final String botToken;
|
||||||
|
private final BotCommandChain commandChain;
|
||||||
|
|
||||||
|
public RubenlagusTelegramBot(String botUsername, String botToken, BotCommandChain botCommandChain) {
|
||||||
|
this.botUsername = botUsername;
|
||||||
|
this.botToken = botToken;
|
||||||
|
this.commandChain = botCommandChain;
|
||||||
|
|
||||||
|
TelegramBotsApi telegramBotsApi;
|
||||||
|
try {
|
||||||
|
telegramBotsApi = new TelegramBotsApi(DefaultBotSession.class);
|
||||||
|
telegramBotsApi.registerBot(this);
|
||||||
|
} catch (TelegramApiException e) {
|
||||||
|
log.error("Error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdateReceived(Update update) {
|
||||||
|
try {
|
||||||
|
commandChain.processCommand(
|
||||||
|
new BotRequestImpl(update),
|
||||||
|
new BotResponseImpl(update, this));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Bot Error:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBotUsername() {
|
||||||
|
return botUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBotToken() {
|
||||||
|
return botToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
ru.penkrat.stbf.impl.rubenlagus.RubenlagusKeyboardBuilder
|
||||||
53
stbf-test/pom.xml
Normal file
53
stbf-test/pom.xml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
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>
|
||||||
|
<parent>
|
||||||
|
<artifactId>stbf-parent</artifactId>
|
||||||
|
<groupId>ru.penkrat.stbf</groupId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>stbf-test</artifactId>
|
||||||
|
<name>stbf-test</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.penkrat.stbf</groupId>
|
||||||
|
<artifactId>stbf-api</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.penkrat.stbf</groupId>
|
||||||
|
<artifactId>stbf-common</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.11</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
<artifactId>hamcrest</artifactId>
|
||||||
|
<version>2.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package ru.penkrat.stbf.test;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import ru.penkrat.stbf.api.BotRequest;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
class BotRequestImpl implements BotRequest {
|
||||||
|
|
||||||
|
private String messageText;
|
||||||
|
private String phoneNumber;
|
||||||
|
private String callbackData;
|
||||||
|
private String callbackMessageText;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder.Default
|
||||||
|
private Long chatId = new Random().nextLong();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getMessageText() {
|
||||||
|
return Optional.ofNullable(messageText);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getPhoneNumber() {
|
||||||
|
return Optional.ofNullable(phoneNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getCallbackData() {
|
||||||
|
return Optional.ofNullable(callbackData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getCallbackMessageText() {
|
||||||
|
return Optional.ofNullable(callbackMessageText);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package ru.penkrat.stbf.test;
|
||||||
|
|
||||||
|
import ru.penkrat.stbf.api.BotResponse;
|
||||||
|
import ru.penkrat.stbf.api.Screen;
|
||||||
|
|
||||||
|
class BotResponseImpl implements BotResponse {
|
||||||
|
|
||||||
|
private Result result;
|
||||||
|
|
||||||
|
public BotResponseImpl(Result result) {
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(Screen screen) {
|
||||||
|
result.addScreen(screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendFile(String filename, byte[] data) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void editMessage(String text) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteMessage() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void edit(Screen screen) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
23
stbf-test/src/main/java/ru/penkrat/stbf/test/Result.java
Normal file
23
stbf-test/src/main/java/ru/penkrat/stbf/test/Result.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package ru.penkrat.stbf.test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import ru.penkrat.stbf.api.Screen;
|
||||||
|
|
||||||
|
public class Result {
|
||||||
|
|
||||||
|
private final List<Screen> screens = new ArrayList<>();
|
||||||
|
|
||||||
|
public String text() {
|
||||||
|
if (screens.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return screens.get(0).getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addScreen(Screen screen) {
|
||||||
|
screens.add(screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
43
stbf-test/src/main/java/ru/penkrat/stbf/test/TestBot.java
Normal file
43
stbf-test/src/main/java/ru/penkrat/stbf/test/TestBot.java
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package ru.penkrat.stbf.test;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import ru.penkrat.stbf.api.BotCommandChain;
|
||||||
|
import ru.penkrat.stbf.api.BotRequest;
|
||||||
|
import ru.penkrat.stbf.api.Command;
|
||||||
|
import ru.penkrat.stbf.api.CommandChain;
|
||||||
|
import ru.penkrat.stbf.test.BotRequestImpl;
|
||||||
|
import ru.penkrat.stbf.test.BotResponseImpl;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class TestBot {
|
||||||
|
|
||||||
|
public static TestBot from(Command... commands) {
|
||||||
|
BotCommandChain bcc = new BotCommandChain();
|
||||||
|
for (int i = 0; i < commands.length; i++) {
|
||||||
|
bcc.add(commands[i]);
|
||||||
|
}
|
||||||
|
return new TestBot(bcc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final CommandChain commandChain;
|
||||||
|
|
||||||
|
public Result whenText(String input) {
|
||||||
|
return process(BotRequestImpl.builder().messageText(input).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result whenPhoneNumber(String input) {
|
||||||
|
return process(BotRequestImpl.builder().phoneNumber(input).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result whenCallback(String data) {
|
||||||
|
return process(BotRequestImpl.builder().callbackData(data).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result process(BotRequest botRequest) {
|
||||||
|
Result result = new Result();
|
||||||
|
commandChain.processCommand(botRequest, new BotResponseImpl(result));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
23
stbf-test/src/test/java/ru/penkrat/stbf/BotTest.java
Normal file
23
stbf-test/src/test/java/ru/penkrat/stbf/BotTest.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package ru.penkrat.stbf;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ru.penkrat.stbf.api.Command;
|
||||||
|
import ru.penkrat.stbf.common.command.SimpleCommand;
|
||||||
|
import ru.penkrat.stbf.test.Result;
|
||||||
|
import ru.penkrat.stbf.test.TestBot;
|
||||||
|
|
||||||
|
public class BotTest {
|
||||||
|
|
||||||
|
private Command start = new SimpleCommand("/start", "Hello, world");
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldAnswerWithHello() {
|
||||||
|
Result result = TestBot.from(start).whenText("/start");
|
||||||
|
|
||||||
|
assertThat(result.text(), containsString("Hello, world"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user