javascripthttpslackboltslack-block-kit

How do you send HTTP POST Requests from a slack app in socket mode?


I am currently creating a bolt slack app with JavaScript that needs to send out an HTTP POST request to an external webhook when a button click occurs. Sending data to my slack app from external sources is simple enough using the slack webhook provided in the app settings, but I can't seem to figure out how to send a message from my app.js file. My app is currently in Socket Mode since I didn't want to set up a Request URL after my Ngrok url didn't seem to work with the verification in slack, and there doesn't seem to be a lot of documentation on this issue. Of the documentation I did find, https://api.slack.com/apis/connections/socket-implement#connect, I wasn't sure how to implement apps.connections.open into my JavaScript file. I am fairly new to JavaScript and HTTP Requests, so any help would be greatly appreciated. I am also using the Bolt app package for slack, below is my code.

const { App } = require('@slack/bolt');
// Initializes your app with your bot token and signing secret

const app = new App({
  token: "xoxb-",
  signingSecret: "",
  appToken: "xapp-",
  socketMode: true,
  port: process.env.PORT || 3000
});

app.message('Hey bot', async ({ message, say }) => {
  // say() sends a message to the channel where the event was triggered

  await say({
    "blocks": [
      {
          "type": "section",
          "text": {
            "type": "mrkdwn",
            "text": `You made a request <@${message.user}>?`
          }},
        {
            "type": "divider"
        },
        {
            "type": "input",
            "element": {
                "type": "plain_text_input",
                "action_id": "plain_text_input-action"
            },
            "label": {
                "type": "plain_text",
                "text": "Error Message",
                "emoji": true
            }
        },
        {
            "type": "input",
            "element": {
                "type": "plain_text_input",
                "multiline": true,
                "action_id": "plain_text_input-action"
            },
            "label": {
                "type": "plain_text",
                "text": "Description of Error",
                "emoji": true
            }
        },
        {
            "type": "input",
            "element": {
                "type": "plain_text_input",
                "action_id": "plain_text_input-action"
            },
            "label": {
                "type": "plain_text",
                "text": "Aditional notes?",
                "emoji": true
            }
        },
        {
            "type": "actions",
            "elements": [
                {
                    "type": "button",
                    "text": {
                        "type": "plain_text",
                        "text": "Submit",
                        "emoji": true
                    },
                    "value": "click_me_123",
                    "action_id": "button_click"
                }
            ]
        }
    ]
  });
});


app.action('button_click', async ({ body, ack, say }) => {
  // Acknowledge the action
  await ack();
  say("No Flagged Issues");

  // My HTTP POST REQUEST would go here, IF I HAD ANY!
}

});

(async () => {
  // Start your app
  await app.start(process.env.PORT || 3000);
  console.log('⚡️ Bolt app is running!');
})();


Solution

  • At the end of the day, Bolt apps are just plain old JS apps, so there's nothing particularly special you would need to do to make a HTTP POST from inside your app.action().

    There's a bunch of libraries out there, but one of the more popular ones is Axios. After importing it, you'd just have code like this inside your app.action method

    axios.get('https://www.nodesource.com/')
      .then(function (response) {
        // handle success
        console.log(response);
      })
      .catch(function (error) {
        // handle error
        console.log(error);
      })
      .then(function () {
        // always executed
      });
    
    // Using async/await
    async function getUser() {
      try {
        const response = await axios.get('https://www.nodesource.com/');
        console.log(response);
      } catch (error) {
        console.error(error);
      }
    }
    

    This snippet is by no means idiomatic JS, but it's enough to get you going.