simple multipage menu

master
Vyacheslav N. Boyko 2018-02-21 16:13:54 +03:00
parent 092a47953e
commit 09c9ce4941
8 changed files with 576 additions and 1 deletions

1
.gitignore vendored 100644
View File

@ -0,0 +1 @@
.idea

131
README.md
View File

@ -1,2 +1,131 @@
# TelegramInlineMultipageMenu
# Telegram Inline Multipage Menu
Multipage inline menu for Telegram Bots API
_powered with [rubenlagus/TelegramBots API](https://github.com/rubenlagus/TelegramBots)_
Create our own dynamical menu like this:
![](https://bvn13.tk/files/81) ![](https://bvn13.tk/files/82) ![](https://bvn13.tk/files/83) ![](https://bvn13.tk/files/84)
## Create your menu
```java
public class MenuBot extends TelegramLongPollingBot {
private MenuManager menuManager = new MenuManager();
//...
}
```
## Init the menu
```java
//...
public void init() {
menuManager.setColumnsCount(2);
menuManager.addMenuItem("Action 1", "action 1");
menuManager.addMenuItem("Action 2", "action 2");
menuManager.addMenuItem("Action 3", "action 3");
menuManager.addMenuItem("Action 4", "action 4");
menuManager.addMenuItem("Action 5", "action 5");
menuManager.addMenuItem("Action 6", "action 6");
menuManager.addMenuItem("Action 7", "action 7");
menuManager.addMenuItem("Action 8", "action 8");
menuManager.addMenuItem("Action 9", "action 9");
menuManager.addMenuItem("Action 10", "action 10");
menuManager.addMenuItem("Action 11", "action 11");
menuManager.addMenuItem("Action 12", "action 12");
menuManager.addMenuItem("Action 13", "action 13");
menuManager.addMenuItem("Action 14", "action 14");
menuManager.addMenuItem("Action 15", "action 15");
menuManager.addMenuItem("Action 16", "action 16");
menuManager.addMenuItem("Action 17", "action 17");
menuManager.addMenuItem("Action 18", "action 18");
menuManager.addMenuItem("Action 19", "action 19");
menuManager.addMenuItem("Action 20", "action 20");
menuManager.init();
}
//...
```
## Render the menu
```java
public void onUpdateReceived(Update update) {
// We check if the update has a message and the message has text
if (update.hasMessage() && update.getMessage().hasText()) {
if (update.getMessage().getText().equals("/menu")) {
long chatId = update.getMessage().getChatId();
// lets render the menu
InlineKeyboardBuilder builder = menuManager.createMenuForPage(0, true);
builder.setChatId(chatId).setText("Choose action:");
SendMessage message = builder.build();
try {
// Send the message
execute(message);
} catch (TelegramApiException e) {
e.printStackTrace();
}
} else {
}
}
}
```
## Don't forget for acting on page switching
```java
public void onUpdateReceived(Update update) {
if (update.hasCallbackQuery()) {
// Set variables
long chatId = update.getCallbackQuery().getMessage().getChatId();
String callData = update.getCallbackQuery().getData();
long messageId = update.getCallbackQuery().getMessage().getMessageId();
// here will be menu buttons callbacks
if (callData.equals(MenuManager.CANCEL_ACTION)) {
replaceMessageWithText(chatId, messageId, "Cancelled.");
} else if (callData.startsWith(MenuManager.PREV_ACTION) || callData.startsWith(MenuManager.NEXT_ACTION)) {
String pageNum = "0";
if (callData.startsWith(MenuManager.PREV_ACTION)) {
pageNum = callData.replace(MenuManager.PREV_ACTION+":", "");
} else {
pageNum = callData.replace(MenuManager.NEXT_ACTION+":", "");
}
InlineKeyboardBuilder builder = menuManager.createMenuForPage(Integer.parseInt(pageNum), true);
builder.setChatId(chatId).setText("Choose action:");
SendMessage message = builder.build();
replaceMessage(chatId, messageId, message);
}
}
}
```

47
pom.xml 100644
View File

@ -0,0 +1,47 @@
<?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>
<groupId>ru.bvn13.examples.bot</groupId>
<artifactId>menubot</artifactId>
<version>1.1.0</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<packaging>jar</packaging>
<name>Menu Bot</name>
<description>Telegram Inline Multipage Menu</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--TelegramAPI-->
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>3.5</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,27 @@
package ru.bvn13.examples.bot;
import org.telegram.telegrambots.ApiContextInitializer;
import org.telegram.telegrambots.TelegramBotsApi;
import org.telegram.telegrambots.exceptions.TelegramApiException;
/**
* Created by bvn13 on 21.02.2018.
*/
public class Application {
public static void main(String[] args) {
// Initialize Api Context
ApiContextInitializer.init();
// Instantiate Telegram Bots API
TelegramBotsApi botsApi = new TelegramBotsApi();
// Register our bot
MenuBot bot = new MenuBot();
bot.init();
try {
botsApi.registerBot(bot);
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,149 @@
package ru.bvn13.examples.bot;
import org.telegram.telegrambots.api.methods.send.SendMessage;
import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageText;
import org.telegram.telegrambots.api.objects.Update;
import org.telegram.telegrambots.api.objects.replykeyboard.InlineKeyboardMarkup;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.exceptions.TelegramApiException;
import ru.bvn13.examples.bot.accessories.InlineKeyboardBuilder;
import ru.bvn13.examples.bot.menu.MenuManager;
/**
* Created by bvn13 on 21.02.2018.
*/
public class MenuBot extends TelegramLongPollingBot {
private MenuManager menuManager = new MenuManager();
public void init() {
menuManager.setColumnsCount(2);
menuManager.addMenuItem("Action 1", "action 1");
menuManager.addMenuItem("Action 2", "action 2");
menuManager.addMenuItem("Action 3", "action 3");
menuManager.addMenuItem("Action 4", "action 4");
menuManager.addMenuItem("Action 5", "action 5");
menuManager.addMenuItem("Action 6", "action 6");
menuManager.addMenuItem("Action 7", "action 7");
menuManager.addMenuItem("Action 8", "action 8");
menuManager.addMenuItem("Action 9", "action 9");
menuManager.addMenuItem("Action 10", "action 10");
menuManager.addMenuItem("Action 11", "action 11");
menuManager.addMenuItem("Action 12", "action 12");
menuManager.addMenuItem("Action 13", "action 13");
menuManager.addMenuItem("Action 14", "action 14");
menuManager.addMenuItem("Action 15", "action 15");
menuManager.addMenuItem("Action 16", "action 16");
menuManager.addMenuItem("Action 17", "action 17");
menuManager.addMenuItem("Action 18", "action 18");
menuManager.addMenuItem("Action 19", "action 19");
menuManager.addMenuItem("Action 20", "action 20");
menuManager.init();
}
private void replaceMessageWithText(long chatId, long messageId, String text) {
EditMessageText newMessage = new EditMessageText()
.setChatId(chatId)
.setMessageId(Math.toIntExact(messageId))
.setText(text);
try {
execute(newMessage);
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
private void replaceMessage(long chatId, long messageId, SendMessage message) {
EditMessageText newMessage = new EditMessageText()
.setChatId(chatId)
.setMessageId(Math.toIntExact(messageId))
.setText(message.getText())
.setReplyMarkup((InlineKeyboardMarkup) message.getReplyMarkup());
try {
execute(newMessage);
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
@Override
public void onUpdateReceived(Update update) {
// We check if the update has a message and the message has text
if (update.hasMessage() && update.getMessage().hasText()) {
if (update.getMessage().getText().equals("/menu")) {
long chatId = update.getMessage().getChatId();
// lets render the menu
InlineKeyboardBuilder builder = menuManager.createMenuForPage(0, true);
builder.setChatId(chatId).setText("Choose action:");
SendMessage message = builder.build();
try {
// Send the message
execute(message);
} catch (TelegramApiException e) {
e.printStackTrace();
}
} else {
}
} else if (update.hasCallbackQuery()) {
// Set variables
long chatId = update.getCallbackQuery().getMessage().getChatId();
String callData = update.getCallbackQuery().getData();
long messageId = update.getCallbackQuery().getMessage().getMessageId();
// here will be menu buttons callbacks
if (callData.equals(MenuManager.CANCEL_ACTION)) {
replaceMessageWithText(chatId, messageId, "Cancelled.");
} else if (callData.startsWith(MenuManager.PREV_ACTION) || callData.startsWith(MenuManager.NEXT_ACTION)) {
String pageNum = "0";
if (callData.startsWith(MenuManager.PREV_ACTION)) {
pageNum = callData.replace(MenuManager.PREV_ACTION+":", "");
} else {
pageNum = callData.replace(MenuManager.NEXT_ACTION+":", "");
}
InlineKeyboardBuilder builder = menuManager.createMenuForPage(Integer.parseInt(pageNum), true);
builder.setChatId(chatId).setText("Choose action:");
SendMessage message = builder.build();
replaceMessage(chatId, messageId, message);
}
}
}
@Override
public String getBotUsername() {
// Return bot username
// If bot username is @MyAmazingBot, it must return 'MyAmazingBot'
return "MenuBot";
}
@Override
public String getBotToken() {
// Return bot token from BotFather
return "12345:qwertyuiopASDGFHKMK";
}
}

View File

@ -0,0 +1,75 @@
package ru.bvn13.examples.bot.accessories;
import org.telegram.telegrambots.api.methods.send.SendMessage;
import org.telegram.telegrambots.api.objects.replykeyboard.InlineKeyboardMarkup;
import org.telegram.telegrambots.api.objects.replykeyboard.buttons.InlineKeyboardButton;
import java.util.ArrayList;
import java.util.List;
/**
* Created by bvn13 on 21.02.2018.
*/
public class InlineKeyboardBuilder {
private Long chatId;
private String text;
private List<List<InlineKeyboardButton>> keyboard = new ArrayList<>();
private List<InlineKeyboardButton> row = null;
private InlineKeyboardBuilder() {}
public static InlineKeyboardBuilder create() {
InlineKeyboardBuilder builder = new InlineKeyboardBuilder();
return builder;
}
public static InlineKeyboardBuilder create(Long chatId) {
InlineKeyboardBuilder builder = new InlineKeyboardBuilder();
builder.setChatId(chatId);
return builder;
}
public InlineKeyboardBuilder setText(String text) {
this.text = text;
return this;
}
public InlineKeyboardBuilder setChatId(Long chatId) {
this.chatId = chatId;
return this;
}
public InlineKeyboardBuilder row() {
this.row = new ArrayList<>();
return this;
}
public InlineKeyboardBuilder button(String text, String callbackData) {
row.add(new InlineKeyboardButton().setText(text).setCallbackData(callbackData));
return this;
}
public InlineKeyboardBuilder endRow() {
this.keyboard.add(this.row);
this.row = null;
return this;
}
public SendMessage build() {
SendMessage message = new SendMessage();
message.setChatId(chatId);
message.setText(text);
InlineKeyboardMarkup keyboardMarkup = new InlineKeyboardMarkup();
keyboardMarkup.setKeyboard(keyboard);
message.setReplyMarkup(keyboardMarkup);
return message;
}
}

View File

@ -0,0 +1,32 @@
package ru.bvn13.examples.bot.menu;
/**
* Created by bvn13 on 21.02.2018.
*/
public class MenuItem {
private String name;
private String action;
public MenuItem(String name, String action) {
this.name = name;
this.action = action;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
}

View File

@ -0,0 +1,115 @@
package ru.bvn13.examples.bot.menu;
import ru.bvn13.examples.bot.accessories.InlineKeyboardBuilder;
import java.util.ArrayList;
import java.util.List;
/**
* Created by bvn13 on 21.02.2018.
*/
public class MenuManager {
public static final String PREV_ACTION = "page-prev";
public static final String NEXT_ACTION = "page-next";
public static final String CANCEL_ACTION = "cancel";
private int buttonsPerPage = 6;
public void setButtonsPerPage(int buttonsPerPage) {
this.buttonsPerPage = buttonsPerPage;
}
private int total;
private int lastPage;
private MenuItem btnPrev = new MenuItem("<<", PREV_ACTION);
private MenuItem btnNext = new MenuItem(">>", NEXT_ACTION);
private MenuItem btnCancel = new MenuItem("Cancel", CANCEL_ACTION);
private List<MenuItem> menu = new ArrayList<>();
private int columnsCount;
public void setColumnsCount(int columnsCount) {
this.columnsCount = columnsCount;
}
public void init() {
this.total = menu.size();
this.lastPage = (int) Math.ceil((double) total / buttonsPerPage) - 1;
}
public void addMenuItem(String name, String action) {
this.menu.add(new MenuItem(name, action));
}
private List<MenuItem> getPage(int page) {
List<MenuItem> pageMenu = new ArrayList<>();
if (page > lastPage) {
return pageMenu;
}
int start = page* buttonsPerPage;
int end = (page+1)* buttonsPerPage -1;
if (start < 0) start = 0;
if (end >= total) end = total-1;
for (int i = start; i <= end; i++) {
pageMenu.add(menu.get(i));
}
return pageMenu;
}
private List<MenuItem> getControlButtonsForPage(int page, boolean hasCancel) {
List<MenuItem> buttons = new ArrayList<>();
if (page > 0) {
buttons.add(btnPrev);
}
if (hasCancel) {
buttons.add(btnCancel);
}
if (page < lastPage) {
buttons.add(btnNext);
}
return buttons;
}
public InlineKeyboardBuilder createMenuForPage(int page, boolean hasCancel) {
List<MenuItem> pageButtons = getPage(page);
List<MenuItem> controlButtons = getControlButtonsForPage(page, hasCancel);
InlineKeyboardBuilder builder = InlineKeyboardBuilder.create();
int col = 0;
int num = 0;
builder.row();
for (MenuItem button : pageButtons) {
builder.button(button.getName(), button.getAction());
if (++col >= columnsCount) {
col = 0;
builder.endRow();
if (num++ <= pageButtons.size()) {
builder.row();
}
}
}
builder.endRow();
builder.row();
for (MenuItem button : controlButtons) {
if (button.getAction().equals(PREV_ACTION)) {
builder.button(button.getName(), button.getAction()+":"+(page-1));
} else if (button.getAction().equals(NEXT_ACTION)) {
builder.button(button.getName(), button.getAction()+":"+(page+1));
} else {
builder.button(button.getName(), button.getAction());
}
}
builder.endRow();
return builder;
}
}