A Python Slack bot framework using asyncio and Slack's Real Time Messaging API
Clone or download
Pull request Compare This branch is 2 commits behind jcarbaugh:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.



A Slack bot framework using Slack's Real Time Messaging API, Python 3 and asyncio.

Butterfield is unstable and being actively developed. Breaking changes will occur.

Echo bot example

This simple bot will listen for message events and echo the message to the same channel.

import asyncio
from butterfield import Bot

def echo(bot, message: 'message'):
	yield from bot.post(

b = Bot('slack-bot-key')


Running butterfield

This package provides the butterfield command line utility. This command takes one argument, a path to a configuration file, and runs the bot as defined.

$ butterfield mybot-config.json

If you are running butterfield in development, you can launch the command line utility directly:

$ python -m "butterfield.cli" mybot-config.json

Bot configuration files

A butterfield config file contains a JSON array containing objects defining the bots that will be created.

		"key": "i-made-this-key-up",
		"plugins": [
		"key": "also-a-made-up-key",
		"plugins": [

The key property contains the Slack bot user key. The plugins property is a list of strings that are module paths to event handler plugins.

Writing your own bot

Bots are created by instantiating an instance with a Slack bot user key.

from butterfield import Bot

mybot = Bot('this-is-not-a-real-key')

Receiving Slack events

Message handlers are asyncio coroutines. When executed, they receive the bot instance that invoked the handler and a copy of the event message from Slack.

import asyncio

def console_printer(bot, message: "message"):
	if 'text' in message:

A parameter annotation is used on the message parameter to specify the message types the coroutine will receive. This can be a single string or a list of strings to specificy multiple message types. To trigger the handler for all event types, use "*" or butterfield.ALL. The full list of event types can be found in the RTM API docs.

Handlers are added to the bot using the listen method. The handler parameter can be either a direct reference to the coroutine or the module path as a string.


Now just start the bot and it will run... FOREVER.


Multiple bots can be started by passing multiple instances to butterfield.run():

butterfield.run(mybot, myotherbot)


allthebots = [mybot, myotherbot]

Posting to Slack

Handlers can post messages back to Slack using the post method on the bot that was passed to it. The first parameter is the id of the channel that will receive the post. The second parameter is the message that will be posted.

bot.post(channel_id, 'Hi, channel!')


They exist. This section should tell you about them.


  • Add HTTP API so messages can be pushed through Butterfield to Slack.
  • Listen for meta events and modify local Slack environment appropriately (list of channels, users, etc.).