{"componentChunkName":"component---src-templates-post-js","path":"/post/working-with-the-slack-api-in-node-js","result":{"data":{"contentfulHero":{"coverImage":{"file":{"url":"//images.ctfassets.net/xmu5vdhtphau/1jqMTE2RJBiMLIcZAnu6It/5495c6ec7df10a55768df442e73fe4b2/home-hero-min.jpg","fileName":"home-hero-min.jpg"}}}},"pageContext":{"post":{"id":"fce359e4-b462-5a49-b1c0-a63b7e051668","slug":"working-with-the-slack-api-in-node-js","title":"Working with the Slack API in Node.js","createdAt":"Jul 31, 2020","tweetText":null,"type":"blog","video":null,"podcast":null,"categories":[{"id":"ee42b4f4-9317-5068-9279-f39223364de0","name":"Integrations","slug":"integrations"}],"image":{"file":{"url":"//images.ctfassets.net/xmu5vdhtphau/gUcdyWWh0CoMfyeYe6kyE/9bff024de2bdafde3ef50f6f008a8032/slack-api.png","fileName":"slack-api.png"}},"author":{"name":"Valeri Karpov","bio":{"childMarkdownRemark":{"html":"<p>Web developer, author, blogger. 1600 days of code.</p>"}},"avatar":{"file":{"fileName":"rDX7vHYT_400x400.jpg","url":"//images.ctfassets.net/xmu5vdhtphau/1nxugWX7Q2ZcCE9EkLi2y1/322db4b3dfba336590c25b370df02f1c/rDX7vHYT_400x400.jpg"}}},"bodyContent":{"childMarkdownRemark":{"html":"<blockquote>\n<p>This blog post was first published in <a href=\"http://thecodebarbarian.com/working-with-the-slack-api-in-node-js.html\">The Code Barbarian Blog</a>.</p>\n</blockquote>\n<hr>\n<p>Integrating with the <a href=\"https://api.slack.com/\">Slack API</a> is becoming an increasingly common task. Slack is the de facto communication platform for many companies, so there's a lot of demand for getting data from Node.js apps to Slack in realtime. In this article, I'll explain the basics of how to send a Slack message from Node.js.</p>\n<h1>Getting Started</h1>\n<p>There are two npm modules that I recommend for working with the Slack API: the <a href=\"https://www.npmjs.com/package/@slack/web-api\">official @slack/web-api</a> module and the <code>slack</code> <a href=\"https://www.npmjs.com/package/slack\">module</a> written primarily by <a href=\"https://www.youtube.com/watch?v=et8xNAc2ic8\">Brian LeRoux of WTFJS fame</a>. I've also used <a href=\"https://www.npmjs.com/package/node-slack\">node-slack</a> in the past, but that module is fairly out of date. However, both <code>@slack/web-api</code> and <code>slack</code> are fairly thin wrappers around the Slack API, so, for the purposes of this article, we'll just use <a href=\"https://www.npmjs.com/package/axios\">axios</a>.</p>\n<p>In order to make an API request to Slack, you need a Slack token. <a href=\"https://api.slack.com/authentication/token-types\">There are several types of Slack token</a>, each with its own permissions. For example, an <a href=\"http://thecodebarbarian.com/oauth-with-node-js-and-express.html\">OAuth</a> token lets you post messages on behalf of a user. But, for the purposes of this article, I'll be using <a href=\"https://api.slack.com/authentication/token-types#bot\">bot user tokens</a>. Bot user tokens let you post messages as a bot user, with a custom name and avatar, as opposed to as an existing user.</p>\n<p>In order to get a bot user token, you first need to <a href=\"https://api.slack.com/apps\">create a new Slack app</a>. Make sure you set \"Development Slack Workspace\" to the Slack Workspace you want to use.</p>\n<p><img src=\"//images.ctfassets.net/xmu5vdhtphau/1AsdF1ATdVJrczusGdtJom/670e3a11d414e24369c30ce037515566/1.png\" alt=\"1\">\nNext, go through the steps to create a bot user. You'll have to add scopes (permissions) to your bot user, and then install your app. First, make sure you add the following scopes to your bot user:</p>\n<ul>\n<li><code>chat-write</code></li>\n<li><code>chat-write.customize</code></li>\n<li><code>chat-write.public</code></li>\n</ul>\n<p><img src=\"//images.ctfassets.net/xmu5vdhtphau/1BfJYFLQgYpi60Eg7klc9O/eefb676717c0f47832c82883829b8c38/2.png\" alt=\"2\">\nOnce you've added the above scopes, click \"Install App\" to install this new Slack app to your workspace. Once you've installed the app, Slack will give you a bot user token:</p>\n<p><img src=\"//images.ctfassets.net/xmu5vdhtphau/24nVVapzB5McsWomsiwMeN/16bf2af53178d1299e4ea0661de02aeb/3.png\" alt=\"3\"></p>\n<h1>Making Your First Request</h1>\n<p>To send a message to a Slack channel, you need to make an HTTP POST request to the <code>https://slack.com/api/chat.postMessage</code> <a href=\"https://api.slack.com/methods/chat.postMessage\">endpoint</a> with your Slack token in the <a href=\"https://masteringjs.io/tutorials/axios/authorization\">authorization header</a>. The POST request body must contain the <code>channel</code> you want to post to, and the <code>text</code> of your message.</p>\n<p>Below is how you can send a 'Hello, World' message with Axios. Note that you must have a <code>#test</code> channel in your Slack workspace for the below request to work.</p>\n<pre><code>const axios = require('axios');\n\nconst slackToken = 'xoxb-YOUR-TOKEN_HERE';\n\nrun().catch(err => console.log(err));\n\nasync function run() {\n  const url = 'https://slack.com/api/chat.postMessage';\n  const res = await axios.post(url, {\n    channel: '#test',\n    text: 'Hello, World!'\n  }, { headers: { authorization: `Bearer ${slackToken}` } });\n\n  console.log('Done', res.data);\n}\n</code></pre>\n<p>If the request is successful, the response will look something like what you see below:</p>\n<pre><code>{\n  ok: true,\n  channel: 'C0179PL5K8E',\n  ts: '1595354927.001300',\n  message: {\n    bot_id: 'B017GED1UEN',\n    type: 'message',\n    text: 'Hello, World!',\n    user: 'U0171MZ51E3',\n    ts: '1595354927.001300',\n    team: 'T2CA1AURM',\n    bot_profile: {\n      id: 'B017GED1UEN',\n      deleted: false,\n      name: 'My Test App',\n      updated: 1595353545,\n      app_id: 'A017NKGAKHA',\n      icons: [Object],\n      team_id: 'T2CA1AURM'\n    }\n  }\n}\n</code></pre>\n<p>And you should see the below message show up in your #test channel.</p>\n<p><img src=\"//images.ctfassets.net/xmu5vdhtphau/1YjKcIYqFQKMQMLcNq7KsC/5a3a06798f2823fc0731eaceddd631d6/4.png\" alt=\"4\">\nBecause of the <code>chat-write.customize</code> scope, this bot can customize the name and avatar associated with this message. For example, you can set the <code>username</code> and <code>icon_emoji</code> properties to customize the user your messages come from as shown below.</p>\n<pre><code>const res = await axios.post(url, {\n  channel: '#test2',\n  text: 'Hello, World!',\n  username: 'Test App',\n  icon_emoji: ':+1:'\n}, { headers: { authorization: `Bearer ${slackToken}` } });\n</code></pre>\n<p>Below is how the above message looks in Slack.</p>\n<p><img src=\"//images.ctfassets.net/xmu5vdhtphau/36m9Ix63IjtPiVsQi0Qlqw/b5b15702e990cc603d8a1046b70c7e7f/5.png\" alt=\"5\"></p>\n<h1>More Sophisticated Features</h1>\n<p>You can send plain text messages, but Slack allows you to add formatting to messages using a <a href=\"https://api.slack.com/reference/surfaces/formatting\">custom formatting language called mrkdwn</a>. Slack's mrkdwn language is conceptually similar to <a href=\"https://www.markdownguide.org/\">markdown</a>. Most notably, mrkdwn supports code samples in much the same way markdown supports code snippets:</p>\n<pre><code>- `foo` with backticks makes \"foo\" an inline code block.\n- Multi-line code blocks are fenced with three backticks ```\n</code></pre>\n<p>But there are also several important differences:</p>\n<ul>\n<li><code>*foo*</code> makes foo bold in mrkdwn, as opposed to italic in markdown. To make text italic in mrkdwn, you should do <code>_foo_</code>.</li>\n<li>To make the substring \"Google\" link to <a href=\"https://www.google.com/\">https://www.google.com/</a> in mrkdwn, you need to write <code>&#x3C;https://www.google.com/|Google></code>\nMrkdwn does <strong>not</strong> support custom HTML. Any HTML is valid Markdown, but not mrkdwn.</li>\n</ul>\n<p>For example, here's how you can send a message with some basic formatting, including a code block.</p>\n<pre><code>const url = 'https://slack.com/api/chat.postMessage';\n\nconst text = `\nCheck out this *cool* function!\n\n\\`\\`\\`\n${hello.toString()}\n\\`\\`\\`\n`;\n\nconst res = await axios.post(url, {\n  channel: '#test',\n  text,\n  username: 'Test App',\n  icon_emoji: ':+1:'\n}, { headers: { authorization: `Bearer ${slackToken}` } });\n</code></pre>\n<p>Here's what the above message looks like:</p>\n<p><img src=\"//images.ctfassets.net/xmu5vdhtphau/vfSO84nzj9711guQMYcaC/02839e9689ba983f56c5281364795c39/6.png\" alt=\"6\"></p>\n<p>Slack also supports more sophisticated layouts via <a href=\"https://api.slack.com/reference/surfaces/formatting#block-formatting\">blocks</a>. Instead of specifying a message's <code>text</code>, you can specify a <code>blocks</code> array. There are several different <a href=\"https://api.slack.com/reference/block-kit/blocks#section\">types of blocks</a>, including a generic <code>section</code> block and an <code>image</code> block for pictures.</p>\n<p>For example, below is a simplified example of sending a notification that a new order came in to an eCommerce platform, including a qr code image.</p>\n<pre><code>const res = await axios.post(url, {\n  channel: '#test',\n  blocks: [\n    {\n      type: 'section',\n      text: { type: 'mrkdwn', text: 'New order!' },\n      fields: [\n        { type: 'mrkdwn', text: '*Name*\\nJohn Smith' },\n        { type: 'mrkdwn', text: '*Amount*\\n$8.50' },\n      ]\n    },\n    {\n      type: 'image',\n      image_url: 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/d0/QR_code_for_mobile_English_Wikipedia.svg/1200px-QR_code_for_mobile_English_Wikipedia.svg.png',\n      alt_text: 'qrcode'\n    }\n  ],\n  username: 'Test App',\n  icon_emoji: ':+1:'\n}, { headers: { authorization: `Bearer ${slackToken}` } });\n</code></pre>\n<p>Below is what the above message looks like in Slack.</p>\n<p><img src=\"//images.ctfassets.net/xmu5vdhtphau/2z742W37t02jTUSnxf7iY7/5ef7446ab9d4062dfc2b7e7f4958a864/7.png\" alt=\"7\"></p>\n<h2>Moving On</h2>\n<p>Once you get a bot token, working with the Slack API from Node.js is fairly straightforward. You can send neatly formatted messages to Slack to notify them of events they might be interested in, whether they be coworkers at your company or clients using one of your products.</p>"}}}}}}