{"id":13617130,"url":"https://github.com/jcarbaugh/butterfield","last_synced_at":"2025-04-14T05:31:58.648Z","repository":{"id":24390697,"uuid":"27790684","full_name":"jcarbaugh/butterfield","owner":"jcarbaugh","description":"A Python Slack bot framework using asyncio and Slack's Real Time Messaging API","archived":false,"fork":false,"pushed_at":"2021-06-11T17:43:52.000Z","size":43,"stargazers_count":61,"open_issues_count":10,"forks_count":8,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-11T03:04:16.242Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jcarbaugh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-12-09T22:35:03.000Z","updated_at":"2023-01-15T01:13:00.000Z","dependencies_parsed_at":"2022-07-25T14:02:14.970Z","dependency_job_id":null,"html_url":"https://github.com/jcarbaugh/butterfield","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcarbaugh%2Fbutterfield","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcarbaugh%2Fbutterfield/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcarbaugh%2Fbutterfield/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcarbaugh%2Fbutterfield/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jcarbaugh","download_url":"https://codeload.github.com/jcarbaugh/butterfield/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248826713,"owners_count":21167731,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T20:01:37.295Z","updated_at":"2025-04-14T05:31:58.424Z","avatar_url":"https://github.com/jcarbaugh.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# Butterfield\n\nA Slack bot framework using Slack's [Real Time Messaging API](https://api.slack.com/rtm), Python 3 and [asyncio](https://docs.python.org/3/library/asyncio.html).\n\n**Butterfield is unstable and being actively developed. Breaking changes will occur.**\n\n## Echo bot example\n\nThis simple bot will listen for *message* events and echo the message to the same channel. \n\n\timport asyncio\n\tfrom butterfield import Bot\n\t\n\t@asyncio.coroutine\n\tdef echo(bot, message: 'message'):\n\t\tyield from bot.post(\n\t\t\tmessage['channel'],\n\t\t\tmessage['text']\n\t\t)\n\t\n\tb = Bot('slack-bot-key')\n\tb.listen(echo)\n\n\tbutterfield.run(b)\n\n## Running butterfield\n\nThis package provides the *butterfield* command line utility. This command takes one argument, a path to a configuration file, and runs the bot as defined.\n\n\t$ butterfield mybot-config.json\n\nIf you are running butterfield in development, you can launch the command line utility directly:\n\n\t$ python -m \"butterfield.cli\" mybot-config.json\n\n### Bot configuration files\n\nA butterfield config file contains a JSON array containing objects defining the bots that will be created.\n\n\t[\n\t\t{\n\t\t\t\"key\": \"i-made-this-key-up\",\n\t\t\t\"plugins\": [\n\t\t\t\t\"butterfield.handlers.devel.log\",\n\t\t\t\t\"butterfield.handlers.devel.emoji\"\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"key\": \"also-a-made-up-key\",\n\t\t\t\"plugins\": [\n\t\t\t\t\"butterfield.handlers.devel.log\",\n\t\t\t]\n\t\t}\n\t]\n\nThe *key* property contains the [Slack bot user](https://api.slack.com/bot-users) key. The *plugins* property is a list of strings that are module paths to event handler plugins.\n\n## Writing your own bot\n\nBots are created by instantiating an instance with a [Slack bot user](https://api.slack.com/bot-users) key.\n\n\tfrom butterfield import Bot\n\t\n\tmybot = Bot('this-is-not-a-real-key')\n\t\n### Receiving Slack events\n\nMessage handlers are asyncio [coroutines](https://docs.python.org/3/library/asyncio-task.html#coroutine). When executed, they receive the bot instance that invoked the handler and a copy of the event message from Slack.\n\n\timport asyncio\n\n\t@asyncio.coroutine\n\tdef console_printer(bot, message: \"message\"):\n\t\tif 'text' in message:\n\t\t\tprint(message['text'])\n\nA [parameter annotation](https://www.python.org/dev/peps/pep-3107/) 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](https://api.slack.com/rtm).\n\nHandlers 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.\n\n\tmybot.listen(console_printer)\n\tmybot.listen(\"butterfield.handlers.devel.log\")\n\nNow just start the bot and it will run... FOREVER.\n\n\tbutterfield.run(mybot)\n\nMultiple bots can be started by passing multiple instances to *butterfield.run()*:\n\n\tbutterfield.run(mybot, myotherbot)\n\nor\n\n\tallthebots = [mybot, myotherbot]\n\tbutterfield.run(*allthebots)\n\n### Posting to Slack\n\nHandlers 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.\n\n\tbot.post(channel_id, 'Hi, channel!')\n\n### Daemons\n\nThey exist. This section should tell you about them.\n\n\n## TODO\n\n* Add HTTP API so messages can be pushed through Butterfield to Slack.\n* Listen for meta events and modify local Slack environment appropriately (list of channels, users, etc.).\n* EVERYTHING ELSE!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcarbaugh%2Fbutterfield","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjcarbaugh%2Fbutterfield","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcarbaugh%2Fbutterfield/lists"}