Steve Cohen Steve Cohen - 13 days ago 7
Node.js Question

Slack-API NodeJS bot response_url not working

I'm currently developing my own slack bot using NodeJS.

For now not a complicated bot, you just type a command and you have an answer. That works fine.

Now I want to send an answer later, because my program call an external API.
As I read here in the slack-API documentation at the end with title "Delayed responses and multiple responses" I need to do a post request to an url I received named "response_url"

Here is what I send in my post resquest :

{
"response_type": "in_channel",
"text": "My delayed text"
}


But when I do my post request with this content on url, nothing append...

Here is the intersting part of my code :

// modules
var http = require('http');
var https = require('http');
var url = require('url');

// Listen slack post request on /
app.post("/", function(req, res) {
var token = req.body.token;
var team_id = req.body.team_id;
var team_domain = req.body.team_domain;
var channel_id = req.body.channel_id;
var channel_name = req.body.channel_name;
var user_id = req.body.user_id;
var user_name = req.body.user_name;
var command = req.body.command;
var text = req.body.text;
var response_url = req.body.response_url;

if (isTokenValid(token)) {
var subcommands = text.trim().split(/\s+/);

// Check if sub-command is provided
if (subcommands.length == 0 || text == '') {
res.status(200).send('Usage: ' + USAGE);
}else { // check sub-command
switch(subcommands[0]) {
case 'test':
res.status(200).send(sendTest(response_url));
default:
res.end('Command "' + subcommands[0] + '" does not exists.\nUsage: ' + USAGE);
}
}
// Bad token
}else {
console.log('Bad token: ' + token);
res.setHeader('Content-Type', 'text/plain');
res.status(403).send('Bad token. This is a personal slack plugin owned by Ninjava team');
}
});

function sendTest(response_url) {
var options = {
host: 'my_api.com',
port: '80',
path: '/v2/content',
method: 'GET'
};

getReq(options, function(output) {
var obj = JSON.parse(output);

var myresult = obj.result;

var host = url.parse(response_url).hostname;
var path = url.parse(response_url).pathname;
var data = {
"response_type": "in_channel",
"text" : "This is the delayed message !"
};

postReq(host, path, data, true, function(output) {
console.log(output);
});
});
return "This is a direct message. Waiting for the delayed message...";
}

function getReq(options, callback) {
//making the http get call
var getReq = http.request(options, function(res) {
var output = '';
res.on('data', function(chunk) {
output += chunk;
});
res.on('end', function() {
process.stdout.write('\r');
callback(output);
});
});

//end the request
getReq.end();
getReq.on('error', function(err){
console.log("Error: ", err);
});
}

function postReq(host, path, data, ssl, callback) {
var post_data = JSON.stringify(data);
var post_options = {
host: host,
port: '80',
path: path,
method: 'POST',
headers: {
'Content-Type' : 'application/json',
'Content-Length': Buffer.byteLength(post_data)
}
};

var protocol = ssl ? https : http;
var post_req = protocol.request(post_options, function(res, b, c) {
var output = '';
res.setEncoding( 'utf8' );
res.on('data', function(chunk) {
output += chunk;
});
res.on('end', function() {
callback(output);
});
});

post_req.on('error', function(err){
console.log("Error: ", err);
});

// post the data
post_req.write(post_data);
post_req.end();
}


I's done a lot of test.


  1. I used https://requestb.in/q9zahiq9?inspect to test what my bot return with the post method (replacing the slack response_url by my requestb.in url). Everything seems to be ok

  2. I used PostMan to check if my post request was recognized by the slack-API, just doing a post request on the response_url with the json object I provided at the begin of my post, and I success received the message on my slack channel.



I don't know why slack do not recognize my request and how to debug it...

Thanks in advance

Edit:
I solved it, please see my answer bellow

Answer

If anyone is intersted, I fixed my issue !

I just changed my request method :

function sendDataToSlack(response_url, data, callback) {
    request({
        url: response_url,
        method: "POST",
        json: true,
        headers: {
            "content-type": "application/json",
        },
        body: JSON.stringify(data)

        }, function (error, response, body) {
        if (!error && response.statusCode === 200) {
            callback(body);
        }
        else {
            console.log("error: " + error)
            console.log("response.statusCode: " + response.statusCode)
            console.log("response.statusText: " + response.statusText)
        }
    });
}

And it works fine