simple multipage menu
This commit is contained in:
parent
092a47953e
commit
09c9ce4941
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.idea
|
129
README.md
129
README.md
@ -1,2 +1,131 @@
|
||||
# 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
Normal file
47
pom.xml
Normal 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>
|
27
src/main/java/ru/bvn13/examples/bot/Application.java
Normal file
27
src/main/java/ru/bvn13/examples/bot/Application.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
149
src/main/java/ru/bvn13/examples/bot/MenuBot.java
Normal file
149
src/main/java/ru/bvn13/examples/bot/MenuBot.java
Normal 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";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
32
src/main/java/ru/bvn13/examples/bot/menu/MenuItem.java
Normal file
32
src/main/java/ru/bvn13/examples/bot/menu/MenuItem.java
Normal 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;
|
||||
}
|
||||
}
|
115
src/main/java/ru/bvn13/examples/bot/menu/MenuManager.java
Normal file
115
src/main/java/ru/bvn13/examples/bot/menu/MenuManager.java
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user