DEV Community

Shun Yamada
Shun Yamada

Posted on

How to publish Slack app using Rails

Alt Text

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

  1. Register Slack app
  2. Develop Rails app
  3. Submit the app
  4. 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 and Client Secret on App Credentials
  • Add redirect URL to Permissions
  • Add channels:read and chat:write:bot to scope on Permissions

Alt Text

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'
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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  
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

You can see the below screen on /auth/slack. And I wish you can create User data with Slack authentication.

Alt Text

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'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Get channels info

The app should allow users to choose a channel that they get notified.

 def channels
   client.channels_list.channels
 end
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

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?
Enter fullscreen mode Exit fullscreen mode
  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
Enter fullscreen mode Exit fullscreen mode

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.

Alt Text

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.

Alt Text

Let it list on Slack App Directory

Done. You would be glad if the app you built listed on Slack App Directory.

Alt Text

Top comments (1)