mirror of
https://github.com/mattermost/mattermost.git
synced 2026-02-03 20:40:00 -05:00
- Use --copies flag when creating venv for distribution - Symlinks point to build machine paths and won't work after extraction - Avoid -e (editable) installs which reference local paths Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
269 lines
7 KiB
Markdown
269 lines
7 KiB
Markdown
# Hello Python - Example Mattermost Plugin
|
|
|
|
A complete example demonstrating the Mattermost Python Plugin SDK.
|
|
|
|
## Overview
|
|
|
|
This plugin showcases the core features of the Python SDK:
|
|
|
|
- **Lifecycle Hooks**: `OnActivate` and `OnDeactivate` for plugin setup/teardown
|
|
- **Message Filtering**: `MessageWillBePosted` to inspect and modify messages
|
|
- **Slash Commands**: `ExecuteCommand` to handle custom `/hello` command
|
|
- **API Client**: Accessing Mattermost APIs via `self.api`
|
|
- **Logging**: Using `self.logger` for plugin logging
|
|
|
|
## Prerequisites
|
|
|
|
- Python 3.9 or higher
|
|
- Mattermost server with Python plugin support enabled
|
|
|
|
## Plugin Structure
|
|
|
|
```
|
|
hello_python/
|
|
plugin.json # Plugin manifest with Python runtime configuration
|
|
plugin.py # Main plugin implementation
|
|
requirements.txt # Python dependencies
|
|
README.md # This file
|
|
```
|
|
|
|
### plugin.json
|
|
|
|
The manifest declares this as a Python plugin:
|
|
|
|
```json
|
|
{
|
|
"server": {
|
|
"executable": "plugin.py",
|
|
"runtime": "python",
|
|
"python_version": ">=3.9"
|
|
}
|
|
}
|
|
```
|
|
|
|
Key fields:
|
|
- `server.executable`: The Python entry point script
|
|
- `server.runtime`: Set to `"python"` to indicate this is a Python plugin
|
|
- `server.python_version`: Minimum Python version required
|
|
|
|
### plugin.py
|
|
|
|
The main plugin implementation. Key patterns:
|
|
|
|
```python
|
|
from mattermost_plugin import Plugin, hook, HookName
|
|
|
|
class HelloPythonPlugin(Plugin):
|
|
@hook(HookName.OnActivate)
|
|
def on_activate(self) -> None:
|
|
self.logger.info("Plugin activated!")
|
|
version = self.api.get_server_version()
|
|
|
|
@hook(HookName.MessageWillBePosted)
|
|
def filter_message(self, context, post):
|
|
# Return (post, "") to allow, (None, "reason") to reject
|
|
return post, ""
|
|
|
|
@hook(HookName.ExecuteCommand)
|
|
def execute_command(self, context, args):
|
|
return {"response_type": "ephemeral", "text": "Hello!"}
|
|
|
|
if __name__ == "__main__":
|
|
from mattermost_plugin.server import run_plugin
|
|
run_plugin(HelloPythonPlugin)
|
|
```
|
|
|
|
## Installation (Development)
|
|
|
|
1. Create and activate a virtual environment:
|
|
|
|
```bash
|
|
cd examples/hello_python
|
|
python3 -m venv venv
|
|
source venv/bin/activate # On Windows: venv\Scripts\activate
|
|
```
|
|
|
|
2. Install the SDK in development mode:
|
|
|
|
```bash
|
|
pip install -e ../../python-sdk
|
|
```
|
|
|
|
3. Verify the plugin parses correctly:
|
|
|
|
```bash
|
|
python3 -c "import plugin; print('Plugin loaded successfully')"
|
|
```
|
|
|
|
## Installation (Production)
|
|
|
|
For production deployments, the SDK will be available via pip:
|
|
|
|
```bash
|
|
pip install mattermost-plugin-sdk
|
|
```
|
|
|
|
## Packaging
|
|
|
|
Python plugins are distributed as `.tar.gz` bundles. There are two packaging approaches:
|
|
|
|
### Option 1: System Python (smaller bundle, requires server-side setup)
|
|
|
|
Create a minimal bundle that relies on system Python:
|
|
|
|
```bash
|
|
cd examples/hello_python
|
|
tar -czvf hello-python-0.1.0.tar.gz \
|
|
plugin.json \
|
|
plugin.py \
|
|
requirements.txt
|
|
```
|
|
|
|
**Server requirement:** Install the SDK on the Mattermost server:
|
|
```bash
|
|
pip3 install mattermost-plugin-sdk
|
|
```
|
|
|
|
### Option 2: Bundled Virtual Environment (self-contained, larger bundle)
|
|
|
|
Create a fully self-contained bundle with all dependencies:
|
|
|
|
```bash
|
|
cd examples/hello_python
|
|
|
|
# Create virtual environment with --copies to include actual Python binaries
|
|
# (symlinks won't work when extracted on a different machine)
|
|
python3 -m venv --copies venv
|
|
source venv/bin/activate # On Windows: venv\Scripts\activate
|
|
pip install mattermost-plugin-sdk # Or: pip install ../../python-sdk
|
|
pip install grpcio protobuf
|
|
deactivate
|
|
|
|
# Create the bundle
|
|
tar -czvf hello-python-0.1.0.tar.gz \
|
|
plugin.json \
|
|
plugin.py \
|
|
requirements.txt \
|
|
venv/
|
|
```
|
|
|
|
**Important notes:**
|
|
- Use `--copies` when creating the venv to include actual Python binaries (not symlinks)
|
|
- Do NOT use `-e` (editable install) for the SDK - it references local paths that won't exist on the server
|
|
- The bundled venv is Python version-specific. If your server has a different Python version than your build machine, use Option 1 or build the venv on a machine with matching Python version
|
|
|
|
## Deployment
|
|
|
|
### Via System Console (UI)
|
|
|
|
1. Log in as a System Admin
|
|
2. Go to **System Console → Plugins → Plugin Management**
|
|
3. Click **Upload Plugin**
|
|
4. Select `hello-python-0.1.0.tar.gz`
|
|
5. Click **Upload**
|
|
6. Find "Hello Python" in the plugin list and click **Enable**
|
|
|
|
### Via CLI (mmctl)
|
|
|
|
```bash
|
|
# Upload the plugin
|
|
mmctl plugin add hello-python-0.1.0.tar.gz
|
|
|
|
# Enable the plugin
|
|
mmctl plugin enable com.mattermost.hello-python
|
|
```
|
|
|
|
### Via API
|
|
|
|
```bash
|
|
# Upload
|
|
curl -X POST \
|
|
-H "Authorization: Bearer YOUR_TOKEN" \
|
|
-F "plugin=@hello-python-0.1.0.tar.gz" \
|
|
https://your-mattermost/api/v4/plugins
|
|
|
|
# Enable
|
|
curl -X POST \
|
|
-H "Authorization: Bearer YOUR_TOKEN" \
|
|
https://your-mattermost/api/v4/plugins/com.mattermost.hello-python/enable
|
|
```
|
|
|
|
## Verifying Installation
|
|
|
|
After enabling the plugin, check the Mattermost server logs for:
|
|
|
|
```
|
|
Python plugin started with gRPC hooks
|
|
Hello Python plugin activated!
|
|
Connected to Mattermost server version: X.X.X
|
|
```
|
|
|
|
Test the plugin:
|
|
1. **Slash command:** Type `/hello` in any channel
|
|
2. **Message filter:** Post a message containing "badword" (should be blocked)
|
|
|
|
## Troubleshooting
|
|
|
|
| Issue | Solution |
|
|
|-------|----------|
|
|
| "Python interpreter not found" | Ensure `python3` is in PATH, or bundle a venv |
|
|
| "Module mattermost_plugin not found" | Install SDK on server or bundle venv |
|
|
| Plugin fails to start | Check server logs for gRPC handshake errors |
|
|
| Hooks not being called | Verify plugin implements `Implemented()` correctly |
|
|
| Bundled venv doesn't work | Python version mismatch; rebuild venv on server |
|
|
|
|
## Hooks Demonstrated
|
|
|
|
### OnActivate
|
|
|
|
Called when the plugin is enabled. Use for:
|
|
- Initializing plugin state
|
|
- Registering slash commands
|
|
- Connecting to external services
|
|
|
|
### OnDeactivate
|
|
|
|
Called when the plugin is disabled. Use for:
|
|
- Cleaning up resources
|
|
- Saving state
|
|
- Disconnecting from services
|
|
|
|
### MessageWillBePosted
|
|
|
|
Called before a message is posted. Return values:
|
|
- `(post, "")` - Allow the message (optionally modified)
|
|
- `(None, "reason")` - Reject the message with a reason
|
|
|
|
### ExecuteCommand
|
|
|
|
Called when a slash command is invoked. Return a response dict:
|
|
- `response_type`: `"ephemeral"` (private) or `"in_channel"` (public)
|
|
- `text`: The response message
|
|
|
|
## Running the Plugin
|
|
|
|
The plugin is designed to be run by the Mattermost server's Python plugin supervisor. The supervisor:
|
|
|
|
1. Starts the plugin process
|
|
2. Establishes gRPC communication
|
|
3. Invokes hooks as events occur
|
|
|
|
For standalone testing:
|
|
|
|
```bash
|
|
python plugin.py
|
|
```
|
|
|
|
Note: The plugin will output a go-plugin handshake line and wait for gRPC connections. In standalone mode, most functionality requires a connected Mattermost server.
|
|
|
|
## Next Steps
|
|
|
|
- Modify the word filter in `MessageWillBePosted`
|
|
- Add new slash commands in `ExecuteCommand`
|
|
- Implement additional hooks from `HookName` enum
|
|
- Use `self.api` to interact with Mattermost (users, channels, posts, etc.)
|
|
|
|
## Resources
|
|
|
|
- [Mattermost Plugin Documentation](https://developers.mattermost.com/extend/plugins/)
|
|
- [Python SDK API Reference](../../python-sdk/README.md)
|