Slack Machine, a plugin framework for ChatOps on Slack
A simple, yet powerful and extendable Slack bot
At a glance
- What is it?
- DonDebonair/slack-machine is a Python framework for building Slack bots, with a regex-driven plugin system, a high-level API for everyday plugins and a low-level API underneath, Socket Mode so the bot needs no public ingress, and pluggable storage for state. A single plugin can be a dozen lines of Python.
- Who is it for?
- Adopt Slack Machine if you want to build internal tooling and ChatOps commands on Slack in Python, and you can host a long-running process. Do not adopt it for a customer-facing assistant, since the framework has no built-in onboarding, conversation state handling or rate limiting and the last release was in August 2025.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What a plugin looks like and why that matters
Slack Machine is described as a simple, yet powerful and extendable Slack bot framework, and the README puts it more strongly: more than just a bot, a framework that helps you develop your Slack workspace into a ChatOps powerhouse.
The plugin system is the core of it, and the README shows how small a plugin can be:
from machine.plugins.base import MachineBasePlugin
from machine.plugins.message import Message
from machine.plugins.decorators import respond_to
class DeploymentPlugin(MachineBasePlugin):
"""Deployments"""
@respond_to(r"deploy (?P<application>\w+) to (?P<environment>\w+)")
async def deploy(self, msg: Message, application, environment):
"""deploy <application> <environment>: deploy application to target environment"""
await msg.say(f"Deploying {application} to {environment}")There is a lot packed into that snippet. The class subclasses MachineBasePlugin, the decorator respond_to takes a regular expression, and the named groups in that expression become arguments on the method. The method is async, so it can await the reply, and msg.say posts the message. The docstring under the method documents the command, which is what makes the built-in help texts work.
The regular expression approach is the design decision that shapes everything else. Matching on a pattern rather than on a command name means a plugin can respond to natural phrasing, and it means the arguments arrive already parsed and typed as strings. The cost is that there is no declarative schema, no argument validation layer and no autocomplete, so a typo in a command silently produces no match rather than an error message.
The framework also distinguishes a high-level API for convenience and a low-level API for flexibility, which is the right split for a framework that has to serve both a two-line plugin and something that talks directly to the Slack Web API.
Socket Mode and the event-driven core
Slack Machine is built on top of the Slack Events API for responding to events in semi real-time, and it uses Socket Mode, so your bot does not need to be exposed to the internet.
That last point is the one that changes deployment decisions. A bot built on the HTTP Events API needs a public endpoint, which means a server, a TLS certificate, and a webhook that anyone on the internet can post to. Socket Mode instead opens an outbound WebSocket connection from your process to Slack, and Slack pushes events over it. For a ChatOps bot running inside a corporate network, that is usually the difference between a deployable service and a networking project.
The framework is built on AsyncIO, and the README gives the reason: to ensure good performance by handling communication with Slack concurrently. That matters for a bot that has to talk to several services while answering a message, and it is why every plugin method is async.
Interactions use the Slack Web API, so the feature list includes support for rich interactions alongside the event stream: blocks, interactive elements and modals from Block Kit, plus legacy message attachments which the README marks with a house emoji as legacy. A plugin can respond with reactions, respond in threads, post ephemeral messages, and send direct messages to any user.
The framework can also listen to and respond to any regular expression, respond to slash commands, capture parts of messages to use as variables, and work in channels, groups and direct message conversations. There is a plugin API for emitting and listening for events, which is how plugins talk to each other, and a scheduling capability backed by APScheduler for actions and messages that need to happen later.
For state, the framework stores and retrieves any kind of data in persistent storage, with Redis, DynamoDB, SQLite and in-memory storage supported.
Installing and running your first bot
Installation is offered through three package managers, and the README is clear about which it prefers:
uv add slack-machinePoetry works the same way with poetry add slack-machine, and pip is available but explicitly not recommended. The reason given is that it is strongly recommended to install slack-machine inside a virtual environment.
The setup sequence in the README is short and specific. Create a directory for the bot, then add a local_settings.py file to it:
mkdir my-slack-bot && cd my-slack-bot
touch local_settings.pyThen create a new app in Slack at api.slack.com/apps, choosing to create the app from an App manifest, and paste in the manifest.yaml file that the repository supplies under docs/extra. That manifest is the piece that saves the most time, because it pre-declares the scopes, the Socket Mode setting and the event subscriptions your bot needs, instead of you working out the OAuth scopes by hand.
The two tokens go into local_settings.py:
SLACK_APP_TOKEN = "xapp-my-app-token"
SLACK_BOT_TOKEN = "xoxb-my-bot-token"The app token is the one that identifies your app to Slack for the Socket Mode connection, and the bot token is the one your bot uses to call the API as itself. Both live in local_settings.py rather than in a checked-in settings file, which is the right call as long as you keep that file out of version control.
The bot is then started with the slack-machine command, and the README's step list ends with a step literally labelled Profit.
Package structure, dependencies and the state of the project
The package metadata tells you what the framework is made of. The core dependencies are slack-sdk for the Slack API, APScheduler for scheduling, httpx and aiohttp for HTTP, pydantic for validation of the data that crosses the API boundary, structlog for logging, pyee for the event emitter that lets plugins talk to each other, dill for serialising objects, and multidict and tzdata.
Storage backends are optional extras rather than core dependencies, which is a sensible choice. The redis extra adds redis and hiredis, the dynamodb extra adds aioboto3, and the pyproject.toml also carries SQLite and in-memory options that need nothing extra.
The version is 0.40.1 and the project classifies itself as Beta. It requires Python 3.9 or newer and below 4.0, and the classifiers cover 3.9 through 3.13. Support for Python 3.8 was dropped in v0.38.0, and the README explains why: Python 3.8 reached end of life on 2024-10-07. That entry is under a Breaking Changes heading, so the README does track what it drops and why, which is a good sign for a library that others depend on.
The repository layout follows modern Python practice: src/ for the package, tests/, a pyproject.toml with a uv.lock file, a noxfile.py for test automation, a pre-commit configuration, a Renovate configuration for dependency updates, and mkdocs.yml with a docs/ directory for the site. There is also a run_dev.py script for local development, a parse_block_kit.py helper at the root, and an AUTHORS file.
The release cadence has slowed. v0.39.0 and v0.40.0 both landed in November 2024, v0.40.1 in August 2025, and the last push to the repository was on 2026-10-20. The code is being worked on, but there has been no tagged release in more than a year.
How it compares with writing a Slack bot directly
The first alternative is to use the Slack SDK directly and write the plumbing yourself. The difference in approach is entirely in what the framework handles for you.
Writing it yourself means opening the Socket Mode WebSocket, dispatching events to handlers, parsing slash command payloads, handling the retry and deduplication that Slack's request semantics require, and building the response payload formats for blocks, modals and ephemeral messages. Each of those is a small task and there are a dozen of them. Slack Machine has done them, and the plugin API reduces your work to a class and a decorated method.
The second alternative is one of the other Python Slack bot frameworks. The comparable ones tend to sit at the same level, so the differences show up in the details rather than the shape. Slack Machine's distinctive features are the regex-driven matching with named groups, the deliberate pairing of a high-level and a low-level API, the plugin-scoped help texts generated from docstrings, and the event bus for plugin to plugin communication.
The third alternative is not a bot library at all but a workflow automation platform. Those give you a visual editor and hosted execution, which suits a team without Python capacity, and they are a poor fit when the bot has to do something bespoke like query an internal service and post a formatted result.
The honest limits of Slack Machine are worth naming. The framework is Beta and its last release was over a year ago. There is no built-in onboarding, no conversation memory, no rate limiting and no admin interface, and the Slack token model means your bot's privileges are exactly the scopes in the manifest, which is a security consideration for a ChatOps bot that can deploy things. The 'Coming Soon' section of the README lists shortcuts and other work, which is a candid signal about what is still open.
Editorial conclusion
Adopt Slack Machine if you want to build internal tooling and ChatOps commands on Slack in Python, and you can host a long-running process. Do not adopt it for a customer-facing assistant, since the framework has no built-in onboarding, conversation state handling or rate limiting and the last release was in August 2025. Verify first by creating a bot from the manifest.yaml from the repository, adding the two tokens to local_settings.py, and confirming that a plugin responding to a regular expression fires in a channel before you build the rest of the command set.
Frequently asked questions
How do I install Slack Machine?
With uv using uv add slack-machine, or with Poetry using poetry add slack-machine. pip is also supported but the README calls it not recommended and strongly advises installing inside a virtual environment.
Do I need to expose my Slack bot to the internet?
No. Slack Machine uses the Slack Events API over Socket Mode, so the bot opens an outbound connection to Slack and does not need to be reachable from the internet, and the README highlights that as a feature.
How do I write a plugin for Slack Machine?
Subclass MachineBasePlugin and decorate an async method with respond_to, passing a regular expression. Named groups in that expression become arguments on the method, and msg.say posts the reply. The method docstring supplies the command description used in the help texts.
Where does Slack Machine store its data?
It stores and retrieves any kind of data in persistent storage, with Redis, DynamoDB, SQLite and in-memory storage supported. The Redis and DynamoDB backends are optional extras, installed with the redis or dynamodb extras.
How do I create the Slack app for Slack Machine?
Create a new app at api.slack.com/apps from an App manifest and paste in the manifest.yaml file supplied in the repository under docs/extra. Then put the app token and bot token in a local_settings.py file in your bot directory and start the bot with the slack-machine command.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/dondebonair-slack-machine)