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
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
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
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)
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 !
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 :)
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 !
Hey Richy,
Thanks for the details!
Our dev team will look into this and we'll get back to you.
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.
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 ?
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!
Again, thank you so much, can't wait to see it !
Hi, just a reminder that I'm still very interested to get more instructions to install the bot !