3

I am trying to use slack webhook. I can read a lot of variation about how I should proceed, but until now, none of them worked properly.

I am using the request node module to make the api call, but I can change if needed.

First try following this

import request from 'request';
const url = 'https://hooks.slack.com/services/xxx';
const text = '(test)!';
request.post(
  {
    headers : { 'Content-type' : 'application/json' },
    url,
    payload : JSON.stringify({ text }),
  },
  (error, res, body) => console.log(error, body, res.statusCode)
);

I get : null 400 'invalid_payload'

Next try following this

request.post(
  {
    headers : { 'Content-type' : 'application/json' },
    url,
    form : JSON.stringify({ text }),
  },
  (error, res, body) => console.log(error, body, res.statusCode)
);

This time, it works, but Slack displays: %28test%29%21 instead of (test)!

Did I miss something?

Sharcoux
  • 5,546
  • 7
  • 45
  • 78
  • I dug out an old postman request I used to test this and it works, but as this is text already in it, the problem appears to around how the JSON is converted to text. Have you tried your first example without JSON.stringify actually ? – d parolin Jun 06 '18 at 14:47

3 Answers3

4

Based on your second example and the working Postman request this is how I got it to work, forgive my change to require as I am running older node version right now. I am not exactly sure what your data would look like that you want to post to Slack, that may change how you want to assemble this.

const request = require('request');

const url = 'https://hooks.slack.com/services/xxxxx';
const text = '(test)!';
request.post(
  {
    headers : { 'Content-type' : 'application/json' },
    url,
    form : {payload: JSON.stringify({ text } )}
  },
  (error, res, body) => console.log(error, body, res.statusCode)
);

If you want to use request you may want to check how slack-node is posting the data, here the relevant snipped from slack-node

Slack.prototype.webhook = function(options, callback) {
    var emoji, payload;
    emoji = this.detectEmoji(options.icon_emoji);
    payload = {
      response_type: options.response_type || 'ephemeral',
      channel: options.channel,
      text: options.text,
      username: options.username,
      attachments: options.attachments,
      link_names: options.link_names || 0
    };
    payload[emoji.key] = emoji.val;
    return request({
      method: "POST",
      url: this.webhookUrl,
      body: JSON.stringify(payload),
      timeout: this.timeout,
      maxAttempts: this.maxAttempts,
      retryDelay: 0
    }, function(err, body, response) {
      if (err != null) {
        return callback(err);
      }
      return callback(null, {
        status: err || response !== "ok" ? "fail" : "ok",
        statusCode: body.statusCode,
        headers: body.headers,
        response: response
      });
    });
  };
d parolin
  • 194
  • 6
1

You can try the slack-node module, wraps the post to the hook. Here a reduced modified real world example I used to push notifications for AWS instances.

[EDIT] Changed to use your text

Now, using slack-node, you assemble the {} yourself, adding text: and other parameters yourself and pass it to .webhook

const Slack = require('slack-node');

const webhookUri = 'https://hooks.slack.com/services/xxxxx';
const slack = new Slack();
slack.setWebhook(webhookUri);

text = "(test)!"

slack.webhook({
        text: text
        // text: JSON.stringify({ text })
    }, function(err, response) {
       console.log(err, response);
});
d parolin
  • 194
  • 6
0

I finally went with Slack-webhook that I liked better than slack-node. The solution of d parolin is the best answer to my question, but I wanted to mention the work of pthm for completion.

Sharcoux
  • 5,546
  • 7
  • 45
  • 78