Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Token refresh documentation #622

4 changes: 3 additions & 1 deletion README.md
Expand Up @@ -51,6 +51,8 @@ through building your first Slack app using Node.js.
that explains and compares the options. If you're still not sure,
[reach out for help](#getting-help) and our community can guide you.

**Building a workspace app?** The `WebClient` can automatically [handle token rotation](https://slackapi.github.io/node-slack-sdk/web_api#using-refresh-tokens) for your app. [Learn more](https://api.slack.com/docs/rotating-and-refreshing-credentials#why) about why you should enable token expiration (hint: its required for App Directory distribution).

## Examples

### Posting a message with Web API
Expand All @@ -63,7 +65,7 @@ how to post a message into a channel, DM, MPDM, or group. This will require eith
```javascript
const { WebClient } = require('@slack/client');

// An access token (from your Slack app or custom integration - xoxp, xoxb, or xoxa)
// An access token (from your Slack app or custom integration - xoxa, xoxp, or xoxb)
const token = process.env.SLACK_TOKEN;

const web = new WebClient(token);
Expand Down
182 changes: 49 additions & 133 deletions docs/_pages/getting_started.md
Expand Up @@ -6,8 +6,7 @@ order: 1
headings:
- title: Create a Slack app
- title: Setting up your local project
- title: Sending a notification with incoming webhooks
- title: Calling a web API method
- title: Sending a message with the web API
---

You've never built a Slack app before? Want some direction on how to use this package? Well, my
Expand All @@ -18,46 +17,27 @@ This guide introduces fundamentals of the Slack Developer Kit for Node.js and Sl
## Create a Slack app

The first step is to [register a new app](https://api.slack.com/apps/new) with Slack at the API
website. Give your app a fun name and choose a Development Slack Workspace. We recommend using
a workspace where you aren't going to disrupt real work getting done -- you can create a new
workspace for free.

You'll be greeted with some basic information. In this guide we'll be setting up an Incoming Webhook
and make a request to the Web API. The webhook allows your app to post rich notifications into
one specific channel that a user gets to decide when they install your app into their workspace.
The Web API allows your app to call methods that can be used for everything from creating a channel
to searching messages. Let's configure our new app for these capabilities.

### Setting up incoming webhooks

Navigate to incoming webhooks and activate the feature. When you click the "Add New Webhook to
Workspace" button, you'll be taken to your app installation page. This page is asking you for
permission to install the app in your development workspace with specific capabilities. That's
right, the development workspace is like every other workspace -- apps must be authorized by a user
each time it asks for more permissions. Go ahead and choose a channel and click "Authorize".
Copy the webhook URL that was added to the table below and keep it safe. This URL should be treated
like a password since it contains the permissions to post in a channel from the outside world. In
a later step, you'll be asked to use this URL in your code.
website. You have the option to build a user-token app or a workspace app. Give your app a fun name and choose a Development Slack Workspace. We recommend using a workspace where you aren't going to disrupt real work getting done -- you can create a new workspace for free.

> ⚠️ For this guide, we'll assume you're building a [workspace app](https://api.slack.com/workspace-apps-preview). Workspace apps support Slack's latest and greatest platform features. However, most steps are the same for user-token apps.

After you create an app, you'll be greeted with some basic information. In this guide we'll be making a request to the Web API to post a message to a channel. Aside from posting messages, the Web API allows your app to call [methods](https://api.slack.com/methods) that can be used for everything from creating a channel to searching messages. Let's configure our new app with proper permissions.

### Getting a token to use the Web API

Navigate to OAuth & Permissions and scroll down to the section for scopes. Slack describes the
various permissions your app could obtain from a user as **scopes**. There are a
[ton of scopes](https://api.slack.com/scopes)! Some are coarse and authorize your app to access lots
[ton of scopes](https://api.slack.com/scopes)! Some are broad and authorize your app to access lots
of data, while others are very specific and let your app touch just a tiny sliver. Your users (and
their IT admins) will have opinions about which data your app should access, so we recommend finding
the scope(s) with the least amount of privilege for your app's needs. In this guide we will use the
Web API to perform a search for messages. The scope required for this is called `search:read`. Use
the dropdown or start typing its name to select and add the scope, then click "Save Changes".

Our app has described which scope it desires in the workspace, but a user hasn't authorized those
scopes for the development workspace yet. Scroll up and click "Install (or Reinstall) App". You'll
be back at the page asking you for permission, but this time with an additional entry corresponding
to the `search:read` scope we just added. Choose your channel again and click "Authorize". When you
return to the OAuth & Permissions page copy the OAuth Access Token. Just like the webhook URL from
above, treat this value like a password and keep it safe. The Web API uses tokens to
to authenticate the requests your app makes. In a later step, you'll be asked to use this token in
your code.
Web API to post a message. The scope required for this is called `chat:write` (or `chat:write:user` for user-token apps). Use the dropdown or start typing its name to select and add the scope, then click "Save Changes".

Our app has described which scope it desires in the workspace, but a user hasn't authorized those scopes for the development workspace yet. Scroll up and click "Install App". You'll be taken to your app installation page. This page is asking you for permission to install the app in your development workspace with specific capabilities. That's right, the development workspace is like every other workspace -- apps must be authorized by a user each time it asks for more permissions.

Go ahead and click "Continue". The next page asks you which conversations the app should be able to post messages in. In this case, choose "No channels", which still allows the app to directly message users who install the App -- which means you.

When you return to the OAuth & Permissions page copy the OAuth Access Token (it should begin with `xoxa`). Treat this value like a password and keep it safe. The Web API uses tokens to to authenticate the requests your app makes. In a later step, you'll be asked to use this token in your code.

## Set up your local project

Expand All @@ -81,7 +61,7 @@ $ npm install @slack/client
Create a new file called `tutorial.js` in this directory and add the following code:

```javascript
const { IncomingWebhook, WebClient } = require('@slack/client');
const { WebClient } = require('@slack/client');

console.log('Getting started with Slack Developer Kit for Node.js');
```
Expand All @@ -95,123 +75,56 @@ Getting started with Slack Developer Kit for Node.js

If you see the same output as above, you're ready to build your Slack app!

## Sending a notification with incoming webhooks
## Sending a message with the Web API

In this guide we'll post a simple notification that contains the current time. We'll also follow
In this guide we'll post a simple message that contains the current time. We'll also follow
the best practice of keeping secrets outside of your code (do not hardcode sensitive data).

Store the webhook URL in a new environment variable. The following example works on Linux and MacOS;
Store the access token in a new environment variable. The following example works on Linux and MacOS;
but [similar commands are available on Windows](https://superuser.com/a/212153/94970). Replace the
value with webhook URL that you copied above.
value with OAuth Access Token that you copied above.

```shell
$ export SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...
$ export SLACK_ACCESS_TOKEN=xoxa-...
```

Open `tutorial.js` and add the following code:
Create a file called `tutorial.js` and add the following code:

```javascript
const timeNotification = new IncomingWebhook(process.env.SLACK_WEBHOOK_URL);
// The current date
const currentTime = new Date().toTimeString();
timeNotification.send(`The current time is ${currentTime}`, (error, resp) => {
if (error) {
return console.error(error);
}
console.log('Notification sent');
});
```

This code creates an instance of the `IncomingWebhook` class, which requires a webhook URL. The
program reads the webhook URL from the environment variable. Then the `.send()` method is called to
send a simple string to the Slack channel. The second argument is a callback which handles any
error by logging it, and otherwise prints "Notification sent".

Run the program. The output should look like the following:

```shell
$ node tutorial.js
Getting started with Slack Developer Kit for Node.js
Notification sent
// Use the `apps.permissions.resources.list` method to find the conversation ID for an app home
web.apps.permissions.resources.list()
.then((res) => {
// Find the app home to use as the conversation to post a message
// At this point, there should only be one app home in the whole response since only one user has installed the app
const appHome = res.resources.find(r => r.type === 'app_home');

// Use the `chat.postMessage` method to send a message from this app
return web.chat.postMessage({
channel: appHome.id,
text: `The current time is ${currentTime}`,
});
})
.then((res) => {
console.log('Message posted!');
})
.catch(console.error);
```

Look inside Slack to verify the notification message was sent.

## Calling a web API method
This code creates an instance of the `WebClient`, which requires an access token to call Web API methods. The program reads the app's access token from the environment variable. Then the [apps.permissions.resources.list](https://api.slack.com/methods/apps.permissions.resources.list) method is called with the `WebClient` to find a conversation where the app can send a message. There will be one resource that represents your own DM with the app (since you were the installing user). We find that resource by finding the first in the list with a `type` that equals `"app_home"`. Lastly, the [chat.postMessage](https://api.slack.com/methods/chat.postMessage) method is called using the conversation ID we just found to send a simple message.

Now that you app has sent a message, let's search for the message using the
[`search.messages`](https://api.slack.com/methods/search.messages) Web API method.

Store the access token in a new environment variable. The following example works on Linux and MacOS;
but [similar commands are available on Windows](https://superuser.com/a/212153/94970). Replace the
value with token that you copied above.

```
$ export SLACK_TOKEN=xoxp-...
```

Open `tutorial.js` and update the code to look like the following:

```javascript
const { IncomingWebhook, WebClient } = require('@slack/client');

console.log('Getting started with Slack Developer Kit for Node.js');

const web = new WebClient(process.env.SLACK_TOKEN);
const timeNotification = new IncomingWebhook(process.env.SLACK_WEBHOOK_URL);
const currentTime = new Date().toTimeString();

timeNotification.send(`The current time is ${currentTime}`, (error, resp) => {
if (error) {
return console.error(error);
}
console.log('Notification sent');
console.log('Waiting a few seconds for search indexes to update...');
setTimeout(() => {
console.log('Calling search.messages');
web.search.messages({ query: currentTime })
.then(resp => {
if (resp.messages.total > 0) {
console.log('First match:', resp.messages.matches[0]);
} else {
console.log('No matches found');
}
})
.catch(console.error)
}, 12000);
});
```

Run the program and you should see output similar to the following:
Run the program. The output should look like the following:

```shell
$ node tutorial.js
Getting started with Slack Developer Kit for Node.js
Notification sent
Waiting a few seconds for search indexes to update...
Calling search.messages
First match: { type: 'message',
ts: '1513884363.000142',
text: 'The current time is 11:26:03 GMT-0800 (PST)',
iid: '0a4d7acd-c0d9-49f4-813f-7a21f3cf78dc',
permalink: 'https://workspace-subdomain.slack.com/archives/C34SDV231/p231234192347',
team: 'T0AS345LD',
channel:
{ id: 'C34SDV231',
is_channel: true,
is_group: false,
is_im: false,
name: 'blah',
is_shared: false,
is_org_shared: false,
is_ext_shared: false,
is_private: false,
is_mpim: false,
pending_shared: [],
is_pending_ext_shared: false } }
Message posted!
```

_If you see no results, try increasing the timeout time and run the program again. Slack's
search indexes could take more than a few seconds._
Look inside Slack to verify the message was sent.

## Next Steps

Expand All @@ -226,11 +139,14 @@ ideas about where to look next:
authentication, you may find the
[`@aoberoi/passport-slack`](https://github.com/aoberoi/passport-slack) strategy package helpful.

* Tokens are an important part of using the Slack platform. Learn about the
[different types of tokens](https://api.slack.com/docs/token-types).

* This tutorial only used one of **over 130 Web API methods** available.
[Look through them](https://api.slack.com/methods) to get ideas about what to build next!

* Token rotation is required if you plan to distribute your app. You can find examples of using
refresh tokens with the `WebClient` [in the documentation](/web_api#using-refresh-tokens), and learn more about refresh tokens and token rotation [on the API site](https://api.slack.com/docs/rotating-and-refreshing-credentials).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line above still references a dev instance in the URL, change that.

* Dive deeper into the `IncomingWebhook`, `WebClient`, and `RTMClient` classes in this package by
exploring their documentation pages.

* Tokens are an important part of using the Slack platform. Learn about the
[different types of tokens](https://api.slack.com/docs/token-types).