My friend nudged me to build a Slack app that shares what's currently playing on Spotify to Slack channel. For a couple of days, I have put the finishing touches on it from nothing.
This is my first time the Slack app built it done having in public although I had some for private workspace before. Only developing it is not enough you ought to submit it to Slack App Directory. Once passed it you would have completed done it.
I'm writing about how to start off building a Slack app on Ruby on Rails and end up it has been in Slack App Directory.
This slack app requires Slack and Spotify authentication and then notify the song information when users start playing on Spotify to the channel they set up on the app. It's simple. I don't write about how to use Spotify API here but they don't have webhook so I get this information once per 10 minutes.
Let the building begin
- Register Slack app
- Develop Rails app
- Submit the app
- Let it list on Slack App Directory
Register Slack app
Before building, you have to set up your own Slack workspace. I don't know so much about it but the app might be deleted at the same time the workspace has been deleted.
Go to Slack API for registering the application. Only you have to set up is below.
- Take a note
Client ID
andClient Secret
on App Credentials - Add
redirect URL
to Permissions - Add
channels:read
andchat:write:bot
to scope on Permissions
Develop Rails app
Add an authentication
Build authentication with a famous gem omniauth
. Installed it and then set up on omniauth.rb
.
gem 'omniauth'
gem 'omniauth-slack'
Rails.application.config.middleware.use OmniAuth::Builder do
provider :slack,
Rails.application.credentials[:slack][:consumer_id],
Rails.application.credentials[:slack][:consumer_secret],
scope: 'channels:read,chat:write:bot'
end
Add Session controller
Develop sessions that users can sign in with Slack and sign out it. You should prepare sessions controller
and user model
.
$ rails g controller sessions new destroy
$ rails g model Users name email provider uid token channel
Don't forget to add the column of uid, token, and channel for Slack authentication data here.
class SessionsController < ApplicationController
def create
user = User.from_omniauth(request.env["omniauth.auth"])
if user.save
session[:user_id] = user.id
redirect_to root_path
else
redirect_to root_path
end
end
def destroy
session[:user_id] = nil
redirect_to root_path
end
end
class User < ApplicationRecord
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_initialize.tap do |user|
user.name = auth.info.name
user.email = auth.info.email
user.token = auth.credentials.token
return user
end
end
end
Rails.application.routes.draw do
get 'auth/:provider/callback', to: 'sessions#create'
get 'auth/failure', to: redirect('/')
get 'signout', to: 'sessions#destroy', as: 'signout'
resources :sessions, only: [:create, :destroy]
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
You can see the below screen on /auth/slack
. And I wish you can create User data with Slack authentication.
Install Slack Ruby Client
Recommend you to continue to develop with slack-ruby-client
. It's a ruby and command-line client for the Slack Web, Real-Time Messaging and Event APIs.
gem 'slack-ruby-client'
Create Slack Ruby Client
Create the model that gets some through Slack API.
class Manager::SlackApiClient
attr_reader :client, :slack_user
def initialize(slack_user)
@slack_user = slack_user
@client = Slack::Web::Client.new(token: slack_user.token)
@client.auth_test
rescue => e
Rails.logger.warn(<<~LOG)
Error @Manager::SlackApiClient#initialize
Msg: #{e.class} #{e.message}
LOG
@client = nil
end
def valid?
client
end
end
end
Get channels info
The app should allow users to choose a channel that they get notified.
def channels
client.channels_list.channels
end
class SettingsController < ApplicationController
def index
@user = current_user
client_manager = Manager::SlackApiClient.new(@user)
if client_manager.valid?
@slack_channels = client_manager.channels
else
flash[:danger] = 'Slack token expired. Please link Slack app again.'
end
end
end
Send notifications when playing
The app should send notifications when users start playing on Spotify. This requires information like song name, URL, artist name and album name.
slack_client_manager = Manager::SlackApiClient.new(user)
slack_client_manager.post_song_message(@current_playing) if slack_client_manager.valid?
def post_song_message(song)
attachments = {
text: "🎧 #{song.user.name} is currently playing #{song.name}",
"fields": [
{
"title": "Artist",
"value": song.artist,
"short": true
},
{
"title": "Album",
"value": song.album,
"short": true
},
{
"title": "Spotify url",
"value": song.url,
"short": false
}
],
color: "#f9da00"
}
client.chat_postMessage(channel: "##{slack_user.channel}", attachments: [attachments])
end
You can arrange what kind of notification content you send. Only text is easy to build it and you can add some features when you build with attachments
. Please check it here.
Okay, That's all. All you have to do left to submit the app to Slack App Directory.
Submit the app
You don't have to submit the app as long as your app is used on your workspace. But Slack requires some tests and reviews before you have it for the public.
Go to Manage distribution
. You have to agree with some terms and check if the app works under the configuration Sack defines. If your app requires the other party, you supposed to write about its authentication information.
It takes you a few days to pass the review. In my experience, this review is not easy. They're careful that the app would work well.
Let it list on Slack App Directory
Done. You would be glad if the app you built listed on Slack App Directory.
Top comments (1)