DEV Community

Cover image for How We Built a Slack Bot for Time Tracking with Ruby on Rails and Vue.js
Codica
Codica

Posted on • Updated on • Originally published at codica.com

How We Built a Slack Bot for Time Tracking with Ruby on Rails and Vue.js

This article was originally published on Codica Blog.

In this article, we want to tell you about our internal time-tracking solution or how we simplified massive routine processes.

Now, this time-tracking chatbot gives us an opportunity to verify and keep in check the company’s development workflow and specify each member performance.

Let’s get started and see how we developed so-called Timebot and what advantages it gives to our dev team.

The challenge

At Codica, we use Slack to deliberate various project issues. And the Slack App provides an opportunity to create a chatbot and thus an idea emerged: Why not to create a time-tracking Slack bot?

Alongside, another part of the reason to build such a tool using Slack was that web solutions are pretty time-consuming. We had an idea to create a more efficient and tailored option for time-tracking.

The solution

Goals

At the very beginning, our primary goal was to meet the following requirements:

  • Streamline the tracking process for the team
  • Provide comprehensive and effective reports to our customers automatically
  • Provide the opportunity to clearly assess the overall workload
  • Record each corporate’s employee contribution to the projects

After several discussions, we came to the realization that the following list of features will help us achieve the determined goals:

  • Time tracking
  • Transparent reporting system
  • Bundling with Trello
  • Administration panel

Development

1. Defining the technology stack

After considering the required functionality, we turned to technical implementation. For development purposes, we have created two applications:

We have chosen the following tools for Slack bot development:

  • Rails 5
  • Ruby 2.4
  • PostgreSQL

And these tools were used during the development of the Admin panel:

  • Vue
  • Vue-router
  • Vuex
  • Vue-element-admin (admin panel template)
  • JWT (JSON Web Token)

2. Bot creation and integration

Firstly, we got through the process of Bot creation at Slack API following the prompts. There, you specify your workspace, define Bot’s name, upload or choose the profile image and get a special API token.

Then, in order to manage API for our Timebot, we have used Slack Ruby Client to adopt the special interface.

Thus, we have inserted the Slack API token into the .env file as follows:

Slack.configure do |config|
  config.token = ENV['SLACK_API_TOKEN']
End
Enter fullscreen mode Exit fullscreen mode

Thus, we have integrated Slack API and now we can configure our Timebot.

3. Creating the list of commands

When the Slack Bot was ready for configuration, we have turned to create the available commands. All of them were created through if..else conditional statements. Here are some commands from the list:

Commands Description
Help print help.
Projects print all available projects.
find project SEARCH_QUERY find a specific project.
PROJECT_NAME HOURS:MINUTES COMMENT log time
/logtime log time via interactive dialogue.
edit NEW_DATE(OPTIONAL) TIME_ENTRY_ID HOURS:MINUTES COMMENT edit an existing time entry.
update(OPTIONAL) DAY.MONTH.YEAR PROJECT_NAME HOURS:MINUTES COMMENT create an entry for the specific date.
add project PROJECT_NAME add a new project.
show day/show week/show month get a report for this day/week/month.
show absence/show absence last year display absences.

Every team member has a special ID to be identified by the Slack bot. When a user enters a command, the bot checks whether it’s a valid command.

Initially, we’ve defined the Event Handler:

class EventHandler
 include Message::Conditions
 include Message::Logger

 attr_reader :client, :data, :sender, :messages, :public_channels

 def initialize(client, data, messages, public_channels)
   @client          = client
   @data            = data
   @public_channels = public_channels
   @sender          = Message::Sender.new
   @messages        = messages
 end

 def handle_message
   return if message_is_not_processable
   user = User.find_by(uid: data.user)
   log_incoming_message(user, data.text)
   if message_is_enter_time
     CreateEntry.call(user, data.text, messages)
   elsif message_is_specify_project
     SpecifyProject.call(user, data.text, messages)
   elsif message_is_request_for_help
     ShowHelp.call(user)
   elsif message_is_remove_entry
     RemoveEntry.call(user, data.text)
   elsif message_is_show_reports
     ShowReport.call(user, data.text)
   elsif message_is_enter_time_for_day
     CreateEntryForDay.call(user, data.text)
   elsif message_is_request_for_project
     ShowProjects.call(user)
...
   else
     DoNotUnderstand.call(user, messages)
   end
 end
End
Enter fullscreen mode Exit fullscreen mode

Next, we’ve defined Classes for every bot’s command, for example:

class AddProject < BaseService
 include ServiceHelper

 attr_reader :user, :text

 def initialize(user, text)
   @user = user
   @text = text
   super()
 end

 def call
   project_name = text.match(Message::Conditions::ADD_PROJECT_REGEXP)[1]
   project = find_project_by_name(project_name)

   if project
     sender.send_message(user, "Project with name #{project.name} already exists.")
     return
   end

   if project_name.length < Project::MINIMUM_PROJECT_NAME_LENGTH
     text = "Project name is too short - must be at least #{Project::MINIMUM_PROJECT_NAME_LENGTH} characters."
     sender.send_message(user, text)
     return
   end

   project = Project.create!(name: project_name)
   sender.send_message(user, "Project with name #{project.name} is created.")
 end
end
Enter fullscreen mode Exit fullscreen mode

We have a possiblity to create new commands at any moment.

Examples of our Timebot workflow

Time tracking gives an opportunity to monitor the number of hours spent on a particular task. This data is available on each employee’s timesheet, which can be viewed and edited.

To add a new time record, you need to enter the project name, time spent for a specific task, and add comments to specify the details.

Absences give an opportunity to track members’ vacation, illnesses, and other reasons for absence.

Reports are developed in order to gather particular data for future statistics and analysis generation.

Projects are defined to let the users track, add, and use the project for time logging.

What we achieved

To summarize, we have presented you how we developed a SlackBot and we believe this guide will be valuable and useful for you and your business.

Here is the list of some of the features and process improvements that our SlackBot brings:

  • Efficient time-tracking tool
  • Tracking both work hours and absences (vacation, sick leave)
  • Notifications with a meeting time that pops up in 10 minutes before the meeting
  • Overall picture of the performance and velocity of the whole company

To read the full list of features, please check our article: Building a Slack Bot for Internal Time Tracking.

Top comments (9)

Collapse
 
richardisred profile image
Richy

Hi, I'm looking to install timebot for my team and followed all the instructions but I did not manage to make it work. Would it be possible to maybe release a video or a more detailed task list for beginners to manage installing the bot? Thank you for your impressive work, hope to get in touch !

Collapse
 
codicacom profile image
Codica

Hi Richy!

Thanks for your interest and feedback!

Can you tell us more about what issues you have? We need more details to be able to help. Have you followed our tutorial? (github.com/codica2/timebot#how-to-...)

We can create a more detailed guide, just need to know which part of the process causes difficulties.

Please let us know :)

Collapse
 
richardisred profile image
Richy • Edited

Thank you so much for your answer.

I have indeed followed the instructions. I tried to install the bot on Heroku. I successfully deployed the code from github, but I don't know where to fetch the "slack_token". Is it the same as the bot token (TIMEBOT_APP_TOKEN=slack_timebot_app_token)?

Once I have set all the variables correctly in the .env file and created the app + bot on slack, am I supposed to do something else to connect everything?

Regarding the interactive components, I can see that I am supposed to write "your_domain_name.com/api/v1/slack/..." in the URL field. Does it mean that I have to do something on Heroku ? or should I just write "https://(myheroku).com/api/v1/slack/submission"?

As you understood, I think a step by step tutorial specifically made for Heroku would be super helpful.

Thank you again !

Thread Thread
 
codicacom profile image
Codica

Hey Richy,

Thanks for the details!

Our dev team will look into this and we'll get back to you.

Thread Thread
 
codicacom profile image
Codica • Edited

Hey!

There have been changes to Slack API, this is why you have troubles.

Here's how you can make it work:

Step 1. Add this file in your project: config/secrets.yml
production:
secret_key_base: <%= ENV['SECRET_KEY'] %>

Step 2. Considering your question: "I don't know where to fetch the "slack_token". Is it the same as the bot token (TIMEBOT_APP_TOKEN=slack_timebot_app_token)?"
Yes, you are right.

Because of changes to Slack API, now you need to get it like this: github.com/slack-ruby/slack-ruby-c...

Step 3. Clone the project github.com/codica2/vue-timebot

In config/dev.env.js fill BASE_API with your Heroku app URL.
Run 'yarn' && 'yarn dev'.

Step 4. Create new admin via heroku console (Admin.create(email: 'your_email', password: 'your_password')).

Please let us know of the result :)

P.S. We are planning to create an updated version considering all the changes with Slack API, however, we don't have a timeline for this at the moment.

Thread Thread
 
richardisred profile image
Richy • Edited

Thank you so much for your answer. Unfortunately I did not manage to make it work... The command still doesn't work on slack, I am making a mistake at some point.

Would you consider making a full step-by-step tutorial including those new instructions ?

Thread Thread
 
codicacom profile image
Codica

Sorry to hear that!

Okay, we'll make a tutorial considering all the changes, however, this will take time - we don't have free resources at the moment.

We would say, this can take at least a couple of weeks.

Will keep you updated!

Thread Thread
 
richardisred profile image
Richy

Again, thank you so much, can't wait to see it !

Thread Thread
 
richardisred profile image
Richy

Hi, just a reminder that I'm still very interested to get more instructions to install the bot !