فهرست منبع

[add][Fix #28] implements undocumented exec and list slash commands

B Thibault 8 سال پیش
والد
کامیت
0d953f95a9
5فایلهای تغییر یافته به همراه116 افزوده شده و 44 حذف شده
  1. 13 28
      cli/workflow.js
  2. 0 6
      srv/public/slack.min.js
  3. 20 0
      srv/src/httpServ.js
  4. 29 4
      srv/src/slack.js
  5. 54 6
      srv/src/slackData.js

+ 13 - 28
cli/workflow.js

@@ -129,22 +129,14 @@ function uploadFile(chan, filename, file, callback) {
 
 /**
  * @param {SlackChan|SlackGroup|SlackIms} chan
- * @param {string} cmd
+ * @param {SlackCommand!} cmd
  * @param {string} args
 **/
 function doCommand(chan, cmd, args) {
-    if (cmd == "me") {
-        if (REPLYING_TO)
-            return false;
-        sendMeMessage(chan, args);
-        return true;
-    } else if (cmd == "shrug") {
-        if (args.length)
-            args += ' ';
-        return onTextEntered(args + "¯_(ツ)_/¯", true);
-    }
-    console.log("Unknown command " +cmd);
-    return false;
+    var xhr = new XMLHttpRequest()
+        ,url = 'api/cmd?room=' +chan.id +"&cmd=" +encodeURIComponent(cmd.name.substr(1)) +"&args=" +encodeURIComponent(args);
+    xhr.open('POST', url, true);
+    xhr.send(null);
 }
 
 /**
@@ -180,18 +172,6 @@ function sendMsg(chan, msg, replyTo) {
     xhr.send(null);
 }
 
-/**
- * @param {SlackChan|SlackGroup|SlackIms} chan
- * @param {string} msg
-**/
-function sendMeMessage(chan, msg) {
-    var xhr = new XMLHttpRequest()
-        ,url = 'api/msg?room=' +chan.id +"&me&text=" +encodeURIComponent(msg);
-
-    xhr.open('POST', url, true);
-    xhr.send(null);
-}
-
 /**
  * @param {string} input
  * @param {boolean=} skipCommand
@@ -205,10 +185,15 @@ function onTextEntered(input, skipCommand) {
     }
     if (input[0] === '/' && skipCommand !== true) {
         var endCmd = input.indexOf(' ')
-            ,cmd = input.substr(1, endCmd === -1 ? undefined : endCmd -1)
-            ,args = endCmd === -1 ? "" : input.substr(endCmd);
+            ,cmd = input.substr(0, endCmd === -1 ? undefined : endCmd)
+            ,args = endCmd === -1 ? "" : input.substr(endCmd)
+            ,cmdObject = SLACK.context.commands.data[cmd];
 
-        return doCommand(SELECTED_ROOM, cmd, args.trim());
+        if (cmdObject) {
+            doCommand(SELECTED_ROOM, cmdObject, args.trim());
+            return true;
+        }
+        return false;
     }
     sendMsg(SELECTED_ROOM, input, REPLYING_TO);
     return true;

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 6
srv/public/slack.min.js


+ 20 - 0
srv/src/httpServ.js

@@ -139,6 +139,26 @@ Server.prototype.onRequest = function(req, res) {
             }
             sessionManager.saveSession(req.session);
             res.end();
+        } else if (req.urlObj.match(["api", "cmd"])) {
+            if (!req.urlObj.queryTokens.room ||
+                !req.urlObj.queryTokens.cmd ||
+                !req.urlObj.queryTokens.args) {
+                res.writeHeader("400", "Bad request");
+                res.end();
+            } else {
+                var chan = res.slack.data.getChannel(req.urlObj.queryTokens.room[0])
+                    ,cmd = res.slack.data.commands.data['/' +req.urlObj.queryTokens.cmd[0]];
+
+                if (!chan) {
+                    res.writeHeader("404", "Chan not found");
+                } else if (!cmd) {
+                    res.writeHeader("404", "No such command");
+                } else {
+                    res.slack.sendCommand(chan, cmd, req.urlObj.queryTokens.args[0]);
+                    res.writeHeader("204", "No Content");
+                }
+                res.end();
+            }
         } else if (req.urlObj.match(["api", "avatar"])) {
             if (!req.urlObj.queryTokens.user) {
                 res.writeHeader("400", "Bad request");

+ 29 - 4
srv/src/slack.js

@@ -25,6 +25,8 @@ const SLACK_ENDPOINT = "https://slack.com/api/"
         ,postFile: "files.upload"
         ,setActive: "users.setActive"
         ,emojiList: "emoji.list"
+        ,slashList: "commands.list"
+        ,slashExec: "chat.command"
         ,addReaction: "reactions.add"
         ,removeReaction: "reactions.remove"
     }
@@ -122,14 +124,37 @@ Slack.prototype.connect = function(knownVersion) {
             return;
         }
         _this.getEmojis((emojis) => {
-            body.emojis = emojis;
-            _this.data.updateStatic(body, Date.now());
-            _this.connectRtm(body.url);
-            _this.waitForEvent(knownVersion);
+            _this.getSlashCommands((commands) => {
+                body.emojis = emojis;
+                body.commands = commands;
+                _this.data.updateStatic(body, Date.now());
+                _this.connectRtm(body.url);
+                _this.waitForEvent(knownVersion);
+            });
         });
     });
 };
 
+Slack.prototype.sendCommand = function(room, cmd, arg) {
+    httpsRequest(
+        SLACK_ENDPOINT
+        +GETAPI.slashExec
+        +"?token=" +this.token
+        +"&command=" +encodeURIComponent(cmd.name)
+        +"&disp=" +encodeURIComponent(cmd.name)
+        +"&channel=" +room.id
+        +"&text=" +arg);
+}
+
+Slack.prototype.getSlashCommands = function(cb) {
+    httpsRequest(SLACK_ENDPOINT +GETAPI.slashList +"?token=" +this.token, (status, body) => {
+        if (!status || !body || !body.ok)
+            cb(null);
+        else
+            cb(body.commands || {});
+    });
+};
+
 Slack.prototype.getEmojis = function(cb) {
     httpsRequest(SLACK_ENDPOINT +GETAPI.emojiList +"?token=" +this.token, (status, body) => {
         if (!status || !body || !body.ok)

+ 54 - 6
srv/src/slackData.js

@@ -377,6 +377,34 @@ SlackBot.prototype.setPresence = function(presenceStr, t) {
     this.version = Math.max(t, this.version);
 }
 
+/**
+ * @constructor
+ * @param {*} data
+**/
+function SlackCommand(data) {
+    /** @const @type {string} */
+    this.desc = data["desc"];
+    /** @const @type {string} */
+    this.name = data["name"];
+    /** @const @type {string} */
+    this.type = data["type"];
+    /** @const @type {string} */
+    this.usage = data["usage"];
+}
+
+/**
+ * @param {number} t
+ * @return {Object}
+**/
+SlackCommand.prototype.toStatic = function(t) {
+    return {
+        "desc": this.desc
+        ,"name": this.name
+        ,"type": this.type
+        ,"usage": this.usage
+    };
+}
+
 /**
  * @constructor
 **/
@@ -395,8 +423,10 @@ function SlackData(slack) {
     this.self = null;
     /** @type {Object.<string, SlackBot>} */
     this.bots = {};
-    /** @type {Object.<string, string>} */
-    this.emojis = {};
+    /** @type {{version: number, data: Object.<string, string>}} */
+    this.emojis = { version: 0, data: {} };
+    /** @type {{version: number, data: Object.<string, SlackCommand>}} */
+    this.commands = {version: 0, data: {} };
     /** @type {Object.<string, Object.<string, number>>} */
     this.typing = {};
 
@@ -579,9 +609,21 @@ SlackData.prototype.updateStatic = function(data, t) {
             groupObj = this.groups[data["groups"][i]["id"]] = new SlackGroup(data["groups"][i]["id"]);
         groupObj.update(this, data["groups"][i], t);
     }
-    if (data["emojis"]) this.emojis = data["emojis"];
-    if (!this.team) this.team = new SlackTeam(data["team"]["id"]);
-    this.team.update(data["team"], t);
+    if (data["emojis"]) {
+        this.emojis.data = data["emojis"];
+        this.emojis.version = t;
+    }
+    if (data["commands"] !== undefined){
+        this.commands.data = {};
+        for (var i in data["commands"]) {
+            this.commands.data[i] = new SlackCommand(data["commands"][i]);
+        }
+        this.commands.version = t;
+    }
+    if (data["team"]) {
+        if (!this.team) this.team = new SlackTeam(data["team"]["id"]);
+        this.team.update(data["team"], t);
+    }
     this.staticV = Math.max(this.staticV, t);
     if (data["self"]) {
         this.self = this.getMember(data["self"]["id"]);
@@ -647,9 +689,15 @@ SlackData.prototype.buildStatic = function(t, now) {
             "id": this.self.id
             ,"prefs": this.self.prefs.toStatic(t)
         }
-        ,"emojis": this.emojis
+        ,"emojis": this.emojis.version > t ? this.emojis.data : undefined
+        ,"commands": undefined
         ,"typing": undefined
     };
+    if (this.commands.version > t) {
+        res["commands"] = {};
+        for (var i in this.commands.data)
+            res["commands"][i] = this.commands.data[i].toStatic(t);
+    }
     for (var chanId in this.channels) {
         var chan = this.channels[chanId].toStatic(t);
         if (chan)

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است