Slack Ruby App. Part 3. Hanging out with a guest like Heroku

Hey readers, this is the third part of the tutorial posts on writing a Slack App using pure Ruby (actually not completely pure, as it turns out).

If you are not familiar with the parts list, here it is (with links):

  1. Writing an application locally via Sinatra and ngrok.

  2. Adding charts or how to render the front on the server.

  3. Hanging out with a guest like Heroku (We’re here).

The state of affairs is such that now the bot is hanging on the local server, I start it manually. The guys from my workspace can use the bot’s functions when it is turned on, no problem with that.

The problem or disadvantage is that the bot is available 24/7. How can you use something if it has ambiguous availability. For example, you go out in the morning on a minibus and you don’t know for sure whether it will be or not. Then, probably, you will choose a different transport for movement; something more reliable.

By shifting responsibility for your application online as much as possible, you will be able to focus on other tasks, think more about new features and new applications. After all, just try to imagine how you start to raise 20 bots on your poor Lenovo in the morning in the hope that today neither the light nor the Internet will turn off? Introduced? Now imagine if 20 bots are hanging on the server and you come in in the morning to see their status using a convenient dashboard. So the 21st application will be just around the corner 🙂

I understand, everything sounds so cool, but you object, but why throw money on the server? It seems to you that your bot is only interesting to you, why spend money. And if I say that there is a service, free, high-quality, functional, which at first seems complicated, but like everything is complicated, you just need to understand it and become a simple and excellent helper.

It looks like a $ 50 promo, but in reality I was only amazed by the fact that if you go to prices, then there is a Hobby section. This is the first time in my memory when the service is free to support the beginnings of developers, and then, when the idea turns out to be workable, you can immediately increase the capabilities of your service. Only for this you can already read on, right?

Step 1: Create an application on Heroku

We go by address… We register. Click New -> Create new app (Figure 1).

Figure 1: Heroku Dashboard
Figure 1: Heroku Dashboard

Enter the name of your application (don’t bother too much about how it will be called, it’s just an identifier among your other applications in this service).

On the next tab, we are interested in the Deployment methods block (Figure 2), select Heroku Git.

Figure 2: Deployment methods
Figure 2: Deployment methods

After the selection, the instructions for the corresponding method of unloading our application will be loaded below (Figure 3):

Figure 3: Uploading via Heroku Git
Figure 3: Uploading via Heroku Git

Actually, now we will execute these commands.

Step 2: Uploading the application to Heroku

We open the terminal and follow the path to our project, which we are going to unload. In my case, I’m using RubyMine, so the terminal in the IDE is already open at the project address.

Actually, we execute commands from top -> down.

  • heroku login -> a window will open in your browser, after authorization in the console, a message about this will appear.

  • If you have not yet created a git repository in the root of the project, then create it, I already have it, so I will skip the commands for creating it

  • Add a link to the heroku-git repository heroku git:remote -a habr-one-love

  • Add all the files, commit and push to this repository.

Push may take some time, because now, for your application, heroku has created a GitHub action, and for each push to the master branch, it will build and run your application. In order not to sit and look at the screen, waiting for the push to end, let’s move on to getting to know the heroku commands.

Step 3: The Basics You Need To Work With Our Application

  1. To send any changes to heroku, you need to push through git. It will not be better in another way, this is the most convenient method available. We test on LAN, push – we see on the dev server.

  2. Commands that can be useful more often than others:

    • heroku logs --tail - отобразит лог событий с твоим приложением в терминале (консоли).
      These events can be viewed through the Heroku Dashboard on the website. To do this, follow the link to list of applications and select your application. Click More-> View logs (Figure 4).

      Figure 4: Inside a Heroku Application
      Figure 4: Inside a Heroku Application
    • heroku local - для запуска приложения локально, используя список команд указаных в Procfile (создадим ниже).
      Optionally, you can specify which process you want to start, by default it is web.

  3. Procfile – this is a file-list of commands that will be executed when your application starts.

  4. `Dyno` – processes that are described in Procfile

  5. `Adds-on` – additional software, for example – PostgreSQL is installed by default.

  6. `Buildpacks` – scripts that will be executed during the build phase of the application, that is, every time you push, but before the Procfile. We are interested in two buildpacks – ruby ​​and chrome headless. Since by default there is no ruby ​​or a browser on the server.

Step 4: Configuring Procfile

Add the file to the root of the project, name it, guess what …. Procfile. We write one command there:

web rackup config.ru -p ${PORT:-5000}

With this command, we will launch our application.

Step 5: add the ENV

heroku config

This command will show you what environment variables are currently available for the application. We need to add the variables here that are currently in the `env` file. To do this, use the following command:

heroku config:set ключ=значение

For example :

heroku config:set SLACK_CLIENT_ID=123456789000.1123555869121

Using the same process, add all the environment variables:

  • SLACK_CLIENT_ID

  • SLACK_API_SECRET

  • SLACK_VERIFICATION_TOKEN

  • SLACK_REDIRECT_URI

To get SLACK_REDIRECT_URI, we need to find out the address of the application. To find it out, go to the Dashboard (Figure 4) and click Open App. In the tab that opens, copy the address, this is the address of the application. Add /finish_auth
and here it is our redirect uri.

After filling in all the keys, we can remove the `env.rb` (also remove the require of this file in the code), now our sensetive data is stored safely!

Step 5: Updating Database Data

Now our database will not be local, but stored on Amazon AWS via Heroku. Let’s change the data for accessing this database. Go to the file `Database.rb` in the init function.

How do I find the values ​​of the new database?

  1. Go to the Heroku Dashboard;

  2. Adds-on block;

  3. Choosing Heroku Postgres;

  4. Click on:

  5. Adds-on will open (Figure 5);

    Figure 5: Adds-on Information
    Figure 5: Adds-on Information
  6. Go to the Settings tab;

  7. Click View Credentials.

While writing this post, I had an idea to write this data to Heroku Config so as not to store access in the code.

Replace all parameters in the init function with:

  def init
    @db = PG.connect(
        host: ENV['HU_POSTGRES_HOST'],
        dbname: ENV['HU_POSTGRES_DBNAME'],
        user: ENV['HU_USER_USER_ENV'],
        password: ENV['HU_POSTGRES_PASS']
    )
  end

And add them, by analogy with the variables for the Slack API, using access to the database from Heroku.

Step 6: Verify Deploy and Connect Slack

Pushing changes to heroku. We look at the log, see the picture as in Figure 6. If everything is so, then you, like me, did everything right!

Figure 6. High-quality log
Figure 6. High-quality log

Since the bot address has changed from localhost, then you need to go to the application settings in Slack API and there change the address wherever possible. For convenience, I will write out a list of potential locations:

Remind, address your application can receive by using Heroku Dashboard!

We reinstall the application to create a table with accesses in the new database.

Also, I rewrote the database module for my application, what exactly changed can be found in these commits: main, fix, fix

Now commit + push to Heroku again.

We go into the slack and write the command that we created earlier:

/who_am_i
Figure 7. The answer we deserve!
Figure 7. The answer we deserve!

If your result coincides with the result in Figure 7 – congratulations! You have successfully hosted your application on Heroku!

Step 7: technical details of my application

In the last lesson, I looked at how to render the front on the server, but I did it on a local machine, where the binaries for the browser already exist. What about a real server? They are not there by definition, but you can add them 🙂

I’ll show you how to do this using Heroku Buildpacks.

  1. We go to the control panel of the Heroku application.

  2. Select the Settings tab.

  3. There we are looking for the Buildpacks block (Figure 8)

    Figure 8. Buidpacks in the Settings Menu
    Figure 8. Buidpacks in the Settings Menu
  4. Click on Add buildpack.

  5. Enter the URL: https://buildpack-registry.s3.amazonaws.com/buildpacks/heroku/google-chrome.tgz

That’s it, now, with the next build, we will have a new buildpack loaded, in which the google-chrome core will be installed.

Now you need to slightly tweak the code itself for rendering the graph so that it finds the file of this browser, in the commands.rb file:

 browser = Ferrum::Browser.new(
        :browser_path => "/app/.apt/usr/bin/google-chrome"
    )

in the same file, change the GET request to the graph screen, from this:

get '/graph_image.png' do
    send_file 'Components/Graph/result.png'
  end

to this:

  get %r{/graph_image/(?<ts>w+)} do
    send_file "/app/#{params[:ts]}_graph.png"
  end

The idea is to sign each screen with a timestamp when it is created, and not overwrite the same file. In addition, the path to the file has changed, because Heroku cannot save the file the way it was saved before. Let’s change the process of saving a screenshot to this form:

    graph_ts = Time.now.to_i
    browser.screenshot(path: "/app/#{graph_ts}_graph.png")

Let’s also change the template itself:

{
  "type": "modal",
  "title": {
    "type": "plain_text",
    "text": "Граф"
  },
  "blocks": [
    {
      "type": "https://habr.com/ru/post/586488/image",
      "image_url": "http://<%= host %>/graph_image/<%= graph_ts %>",
      "alt_text": "Сер Граф"
    }
  ]
}

These changes are described in the commits 1,2 and 3

Commit and push to Heroku! From now on, the build of the application will take longer due to the new buildpack.

Now you can go to the Slack workspace and write / graph.

If everything is done correctly, then we will get the answer we expected!

results

After successfully completing all the stages, you, like me, should receive:

  • An attachment uploaded to Heroku that can communicate with the Slack API, render html and just be online 24/7.

  • Environment variables are now in a safer place.

  • The database module has been rewritten into a class and can now create databases based on dynamic functions (sounds like something special, but I don’t know what else to call it, whoever looked at the commits will understand).

  • The functionality of receiving charts has been updated.

We can summarize the successful passage of a series of 3 articles on developing a Slack Ruby bot on Sinatra, which successfully runs on Heroku and has functionality for working with Google Chrome Headless, Slack Modals and Slack Slash Commands. In addition, he can add and maintain multiple users.

From now on, you yourself will already have the necessary skills for the further development of this application, but if you are interested in my articles and this topic, I can continue to describe interesting technologies and solutions that I will come across in the future. Now, by the way, there is material for writing such articles:

  • Refactoring a real application to Ruby on Rails, as Sinatra already creates more inconvenience than convenience.

  • Add and configure Home Page for Slack App.

  • Slack App integration with Jira for auto-tracking time by tasks.

Link to Git repositorywho you like – put stars, I tried and this is the best way to support me!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *