Deploying my Python Slackbot onto Heroku

I just build a Slack chatbot in Python within a night.

With all the hypes about building a chatbot, that was way easier than I imagine.

I pretty much just followed the tutorial at Full Stack Python: How to Build Your First Slack Bot with Python, which was pretty quick and easy. I hilariously tried to test out my slackbot for 10 minute before realizing I was in localhost. Duh.

So here is the long story version of my troubleshooting:
Most of the time I took to build the slackbot was actually the deployment to Heroku, since I have only ever used it once. When the warning “No default language could be detected for this app. HINT: This occurs when Heroku cannot detect the buildpack to use for this application automatically.” popped up, I was pretty clueless (“What’s a Buildpack?”).

So, I went to the Heroku site and added the Python Buildpack. Since it was giving out error message about not detecting Python, it reminded me that I was working with a virtual environment. Thus, I should do a pip freeze > requirement.txt so the deployment environment knows what to load. So I did that. Let’s git push again…

Python app detected Warning: Your application is missing a Procfile. This file tells Heroku how to run your application… Installing python-2.7.12

Python app is detected, but missing a Procfile? Isn’t that just for Django (my only encounter with Procfile so far is the Django Girls tutorial)? Also, why is it installing Python 2.7.12?

A quick Google revealed that I can create a runtime.txt file to state which Python version I want. I also did some reading on Procfile in term of Heroku and Python deployment. For apps, the example provided was web: gunicorn gettingstarted.wsgi and web: gunicorn hello:app. The later seemed to be more for frameworks like Django, so I went with the later and added web: gunicorn starterbot.wsgi –log-file –. I then pip install gunicorn and redo pip freeze > requirement.txt.

Along the way, I also saw another Heroku deployment tutorial that reminded me that I should use .gitignore. That’s right, I shouldn’t deploy my virtual environment files for security reason. That’s why the “SLACK_BOT_TOKEN” and “BOT_ID” are exported in the first place! So I went and delete my Heroku app, deleted my .git, create the .gitignore and Procfile file, and deploy my app again.

The slackbot, however, didn’t seemed to be running. In the slackchat, the dot that indicate activity status remained grey instead of green. Doing heroku logs revealed that “ImportError: No module named ‘starterbot.wsgi’; ‘starterbot’ is not a package“. So its the Procfile. After some more reading and I narrowed down to the Heroku statement that Procfile “…explicitly declares what command should be executed to start your app.“. So, I tried web: python startbot.py, because that’s what get the program running, right?

That does get it running! At first, it seems to work well, but the slackbot keeps shutting itself down after a while, and it never respond to my command. Another heroku logs reveals that “Stopping all processes with SIGTERM… Process exited with status 143 …Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch… Stopping process with SIGKILL… Process exited with status 137… State changed from starting to crashed“.

It seemed something was wrong with the PORT variable. So, I went to the Heroku site and manually added the PORT config variable, testing the deployment with different port. None seemed to work.

I did a search of “heroku chatbot port”. Surprising, I found the answer in a Node.js tutorial – the author,┬áLuciano Mammino, used “worker: node bin/bot.js” for his Procfile. What would happen if I use “worker: python starterbot.py“?

That got it running, permanently, without any error message about port binding!

My bot is still not outputting anything when I was typing commands though. I added in error checking statement in the if-else statement and eventually realized I have missed a simple colon sign in my command (“@starterbot:”). But once I started adding that, my slackbot worked!

The short, listed version:

  1. heroku create
  2. Find the corresponding app in the Heroku account. Go to Settings and add “SLACK_BOT_TOKEN” and “BOT_ID” to the Config Vars.
  3. pip freeze > requirements.txt
  4. echo “python-3.5.2” > runtime.txt (or whatever Python version you are working with)
  5. echo “worker: python starterbot.py” > Procfile
  6. Add the virtual environment directory name and *.pyc into .gitignore.
  7. Do git add, commit, and push.The bot should be up and running!