Creating a bot for slack

Slack is one of the coolest and most versatile IM platforms available today, we use it all the time here at Devecoop as our primary channel for communication. One of the greatest things it has, is its integration capabilities with 3rd part services (i.e.: twitter, github, bitbucket, circleci, etc), that can be exploited right out of the box, without too much hussle. On this opportunity I will show you how you can create your own bot, using Slack's outgoing webhooks feature.

Lets get to work.

As all we need on our side is a small webserver , listening to requests from slack, we are going to start writing it using Python and its BaseHTTPServer module

  1. #!/usr/bin/python
  2.  
  3. import cgi
  4. import io
  5. from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
  6.  
  7. PORT_NUMBER = 3000
  8.  
  9. class SlackBotHandler(BaseHTTPRequestHandler):
  10. def do_something(self, text):
  11. with io.open('slacklog.txt', 'a') as file:
  12. file.write(text + "\n")
  13.  
  14. def do_POST(self):
  15. content_len = int(self.headers.getheader('content-length', 0))
  16. post_body = self.rfile.read(content_len)
  17. try:
  18. postvars = cgi.parse_qs(post_body, keep_blank_values=1)
  19. user_name = postvars.get('user_name')[0]
  20. text = postvars.get('text')[0]
  21. text = text.strip("!save <").rstrip(">")
  22.  
  23. self.send_response(200)
  24. self.send_header('Content-type','text/html')
  25. self.end_headers()
  26. self.do_something(text)
  27.  
  28. payload = '{"text" : "Your data has been save %s!"}' % user_name;
  29. except:
  30. payload = '{"text" : "Sorry %s Could not save your data!}' % user_name;
  31.  
  32. # Send the html message
  33. self.wfile.write(payload)
  34. return
  35.  
  36.  
  37. try:
  38. #Create a web server and define the handler to manage the
  39. #incoming request
  40. server = HTTPServer(('', PORTNUMBER), SlackBotHandler)
  41. print 'Started httpserver on port ' , PORTNUMBER
  42. server.serve_forever()
  43.  
  44. except KeyboardInterrupt:
  45. print '^C received, shutting down the web server'
  46. server.socket.close()

What this small script does is pretty simple. It fires an httpserver that listens on port 3000, then when it receives a post, the "doPOST" method handles it, writing the text it receives to a text file and returning a simple message to slack. All you need to do is execute this script and it will start serving and listening for slack events. You need a server with  a public IPAddress in order for this to work, alternativately you can use a service like Heroku. Lets say our hostname is example.com so the url we have to put on slack would be "http://example.com:3000·

The second part is far more simple. On the Slack website, go to the upper left corner and click on the dropdown link with the name of your team, then Click on "Configure integrations"-> "Outgoing webhooks" -> "Add Outgoing Webhooks Integration", the fields you need to fill are self explanAtory, the most important ones are what channel/s you want your hook to get called, the word/s that are going to be used to fire the hook, and the url/s it will call when matching those words.

In our case we will use this bot on any channel and configure the hook to be fired when hitting the "!save" keyword, and the url as we previously mention will be "http://example.com:3000.

All we need to do then is press save, go to a channel write a line using the magic "!save" word and enjoy our fresh new bot!

Note: In order to add more security, each hook we create generates a token, we should use this value if we want our server to reject anything that does not have this token on the body.