This is Part 2 of my guide to building an app using the Spotify API and Slack API. If you haven’t read Part 1 yet, read it here. This app lets you create Spotify playlists directly from Slack and add any songs to that playlist when it is sent as messages in Slack.
Table of Contents
Creating a Slack App
The first step is to sign up for Slack and visit the Slack Apps page. Click Create New App
and give it a name.
Note: The Slack Apps website and the Slack App might have changed since this article was written.
Once the app is created we’ll need to grab the Signing Secret
from the App Credentials
section. When requests are made from Slack to our server, we need to ensure that not only did the request actually came from Slack, but from our Slack app. Add the secret to either your .zshrc
, .bashrc
or .env.development
file.
There are two features we need to add to the app: Slash Commands
and Event Subscriptions
.
Slash Commands
Find the section for Slash Commands on the Slack apps page and create a new one. For the command, enter /create-playlist
. The request URL is going to be an ngrok
URL. See Part 1 for details on setting up ngrok
. Add the ngrok
URL to this form when we set up the server later in this article.
https://123abcd.ngrok.io/command
Add a description and a hint. For the hint you can enter name, description
because that will be the format of how the request will be sent.
Event Subscriptions
Find the section for Event Subscriptions on the Slack apps page and turn it on. Add the ngrok
URL to the Request URL form field once we create a server later in this post.
We also need to add a bot event. Create a new bot event under the Subscribe to bot events
section. The event we need to listen to is message.channels
Add the App to Slack
Go to the Slack channel you want to add the app to. Click Details
and under More
click Add apps
. Select your app and give it permission to read messages.
Creating The Slash Command Server
First, install the necessary dependencies:
yarn add @slack/events-api body-parser
In a new file src/slack/index.js
add the following:
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
const portCommands = 5000;
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.listen(portCommands, () => {
console.log(`Slack Server started. Listening for slash commands on port ${portCommands}`);
});
Here we have an express server running on port 5000.
To start the server use nodemon
and use ngrok
to tunnel the request
nodemon src/slack/index.js
ngrok http 5000
Add this URL to the slash command configuration we setup in the first section. The URL should look like:
https://123abcd.ngrok.io/command
Now let’s write the code to handle the request:
app.post("/command", async (req, res) => {
try {
const { text } = req.body;
const [name, description] = text.split(",");
const response = await axios({
url: `${SPOTIFY_SERVER_URL}/playlists`,
method: "post",
data: {
name,
description,
},
});
console.log("Successfully created playlist", response);
const responseJSON = JSON.stringify({
response_type: "in_channel",
text: `Here\'s your playlist!\n ${response.data}`,
});
res.setHeader("Content-Type", "application/json");
res.send(responseJSON);
} catch (error) {
console.log("Error creating playlist", error);
res.send("Whoops! Something went wrong creating a playlist", error);
}
});
Let’s break down this code line by line. When a POST
request is made to the /command
route, we begin by extracting our the message text
from the request body req.body
. We then split the text by a comma because our message format is [playlist name] , [playlist description]
. Now that we have extracted out the name and description we can make a POST
request to the Spotify server /playlist
route to create it. Once that request completes, we send back the playlist URL to the slack channel.
When we execute the slash command, Slack will make a POST
request to our server running on port 5000 at the /command
path. To execute the command enter this into the Slack chat:
/create-playlist my first playlist, made using the Slack & Spotify APIs!
The body of the request to our server will contain the text after /create-playlist
.
Creating The Event Subscription Server
To keep things simple, we’ll add the event subscription server in the same file. We could have just used one server to handle both requests (message events and slash commands). However to make the code easier to read and maintain I made two separate servers.
const { createEventAdapter } = require("@slack/events-api");
const signingSecret = process.env.SLACK_SIGNING_SECRET;
const slackEvents = createEventAdapter(signingSecret);
const portEvents = 4000;
(async () => {
await slackEvents.start(portEvents);
console.log(`Slack Server started. Listening for message events on port ${portEvents}`);
})();
The @slack/events-api
library makes it easy to connect to events that the Slack app listens to. First, we import the createEventAdapter
from the library and pass in the signing secret to initialize it. This is crucial because we need to verify that the request we receive is legitimate.
Next we run an immediately invoked function to start the server on port 4000. Now that the server is setup we need to listen for message events. The @slack/events-api
library makes this super simple for us:
const axios = require("axios");
slackEvents.on("message", async (event) => {
if (event.text && event.text.includes("https://open.spotify.com/track")) {
try {
const response = await axios({
url: `${SPOTIFY_SERVER_URL}/playlist`,
method: "post",
data: {
song: event.text,
},
});
console.log("Successfully added song", response.status, response.statusText);
} catch (error) {
console.log("Error adding song", error);
}
}
});
The code above listens for the message
event from Slack. If the message body contains a Spotify URL then it makes a request to the Spotify server we created in Part 1.
Restart the server and run ngrok
on both ports:
nodemon src/slack/index.js
ngrok http 4000
ngrok http 5000
Copy the ngrok
URL for port 4000 and add it to the Slack app Event Subscriptions configuration we set up in the previous section.
If you have your Spotify app running and the Slack app added to a channel, sending a Spotify URL should now add the song to a playlist.
Summary
That’s it! We have seen how we can set up a Slack app which listens slash commands and event subscriptions. Using the command we were able to hit a Spotify server we wrote previously to create a playlist. Our Slack server listens to messages so when a Spotify song gets messaged we can hit our Spotify server again with a request to add that song to the playlist.