Skip to content

Instantly share code, notes, and snippets.

@bandicoot86
Created September 4, 2017 10:28
Show Gist options
  • Save bandicoot86/8169a2e2dda6a94e978150f90b443e9f to your computer and use it in GitHub Desktop.
Save bandicoot86/8169a2e2dda6a94e978150f90b443e9f to your computer and use it in GitHub Desktop.
RestCtrl
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.consumiqate.controllers;
import static com.consumiqate.controllers.BasicController.logger;
import com.consumiqate.scheduler.telegram.BotInfoRunnable;
import com.consumiqate.scheduler.telegram.TelegramBotRunnable;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.http.client.fluent.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
*
* @author kraav
*/
@Controller
@RequestMapping("api/bots")
public class BotController extends BasicController {
@RequestMapping(method = RequestMethod.GET, value = "/info/{users}", produces = "application/json")
@ResponseBody
public byte[] botInfo(@RequestHeader HttpHeaders headers, HttpServletResponse res, @PathVariable(value = "users") Boolean fetchUsers) throws JsonProcessingException {
byte[] out = null;
try {
String clientId = auth(headers);
if (StringUtils.isBlank(clientId)) {
res.sendError(401);
return null;
}
Query query = Query.query(Criteria.where("client").is(clientId));
query.fields().exclude("_id");
List<HashMap> bots = mongo.find(query, HashMap.class, "bots");
SetOperations<String, String> ops = redis.opsForSet();
ArrayNode array = jackson.createArrayNode();
for (HashMap en : bots) {
ObjectNode o = array.addObject();
JsonNode node = jackson.convertValue(en, JsonNode.class);
boolean isTelegram = node.path("tg").asBoolean();
if (isTelegram) {
JsonNode rs = node.path("result");
Long id = rs.path("id").asLong();
o.put("botId", id);
o.put("type", "tg");
o.put("name", rs.path("first_name").asText());
if (fetchUsers) {
Set<String> members = ops.members("tg:users:" + id);
Long m = redis.opsForValue().increment("tg:m:" + id, 0L);
o.put("messages", m);
o.put("usersCount", members.size());
o.putPOJO("availableUsers", members);
}
} else {
Long id = node.path("page").asLong();
o.put("botId", id);
o.put("name", node.path("name").asText());
o.put("type", "fb");
if (fetchUsers) {
Set<String> members = ops.members("fb:users:" + id);
Long m = redis.opsForValue().increment("fb:m:" + id, 0L);
o.put("messages", m);
o.put("usersCount", members.size());
o.putPOJO("availableUsers", members);
}
}
}
out = jackson.writeValueAsBytes(array);
} catch (Exception e) {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
return out;
}
@RequestMapping(method = RequestMethod.GET, value = "/info/all", produces = "application/json")
@ResponseBody
public byte[] allBots(@RequestHeader HttpHeaders headers, HttpServletResponse res) throws JsonProcessingException {
byte[] out = null;
try {
String clientId = auth(headers);
if (StringUtils.isBlank(clientId)) {
res.sendError(401);
return null;
}
HashMap client = mongo.findOne(Query.query(Criteria.where("clientid").is(clientId)), HashMap.class, "clients");
if (client == null) {
res.sendError(401);
return null;
}
ObjectNode adminNode = jackson.convertValue(client, ObjectNode.class);
if (!adminNode.has("roles") || !jackson.convertValue(adminNode.path("roles"), Set.class).contains("admin")) {
res.sendError(401);
return null;
};
Query query = Query.query(Criteria.where("").is(""));
query.fields().exclude("_id");
List<HashMap> bots = mongo.find(query, HashMap.class, "bots");
ArrayNode array = jackson.createArrayNode();
for (HashMap en : bots) {
ObjectNode o = array.addObject();
JsonNode node = jackson.convertValue(en, JsonNode.class);
boolean isTelegram = node.path("tg").asBoolean();
o.put("client", node.path("client").asText());
if (isTelegram) {
JsonNode rs = node.path("result");
Long id = rs.path("id").asLong();
o.put("botId", id);
o.put("type", "tg");
o.put("name", rs.path("first_name").asText());
} else {
Long id = node.path("page").asLong();
o.put("botId", id);
o.put("name", node.path("name").asText());
o.put("type", "fb");
}
}
out = jackson.writeValueAsBytes(array);
} catch (Exception e) {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
return out;
}
@RequestMapping(method = RequestMethod.GET, value = "/tg/{t}", produces = "application/json")
@ResponseBody
public String checkTgToken(@RequestHeader HttpHeaders headers, HttpServletResponse res, @PathVariable(value = "t") String token) throws JsonProcessingException {
String out = null;
try {
String clientId = auth(headers);
if (StringUtils.isBlank(clientId)) {
res.sendError(401);
return null;
}
logger.info("Checking token [{}] [{}]", token, env.getProperty("telegram.api") + "bot" + token + "/getUpdates");
out = Request.Get(env.getProperty("telegram.api") + "bot" + token + "/getUpdates").execute().returnContent().asString();
logger.info("Out {}", out);
} catch (Exception e) {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
return out;
}
@Autowired
ScheduledExecutorService task;
@RequestMapping(method = RequestMethod.POST, value = "/tg/add", produces = "application/json")
@ResponseBody
public String add(@RequestBody String json, @RequestHeader HttpHeaders headers, HttpServletResponse res) throws JsonProcessingException {
String out = null;
try {
String clientId = auth(headers);
if (StringUtils.isBlank(clientId)) {
res.sendError(401);
return null;
}
Map<String, Object> map = parse(json);
logger.info("Adding bot {}", map);
map.put("client", clientId);
map.put("tg", true);
map.put("scheduled", true);
mongo.insert(map, "bots");
String botToken = map.get("botToken").toString();
BotInfoRunnable infoRunnable = ctx.getBean(BotInfoRunnable.class).withToken(botToken).withClient(clientId);
String botId = infoRunnable.call();
logger.info("Tg bot id {}", botId);
TelegramBotRunnable botRunnable = ctx.getBean(TelegramBotRunnable.class).withToken(botToken).withClient(clientId).
withBotId(botId);
logger.info("Scheduling tg bot {}", botRunnable);
ScheduledFuture<?> bot = task.scheduleWithFixedDelay(botRunnable, 0, 150, TimeUnit.MILLISECONDS);
botRunnable.selfAware(bot);
} catch (Exception e) {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
return out;
}
@RequestMapping(method = RequestMethod.POST, value = "/users", produces = "application/json")
@ResponseBody
public byte[] users(@RequestBody ObjectNode json, @RequestHeader HttpHeaders headers, HttpServletResponse res) throws JsonProcessingException {
byte[] out = null;
try {
String clientId = auth(headers);
if (StringUtils.isBlank(clientId)) {
res.sendError(401);
return null;
}
Integer botId = json.path("botId").asInt();
Query q = Query.query(Criteria.where("client").is(clientId).andOperator(Criteria.where("botId").is(botId)));
q.fields().exclude("_id").exclude("client");
List<HashMap> users = mongo.find(q, HashMap.class, "users");
if (users == null) {
return jackson.writeValueAsBytes(jackson.createArrayNode());
}
out = jackson.writeValueAsBytes(users);
} catch (Exception e) {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
return out;
}
@RequestMapping(method = RequestMethod.POST, value = "/session", produces = "application/json")
@ResponseBody
public byte[] sessionUser(@RequestBody ObjectNode json, @RequestHeader HttpHeaders headers, HttpServletResponse res) throws JsonProcessingException {
byte[] out = null;
try {
String clientId = auth(headers);
if (StringUtils.isBlank(clientId)) {
res.sendError(401);
return null;
}
Long botId = json.path("botId").asLong();
String userId = json.path("userId").asText();
out = doSessionUser(clientId, botId, userId);
} catch (Exception e) {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
return out;
}
public byte[] doSessionUser(String clientId, Long botId, String userId) throws JsonProcessingException {
byte[] out = null;
try {
Query q = Query.query(Criteria.where("client").is(clientId).andOperator(Criteria.where("botId").is(botId), Criteria.where("id").is(userId)));
q.fields().exclude("_id").exclude("client");
boolean userExists = mongo.exists(q, "users");
if (!userExists) {
return jackson.writeValueAsBytes(jackson.createObjectNode().put("result", "error").
put("code", 2).put("errorDescription", "No such user ever tried the bot"));
}
ValueOperations<String, String> ops = redis.opsForValue();
String cmd = ops.get(botId + ":" + userId);
String subcmd = ops.get(botId + ":" + userId + ":sub");
ObjectNode o = jackson.createObjectNode();
o.put("userId", userId);
o.put("hasSession", false);
if (StringUtils.isNotBlank(cmd)) {
o.put("hasSession", true);
o.set("session", jackson.readTree(cmd));
} else if (StringUtils.isNotBlank(subcmd)) {
o.put("hasSession", true);
o.set("session", jackson.readTree(subcmd));
}
out = jackson.writeValueAsBytes(o);
} catch (Exception e) {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
return out;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment