我构建了一个Slack斜杠命令,它以某种方式,形状或形式与自定义Node API和POSTS首字母缩略词数据进行通信。它要么获得首字母缩略词的含义,要么添加/删除Mongo数据库的新缩写。
到目前为止,该命令运行良好,但Slack偶尔会返回超时错误,因为它预计会在3秒内响应。结果,我试图实施延迟回复。 我不确定我是否正在为Slack斜杠命令正确实施延迟响应&节点API。
This resource on Slack slash commands有关于延迟回复的信息。我的想法是,我想立即发送200响应,让Slack用户知道他们的请求已被处理。然后我想向slackReq.response_url
发送一个延迟响应,该响应不受3秒时间限制的约束。
守则
let jwt = require('jsonwebtoken');
let request = require('request');
let slackHelper = require('../helpers/slack');
// ====================
// Slack Request Body
// ====================
// {
// "token":"~",
// "team_id":"~"
// "team_domain":"~",
// "channel_id":"~",
// "channel_name":"~",
// "user_id":"~",
// "user_name":"~",
// "command":"~",
// "text":"~",
// "response_url":"~"
// }
exports.handle = (req, res) => {
let slackReq = req.body;
let token = slackReq.token;
let teamId = slackReq.team_id;
if (!token || !teamId || !slackHelper.match(token, teamId)) {
// Handle an improper Slack request
res.json({
response_type: 'ephemeral',
text: 'Incorrect request'
});
} else {
// Handle a valid Slack request
slackHelper.handleReq(slackReq, (err, slackRes) => {
if (err) {
res.json({
response_type: 'ephemeral',
text: 'There was an error'
});
} else {
// NOT WORKING - Immediately send a successful response
res.json({
response_type: 'ephemeral',
text: 'Got it! Processing your acronym request...'
})
let options = {
method: 'POST',
uri: slackReq.response_url,
body: slackRes,
json: true
};
// Send a delayed response with the actual acronym data
request(options, err => {
if (err) console.log(err);
});
}
});
}
};
现在发生了什么
说我想找到缩写词NBA的含义。我继续Slack并拍摄以下内容:
/acronym NBA
然后我点击了3秒的超时错误 - Darn – that slash command didn't work (error message: Timeout was reached). Manage the command at slash-command
。
我再发送一次请求(2到4次),然后API终于一次性返回:
Got it! Processing your acronym request...
NBA means "National Basketball Association".
我想要发生什么
我继续Slack并拍摄以下内容:
/acronym NBA
我立即得到以下信息:
Got it! Processing your acronym request...
然后,在3秒窗口之外,我得到以下内容:
NBA means "National Basketball Association".
我从未遇到超时错误。
结论
我在这里做错了什么?出于某种原因,带有处理消息的res.json()
不会立即被发回。我该怎么做才能解决这个问题?
提前谢谢!
修改1
我尝试将res.json()
来电替换为res.sendStatus(200).json()
,但遗憾的是,这只是回复了“{1}}”。没有实际处理请求。
我随后尝试res.status(200).send({..stuff..})
,但这导致了我之前遇到的同样问题。
我认为res.json()
无论如何都会自动发送200,但由于某些原因,它的响应速度不够快。
解决方案
我最终想出了这个。我一直在实施延迟回复。
由于我使用Heroku的免费计划,托管我的应用程序的dyno将在30分钟不活动后停止运行。当应用程序出现故障时,在正确响应请求之前,前几个请求会在Slack上超时。
对此的解决方案是:1)升级到一直保持dyno始终处于活动状态的新计划,或者2)每15分钟左右用简单的get请求ping应用程序,如下所示:
const intervalMins = 15;
setInterval(() => {
http.get("<insert app url here>");
console.log('Ping!');
}, intervalMin * 60000)
我决定选择后者。我不会再遇到dyno睡觉的问题了。我需要查看this article了解详情。