实施Slack斜杠命令延迟响应

时间:2017-06-10 15:34:13

标签: javascript node.js heroku slack-api

我构建了一个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了解详情。

0 个答案:

没有答案