Created
September 4, 2017 10:28
-
-
Save bandicoot86/8169a2e2dda6a94e978150f90b443e9f to your computer and use it in GitHub Desktop.
RestCtrl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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