commands with callbackData support
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2021-09-09 23:55:14 +03:00
parent 932da0549a
commit 24b15ca4fe
15 changed files with 353 additions and 176 deletions

View File

@@ -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
} }
} }

View File

@@ -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) {

View File

@@ -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);
}
} }

View File

@@ -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()));
}
} }

View File

@@ -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>

View File

@@ -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;

View File

@@ -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)";
}
}

View File

@@ -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();
} }
} }

View File

@@ -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);
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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));
}
} }

View File

@@ -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);
} }

View File

@@ -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();
} }

View File

@@ -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);
} }