|
|
@@ -1,10 +1,146 @@
|
|
|
|
|
|
+const
|
|
|
+ WebSocket = require('ws'),
|
|
|
+ https = require('https'),
|
|
|
+ sleep = require("sleep").sleep
|
|
|
+
|
|
|
+ ,SlackData = require("./slackData.js").SlackData
|
|
|
+ ,config = require("../config.js")
|
|
|
+;
|
|
|
+
|
|
|
+const SLACK_ENDPOINT = "https://slack.com/api/"
|
|
|
+,GETAPI = {
|
|
|
+ rtmStart: "rtm.start"
|
|
|
+ ,oauth: "oauth.access"
|
|
|
+};
|
|
|
+
|
|
|
function Slack(sess) {
|
|
|
- console.log("creating new slack RTM for ", sess);
|
|
|
+ this.token = sess.slackToken;
|
|
|
+ this.rtm = null;
|
|
|
+ this.data = new SlackData();
|
|
|
+ this.connected = false;
|
|
|
+}
|
|
|
+
|
|
|
+Slack.prototype.onRequest = function(knownVersion, cb) {
|
|
|
+ this.lastCb = cb;
|
|
|
+ if (this.connected === false) {
|
|
|
+ this.connect(knownVersion);
|
|
|
+ } else {
|
|
|
+ this.waitForEvent(knownVersion);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function httpsRequest(url, cb) {
|
|
|
+ https.get(url, (res) => {
|
|
|
+ if (res.statusCode !== 200) {
|
|
|
+ cb(res.statusCode, null);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var body = null;
|
|
|
+ res.on('data', (chunk) => {
|
|
|
+ body = body ? Buffer.concat([body, chunk], body.length +chunk.length) : Buffer.from(chunk);
|
|
|
+ });
|
|
|
+ res.on('end', () => {
|
|
|
+ try {
|
|
|
+ body = JSON.parse(body.toString("utf8"));
|
|
|
+ } catch (e) {}
|
|
|
+ cb(res.statusCode, body);
|
|
|
+ });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+Slack.prototype.connect = function(knownVersion) {
|
|
|
+ var _this = this;
|
|
|
+
|
|
|
+ this.connected = undefined;
|
|
|
+ httpsRequest(SLACK_ENDPOINT +GETAPI.rtmStart +"?token=" +this.token, (status, body) => {
|
|
|
+ if (status !== 200) {
|
|
|
+ _this.error = body.error;
|
|
|
+ _this.connected = false;
|
|
|
+ console.error("Slack api responded " +status);
|
|
|
+ _this.lastCb(_this);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!body) {
|
|
|
+ _this.error = "Slack API error";
|
|
|
+ _this.connected = false;
|
|
|
+ _this.lastCb(_this);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!body.ok) {
|
|
|
+ _this.error = body.error;
|
|
|
+ _this.connected = false;
|
|
|
+ console.error("Slack api responded !ok with ", body);
|
|
|
+ _this.lastCb(_this);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ _this.data.updateStatic(body);
|
|
|
+ _this.connectRtm(body.url);
|
|
|
+ _this.waitForEvent(knownVersion);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+Slack.prototype.waitForEvent = function(knownVersion) {
|
|
|
+ var tick = 0
|
|
|
+ ,_this = this
|
|
|
+ ,interval;
|
|
|
+
|
|
|
+ interval = setInterval(() => {
|
|
|
+ tick++;
|
|
|
+ var updated = this.data.getUpdates(knownVersion);
|
|
|
+ if (!_this.lastCb) {
|
|
|
+ clearInterval(interval);
|
|
|
+ }
|
|
|
+ if (updated.length > 0) {
|
|
|
+ clearInterval(interval);
|
|
|
+ _this.lastCb(_this, { v: knownVersion, u: updated });
|
|
|
+ } else if (tick === 55) { // < 1 minute timeout
|
|
|
+ clearInterval(interval);
|
|
|
+ _this.lastCb(_this, { v: knownVersion });
|
|
|
+ }
|
|
|
+ }, 1000);
|
|
|
+}
|
|
|
+
|
|
|
+Slack.prototype.connectRtm = function(url, cb) {
|
|
|
+ var _this = this;
|
|
|
+
|
|
|
+ this.rtm = new WebSocket(url);
|
|
|
+ this.rtm.on("message", function(msg) {
|
|
|
+ if (!_this.connected && cb) {
|
|
|
+ cb();
|
|
|
+ }
|
|
|
+ _this.connected = true;
|
|
|
+ msg = JSON.parse(msg);
|
|
|
+ console.log("RTM >>> ", msg);
|
|
|
+ });
|
|
|
+ this.rtm.once("error", function(e) {
|
|
|
+ _this.connected = false;
|
|
|
+ console.error(e);
|
|
|
+ _this.close();
|
|
|
+ });
|
|
|
+ this.rtm.once("end", function() {
|
|
|
+ _this.connected = false;
|
|
|
+ console.error("RTM hang up");
|
|
|
+ _this.close();
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
Slack.prototype.close = function() {
|
|
|
}
|
|
|
|
|
|
+Slack.getOauthToken = function(code, cb) {
|
|
|
+ httpsRequest(SLACK_ENDPOINT+GETAPI.oauth
|
|
|
+ +"?client_id=" +config.clientId
|
|
|
+ +"&client_secret=" +config.clientSecret
|
|
|
+ +"&code=" +code,
|
|
|
+ (status, resp) => {
|
|
|
+ if (status === 200 && resp.ok) {
|
|
|
+ cb(resp);
|
|
|
+ } else {
|
|
|
+ cb(null);
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
module.exports.Slack = Slack;
|
|
|
|