diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..485dee6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.idea
diff --git a/README.md b/README.md
index cbd7beb..a3c5d31 100644
--- a/README.md
+++ b/README.md
@@ -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);
+
+ }
+ }
+}
+```
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..5719925
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,47 @@
+
+
+ 4.0.0
+
+ ru.bvn13.examples.bot
+ menubot
+ 1.1.0
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 1.8
+
+
+
+
+ jar
+
+ Menu Bot
+ Telegram Inline Multipage Menu
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
+
+
+
+
+ org.telegram
+ telegrambots
+ 3.5
+
+
+
+
+
+
+
diff --git a/src/main/java/ru/bvn13/examples/bot/Application.java b/src/main/java/ru/bvn13/examples/bot/Application.java
new file mode 100644
index 0000000..e2932b8
--- /dev/null
+++ b/src/main/java/ru/bvn13/examples/bot/Application.java
@@ -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();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/ru/bvn13/examples/bot/MenuBot.java b/src/main/java/ru/bvn13/examples/bot/MenuBot.java
new file mode 100644
index 0000000..47b4289
--- /dev/null
+++ b/src/main/java/ru/bvn13/examples/bot/MenuBot.java
@@ -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";
+ }
+
+}
+
diff --git a/src/main/java/ru/bvn13/examples/bot/accessories/InlineKeyboardBuilder.java b/src/main/java/ru/bvn13/examples/bot/accessories/InlineKeyboardBuilder.java
new file mode 100644
index 0000000..d07a28b
--- /dev/null
+++ b/src/main/java/ru/bvn13/examples/bot/accessories/InlineKeyboardBuilder.java
@@ -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> keyboard = new ArrayList<>();
+ private List 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;
+ }
+
+}
diff --git a/src/main/java/ru/bvn13/examples/bot/menu/MenuItem.java b/src/main/java/ru/bvn13/examples/bot/menu/MenuItem.java
new file mode 100644
index 0000000..31e2166
--- /dev/null
+++ b/src/main/java/ru/bvn13/examples/bot/menu/MenuItem.java
@@ -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;
+ }
+}
diff --git a/src/main/java/ru/bvn13/examples/bot/menu/MenuManager.java b/src/main/java/ru/bvn13/examples/bot/menu/MenuManager.java
new file mode 100644
index 0000000..f423f0d
--- /dev/null
+++ b/src/main/java/ru/bvn13/examples/bot/menu/MenuManager.java
@@ -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