I'm setting up a Slack bot using node.js. The event system works perfectly and gives me POSTs with valid bodies from Slack, and I am able to successfully send messages (both interactive and not) to Slack.
However, the POSTs Slack sends me in response to an interaction with the buttons on interactive messages has an empty body. Interestingly, the Slack headers are still well-formed, although it fails to pass the signing secret test (which I know I implemented properly since event POSTs from Slack pass it).
I've set up everything for interactions according to Slack's own documentation here: https://api.slack.com/messaging/interactivity/enabling. I'm using express, request, and XMLHttpRequest to receive and send HTTP methods. If anyone has encountered this problem or has any insights, that would be great. Thanks!
Here's a code snippet for my function receiving POSTs from interactions:
var express = require('express');
var request = require('request');
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.post('/interaction', (req, res) => {
res.sendStatus(200);
var payload = {
"channel": req.body.payload.channel, // Breaks here since req.body is empty
"text": "Selected choice " + req.body.payload.actions.text.text
}
var r = new XMLHttpRequest();
r.onload = () => { var status = request.status; var data = request.responseText; }
r.open("POST", request_url, true);
r.setRequestHeader("Content-Type", "application/json");
r.setRequestHeader("Authorization", "Bearer " + botToken);
r.send(JSON.stringify(payload));
});
The Slack documentation doesn't seem to mention this, but empirically it would seem that the content type for webhook calls to apps uses Content-Type: application/x-www-form-urlencoded
. You'll want to add:
app.use(bodyParser.urlencoded({ extended: true }));
In addition, the payload
parameter can't be accessed as you're doing: it's actually a JSON object serialized as a string. This is documented here: https://api.slack.com/messaging/interactivity/enabling#understanding_payloads
The request will be made to your specified request URL in an HTTP POST. The body of that request will contain a payload parameter. Your app should parse this payload parameter as JSON.
So your code will want to do something like this:
var slack_payload = JSON.parse(req.body.payload);
var payload = {
"channel": slack_payload.channel,
"text": "Selected choice " + slack_payload.actions.text.text
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With