3 min read

There are many ways you can customize your Slack program, but with a little bit of programming you can create things that can provide you with all sorts of productivity-enhancing options. In this post, you are going to learn how to use Python to create a custom progress bar that will run in your very own Slack channel. You can use this progress bar in so many different ways. We won’t get into the specifics beyond the progress bar, but one idea would be to use it to broadcast the progress of a to-do list in Trello. That is something that is easy to set up in Slack.

Let’s get started.

Real-time notifications are a great way to follow along with the events of the day. For ever-changing and long-running events though, a stream of update messages quickly becomes spammy and overwhelming. If you make a typo in a sent message, or want to append additional details, you know that you can go back and edit it without sending a new chat(and subsequently a new notification for those in the channel); so why can’t your bot friends do the same? As you may have guessed by now, they can!

This program will make use of Slack’s chat.update method to create a dynamic progress bar with just one single-line message.

Save the below script to a file namedprogress.py, updating the SLACK_TOKEN and SLACK_CHANNEL variables at the top with your configured token and desired channel name.

from time import sleep
from slacker import Slacker
from random importrandint

SLACK_TOKEN = '<token>'
SLACK_CHANNEL = '#general'

classSlackSimpleProgress(object):
def__init__(self, slack_token, slack_channel):
self.slack = Slacker(slack_token)
self.channel = slack_channel

        res = self.slack.chat.post_message(self.channel, self.make_bar(0))
self.msg_ts = res.body['ts']
self.channel_id = res.body['channel']

def update(self, percent_done):
self.slack.chat.update(self.channel_id, self.msg_ts,
self.make_bar(percent_done))

@staticmethod
defmake_bar(percent_done): 
return'%s%s%%' % ((round(percent_done / 5) * chr(9608)), percent_done)

if__name__ == '__main__':
progress_bar = SlackSimpleProgress(SLACK_TOKEN, SLACK_CHANNEL) # initialize the progress bar
percent_complete = 1
whilepercent_complete<100:
progress.update(percent_complete)
percent_complete += randint(1,10)
        sleep(1)
progress_bar.update(100)

Run the script with a simple python progress.py and, like magic, your progress bar will appear in the channel, updating at regular intervals until completion:

 

How It Works

In the last six lines of the script:

  • A progress bar is initially created with SlackSimpleProgress.
  • The update method is used to refresh the current position of the bar once a second.
  • percent_complete is slowly incremented by a random amount using Python’s random.randint.
  • We set the progress bar to 100% when completed.

Extending

With the basic usage down, the same script can be updated to serve a real purpose. Say we’re copying a large amount of files between directories for a backup—we’ll replace the __main__ part of the script with:

importos
import sys
importshutil

src_path = sys.argv[0]
dest_path = sys.argv[1]
all_files = next(os.walk('/usr/lib'))[2]

progress_bar = SlackSimpleProgress(SLACK_TOKEN, SLACK_CHANNEL) # initialize the progress bar
files_copied = 0
forfile in all_files:
src_file = '%s/%s' % (src_path, file)
dest_file = '%s/%s' % (dest_path, file)
print('copying %s to %s' % (src_file, dest_file)) # print the file being copied
shutil.copy2(src_file, dest_file)
files_copied += 1# increment files copied
percent_done = files_copied / len(all_files) * 100# calculate percent done
progress_bar.update(percent_done)

The script can now be run with two arguments: python progress.py /path/to/files /path/to/destination. You’ll see the name of each file copied in the output of the script, and your teammates will be able to follow along with the status of the copy as it progresses in your Slack channel!

I hope you find many uses for ways to implement this progress bar in Slack!

About the author

Bradley Cicenas is a New York City-based infrastructure engineer with an affinity for microservices, systems design, data science, and stoops.

LEAVE A REPLY

Please enter your comment!
Please enter your name here