2017-10-05 61 views
3

我正在尝试使用hook.io microservice来制作一个松弛的斜杠命令机器人。根据docs,我应该可以立即发送响应,然后再发送单独的POST。但我无法立即得到回应,后来又发布了两篇文章。如何将即时和延迟响应都返回到松弛斜线命令?

这是我的测试代码。

module['exports'] = function testbot(hook) { 

var request = require('request'); 
// The parameters passed in via the slash command POST request. 
var params = hook.params; 

data = { 
    "response_type": "ephemeral", 
    "text": "Immediate Response" 
} 
hook.res.setHeader('Content-Type', 'application/json'); 
console.log("returning immediate response") 
hook.res.write(JSON.stringify(data), 'utf8', delay(params)); 
//calling end() here sends the immediate response but the POST never happens. 
// but if end() is called below instead slack gives a timeout error but the POST succeeds. 
//hook.res.end() 

//test with 3.5 second delay 
function delay(params) { 
    setTimeout(function() {post_response(params)},3500); 
} 

function post_response(params) { 

    console.log("posting delayed response") 
    // Set up the options for the HTTP request. 
    var options = { 
     // Use the Webhook URL from the Slack Incoming Webhooks integration. 
     uri: params.response_url, 
     method: 'POST', 
     // Slack expects a JSON payload with a "text" property. 
     json: {"response_type":"in_channel", "text":"Delayed response","parse":"full"} 
    }; 


    // Make the POST request to the Slack incoming webhook. 
    request(options, function (error, response, body) { 
     // Pass error back to client if request endpoint can't be reached. 
     if (error) { 
      console.log(error); 
      hook.res.end(error.message); 
     } else { 
      console.log("post OK"); 
     } 
     // calling end() here sends the POST but the immediate response is lost to a slack timeout error. 
     hook.res.end() 
    }) 
}; 
} 

如调用res.end意见详细()早期指即时响应被发送,但POST从未发生过,而延迟res.end(),直至立柱装置延迟发送响应,但它产生之后在此期间,由于松弛造成的超时错误。

我是一个javascript新手,所以希望有一个简单的解决方案,我忽略了。

+0

为什么从3.5秒延迟开始?根据松散的文档,如果您等待超过3秒钟的响应,则松弛会引发超时错误。 – Marak

+0

看起来您正在将'delay'函数作为参数传递给'hook.res.write'。这不正确,因为'hook.res.write'不接受回调参数。 – Marak

+0

@ Marak- 3.5秒故意超过闲置超时。我的目标是找到一种方法来立即作出回应,然后继续在后台处理数据并将结果作为单独的事务重新发回。上面显示的代码按照描述工作(post_response在3.5秒后成功完成),所以我有点困惑于你声称hook.res.write()不接受回调。 – rw950431

回答

0

一旦您在hook.io中调用res.end(),脚本将立即中止并结束处理。这相当于拨打process.exit。如果你没有结束这个请求,hook.io最终会打到它自己的Time-out Limit

hook.io应该能够在Slack需要的三秒内回应Slack。

这里是一个指南,可帮助:Making a Custom Slack Slash Command with hook.io

+0

谢谢@ Marak-多数民众赞成在我怀疑。看起来hook.io虽然是一个很棒的产品,但它不适合这个应用程序,因为它涉及的数据库查找有时比超时时间要长。最初的迹象是https://webtask.io/docs/model“Custom Programming Model”在这种情况下可能更适合。 – rw950431

+0

webtask API将以完全相同的方式工作。我认为您不能找到解决方案,除非您立即响应以将Slack URL放在hook.io数据存储或webtask存储中。 – Marak

0

不好的形式回答了自己的问题,我知道,但我使用webtask对于下面的工作,所以我包括在这里的情况下,其他人发现它是有用的。

var express = require('express'); 
var Webtask = require('webtask-tools'); 
var bodyParser = require('body-parser'); 
var request = require('request'); 
var app = express(); 

app.use(bodyParser.urlencoded({ extended: false })); 
app.use(bodyParser.json()); 

//visiting above url in browser is handled by get 
app.get('/', function (req, res) { 
    console.log(req.query) 
    res.send('OK'); 
}); 

//post from slack handled here 
app.post('/', function (req, res) { 
    var params = req.body; 
    console.log(params); 
    var data = { 
     "response_type": "ephemeral", 
     "text": "Immediate Response" 
    } 
    res.setHeader('Content-Type', 'application/json'); 
    res.send(data); 
    // deliberate delay longer than Slack timeout 
    // in order to test delayed response. 
    setTimeout(function() { post_response(params) }, 3500); 
}); 

function post_response(params) { 

    console.log("posting delayed response") 
    // Set up the options for the HTTP request. 
    var options = { 
     // Use the Webhook URL supplied by the slack request. 
     uri: params.response_url, 
     method: 'POST', 
     // Slack expects a JSON payload with a "text" property. 
     json: { "response_type": "in_channel", "text": "Delayed response", "parse": "full" } 
    }; 


    // Make the POST request to the Slack incoming webhook. 
    request(options, function (error, response, body) { 
     if (error) { 
      console.log(error); 
     } else { 
      console.log("post OK"); 
     } 
    }) 
}; 
module.exports = Webtask.fromExpress(app); 
+0

谢谢。根据他们的文档,我现在可以看到,在响应结束长达30秒之后,webtask会保持脚本运行。我会进行调查,但我们应该可以在hook.io上做同样的事情,以便在初始响应后进行后期处理。 – Marak