commands with callbackData support
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -7,51 +7,51 @@ import lombok.ToString;
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Builder
|
@Builder
|
||||||
@ToString(of = "text")
|
@ToString(of = {"text", "inline"})
|
||||||
public class Action {
|
public class Action {
|
||||||
|
|
||||||
public static Action simple(String text) {
|
public static Action simple(String text) {
|
||||||
return builder().text(text).build();
|
return builder().text(text).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Action simple(String text, String cmd) {
|
public static Action simple(String text, String cmd) {
|
||||||
validateCmd(cmd);
|
validateCmd(cmd);
|
||||||
return builder().text(text).cmd(cmd).build();
|
return builder().text(text).cmd(cmd).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Action callback(String text, String callbackData) {
|
public static Action callback(String text, String callbackData) {
|
||||||
return builder().inline(true).text(text).callbackData(callbackData).build();
|
return builder().inline(true).text(text).callbackData(callbackData).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Action requestContact(String text) {
|
public static Action requestContact(String text) {
|
||||||
return builder().text(text).requestContact(true).build();
|
return builder().text(text).requestContact(true).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean inline;
|
private boolean inline;
|
||||||
|
|
||||||
private String text;
|
private String text;
|
||||||
|
|
||||||
private String cmd;
|
private String cmd;
|
||||||
|
|
||||||
// in-line
|
// in-line
|
||||||
private String callbackData;
|
private String callbackData;
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
// keyboard
|
// keyboard
|
||||||
private boolean requestContact;
|
private boolean requestContact;
|
||||||
private boolean requestLocation;
|
private boolean requestLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Text of the command, 1-32 characters. Can contain only lowercase English
|
* Text of the command, 1-32 characters. Can contain only lowercase English
|
||||||
* letters, digits and underscores.
|
* letters, digits and underscores.
|
||||||
*/
|
*/
|
||||||
private static void validateCmd(@NonNull String cmd) {
|
private static void validateCmd(@NonNull String cmd) {
|
||||||
if (cmd.length() > 32) {
|
if (cmd.length() > 32) {
|
||||||
throw new IllegalArgumentException("Max length - 32 characters");
|
throw new IllegalArgumentException("Max length - 32 characters");
|
||||||
}
|
}
|
||||||
if (!cmd.startsWith("/")) {
|
if (!cmd.startsWith("/")) {
|
||||||
throw new IllegalArgumentException("Command must start / character");
|
throw new IllegalArgumentException("Command must start / character");
|
||||||
}
|
}
|
||||||
// TODO validate lowercase etc
|
// TODO validate lowercase etc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class BotCommandChain implements CommandChain {
|
|||||||
if (!commands.isEmpty()) {
|
if (!commands.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
Command command = commands.get(0);
|
Command command = commands.get(0);
|
||||||
log.debug("Run command {}", command.getClass().getSimpleName());
|
log.debug("Run command {} ({})", command.getClass().getSimpleName(), command);
|
||||||
command.process(botRequest, botResponse,
|
command.process(botRequest, botResponse,
|
||||||
new BotCommandChain(commands.subList(1, commands.size())));
|
new BotCommandChain(commands.subList(1, commands.size())));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -1,8 +1,20 @@
|
|||||||
package ru.penkrat.stbf.api;
|
package ru.penkrat.stbf.api;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface RequestMatcher {
|
public interface RequestMatcher {
|
||||||
|
|
||||||
boolean match(BotRequest botRequest);
|
boolean match(BotRequest botRequest);
|
||||||
|
|
||||||
|
default RequestMatcher or(RequestMatcher other) {
|
||||||
|
Objects.requireNonNull(other);
|
||||||
|
return (botRequest) -> match(botRequest) || other.match(botRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
default RequestMatcher and(RequestMatcher other) {
|
||||||
|
Objects.requireNonNull(other);
|
||||||
|
return (botRequest) -> match(botRequest) && other.match(botRequest);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,55 @@ import lombok.experimental.UtilityClass;
|
|||||||
import ru.penkrat.stbf.api.Action;
|
import ru.penkrat.stbf.api.Action;
|
||||||
import ru.penkrat.stbf.api.RequestMatcher;
|
import ru.penkrat.stbf.api.RequestMatcher;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class RequestMatchers {
|
public class RequestMatchers {
|
||||||
|
|
||||||
public RequestMatcher action(Action action) {
|
public RequestMatcher action(Action action) {
|
||||||
return request -> request.getMessageText()
|
return request -> request.getMessageText()
|
||||||
.filter(text -> matchText(action, text))
|
.filter(text -> matchText(action, text))
|
||||||
.isPresent();
|
.isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean matchText(Action action, String inputText) {
|
public RequestMatcher cmd(Action action) {
|
||||||
return inputText.equalsIgnoreCase(action.getText())
|
return request -> request.getMessageText()
|
||||||
|| (action.getCmd() != null && inputText.equalsIgnoreCase(action.getCmd()));
|
.filter(Objects::nonNull)
|
||||||
}
|
.filter(data -> Objects.equals(action.getCmd(), data))
|
||||||
|
.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestMatcher text(String callbackData) {
|
||||||
|
return request -> request.getCallbackData()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.filter(data -> Objects.equals(callbackData, data))
|
||||||
|
.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestMatcher callbackData(String callbackData) {
|
||||||
|
return request -> request.getCallbackData()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.filter(data -> Objects.equals(callbackData, data))
|
||||||
|
.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestMatcher callbackDataStartsWith(String callbackDataPrefix) {
|
||||||
|
return request -> request.getCallbackData()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.filter(data -> data.startsWith(callbackDataPrefix))
|
||||||
|
.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestMatcher callbackDataRegexp(String callbackDataPrefix) {
|
||||||
|
return request -> request.getCallbackData()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.filter(Pattern.compile(callbackDataPrefix).asPredicate())
|
||||||
|
.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean matchText(Action action, String inputText) {
|
||||||
|
return inputText.equalsIgnoreCase(action.getText())
|
||||||
|
|| (action.getCmd() != null && inputText.equalsIgnoreCase(action.getCmd()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,27 +2,74 @@
|
|||||||
<actions>
|
<actions>
|
||||||
<action id="10001" name="start-action" command="/start">Start</action>
|
<action id="10001" name="start-action" command="/start">Start</action>
|
||||||
<action id="10002" name="help-action" command="/help">Help</action>
|
<action id="10002" name="help-action" command="/help">Help</action>
|
||||||
|
<action id="10003" name="to-inline-action" command="/inline">Inline</action>
|
||||||
|
<action id="10004" name="inline1-action" callbackData="cmd:inline1">Inline button #1</action>
|
||||||
|
<action id="10005" name="inline2-action" callbackData="cmd:inline2">Inline button #2</action>
|
||||||
|
<action id="10006" name="url-action" url="https://git.penkrat.ru/ruslan/stbf">Git repo</action>
|
||||||
</actions>
|
</actions>
|
||||||
<screens>
|
<screens>
|
||||||
<screen id="20001" name="on-start-screen">
|
<screen id="20001" name="on-start-screen">
|
||||||
<text>This is demo bot</text>
|
<text>This is demo bot
|
||||||
|
use Help or /help to view help
|
||||||
|
</text>
|
||||||
<keyboard>
|
<keyboard>
|
||||||
<row>
|
<row>
|
||||||
<button actionRef="help-action">Action.name</button>
|
<button actionRef="help-action">Action.name</button>
|
||||||
</row>
|
</row>
|
||||||
</keyboard>
|
</keyboard>
|
||||||
</screen>
|
</screen>
|
||||||
<screen id="20001" name="on-help-screen">
|
<screen id="20002" name="on-help-screen">
|
||||||
<text>This is demo help</text>
|
<text>This is demo help
|
||||||
|
use /inline to switch to inline mode
|
||||||
|
</text>
|
||||||
<keyboard>
|
<keyboard>
|
||||||
<row>
|
<row>
|
||||||
<button actionRef="help-action">Action.name</button>
|
<button actionRef="help-action">Action.name</button>
|
||||||
</row>
|
</row>
|
||||||
</keyboard>
|
</keyboard>
|
||||||
</screen>
|
</screen>
|
||||||
|
<screen id="20003" name="inline-test-screen">
|
||||||
|
<text>This is inline buttons:</text>
|
||||||
|
<keyboard>
|
||||||
|
<row>
|
||||||
|
<button actionRef="inline1-action"></button>
|
||||||
|
<button actionRef="inline2-action"></button>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<button actionRef="url-action"></button>
|
||||||
|
</row>
|
||||||
|
</keyboard>
|
||||||
|
</screen>
|
||||||
|
<screen id="20004" name="inline-test-1-screen">
|
||||||
|
<text>Inline Screen #1</text>
|
||||||
|
<keyboard>
|
||||||
|
<row>
|
||||||
|
<button actionRef="inline1-action"></button>
|
||||||
|
<button actionRef="inline2-action"></button>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<button actionRef="url-action"></button>
|
||||||
|
</row>
|
||||||
|
</keyboard>
|
||||||
|
</screen>
|
||||||
|
<screen id="20005" name="inline-test-2-screen">
|
||||||
|
<text>Inline Screen #2</text>
|
||||||
|
<keyboard>
|
||||||
|
<row>
|
||||||
|
<button actionRef="inline1-action"></button>
|
||||||
|
<button actionRef="inline2-action"></button>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<button actionRef="url-action"></button>
|
||||||
|
</row>
|
||||||
|
</keyboard>
|
||||||
|
</screen>
|
||||||
</screens>
|
</screens>
|
||||||
<commands>
|
<commands>
|
||||||
<command actionRef="start-action" screenRef="on-start-screen" id="30001" name="startCommand"/>
|
<command actionRef="start-action" screenRef="on-start-screen" id="30001" name="startCommand"/>
|
||||||
<command actionRef="help-action" screenRef="on-help-screen" id="30002" name="helpCommand"/>
|
<command actionRef="help-action" screenRef="on-help-screen" id="30002" name="helpCommand"/>
|
||||||
|
<command actionRef="to-inline-action" screenRef="inline-test-screen" id="30003" name="inlineTestCommand"/>
|
||||||
|
<command actionRef="inline1-action" screenRef="inline-test-1-screen" edit="true" id="30004" name="inlineTest1Command"/>
|
||||||
|
<command actionRef="inline2-action" screenRef="inline-test-2-screen" edit="true" id="30005" name="inlineTest2Command"/>
|
||||||
</commands>
|
</commands>
|
||||||
</flow>
|
</flow>
|
||||||
@@ -2,7 +2,11 @@ package ru.penkrat.stbf.impl.pengrad;
|
|||||||
|
|
||||||
import com.pengrad.telegrambot.TelegramBot;
|
import com.pengrad.telegrambot.TelegramBot;
|
||||||
import com.pengrad.telegrambot.model.Update;
|
import com.pengrad.telegrambot.model.Update;
|
||||||
import com.pengrad.telegrambot.model.request.*;
|
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.DeleteMessage;
|
||||||
import com.pengrad.telegrambot.request.EditMessageText;
|
import com.pengrad.telegrambot.request.EditMessageText;
|
||||||
import com.pengrad.telegrambot.request.SendDocument;
|
import com.pengrad.telegrambot.request.SendDocument;
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package ru.penkrat.stbf.impl.pengrad;
|
||||||
|
|
||||||
|
import ru.penkrat.stbf.api.Keyboard;
|
||||||
|
|
||||||
|
class NoKeyboard implements Keyboard {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "EmptyKeyboard(pengrad)";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2,149 +2,166 @@ package ru.penkrat.stbf.impl.pengrad;
|
|||||||
|
|
||||||
import com.pengrad.telegrambot.model.request.InlineKeyboardButton;
|
import com.pengrad.telegrambot.model.request.InlineKeyboardButton;
|
||||||
import com.pengrad.telegrambot.model.request.KeyboardButton;
|
import com.pengrad.telegrambot.model.request.KeyboardButton;
|
||||||
|
|
||||||
import ru.penkrat.stbf.api.Action;
|
import ru.penkrat.stbf.api.Action;
|
||||||
import ru.penkrat.stbf.api.Keyboard;
|
import ru.penkrat.stbf.api.Keyboard;
|
||||||
import ru.penkrat.stbf.api.KeyboardBuilder;
|
import ru.penkrat.stbf.api.KeyboardBuilder;
|
||||||
|
|
||||||
public class PengradKeyboardBuilder implements KeyboardBuilder {
|
public class PengradKeyboardBuilder implements KeyboardBuilder {
|
||||||
|
|
||||||
private KeyboardButton[][] keyboard;
|
private KeyboardButton[][] keyboard;
|
||||||
|
|
||||||
private InlineKeyboardButton[][] inlineKeyboard;
|
private InlineKeyboardButton[][] inlineKeyboard;
|
||||||
|
|
||||||
private String keyboardStr = "";
|
private String keyboardStr = "";
|
||||||
|
|
||||||
public static Keyboard singleKey(Action action) {
|
public static Keyboard singleKey(Action action) {
|
||||||
return KeyboardBuilder.newKeyboard().add(action).build();
|
return KeyboardBuilder.newKeyboard().add(action).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Keyboard build() {
|
public Keyboard build() {
|
||||||
return new KeyboardImpl(keyboard, inlineKeyboard);
|
if (keyboard != null) {
|
||||||
}
|
return new KeyboardImpl(keyboard, null);
|
||||||
|
}
|
||||||
|
if (inlineKeyboard != null) {
|
||||||
|
InlineKeyboardButton[][] smallerArray = new InlineKeyboardButton[inlineKeyboard.length - 1][];
|
||||||
|
System.arraycopy(inlineKeyboard, 0, smallerArray, 0, inlineKeyboard.length - 1);
|
||||||
|
return new KeyboardImpl(null, smallerArray);
|
||||||
|
}
|
||||||
|
return new NoKeyboard();
|
||||||
|
}
|
||||||
|
|
||||||
public KeyboardBuilder addGetContact(String text) {
|
public KeyboardBuilder addGetContact(String text) {
|
||||||
put(new KeyboardButton(text).requestContact(true));
|
put(new KeyboardButton(text).requestContact(true));
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyboardBuilder add(String text) {
|
public KeyboardBuilder add(String text) {
|
||||||
put(new KeyboardButton(text));
|
put(new KeyboardButton(text));
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyboardBuilder add(Action action) {
|
public KeyboardBuilder add(Action action) {
|
||||||
put(action);
|
put(action);
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyboardBuilder row(KeyboardButton... buttons) {
|
public KeyboardBuilder row(KeyboardButton... buttons) {
|
||||||
for (int i = 0; i < buttons.length; i++) {
|
for (int i = 0; i < buttons.length; i++) {
|
||||||
put(buttons[i]);
|
put(buttons[i]);
|
||||||
}
|
}
|
||||||
nextRow();
|
nextRow();
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyboardBuilder row(Action... buttons) {
|
public KeyboardBuilder row(Action... buttons) {
|
||||||
for (int i = 0; i < buttons.length; i++) {
|
for (int i = 0; i < buttons.length; i++) {
|
||||||
put(buttons[i]);
|
put(buttons[i]);
|
||||||
}
|
}
|
||||||
nextRow();
|
if (buttons.length > 0) {
|
||||||
return self();
|
if (buttons[0].isInline()) {
|
||||||
}
|
nextRowI();
|
||||||
|
} else {
|
||||||
|
nextRow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyboardBuilder column(Action... buttons) {
|
public KeyboardBuilder column(Action... buttons) {
|
||||||
for (int i = 0; i < buttons.length; i++) {
|
for (int i = 0; i < buttons.length; i++) {
|
||||||
put(buttons[i]);
|
put(buttons[i]);
|
||||||
if (buttons[i].isInline()) {
|
if (buttons[i].isInline()) {
|
||||||
nextRowI();
|
nextRowI();
|
||||||
} else {
|
} else {
|
||||||
nextRow();
|
nextRow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyboardBuilder addNl(String text) {
|
public KeyboardBuilder addNl(String text) {
|
||||||
add(text);
|
add(text);
|
||||||
nextRow();
|
nextRow();
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PengradKeyboardBuilder add(String text, String data) {
|
public PengradKeyboardBuilder add(String text, String data) {
|
||||||
put(new InlineKeyboardButton(text).callbackData(data));
|
put(new InlineKeyboardButton(text).callbackData(data));
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyboardBuilder addNl(String text, String data) {
|
public KeyboardBuilder addNl(String text, String data) {
|
||||||
add(text, data);
|
add(text, data);
|
||||||
nextRowI();
|
nextRowI();
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void nextRow() {
|
private void nextRow() {
|
||||||
KeyboardButton[][] n = new KeyboardButton[keyboard.length + 1][];
|
KeyboardButton[][] n = new KeyboardButton[keyboard.length + 1][];
|
||||||
System.arraycopy(keyboard, 0, n, 0, keyboard.length);
|
System.arraycopy(keyboard, 0, n, 0, keyboard.length);
|
||||||
keyboard = n;
|
keyboard = n;
|
||||||
keyboard[keyboard.length - 1] = new KeyboardButton[] {};
|
keyboard[keyboard.length - 1] = new KeyboardButton[]{};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void nextRowI() {
|
private void nextRowI() {
|
||||||
InlineKeyboardButton[][] n = new InlineKeyboardButton[inlineKeyboard.length + 1][];
|
InlineKeyboardButton[][] n = new InlineKeyboardButton[inlineKeyboard.length + 1][];
|
||||||
System.arraycopy(inlineKeyboard, 0, n, 0, inlineKeyboard.length);
|
System.arraycopy(inlineKeyboard, 0, n, 0, inlineKeyboard.length);
|
||||||
inlineKeyboard = n;
|
inlineKeyboard = n;
|
||||||
inlineKeyboard[inlineKeyboard.length - 1] = new InlineKeyboardButton[] {};
|
inlineKeyboard[inlineKeyboard.length - 1] = new InlineKeyboardButton[]{};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PengradKeyboardBuilder self() {
|
protected PengradKeyboardBuilder self() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void put(Action action) {
|
private void put(Action action) {
|
||||||
if (action.isInline()) {
|
if (action.isInline()) {
|
||||||
put(new InlineKeyboardButton(action.getText()).callbackData(action.getCallbackData()));
|
put(new InlineKeyboardButton(action.getText())
|
||||||
} else {
|
.callbackData(action.getCallbackData())
|
||||||
put(new KeyboardButton(action.getText()).requestContact(action.isRequestContact()));
|
.url(action.getUrl()));
|
||||||
}
|
} else {
|
||||||
}
|
put(new KeyboardButton(action.getText())
|
||||||
|
.requestContact(action.isRequestContact())
|
||||||
|
.requestLocation(action.isRequestLocation()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void put(KeyboardButton btn) {
|
private void put(KeyboardButton btn) {
|
||||||
if (keyboard == null) {
|
if (keyboard == null) {
|
||||||
keyboard = new KeyboardButton[][] {
|
keyboard = new KeyboardButton[][]{
|
||||||
new KeyboardButton[] { btn }
|
new KeyboardButton[]{btn}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
KeyboardButton[] k = keyboard[keyboard.length - 1];
|
KeyboardButton[] k = keyboard[keyboard.length - 1];
|
||||||
KeyboardButton[] n = new KeyboardButton[k.length + 1];
|
KeyboardButton[] n = new KeyboardButton[k.length + 1];
|
||||||
System.arraycopy(k, 0, n, 0, k.length);
|
System.arraycopy(k, 0, n, 0, k.length);
|
||||||
n[k.length] = btn;
|
n[k.length] = btn;
|
||||||
keyboard[keyboard.length - 1] = n;
|
keyboard[keyboard.length - 1] = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void put(InlineKeyboardButton btn) {
|
private void put(InlineKeyboardButton btn) {
|
||||||
if (inlineKeyboard == null) {
|
if (inlineKeyboard == null) {
|
||||||
inlineKeyboard = new InlineKeyboardButton[][] {
|
inlineKeyboard = new InlineKeyboardButton[][]{
|
||||||
new InlineKeyboardButton[] { btn }
|
new InlineKeyboardButton[]{btn}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
InlineKeyboardButton[] k = inlineKeyboard[inlineKeyboard.length - 1];
|
InlineKeyboardButton[] k = inlineKeyboard[inlineKeyboard.length - 1];
|
||||||
InlineKeyboardButton[] n = new InlineKeyboardButton[k.length + 1];
|
InlineKeyboardButton[] n = new InlineKeyboardButton[k.length + 1];
|
||||||
System.arraycopy(k, 0, n, 0, k.length);
|
System.arraycopy(k, 0, n, 0, k.length);
|
||||||
n[k.length] = btn;
|
n[k.length] = btn;
|
||||||
inlineKeyboard[inlineKeyboard.length - 1] = n;
|
inlineKeyboard[inlineKeyboard.length - 1] = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyboardBuilder newInstance() {
|
public KeyboardBuilder newInstance() {
|
||||||
return new PengradKeyboardBuilder();
|
return new PengradKeyboardBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package ru.penkrat.stbf.templates;
|
package ru.penkrat.stbf.templates;
|
||||||
|
|
||||||
import ru.penkrat.stbf.api.Action;
|
import ru.penkrat.stbf.api.Action;
|
||||||
|
import ru.penkrat.stbf.api.RequestMatcher;
|
||||||
|
|
||||||
public interface ActionResolver {
|
public interface ActionResolver {
|
||||||
|
|
||||||
Action getAction(String name);
|
Action getAction(String name);
|
||||||
|
|
||||||
|
RequestMatcher getMatcher(String actionName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,12 @@ class ActionItem extends NamedItem {
|
|||||||
@JacksonXmlProperty(isAttribute = true)
|
@JacksonXmlProperty(isAttribute = true)
|
||||||
private String callbackData;
|
private String callbackData;
|
||||||
|
|
||||||
|
@JacksonXmlProperty(isAttribute = true)
|
||||||
|
private String callbackDataRegexp;
|
||||||
|
|
||||||
|
@JacksonXmlProperty(isAttribute = true)
|
||||||
|
private String callbackDataStartWith;
|
||||||
|
|
||||||
@JacksonXmlProperty(isAttribute = true)
|
@JacksonXmlProperty(isAttribute = true)
|
||||||
private String url;
|
private String url;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,4 +21,7 @@ public class CommandItem extends NamedItem {
|
|||||||
@JacksonXmlProperty(isAttribute = true, localName = "class")
|
@JacksonXmlProperty(isAttribute = true, localName = "class")
|
||||||
private String clazz;
|
private String clazz;
|
||||||
|
|
||||||
|
@JacksonXmlProperty(isAttribute = true)
|
||||||
|
private boolean edit;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package ru.penkrat.stbf.templates.xml;
|
package ru.penkrat.stbf.templates.xml;
|
||||||
|
|
||||||
import ru.penkrat.stbf.api.Action;
|
import ru.penkrat.stbf.api.Action;
|
||||||
|
import ru.penkrat.stbf.api.RequestMatcher;
|
||||||
import ru.penkrat.stbf.templates.ActionResolver;
|
import ru.penkrat.stbf.templates.ActionResolver;
|
||||||
import ru.penkrat.stbf.templates.utils.StringUtils;
|
import ru.penkrat.stbf.templates.utils.StringUtils;
|
||||||
|
import ru.penkrat.stbf.tools.RequestMatchers;
|
||||||
|
|
||||||
class FlowActionResolverDelegate implements ActionResolver {
|
class FlowActionResolverDelegate implements ActionResolver {
|
||||||
|
|
||||||
@@ -17,7 +19,7 @@ class FlowActionResolverDelegate implements ActionResolver {
|
|||||||
final ActionItem actionItem = resolver.get(key);
|
final ActionItem actionItem = resolver.get(key);
|
||||||
|
|
||||||
boolean isInline = StringUtils.isNotEmpty(actionItem.getCallbackData())
|
boolean isInline = StringUtils.isNotEmpty(actionItem.getCallbackData())
|
||||||
&& StringUtils.isNotEmpty(actionItem.getUrl());
|
|| StringUtils.isNotEmpty(actionItem.getUrl());
|
||||||
|
|
||||||
if (isInline) {
|
if (isInline) {
|
||||||
if (StringUtils.isNotEmpty(actionItem.getCommand())) {
|
if (StringUtils.isNotEmpty(actionItem.getCommand())) {
|
||||||
@@ -43,4 +45,21 @@ class FlowActionResolverDelegate implements ActionResolver {
|
|||||||
.url(actionItem.getUrl())
|
.url(actionItem.getUrl())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RequestMatcher getMatcher(String actionName) {
|
||||||
|
final ActionItem actionItem = resolver.get(actionName);
|
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(actionItem.getCallbackDataRegexp())) {
|
||||||
|
return RequestMatchers.callbackDataRegexp(actionItem.getCallbackDataRegexp());
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(actionItem.getCallbackDataStartWith())) {
|
||||||
|
return RequestMatchers.callbackDataStartsWith(actionItem.getCallbackDataStartWith());
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(actionItem.getCallbackData())) {
|
||||||
|
return RequestMatchers.callbackData(actionItem.getCallbackData());
|
||||||
|
}
|
||||||
|
|
||||||
|
return RequestMatchers.action(getAction(actionName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import ru.penkrat.stbf.templates.ActionResolver;
|
|||||||
import ru.penkrat.stbf.templates.CommandResolver;
|
import ru.penkrat.stbf.templates.CommandResolver;
|
||||||
import ru.penkrat.stbf.templates.ScreenResolver;
|
import ru.penkrat.stbf.templates.ScreenResolver;
|
||||||
import ru.penkrat.stbf.templates.utils.StringUtils;
|
import ru.penkrat.stbf.templates.utils.StringUtils;
|
||||||
import ru.penkrat.stbf.tools.RequestMatchers;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -51,31 +50,35 @@ public class FlowCommandResolverDelegate implements CommandResolver {
|
|||||||
|
|
||||||
private Command createCommand(CommandItem commandItem) {
|
private Command createCommand(CommandItem commandItem) {
|
||||||
Action action = null;
|
Action action = null;
|
||||||
|
RequestMatcher actionMatcher = null;
|
||||||
Screen screen = null;
|
Screen screen = null;
|
||||||
Function<Object, Screen> screenFactory;
|
Function<Object, Screen> screenFactory;
|
||||||
if (StringUtils.isNotEmpty(commandItem.getActionRef())) {
|
if (StringUtils.isNotEmpty(commandItem.getActionRef())) {
|
||||||
action = actionResolver.getAction(commandItem.getActionRef());
|
action = actionResolver.getAction(commandItem.getActionRef());
|
||||||
|
actionMatcher = actionResolver.getMatcher(commandItem.getActionRef());
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotEmpty(commandItem.getScreenRef())) {
|
if (StringUtils.isNotEmpty(commandItem.getScreenRef())) {
|
||||||
screen = screenResolver.getScreen(commandItem.getScreenRef());
|
screen = screenResolver.getScreen(commandItem.getScreenRef());
|
||||||
screenFactory = screenResolver.getScreenFactory(commandItem.getScreenRef());
|
screenFactory = screenResolver.getScreenFactory(commandItem.getScreenRef());
|
||||||
}
|
}
|
||||||
if (action != null && screen != null) {
|
if (actionMatcher != null && screen != null) {
|
||||||
return simpleCommand(action, screen, commandItem.getId(), commandItem.getName());
|
return simpleCommand(actionMatcher, screen, commandItem.isEdit(), commandItem.getId(), commandItem.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Command simpleCommand(Action action, Screen screen, String id, String name) {
|
private Command simpleCommand(RequestMatcher matcher, Screen screen, boolean edit, String id, String name) {
|
||||||
return new Command() {
|
return new Command() {
|
||||||
RequestMatcher matcher = RequestMatchers.action(action);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(BotRequest botRequest, BotResponse botResponse, CommandChain chain) {
|
public void process(BotRequest botRequest, BotResponse botResponse, CommandChain chain) {
|
||||||
if (matcher.match(botRequest)) {
|
if (matcher.match(botRequest)) {
|
||||||
botResponse.send(screen);
|
if (edit) {
|
||||||
|
botResponse.edit(screen);
|
||||||
|
} else {
|
||||||
|
botResponse.send(screen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
chain.processCommand(botRequest, botResponse);
|
chain.processCommand(botRequest, botResponse);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ class FlowScreenResolverDelegate implements ScreenResolver {
|
|||||||
.map(btn -> getAction(btn))
|
.map(btn -> getAction(btn))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
log.info("Keyboard: {}", buttons);
|
||||||
|
|
||||||
builder.row(buttons.toArray(new Action[buttons.size()]));
|
builder.row(buttons.toArray(new Action[buttons.size()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,6 +99,9 @@ class FlowScreenResolverDelegate implements ScreenResolver {
|
|||||||
.text(btn.getText())
|
.text(btn.getText())
|
||||||
.requestContact(btn.isRequestContact())
|
.requestContact(btn.isRequestContact())
|
||||||
.requestLocation(btn.isRequestLocation())
|
.requestLocation(btn.isRequestLocation())
|
||||||
|
.url(btn.getUrl())
|
||||||
|
.callbackData(btn.getCallbackData())
|
||||||
|
.inline(StringUtils.isNotEmpty(btn.getUrl()) || StringUtils.isNotEmpty(btn.getCallbackData()))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package ru.penkrat.stbf.templates.xml;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import ru.penkrat.stbf.api.Action;
|
import ru.penkrat.stbf.api.Action;
|
||||||
import ru.penkrat.stbf.api.Command;
|
import ru.penkrat.stbf.api.Command;
|
||||||
|
import ru.penkrat.stbf.api.RequestMatcher;
|
||||||
import ru.penkrat.stbf.api.Screen;
|
import ru.penkrat.stbf.api.Screen;
|
||||||
import ru.penkrat.stbf.templates.TemplateRenderer;
|
import ru.penkrat.stbf.templates.TemplateRenderer;
|
||||||
|
|
||||||
@@ -47,6 +48,11 @@ public class XmlFlowResolver implements FlowResolver {
|
|||||||
return actionDelegate.getAction(name);
|
return actionDelegate.getAction(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RequestMatcher getMatcher(String actionName) {
|
||||||
|
return actionDelegate.getMatcher(actionName);
|
||||||
|
}
|
||||||
|
|
||||||
public void setTemplateRenderer(TemplateRenderer templateRenderer) {
|
public void setTemplateRenderer(TemplateRenderer templateRenderer) {
|
||||||
screenDelegate.setTemplateRenderer(templateRenderer);
|
screenDelegate.setTemplateRenderer(templateRenderer);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user