【问题标题】:Slack bot - prevent bot from replying to each incoming webhookSlack bot - 防止 bot 回复每个传入的 webhook
【发布时间】:2016-08-09 10:30:30
【问题描述】:

我做了一个 Slack 命令,允许用户代表其他人发帖……只是为了好玩。这是一个存在于 AWS Lambda 中的节点函数。

通过输入 /mybot danturcotte^ hello 我进入 Slack:

烦人的是每次我发帖,我的 Slackbot “Dante”都会回复。

当我postToSlack 时,我尝试了这两个选项以确保我的机器人不会跟进松弛的帖子:

1) context.succeed();

2) callback(error, null);

两种方式仍然让 Dante 回复 null。我怎样才能只发布传入的 webhook 而没有其他内容(又名 danturcotte 打招呼)?

AWS Lambda NodeJS 代码 sn-p:

var AWS = require('aws-sdk');
var qs = require('querystring');
var request = require('request');

exports.handler = function (event, context, callback) {

    var params = qs.parse(event.postBody);

    var botPayload = {};
    botPayload.channel = params.channel_name;

    if (typeof params.text !== 'undefined') {

        botPayload.userToGet = params.text.split('^')[0];

        getUserData(botPayload, function (error, status, body) {

            var userDataArray = JSON.parse(body),
                profileFound = false;

            for (var i = 0; i < userDataArray.members.length; i++) {
                if (!profileFound) {
                    if (userDataArray.members[i].name === botPayload.userToGet) {
                        //set bot to user
                    }
                }
            }

            postToSlack(botPayload, function (error, status, body) {
                //context.succeed();
                callback(error, null);
            });
        });
    }
};


function getUserData (payload, callback) {
    request({
        uri: 'https://slack.com/api/users.list?token=mytoken',
        method: 'GET'
    }, function (error, response, body) {
        callback(error, response.statusCode, body);
    });
};

function postToSlack (payload, callback) {

    var incoming_webhook = 'https://hooks.slack.com/services/T02LHM7GA/B11BS608F';

    request({
        headers: {
            'content-type': 'application/json'
        },
        uri: incoming_webhook,
        body: JSON.stringify(payload),
        method: 'POST'
    }, function (error, response, body) {
        if (error) {
            return callback(error);
        }
        callback(null, response.statusCode, body);
    });
};

【问题讨论】:

    标签: node.js amazon-web-services lambda slack


    【解决方案1】:

    我认为仅使用 Lambda 和 Slack 是不可能的。 Slack slash command documentation 说:

    如果您的命令不需要发回任何内容(无论是私下 或公开),以空的 HTTP 200 响应进行响应。

    因此,您的目标是让您的 Lambda 函数生成没有正文的 HTTP 响应。不幸的是,根据the AWS Lambda documentation for Node.js,看起来所有 HTTP 响应都是 JSON:

    提供的结果必须与 JSON.stringify 兼容。如果提供错误,则忽略此参数。

    如果您的代码中不使用回调,AWS Lambda 会隐式调用它,返回值为 null。

    因此,无论您做什么,您的函数都会以某种 JSON 响应,并且没有任何 JSON 可以发送回 Slack,这将导致不显示任何消息。 (null 将显示null,空字符串将返回为""{"text": ""} 将导致no_text 错误。)

    我相信您需要在 AWS Lambda 前面放置一些层,这会导致返回一个空主体。听起来 AWS API Gateway 是这一层的一种可能性(请参阅mapping templates),但我没有任何第一手经验。

    更新

    看起来这确实可以通过 AWS API Gateway 完成。我通过为application/json 创建一个映射到$input.path('$') 的“身体映射模板”来完成这项工作。这意味着您可以将一个空字符串 ("") 传递给 callback 以导致根本没有响应正文。 (如果您确实想以某种方式响应,只需确保返回一个字符串。)

    【讨论】:

    • 我遇到了这个确切的问题,但 AWS 控制台对用户不太友好。您能否详细介绍一下如何在 API 网关控制台中创建 Body Mapping 模板?
    • 这个更新对我有用。对其他人的一个澄清说明,整个映射只是 $input.path('$') 行,你把它放在 Integration Response 部分。
    猜你喜欢
    • 2017-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    相关资源
    最近更新 更多