diff --git a/Bots.ipr b/Bots.ipr index ee3dd609..992b5bc6 100644 --- a/Bots.ipr +++ b/Bots.ipr @@ -18,6 +18,7 @@ + @@ -33,6 +34,7 @@ + @@ -502,6 +504,7 @@ + @@ -840,6 +843,7 @@ + @@ -980,6 +984,17 @@ + + + + + + + + + + + @@ -991,6 +1006,17 @@ + + + + + + + + + + + @@ -1156,6 +1182,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1541,6 +1666,17 @@ + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 04fea329..fb5dfcfd 100644 --- a/pom.xml +++ b/pom.xml @@ -15,6 +15,7 @@ telegrambots-extensions telegrambots-abilities telegrambots-spring-boot-starter + telegrambots-chat-session-bot diff --git a/telegrambots-chat-session-bot/README.md b/telegrambots-chat-session-bot/README.md new file mode 100644 index 00000000..e6237511 --- /dev/null +++ b/telegrambots-chat-session-bot/README.md @@ -0,0 +1,55 @@ +
+ +[![Build Status](https://travis-ci.org/rubenlagus/TelegramBots.svg?branch=master)](https://travis-ci.org/rubenlagus/TelegramBots) +[![Jitpack](https://jitpack.io/v/rubenlagus/TelegramBots.svg)](https://jitpack.io/#rubenlagus/TelegramBots) +[![Telegram](http://trellobot.doomdns.org/telegrambadge.svg)](https://telegram.me/JavaBotsApi) + +
+ +Usage +----- + +**Maven** + +```xml + + org.telegram + telegrambots-chat-session-bot + 4.0.0 + +``` + +Motivation +---------- +Implementation of bot dialogs require saving some data about current state of conversation. +That brings us to idea of chat session management. + +How to use +---------- +`Chat session bot` was implemented by using [`Shiro Apache`](https://shiro.apache.org/) session manager. +That allow to manage and store sessions. + + +To create default Long Polling Session Bot with in-memory store, +you need simply implement `TelegramLongPollingSessionBot` +```java +public class ExampleBotWithSession extends TelegramLongPollingSessionBot { + + @Override + public void onUpdateReceived(Update update, Optional optionalSession) { + //Do some action with update and session + } + + @Override + public String getBotUsername() { + return "ExampleBotWithSessionBot"; + } + + @Override + public String getBotToken() { + return "1234"; + } +} +``` + +Where session is implementation of `org.apache.shiro.session.Session` \ No newline at end of file diff --git a/telegrambots-chat-session-bot/pom.xml b/telegrambots-chat-session-bot/pom.xml new file mode 100644 index 00000000..23050544 --- /dev/null +++ b/telegrambots-chat-session-bot/pom.xml @@ -0,0 +1,254 @@ + + + 4.0.0 + org.telegram + telegrambots-chat-session-bot + 4.0.0 + jar + + Telegram Bots Chat Session Bot + https://github.com/rubenlagus/TelegramBots + Telegram bot with chat session support + + + https://github.com/rubenlagus/TelegramBots/issues + GitHub Issues + + + + https://github.com/rubenlagus/TelegramBots + scm:git:git://github.com/rubenlagus/TelegramBots.git + scm:git:git@github.com:rubenlagus/TelegramBots.git + + + + https://travis-ci.org/rubenlagus/TelegramBots + Travis + + + + + rberlopez@gmail.com + Ruben Bermudez + https://github.com/rubenlagus + rubenlagus + + + bochkarevei@gmail.com + Egor Bochkarev + https://github.com/EgorBochkarev + EgorBochkarev + + + + + + MIT License + http://www.opensource.org/licenses/mit-license.php + repo + + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + UTF-8 + UTF-8 + 4.0.0 + 1.4.0 + + + + + + org.telegram + telegrambots + ${bots.version} + + + + + org.apache.shiro + shiro-core + ${shiro.version} + + + + org.mockito + mockito-all + 2.0.2-beta + test + + + junit + junit + 4.11 + test + + + + + ${project.basedir}/target + ${project.build.directory}/classes + ${project.artifactId}-${project.version} + ${project.build.directory}/test-classes + ${project.basedir}/src/main/java + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.3 + true + + ossrh + https://oss.sonatype.org/ + true + + + + maven-clean-plugin + 3.0.0 + + + clean-project + clean + + clean + + + + + + maven-assembly-plugin + 2.6 + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.0 + + + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + + jar + + + -Xdoclint:none + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.7.201606060606 + + + + prepare-agent + + + + report + test + + report + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 1.4.1 + + + enforce-versions + + enforce + + + + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.4 + + + copy + package + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/telegrambots-chat-session-bot/src/main/java/org/telegram/telegrambots/session/ChatIdConverter.java b/telegrambots-chat-session-bot/src/main/java/org/telegram/telegrambots/session/ChatIdConverter.java new file mode 100644 index 00000000..43d6ab33 --- /dev/null +++ b/telegrambots-chat-session-bot/src/main/java/org/telegram/telegrambots/session/ChatIdConverter.java @@ -0,0 +1,10 @@ +package org.telegram.telegrambots.session; + +import org.apache.shiro.session.mgt.SessionKey; +import org.apache.shiro.session.mgt.eis.SessionIdGenerator; + +import java.io.Serializable; + +public interface ChatIdConverter extends SessionKey, SessionIdGenerator { + void setSessionId(Serializable sessionId); +} \ No newline at end of file diff --git a/telegrambots-chat-session-bot/src/main/java/org/telegram/telegrambots/session/DefaultChatIdConverter.java b/telegrambots-chat-session-bot/src/main/java/org/telegram/telegrambots/session/DefaultChatIdConverter.java new file mode 100644 index 00000000..5e5dd571 --- /dev/null +++ b/telegrambots-chat-session-bot/src/main/java/org/telegram/telegrambots/session/DefaultChatIdConverter.java @@ -0,0 +1,34 @@ +package org.telegram.telegrambots.session; + +import org.apache.shiro.session.Session; + +import java.io.Serializable; + +@SuppressWarnings({"unused", "WeakerAccess"}) +public class DefaultChatIdConverter implements ChatIdConverter { + private long sessionId; + + public DefaultChatIdConverter() { + super(); + } + + public DefaultChatIdConverter(long sessionId) { + this(); + this.sessionId = sessionId; + } + + @Override + public void setSessionId(Serializable sessionId){ + this.sessionId = (long) sessionId; + }; + + @Override + public Serializable getSessionId() { + return sessionId; + } + + @Override + public Serializable generateId(Session session) { + return getSessionId(); + } +} diff --git a/telegrambots-chat-session-bot/src/main/java/org/telegram/telegrambots/session/DefaultChatSessionContext.java b/telegrambots-chat-session-bot/src/main/java/org/telegram/telegrambots/session/DefaultChatSessionContext.java new file mode 100644 index 00000000..08ef999f --- /dev/null +++ b/telegrambots-chat-session-bot/src/main/java/org/telegram/telegrambots/session/DefaultChatSessionContext.java @@ -0,0 +1,37 @@ +package org.telegram.telegrambots.session; + +import org.apache.shiro.session.mgt.SessionContext; + +import java.io.Serializable; +import java.util.HashMap; + +@SuppressWarnings("WeakerAccess") +public class DefaultChatSessionContext extends HashMap implements SessionContext { + private long sessionId; + private String host; + + public DefaultChatSessionContext(long sessionId, String host) { + this.sessionId = sessionId; + this.host = host; + } + + @Override + public String getHost() { + return host; + } + + @Override + public void setHost(String host) { + this.host = host; + } + + @Override + public Serializable getSessionId() { + return sessionId; + } + + @Override + public void setSessionId(Serializable serializable) { + this.sessionId = (long) serializable; + } +} diff --git a/telegrambots-chat-session-bot/src/main/java/org/telegram/telegrambots/session/TelegramLongPollingSessionBot.java b/telegrambots-chat-session-bot/src/main/java/org/telegram/telegrambots/session/TelegramLongPollingSessionBot.java new file mode 100644 index 00000000..8182578e --- /dev/null +++ b/telegrambots-chat-session-bot/src/main/java/org/telegram/telegrambots/session/TelegramLongPollingSessionBot.java @@ -0,0 +1,67 @@ +package org.telegram.telegrambots.session; + +import org.apache.shiro.session.Session; +import org.apache.shiro.session.UnknownSessionException; +import org.apache.shiro.session.mgt.DefaultSessionManager; +import org.apache.shiro.session.mgt.SessionContext; +import org.apache.shiro.session.mgt.eis.AbstractSessionDAO; +import org.telegram.telegrambots.meta.api.objects.Message; +import org.telegram.telegrambots.meta.api.objects.Update; +import org.telegram.telegrambots.bots.TelegramLongPollingBot; + +import java.util.Optional; + +@SuppressWarnings({"WeakerAccess", "OptionalUsedAsFieldOrParameterType", "unused"}) +public abstract class TelegramLongPollingSessionBot extends TelegramLongPollingBot { + DefaultSessionManager sessionManager; + + ChatIdConverter chatIdConverter; + + public TelegramLongPollingSessionBot(){ + this(new DefaultChatIdConverter()); + } + + public TelegramLongPollingSessionBot(ChatIdConverter chatIdConverter){ + this.setSessionManager(new DefaultSessionManager()); + this.setChatIdConverter(chatIdConverter); + AbstractSessionDAO sessionDAO = (AbstractSessionDAO) sessionManager.getSessionDAO(); + sessionDAO.setSessionIdGenerator(chatIdConverter); + } + + public void setSessionManager(DefaultSessionManager sessionManager) { + this.sessionManager = sessionManager; + } + + public void setChatIdConverter(ChatIdConverter chatIdConverter) { + this.chatIdConverter = chatIdConverter; + } + + @Override + public void onUpdateReceived(Update update) { + Optional chatSession; + Message message; + if (update.hasMessage()) { + message = update.getMessage(); + } else if (update.hasCallbackQuery()) { + message = update.getCallbackQuery().getMessage(); + } else { + chatSession = Optional.empty(); + onUpdateReceived(update, chatSession); + return; + } + chatIdConverter.setSessionId(message.getChatId()); + chatSession = this.getSession(message); + onUpdateReceived(update, chatSession); + } + + public Optional getSession(Message message){ + try { + return Optional.of(sessionManager.getSession(chatIdConverter)); + } catch (UnknownSessionException e) { + SessionContext botSession = new DefaultChatSessionContext(message.getChatId(), message.getFrom().getUserName()); + return Optional.of(sessionManager.start(botSession)); + } + } + + public abstract void onUpdateReceived(Update update, Optional botSession); +}