Slack Integration
💬

Slack Integration

Created
Apr 8, 2022 8:13 AM
Department
Engineering
Category
Well Documented
Technology
slack
Tags
Date
URL

Creating a Slackbot for posting messages in channels

Register your Slack app

  1. Before registering your slack app create a workspace in Slack which we'll use to test the app when we develop it
  2. Go to https://api.slack.com/apps and sign in.
  3. On this page click on Create New App CTA and select From Scratch option. After that, you'll see this form. Input the Name and select the test workspace from the dropdown and click Create App CTA.
  4. image
  5. You'll land on the Admin Panel of the newly created slack app. On this page, you'll be able to see the App Credentials and other options such as Display Information.
  6. Scroll down to the Install your app section. Here the Install to Workspace CTA will be disabled with the note Please add at least one feature or permission scope to install your app. We need to give the app some permission before we can install the app in our workspace.
  7. image

  1. Click on the permission scope hyperlink. And scroll down to the Scopes section. Hereunder Bot Token Scopes click on Add an OAuth Scope. This drop-down menu contains all the actions that the app can perform at a bot level. From the dropdown menu select the chat:write option and that permission will be added to the app.
  2. image
  3. After adding the scope, scroll up and you'll see Install to Workspace CTA which now is enabled. Click on it to install it in the workspace.
  4. After the installation is complete, you can see the app installed on the workspace under the Apps section. Also on the Admin Panel, you'll see the bot token field. We'll need this token to configure the app in our code. Copy this code and put it in the credentials file or environment variables.
  5. image
  6. We also have to add this app to the channel where we want to post the messages otherwise when we'll try to send the message, the Slack Client in the code will throw an error.
  7. Every slack request need to be verified, something like this
  8. image
  9. If an OAuth scope was added to a bot token earlier, and you no longer require it, then removing the scope from our App's OAuth client won't help, the token(Slack API) itself needs to be revoked, then only the scope will get removed from the token. Because if we submit the app for review from slack it won't get approved, because there will be a mismatch in scope
  10. image

Integrate the slack app in Ruby on Rails

  1. In your GemFile add and Bundle Install.
  2.  gem 'slack-ruby-client'
  3. Create a new concern which will contain the code for integrating the app.
  4. In this file write a method where we will
  5. Create a Slack Client and configure it with the bot token
  6. Do an auth_test
  7. Post the message in a channel with a payload.
  8. def self.send_message_on_slack_channel(payload, channel)
    	client = Slack::Web::Client.new(token:Rails.application.credentials[Rails.env.to_sym][:slack_token])
    	client.auth_test
    	client.chat_postMessage(channel:channel, text:'New message from Your app', blocks:payload, as_user:true)
    end

    When this method is executed the Slack client will post a message that is defined in the payload with the notification appearing as " New message from Your app" in the channel that will be passed.

Design the payload with Block Kit

  1. To create the message we use something called Block Kit, you can read more about Block Kit here - https://app.slack.com/block-kit.
  2. Go to https://app.slack.com/block-kit-builder and sign in if not automatically didn't. The Block Kit editor will open up where you can design your payload.
  3. After designing the message copy the payload from the editor
  4. image

Write a method to format the payload

  1. The copied message payload from the previous step needs to be formatted by replacing the static placeholder data with dynamic content.
  2. One key thing to remember is to remove the " blocks" key from the payload.
  3. Create a method that will format the payload and call the send_message_on_slack_channel which will send the message.
  4. Below is an example from the project Gehna.

    def post_order_created_message
    	payload = [
    		{
    			"type": "section",
          "text": {
    	      "type": "mrkdwn",
            "text": ":memo: New order received!  <@#{Rails.application.credentials[Rails.env.to_sym][:vineeth_slack_id]}>, <@#{Rails.application.credentials[Rails.env.to_sym][:padma_slack_id]}>"
          }
        },
        {
          "type": "section",
          "fields": [
            {
    	        "type": "mrkdwn",
    	        "text": "*Order ID:*\nGEH-#{self.id}"
            },
            {
    	        "type": "mrkdwn",
              "text": "*Date:*\n#{self.created_at.localtime.strftime("%d %B %Y, %A, %I:%M %p")}"
            },
    				{
    					"type": "mrkdwn",
    					"text": "*Client Name:*\n#{self.client.client_name}"
    				},
            {
    					"type": "mrkdwn",
    					"text": "*Total Value:*\n ₹#{self.sub_total.to_s}"
    				},
    				{
    					"type": "mrkdwn",
    					"text": "*Payment Type:*\n #{self.payment_modes}"
    				},
    				{
    					"type": "mrkdwn",
    					"text": "*POS:*\n #{self.point_of_sale.name}"
    				}
    			]
    		},
    		{
    			"type": "section",
    			"fields": [
    				{
    					"type": "mrkdwn",
    					"text": "*Items:*\n #{self.order_items_list_with_link}"
    				}
    			]
    		},
    		{
    			"type": "actions",
    			"elements": [
    				{
    					"type": "button",
    					"text": {
    						"type": "plain_text",
    						"emoji": true,
    						"text": "View Order"
    					},
    					"style": "primary",
    						"url": "#{Rails.application.credentials[Rails.env.to_sym][:admin_panel_url]}/orders/#{self.id}"
    				}
    			]
    		}
    	]
    
    	GehnaSlackApp.send_message_on_slack_channel(payload, "#gehna-website-orders")
    
    end

    Note: It's advisable to call the post_order_created_messageusing a background job.

  5. When the above method is run, it'll pass the formatted payload and the channel name to send_message_on_slack_channel method, which will send the message to the slack channel

Event Subscriptions and Interactions -

  • Events - Reference
    • Events are basically any event occurring on the slack app like clicking the home tab, a user gets added to the team, the user making changes to his details, etc.,
    • For events, we should provide a post request URL to slack, in which the slack will send a challenge parameter and in response, we should provide the challenge value. IF the URL isn't able to respond to the challenge parameter, the URL won't get approved by slack.
    • As per any event occurrence, we can handle the actions in our platform with the payload response provided by slack.
    • There are scopes for Bot and User events, we can subscribe to respective events as per our requirement
    • image
      image
  • Interactivity & Shortcuts - Reference
    • Interactions are any user interactions with the slack app like clicking buttons, opening modals, or with any other interactive components.
    • We have to define a Post request URL in slack for these kinds of interactions
    • There are multiple interactions with slack like Shortcuts, Block actions, View submissions, View closed, etc..,
    • On any interaction with the application, we must provide an acknowledgment response (HTTP Post 200) to slack and this should be provided within 3 seconds.
    • Some interactions can lead to multiple simultaneous interactions. For these kinds of interactions, we can use a response_url which was provided on the response of every slack request. This URL will be unique for every request. We can post a response(Block kit) to this URL.
    • If response_url is not present, every interaction response will contain a variable called trigger_id. We can use this trigger_id in params while posting back our response to slack. Using this we can replace messages, modals, dropdowns, etc.., These responses can be sent up to 5 times within 30 minutes of receiving the payload.
    • While the interactions if we want to send and get data through the block kit, we can use a parameter called private_metadata in the view section of the block kit.
    • Shortcuts - We can create custom shortcuts with callback_id for the reference of what kind of shortcut that is. While any shortcut is being triggered, slack will send a request with that callback_id with the response type as shortcuts and we can carry out actions from there.
    • Block actions - This interaction occurs while any interactive element is being triggered Ex., Dropdowns, Buttons. In every block element, we can define a custom action_id from which we can get what kind of the action is being called. And in response, we can provide a block kit response to slack which we desire.

Slash Commands -

  1. Slash commands are similar to shortcuts. But every command will require a unique request URL.
  2. We can define the command, request URL, and description in the application.
  3. While any command was being triggered slack will hit the respective request URLs. From there we can carry out our actions.

Deploying the app

  1. After the tests are done all we have to do is create another app using the actual workspace by repeating the above steps.
  2. The bot token that's generated has to be placed inside the credentials or environment variables so appropriate slack channels are used for different environments.