package com.juick.api; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.juick.service.MessagesService; import com.juick.service.TelegramService; import com.pengrad.telegrambot.Callback; import com.pengrad.telegrambot.TelegramBot; import com.pengrad.telegrambot.TelegramBotAdapter; import com.pengrad.telegrambot.model.request.InlineKeyboardButton; import com.pengrad.telegrambot.model.request.InlineKeyboardMarkup; import com.pengrad.telegrambot.request.SendMessage; import com.pengrad.telegrambot.request.SetWebhook; import com.pengrad.telegrambot.response.SendResponse; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.PingMessage; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.client.WebSocketConnectionManager; import org.springframework.web.socket.handler.TextWebSocketHandler; import javax.inject.Inject; import java.io.IOException; import java.util.List; import static com.juick.formatters.PlainTextFormatter.formatPost; import static com.juick.formatters.PlainTextFormatter.formatUrl; /** * Created by vt on 12/05/16. */ public class TGBot extends TextWebSocketHandler { private static final Logger logger = LoggerFactory.getLogger(TGBot.class); TelegramBot bot; private ObjectMapper ms; @Inject TelegramService telegramService; @Inject MessagesService messagesService; @Inject static WebSocketConnectionManager connectionManager; WebSocketSession session; private TGBot() { throw new IllegalStateException(); } public TGBot(String token) { if (StringUtils.isBlank(token)) { return; } bot = TelegramBotAdapter.build(token); ms = new ObjectMapper(); ms.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); ms.setSerializationInclusion(JsonInclude.Include.NON_NULL); ms.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT); try { SetWebhook webhook = new SetWebhook().url("https://api.juick.com/tlgmbtwbhk"); if (!bot.execute(webhook).isOk()) { logger.error("error setting webhook"); } } catch (Exception e) { logger.warn("couldn't initialize telegram bot", e); } } @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { logger.info("WebSocket connected"); this.session = session; } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { logger.info("WebSocket disconnected with code {}: {}, trying to reconnect", status.getCode(), status.getReason()); connectionManager.start(); } @Scheduled(fixedRate = 30000) public void ping() throws IOException { if (session != null) { logger.debug("Sending WebSocket ping"); session.sendMessage(new PingMessage()); } } @Override protected void handleTextMessage(WebSocketSession session, TextMessage text) throws Exception { com.juick.Message jmsg = ms.readValue(text.asBytes(), com.juick.Message.class); if (logger.isInfoEnabled()) // prevent writeValueAsString execution if logger disabled logger.info("got jmsg: {}", ms.writeValueAsString(jmsg)); String msgUrl = formatUrl(jmsg); if (jmsg.getRid() == 0) { String msg = formatPost(jmsg); List users = telegramService.getSubscribers(jmsg.getUser().getUid()); List chats = telegramService.getChats(); // registered subscribed users users.forEach(c -> telegramNotify(c, msg, msgUrl)); // anonymous chats.stream().filter(u -> telegramService.getUser(u) == 0).forEach(c -> telegramNotify(c, msg, msgUrl)); } else { // get quote com.juick.Message msg = messagesService.getReply(jmsg.getMid(), jmsg.getRid()); String fmsg = formatPost(msg); telegramService.getSubscribersToComments(jmsg.getMid(), jmsg.getUser().getUid()).forEach(c -> telegramNotify(c, fmsg, msgUrl)); } } public void telegramNotify(Long c, String msg, String msgUrl) { SendMessage telegramMessage = new SendMessage(c, msg); if (msgUrl != null) { telegramMessage.replyMarkup( new InlineKeyboardMarkup( new InlineKeyboardButton[]{ new InlineKeyboardButton("See on Juick").url(msgUrl) } )); } bot.execute(telegramMessage, new Callback() { @Override public void onResponse(SendMessage request, SendResponse response) { logger.info("got response: {}", response.message()); } @Override public void onFailure(SendMessage request, IOException e) { logger.warn("telegram failure", e); } }); } public void telegramSignupNotify(Long telegramId, String hash) { bot.execute(new SendMessage(telegramId, "You are subscribed to all Juick messages. " + "Create or link an existing Juick account to control " + "what do you want to receive").replyMarkup( new InlineKeyboardMarkup( new InlineKeyboardButton[]{ new InlineKeyboardButton("SIGNUP").url("http://juick.com/signup?type=durov&hash=" + hash) })), new Callback() { @Override public void onResponse(SendMessage request, SendResponse response) { logger.info("got response: {}", response.message()); } @Override public void onFailure(SendMessage request, IOException e) { logger.warn("telegram failure", e); } }); } }