Slack 延迟消息与 Node TypeScript 和 Lambda 的集成 [英] Slack delayed message integration with Node TypeScript and Lambda

查看:70
本文介绍了Slack 延迟消息与 Node TypeScript 和 Lambda 的集成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始实施一个不断发展的斜线命令,最终可能会达到 3 秒的松弛响应限制.我将 serverless-stackNodeTypeScript 一起使用.使用 sst(以及 vscode 启动文件),它可以将调试器挂钩并附加到非常漂亮的 lambda 函数中整洁的调试.

I started implementing a slash-command which kept evolving and eventually might hit the 3-second slack response limit. I am using serverless-stack with Node and TypeScript. With sst (and the vscode launchfile) it hooks and attaches the debugger into the lambda function which is pretty neat for debugging.

当访问 api 端点时,我尝试了各种方法来发回对 slack 的确认,做我的事情并发送延迟消息但没有成功.我没有太多运气找到这方面的信息,但一个很好的来源是这个 SO Answer - 不幸的是它没有用.我没有使用 request-promise 因为它已被弃用并试图用普通方法实现它(也许这就是我失败的地方?).但从内部调用第二个 lambda 函数(如帖子的第一个示例)似乎不在 3s 限制内.

When hitting the api endpoint I tried various methods to send back an acknowledgement to slack, do my thing and send a delayed message back without success. I didnt have much luck finding info on this but one good source was this SO Answer - unfortunetly it didn't work. I didn't use request-promise since it's deprecated and tried to implement it with vanilla methods (maybe that's where i failed?). But also invoking a second lambda function from within (like in the first example of the post) didn't seem to be within the 3s limitation.

我想知道我是否做错了什么,或者调试器是否需要很长时间等等.但是,在尝试发送延迟消息之前,它可以包括访问和扫描 dynamodb 记录、操作结果,然后在连接调试器时响应 slack,而不会超时.

I am wondering if I am doing something wrong or if attachinf the debugger is just taking to long etc. However, before attempting to send a delayed message it was fine including accessing and scaning dynamodb records, manipulating the results and then responding back to slack while debugger attached without hitting the timeout.

尝试使用帖子

export const answer: APIGatewayProxyHandlerV2 = async (
    event: APIGatewayProxyEventV2, context, callback
) => {


    const slack = decodeQueryStringAs<SlackRequest>(event.body);


    axios.post(slack.response_url, {
        text: "completed",
        response_type: "ephemeral",
        replace_original: "true"
    });


    return { statusCode: 200, body: '' };
}

承诺从未解决,我猜一旦点击函数的返回值,lambda 函数就会被处理掉,所以承诺?

The promise never resolved, i guess that once hitting return on the function the lambda function gets disposed and so the promise?

调用第二个 Lambda 函数

Invoking 2nd Lambda function

export const v2: APIGatewayProxyHandlerV2 = async (
    event: APIGatewayProxyEventV2, context, callback
): Promise<any> => {

    //tried with CB here and without
    //callback(null, { statusCode: 200, body: 'processing' });

    const slack = decodeQueryStringAs<SlackRequest>(event.body);
    const originalMessage = slack.text;
    const responseInfo = url.parse(slack.response_url)

    const data = JSON.stringify({
        ...slack,
    })
    const lambda = new AWS.Lambda()
    const params = {
        FunctionName: 'dev-****-FC******SmE7',
        InvocationType: 'Event', // Ensures asynchronous execution
        Payload: data
    }

    return lambda.invoke(params).promise()// Returns 200 immediately after invoking the second lambda, not waiting for the result
        .then(() => callback(null, { statusCode: 200, body: 'working on it' }))
};

查看调试器日志,它确实发送了 200 代码并调用了新的 lambda 函数,尽管 slack 仍然超时.

Looking at the debugger logs it does send the 200 code and invokes the new lambda function though slack still times out.

逻辑上没有什么特别的事情......当前的非延迟消息实现在逻辑上做得更多(访问数据库和操作结果数据)并且设法不超时.

Nothing special happens logic wise ... the current non-delayed-message implementation does much more logic wise (accessing DB and manipulating result data) and manages not to timeout.

欢迎任何建议或帮助.

推荐答案

快速旁注,我在链接的 SO 问题的答案中使用了 request-promise,因为 JS 原生 Promise 对象不是目前尚可在 AWS Lambda 的容器上使用.

Quick side note, I used request-promise in the linked SO question's answer since the JS native Promise object was not yet available on AWS Lambda's containers at the time.

根据我的理解,链接问题中的功能编排与您自己的编排之间存在根本差异,但我认为您有相同的目标:

There's a fundamental difference between the orchestration of the functions in the linked question and your own from what I understand but I think you have the same goal:

>从 Slack 调用异步操作,一旦有结果就会回发到 slack

这是您当前方法的问题:Slack 向您的(第一个)lambda 函数发送请求,该函数返回对 slack 的响应,然后调用第二个 lambda 函数.

Here's the problem with your current approach: Slack sends a request to your (1st) lambda function, which returns a response to slack, and then invokes the second lambda function.

一旦您的第一个 lambda 返回 200,slack 事件将不再接受响应.这就是您的方法和链接的 SO 问题之间的区别.

The slack event is no longer accepting responses once your first lambda returns the 200. Here lies the difference between your approach and the linked SO question.

所需的方法按顺序如下所示:

The desired approach would sequentially look like this:

  1. Slack 向 Lambda 发送请求.1
  2. Lambda 编号1 向 Slack 返回 200 响应
  3. Lambda 编号1 调用 Lambda 编号.2
  4. Lambda 编号2 向 slack URL 发送 POST 请求(google 传入的 slack 网络钩子)
  5. Slack 接收 POST 请求并将其显示在您为网络钩子选择的频道中.

从代码上看,这将如下所示(没有请求承诺,哈哈):

Code wise this would look like the following (without request-promise lol):

module.exports = async (event, context) => {
    // Invoking the second lambda function
    const AWS = require('aws-sdk')
    const lambda = new AWS.Lambda()
    const params = {
        FunctionName: 'YOUR_SECOND_FUNCTION_NAME',
        InvocationType: 'Event', // Ensures asynchronous execution
        Payload: JSON.stringify({
            ... your payload for lambda 2 ...
        })
    }
    await lambda.invoke(params).promise() // Starts Lambda 2

    return {
        text: "working...",
        response_type: "ephemeral",
        replace_original: "true"
    }        
}

Lambda 2

module.exports = async (event, context) => {
    // Use event (payload sent from Lambda 1) and do what you need to do

    return axios.post('YOUR_INCOMING_WEBHOOK_URL', {
        text: 'this will be sent to slack'
    });
}

这篇关于Slack 延迟消息与 Node TypeScript 和 Lambda 的集成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆