matrix-python 1.4.9a0__tar.gz → 1.4.10a0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- matrix_python-1.4.10a0/.github/workflows/docs.yml +39 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/.gitignore +2 -1
- {matrix_python-1.4.9a0/matrix_python.egg-info → matrix_python-1.4.10a0}/PKG-INFO +60 -39
- matrix_python-1.4.10a0/README.md +99 -0
- matrix_python-1.4.10a0/docs/docs/examples/checks.md +15 -0
- matrix_python-1.4.10a0/docs/docs/examples/cooldown.md +14 -0
- matrix_python-1.4.10a0/docs/docs/examples/error-handling.md +17 -0
- matrix_python-1.4.10a0/docs/docs/examples/extension.md +26 -0
- matrix_python-1.4.10a0/docs/docs/examples/index.md +20 -0
- matrix_python-1.4.10a0/docs/docs/examples/ping.md +9 -0
- matrix_python-1.4.10a0/docs/docs/examples/reaction.md +14 -0
- matrix_python-1.4.10a0/docs/docs/examples/scheduler.md +19 -0
- matrix_python-1.4.10a0/docs/docs/guides/bigger-bot.md +95 -0
- matrix_python-1.4.10a0/docs/docs/guides/checks.md +114 -0
- matrix_python-1.4.10a0/docs/docs/guides/commands.md +158 -0
- matrix_python-1.4.10a0/docs/docs/guides/configuration.md +86 -0
- matrix_python-1.4.10a0/docs/docs/guides/error-handling.md +97 -0
- matrix_python-1.4.10a0/docs/docs/guides/events.md +115 -0
- matrix_python-1.4.10a0/docs/docs/guides/groups.md +111 -0
- matrix_python-1.4.10a0/docs/docs/guides/index.md +87 -0
- matrix_python-1.4.10a0/docs/docs/guides/introduction.md +126 -0
- matrix_python-1.4.10a0/docs/docs/img/favicon.svg +68 -0
- matrix_python-1.4.10a0/docs/docs/img/matrixpy-black.svg +72 -0
- matrix_python-1.4.10a0/docs/docs/img/matrixpy-white.svg +89 -0
- matrix_python-1.4.10a0/docs/docs/index.md +168 -0
- matrix_python-1.4.10a0/docs/docs/reference/bot.md +20 -0
- matrix_python-1.4.10a0/docs/docs/reference/checks.md +17 -0
- matrix_python-1.4.10a0/docs/docs/reference/command.md +15 -0
- matrix_python-1.4.10a0/docs/docs/reference/config.md +19 -0
- matrix_python-1.4.10a0/docs/docs/reference/content.md +34 -0
- matrix_python-1.4.10a0/docs/docs/reference/context.md +15 -0
- matrix_python-1.4.10a0/docs/docs/reference/errors.md +18 -0
- matrix_python-1.4.10a0/docs/docs/reference/extension.md +30 -0
- matrix_python-1.4.10a0/docs/docs/reference/group.md +19 -0
- matrix_python-1.4.10a0/docs/docs/reference/message.md +15 -0
- matrix_python-1.4.10a0/docs/docs/reference/protocols.md +5 -0
- matrix_python-1.4.10a0/docs/docs/reference/registry.md +7 -0
- matrix_python-1.4.10a0/docs/docs/reference/room.md +15 -0
- matrix_python-1.4.10a0/docs/docs/reference/scheduler.md +16 -0
- matrix_python-1.4.10a0/docs/docs/reference/types.md +26 -0
- matrix_python-1.4.10a0/docs/docs/stylesheets/extra.css +3 -0
- matrix_python-1.4.10a0/docs/mkdocs.yml +120 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/_version.py +3 -3
- matrix_python-1.4.10a0/matrix/checks.py +29 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/command.py +45 -48
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/context.py +0 -3
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/group.py +15 -7
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/help/help_command.py +62 -72
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/help/pagination.py +4 -22
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/scheduler.py +7 -9
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0/matrix_python.egg-info}/PKG-INFO +60 -39
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix_python.egg-info/SOURCES.txt +39 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix_python.egg-info/requires.txt +6 -1
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/pyproject.toml +6 -1
- matrix_python-1.4.9a0/README.md +0 -82
- matrix_python-1.4.9a0/matrix/checks.py +0 -21
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/.github/dependabot.yml +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/.github/workflows/CODEOWNERS +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/.github/workflows/codeql.yml +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/.github/workflows/publish.yml +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/.github/workflows/scorecard.yml +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/.github/workflows/tests.yml +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/CODE_OF_CONDUCT.md +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/CONTRIBUTING.md +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/LICENSE +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/examples/README.md +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/examples/checks.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/examples/config.yaml +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/examples/cooldown.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/examples/error_handling.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/examples/extension.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/examples/ping.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/examples/reaction.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/examples/scheduler.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/__init__.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/bot.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/config.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/content.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/errors.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/extension.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/help/__init__.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/message.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/protocols.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/py.typed +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/registry.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/room.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix/types.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix_python.egg-info/dependency_links.txt +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/matrix_python.egg-info/top_level.txt +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/mypy.ini +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/setup.cfg +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/tests/help/test_default_help_command.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/tests/help/test_help_command.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/tests/help/test_pagination.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/tests/test_bot.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/tests/test_command.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/tests/test_config.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/tests/test_context.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/tests/test_extension.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/tests/test_group.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/tests/test_message.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/tests/test_registry.py +0 -0
- {matrix_python-1.4.9a0 → matrix_python-1.4.10a0}/tests/test_room.py +0 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Deploy Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
pages: write
|
|
11
|
+
id-token: write
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
deploy:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
environment:
|
|
17
|
+
name: github-pages
|
|
18
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.10"
|
|
26
|
+
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: pip install .[doc]
|
|
29
|
+
|
|
30
|
+
- name: Build docs
|
|
31
|
+
run: mkdocs build --config-file docs/mkdocs.yml
|
|
32
|
+
|
|
33
|
+
- uses: actions/upload-pages-artifact@v3
|
|
34
|
+
with:
|
|
35
|
+
path: docs/site
|
|
36
|
+
|
|
37
|
+
- name: Deploy to GitHub Pages
|
|
38
|
+
id: deployment
|
|
39
|
+
uses: actions/deploy-pages@v4
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: matrix-python
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.10a0
|
|
4
4
|
Summary: An easy-to-use Matrix bot framework designed for quick development and minimal setup
|
|
5
5
|
Author: Simon Roy, Chris Dedman Rollet
|
|
6
6
|
Maintainer-email: Code Society Lab <admin@codesociety.xyz>
|
|
@@ -40,57 +40,72 @@ Provides-Extra: dev
|
|
|
40
40
|
Requires-Dist: pytest==9.0.3; extra == "dev"
|
|
41
41
|
Requires-Dist: pytest-asyncio==1.3.0; extra == "dev"
|
|
42
42
|
Requires-Dist: black==26.3.1; extra == "dev"
|
|
43
|
-
Requires-Dist: mypy==1.20.
|
|
43
|
+
Requires-Dist: mypy==1.20.1; extra == "dev"
|
|
44
44
|
Requires-Dist: types-PyYAML==6.0.12.20260408; extra == "dev"
|
|
45
45
|
Requires-Dist: types-Markdown==3.10.2.20260408; extra == "dev"
|
|
46
|
+
Provides-Extra: doc
|
|
47
|
+
Requires-Dist: mkdocs==1.6.1; extra == "doc"
|
|
48
|
+
Requires-Dist: mkdocs-material==9.7.6; extra == "doc"
|
|
49
|
+
Requires-Dist: mkdocstrings[python]==1.0.4; extra == "doc"
|
|
46
50
|
|
|
47
51
|
<div align="center">
|
|
48
52
|
<em>A simple, developer-friendly library to create powerful <a href="https://matrix.org">Matrix</a> bots.</em>
|
|
49
53
|
</div>
|
|
50
54
|
|
|
51
|
-
<
|
|
55
|
+
<div align="center">
|
|
56
|
+
<img alt="matrix.py" src="https://github.com/user-attachments/assets/d9140a9e-27fa-44e4-a5ca-87ee7bbf868f" />
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<div align="center">
|
|
52
60
|
|
|
53
|
-
<
|
|
61
|
+
[<img src="https://img.shields.io/badge/Get%20Started-black?style=for-the-badge" />](https://matrixpy.code-society.xyz/guides/introduction/)
|
|
62
|
+
[<img src="https://img.shields.io/badge/Reference-555555?style=for-the-badge" />](https://matrixpy.code-society.xyz/reference/bot/)
|
|
63
|
+
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<div align="center">
|
|
54
67
|
|
|
55
|
-
[](https://github.com/Code-Society-Lab/matrixpy/wiki)
|
|
56
68
|
[](https://discord.gg/code-society-823178343943897088)
|
|
57
|
-
[](https://matrix.to/#/%23codesociety:matrix.org
|
|
69
|
+
[](https://matrix.to/#/%23codesociety:matrix.org)
|
|
58
70
|
[](https://github.com/Code-Society-Lab/matrixpy/actions/workflows/tests.yml)
|
|
59
71
|
[](https://github.com/Code-Society-Lab/matrixpy/actions/workflows/codeql.yml)
|
|
60
72
|
[](https://securityscorecards.dev/viewer/?uri=github.com/Code-Society-Lab/matrixpy)
|
|
61
73
|
|
|
62
|
-
|
|
63
|
-
the [Matrix protocol](https://matrix.org). It provides a clean,
|
|
64
|
-
decorator-based API similar to popular event-driven frameworks, allowing
|
|
65
|
-
developers to focus on behavior rather than boilerplate.
|
|
74
|
+
</div>
|
|
66
75
|
|
|
67
|
-
|
|
76
|
+
---
|
|
68
77
|
|
|
69
|
-
|
|
70
|
-
-
|
|
71
|
-
|
|
72
|
-
- Automatic event handler registration
|
|
73
|
-
- Built on [matrix-nio](https://github.com/matrix-nio/matrix-nio)
|
|
78
|
+
Matrix.py is a lightweight and intuitive Python library to build bots on the [Matrix protocol](https://matrix.org). It
|
|
79
|
+
provides a clean, decorator-based API similar to popular event-driven frameworks, allowing developers to focus on
|
|
80
|
+
behavior rather than boilerplate.
|
|
74
81
|
|
|
75
|
-
|
|
82
|
+
- **Minimal setup** — install and have a working bot running in minutes
|
|
83
|
+
- **Event-driven** — async/await API reacting to any Matrix room event
|
|
84
|
+
- **Command system** — decorator-based commands with automatic argument parsing
|
|
85
|
+
- **Extensions** — split your bot into modules as it grows
|
|
76
86
|
|
|
77
|
-
|
|
87
|
+
## Quickstart
|
|
78
88
|
|
|
79
|
-
|
|
89
|
+
**Requirements:** Python 3.10+
|
|
80
90
|
|
|
81
|
-
```
|
|
91
|
+
```bash
|
|
82
92
|
pip install matrix-python
|
|
83
93
|
```
|
|
84
94
|
|
|
85
|
-
|
|
95
|
+
Using a virtual environment is strongly recommended:
|
|
86
96
|
|
|
87
|
-
```
|
|
88
|
-
|
|
97
|
+
```bash
|
|
98
|
+
python -m venv venv
|
|
99
|
+
source venv/bin/activate # Windows: venv\Scripts\activate
|
|
100
|
+
pip install matrix-python
|
|
89
101
|
```
|
|
90
102
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
103
|
+
Create a `config.yml`:
|
|
104
|
+
|
|
105
|
+
```yaml
|
|
106
|
+
USERNAME: "@yourbot:matrix.org"
|
|
107
|
+
PASSWORD: "your_password"
|
|
108
|
+
```
|
|
94
109
|
|
|
95
110
|
```python
|
|
96
111
|
from matrix import Bot, Context
|
|
@@ -106,23 +121,29 @@ async def ping(ctx: Context):
|
|
|
106
121
|
bot.start(config="config.yml")
|
|
107
122
|
```
|
|
108
123
|
|
|
109
|
-
|
|
124
|
+
Send `!ping` in any room the bot is in, it will reply `Pong!`.
|
|
125
|
+
|
|
126
|
+
## Where to go next
|
|
110
127
|
|
|
111
|
-
|
|
128
|
+
- [**Guides**](https://matrixpy.codesociety.xyz/guides/introduction/) — step-by-step tutorials covering commands,
|
|
129
|
+
events, checks, extensions, and more
|
|
130
|
+
- [**Reference**](https://matrixpy.codesociety.xyz/reference/bot/) — complete API documentation for every class and
|
|
131
|
+
function
|
|
132
|
+
- [**Examples**](https://matrixpy.codesociety.xyz/examples/) — ready-to-run example bots
|
|
133
|
+
demonstrating common patterns
|
|
112
134
|
|
|
113
|
-
|
|
135
|
+
## Contributing
|
|
114
136
|
|
|
115
|
-
Whether it's fixing bugs, suggesting features, or improving the docs
|
|
137
|
+
We welcome everyone to contribute! Whether it's fixing bugs, suggesting features, or improving the docs. Every bit
|
|
138
|
+
helps.
|
|
116
139
|
|
|
117
|
-
- Submit an issue
|
|
118
|
-
- Open a pull request
|
|
119
|
-
-
|
|
120
|
-
or [Discord](https://discord.gg/code-society-823178343943897088)
|
|
140
|
+
- [Submit an issue](https://github.com/Code-Society-Lab/matrixpy/issues)
|
|
141
|
+
- [Open a pull request](https://github.com/Code-Society-Lab/matrixpy/blob/main/CONTRIBUTING.md)
|
|
142
|
+
- Hop into our [Matrix](https://matrix.to/#/%23codesociety:matrix.org)
|
|
143
|
+
or [Discord](https://discord.gg/code-society-823178343943897088) and say hi!
|
|
121
144
|
|
|
122
|
-
|
|
123
|
-
contributor** is expected to follow the [code of conduct](./CODE_OF_CONDUCT.md).
|
|
145
|
+
Please read the [CONTRIBUTING.md](./CONTRIBUTING.md) and follow the [code of conduct](./CODE_OF_CONDUCT.md).
|
|
124
146
|
|
|
125
|
-
|
|
147
|
+
## License
|
|
126
148
|
|
|
127
|
-
|
|
128
|
-
of [MIT license](https://github.com/Code-Society-Lab/matrixpy/blob/main/LICENSE).
|
|
149
|
+
Released under the [MIT License](https://github.com/Code-Society-Lab/matrixpy/blob/main/LICENSE).
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<em>A simple, developer-friendly library to create powerful <a href="https://matrix.org">Matrix</a> bots.</em>
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
<div align="center">
|
|
6
|
+
<img alt="matrix.py" src="https://github.com/user-attachments/assets/d9140a9e-27fa-44e4-a5ca-87ee7bbf868f" />
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<div align="center">
|
|
10
|
+
|
|
11
|
+
[<img src="https://img.shields.io/badge/Get%20Started-black?style=for-the-badge" />](https://matrixpy.code-society.xyz/guides/introduction/)
|
|
12
|
+
[<img src="https://img.shields.io/badge/Reference-555555?style=for-the-badge" />](https://matrixpy.code-society.xyz/reference/bot/)
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div align="center">
|
|
17
|
+
|
|
18
|
+
[](https://discord.gg/code-society-823178343943897088)
|
|
19
|
+
[](https://matrix.to/#/%23codesociety:matrix.org)
|
|
20
|
+
[](https://github.com/Code-Society-Lab/matrixpy/actions/workflows/tests.yml)
|
|
21
|
+
[](https://github.com/Code-Society-Lab/matrixpy/actions/workflows/codeql.yml)
|
|
22
|
+
[](https://securityscorecards.dev/viewer/?uri=github.com/Code-Society-Lab/matrixpy)
|
|
23
|
+
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
Matrix.py is a lightweight and intuitive Python library to build bots on the [Matrix protocol](https://matrix.org). It
|
|
29
|
+
provides a clean, decorator-based API similar to popular event-driven frameworks, allowing developers to focus on
|
|
30
|
+
behavior rather than boilerplate.
|
|
31
|
+
|
|
32
|
+
- **Minimal setup** — install and have a working bot running in minutes
|
|
33
|
+
- **Event-driven** — async/await API reacting to any Matrix room event
|
|
34
|
+
- **Command system** — decorator-based commands with automatic argument parsing
|
|
35
|
+
- **Extensions** — split your bot into modules as it grows
|
|
36
|
+
|
|
37
|
+
## Quickstart
|
|
38
|
+
|
|
39
|
+
**Requirements:** Python 3.10+
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install matrix-python
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Using a virtual environment is strongly recommended:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
python -m venv venv
|
|
49
|
+
source venv/bin/activate # Windows: venv\Scripts\activate
|
|
50
|
+
pip install matrix-python
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Create a `config.yml`:
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
USERNAME: "@yourbot:matrix.org"
|
|
57
|
+
PASSWORD: "your_password"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from matrix import Bot, Context
|
|
62
|
+
|
|
63
|
+
bot = Bot()
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@bot.command("ping")
|
|
67
|
+
async def ping(ctx: Context):
|
|
68
|
+
await ctx.reply("Pong!")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
bot.start(config="config.yml")
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Send `!ping` in any room the bot is in, it will reply `Pong!`.
|
|
75
|
+
|
|
76
|
+
## Where to go next
|
|
77
|
+
|
|
78
|
+
- [**Guides**](https://matrixpy.codesociety.xyz/guides/introduction/) — step-by-step tutorials covering commands,
|
|
79
|
+
events, checks, extensions, and more
|
|
80
|
+
- [**Reference**](https://matrixpy.codesociety.xyz/reference/bot/) — complete API documentation for every class and
|
|
81
|
+
function
|
|
82
|
+
- [**Examples**](https://matrixpy.codesociety.xyz/examples/) — ready-to-run example bots
|
|
83
|
+
demonstrating common patterns
|
|
84
|
+
|
|
85
|
+
## Contributing
|
|
86
|
+
|
|
87
|
+
We welcome everyone to contribute! Whether it's fixing bugs, suggesting features, or improving the docs. Every bit
|
|
88
|
+
helps.
|
|
89
|
+
|
|
90
|
+
- [Submit an issue](https://github.com/Code-Society-Lab/matrixpy/issues)
|
|
91
|
+
- [Open a pull request](https://github.com/Code-Society-Lab/matrixpy/blob/main/CONTRIBUTING.md)
|
|
92
|
+
- Hop into our [Matrix](https://matrix.to/#/%23codesociety:matrix.org)
|
|
93
|
+
or [Discord](https://discord.gg/code-society-823178343943897088) and say hi!
|
|
94
|
+
|
|
95
|
+
Please read the [CONTRIBUTING.md](./CONTRIBUTING.md) and follow the [code of conduct](./CODE_OF_CONDUCT.md).
|
|
96
|
+
|
|
97
|
+
## License
|
|
98
|
+
|
|
99
|
+
Released under the [MIT License](https://github.com/Code-Society-Lab/matrixpy/blob/main/LICENSE).
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Checks
|
|
2
|
+
|
|
3
|
+
Shows how to restrict a command to a specific set of users using a [check](../reference/checks.md). The `!secret` command is only accessible to users in the `allowed_users` set — anyone else receives an "Access denied" reply.
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
--8<-- "examples/checks.py"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Key points:
|
|
10
|
+
|
|
11
|
+
- `@secret_command.check` decorates an async function that returns `True` (allow) or `False` (deny). Returning `False` raises a [`CheckError`](../reference/errors.md).
|
|
12
|
+
- `@secret_command.error(CheckError)` handles the denial and sends a friendly reply instead of silently failing.
|
|
13
|
+
- `ctx.sender` is the full Matrix ID of the user who sent the command (e.g. `@alice:matrix.org`).
|
|
14
|
+
|
|
15
|
+
See the [Checks guide](../guides/checks.md) for built-in checks like `@is_owner` and how to compose multiple checks.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Cooldowns
|
|
2
|
+
|
|
3
|
+
Demonstrates two ways to apply a rate limit to a command, and how to handle the [`CooldownError`](../reference/errors.md) when the limit is exceeded.
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
--8<-- "examples/cooldown.py"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
There are two ways to set a cooldown:
|
|
10
|
+
|
|
11
|
+
- **`@cooldown(rate, period)` decorator** — applied before `@bot.command`. `rate=2, period=10` means 2 uses per 10 seconds per user.
|
|
12
|
+
- **`cooldown=(rate, period)` argument** — passed directly to `@bot.command` for a more compact one-liner.
|
|
13
|
+
|
|
14
|
+
Both produce a `CooldownError` when the limit is exceeded. The error object exposes `error.retry` — the number of seconds until the user can try again — which you can surface in the reply.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Error Handling
|
|
2
|
+
|
|
3
|
+
Shows both per-command error handlers and a global error handler, covering argument validation, runtime errors, and unknown commands.
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
--8<-- "examples/error_handling.py"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Three layers of error handling are demonstrated:
|
|
10
|
+
|
|
11
|
+
- **Global handler** — `@bot.error(CommandNotFoundError)` catches any command the bot doesn't recognise, across the whole bot. No `ctx` is available here since no command was matched.
|
|
12
|
+
- **Per-command handlers** — `@division.error(ZeroDivisionError)` and `@division.error(ValueError)` handle errors raised inside the `division` function itself.
|
|
13
|
+
- **Argument handler** — `@division.error(MissingArgumentError)` fires when the user doesn't supply enough arguments.
|
|
14
|
+
|
|
15
|
+
Handlers are matched by exception type. If no handler is registered for a raised exception, it propagates normally.
|
|
16
|
+
|
|
17
|
+
See the [Error Handling guide](../guides/error-handling.md) for the full picture.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Extension
|
|
2
|
+
|
|
3
|
+
Demonstrates how to split a bot into modules using [`Extension`](../reference/extension.md) and how to organise related commands into a [`Group`](../reference/group.md).
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
--8<-- "examples/extension.py"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Key points:
|
|
10
|
+
|
|
11
|
+
- `Extension("math")` creates a standalone module. It supports commands, groups, events, checks, and error handlers — everything `Bot` supports.
|
|
12
|
+
- `@extension.group("math")` creates a command group. Sub-commands are registered with `@math_group.command()` and invoked as `!math add`, `!math subtract`, etc.
|
|
13
|
+
- Per-command error handlers work the same as on `Bot`: `@divide.error(ZeroDivisionError)` handles division by zero inside the group.
|
|
14
|
+
|
|
15
|
+
To load this extension in your bot:
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
from matrix import Bot
|
|
19
|
+
from math_extension import extension as math_extension
|
|
20
|
+
|
|
21
|
+
bot = Bot()
|
|
22
|
+
bot.load_extension(math_extension)
|
|
23
|
+
bot.start(config="config.yaml")
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
See the [Bigger Bot guide](../guides/bigger-bot.md) for a full project layout using multiple extensions.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
Ready-to-run bots demonstrating common patterns. Each example is a complete, working bot you can copy and adapt.
|
|
4
|
+
|
|
5
|
+
All examples expect a `config.yaml` file in the same directory:
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
USERNAME: "@yourbot:matrix.org"
|
|
9
|
+
PASSWORD: "your_password"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
| Example | What it shows |
|
|
13
|
+
|---------|--------------|
|
|
14
|
+
| [Ping Bot](ping.md) | Minimal bot with a single command |
|
|
15
|
+
| [Reactions](reaction.md) | Listening to events and reacting to messages |
|
|
16
|
+
| [Checks](checks.md) | Restricting commands to specific users |
|
|
17
|
+
| [Cooldowns](cooldown.md) | Rate-limiting commands per user |
|
|
18
|
+
| [Error Handling](error-handling.md) | Per-command and global error handlers |
|
|
19
|
+
| [Extension](extension.md) | Splitting a bot into modules with command groups |
|
|
20
|
+
| [Scheduler](scheduler.md) | Running tasks on a cron schedule |
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Ping Bot
|
|
2
|
+
|
|
3
|
+
The simplest possible bot — one command that replies to `!ping` with `Pong!`. Start here if you're new to matrix.py.
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
--8<-- "examples/ping.py"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
`ctx.reply()` sends a message back to the same room the command was received in. Swap `"Pong!"` for any string, including formatted text.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Reactions
|
|
2
|
+
|
|
3
|
+
Demonstrates event listeners and the [`Message.react()`](../reference/message.md) API. The bot watches for incoming messages and reactions, and responds with emoji reactions of its own.
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
--8<-- "examples/reaction.py"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Two event handlers are registered here:
|
|
10
|
+
|
|
11
|
+
- `on_message` — fires on every `RoomMessageText` event. It fetches the full message object and reacts based on the message body.
|
|
12
|
+
- `on_react` — fires on every `ReactionEvent`. It fetches the original message that was reacted to and chains a follow-up reaction.
|
|
13
|
+
|
|
14
|
+
`room.fetch_message()` returns a [`Message`](../reference/message.md) object. You can react with an emoji string or any short text.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Scheduler
|
|
2
|
+
|
|
3
|
+
Shows how to run tasks on a cron schedule using `@bot.schedule`. Tasks run independently of commands — they fire at the specified time whether or not anyone sends a message.
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
--8<-- "examples/scheduler.py"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
`@bot.schedule` accepts a standard 5-field cron expression:
|
|
10
|
+
|
|
11
|
+
| Expression | Meaning |
|
|
12
|
+
|---|---|
|
|
13
|
+
| `* * * * *` | Every minute |
|
|
14
|
+
| `0 * * * *` | Every hour (on the hour) |
|
|
15
|
+
| `0 9 * * 1-5` | 9 AM every weekday |
|
|
16
|
+
|
|
17
|
+
The scheduled function receives no arguments. To send a message you need a [`Room`](../reference/room.md) object — get one with `bot.get_room(room_id)` before the bot starts, then call `room.send()` inside the task.
|
|
18
|
+
|
|
19
|
+
See the [`Scheduler` reference](../reference/scheduler.md) for the full API.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Bigger Bot - Extension
|
|
2
|
+
|
|
3
|
+
As your bot grows, keeping everything in a single file becomes harder to manage. That's where [`Extension`](../reference/extension.md) comes in, it lets you split your code into separate modules.
|
|
4
|
+
|
|
5
|
+
Here's an example file structure for a larger bot:
|
|
6
|
+
```
|
|
7
|
+
.
|
|
8
|
+
├─ bot
|
|
9
|
+
│ ├─ __init__.py
|
|
10
|
+
│ ├─ helpers.py
|
|
11
|
+
│ ├─ my_bot.py
|
|
12
|
+
│ └─ extensions
|
|
13
|
+
│ ├─ __init__.py
|
|
14
|
+
│ ├─ dev.py
|
|
15
|
+
│ ├─ moderation.py
|
|
16
|
+
│ └─ weather.py
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The `bot` package contains everything related to your bot, with `my_bot.py` as its entry point. It's responsible for importing and registering all extensions. This is just one way to structure your project, extensions are flexible enough to fit whatever organization works best for you.
|
|
20
|
+
|
|
21
|
+
## What is an `Extension`?
|
|
22
|
+
|
|
23
|
+
An `Extension` is a mechanism that lets you split your bot's functionality across multiple modules. Extensions support everything a [`Bot`](../reference/bot.md) supports, including:
|
|
24
|
+
|
|
25
|
+
- Event handlers
|
|
26
|
+
- Error handlers
|
|
27
|
+
- Commands
|
|
28
|
+
- Groups
|
|
29
|
+
- Checks
|
|
30
|
+
- Cron tasks
|
|
31
|
+
|
|
32
|
+
...and more.
|
|
33
|
+
|
|
34
|
+
## How to Create an Extension
|
|
35
|
+
|
|
36
|
+
Below is a basic definition of a `moderation` extension. It registers two commands, `ban` and `kick`, and an event handler for `on_member_ban`:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from nio import RoomMemberEvent
|
|
40
|
+
from matrix import Extension, Context
|
|
41
|
+
from bot.helpers import is_admin
|
|
42
|
+
|
|
43
|
+
extension = Extension("moderation")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@is_admin
|
|
47
|
+
@extension.command(description="Ban a member")
|
|
48
|
+
async def ban(ctx: Context, username: str) -> None:
|
|
49
|
+
...
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@is_admin
|
|
53
|
+
@extension.command(description="Kick a member")
|
|
54
|
+
async def kick(ctx: Context, username: str) -> None:
|
|
55
|
+
...
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@extension.event
|
|
59
|
+
def on_member_ban(event: RoomMemberEvent) -> None:
|
|
60
|
+
# Triggered when a user is banned
|
|
61
|
+
...
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## How to Register Extensions
|
|
65
|
+
|
|
66
|
+
To use an extension, import it and pass it to `bot.load_extension()`:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from matrix import Bot, Context
|
|
70
|
+
from bot.extensions.moderation import extension as moderation_extension
|
|
71
|
+
from bot.extensions.weather import extension as weather_extension
|
|
72
|
+
from bot.extensions.dev import extension as dev_extension
|
|
73
|
+
|
|
74
|
+
bot = Bot()
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@bot.command(description="Respond with 'Pong!'")
|
|
78
|
+
async def ping(ctx: Context):
|
|
79
|
+
await ctx.reply("Pong!")
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
bot.load_extension(moderation_extension)
|
|
83
|
+
bot.load_extension(weather_extension)
|
|
84
|
+
|
|
85
|
+
# Load the dev extension only in development environments
|
|
86
|
+
if in_dev:
|
|
87
|
+
bot.load_extension(dev_extension)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
bot.start(config="config.yml")
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Your bot now has three extensions registered: `moderation`, `weather`, and `dev` (the last one only in development).
|
|
94
|
+
|
|
95
|
+
You can also unload an extension using `bot.unload_extension()`.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# What is a Check?
|
|
2
|
+
A check is a function that runs _before_ your command. It returns:
|
|
3
|
+
- `True` - Allow the command to run
|
|
4
|
+
- `False` - Block the command and raise [`CheckError`](../reference/errors.md)
|
|
5
|
+
|
|
6
|
+
See also the [`checks`](../reference/checks.md) reference for built-in check decorators.
|
|
7
|
+
|
|
8
|
+
# Add a Check
|
|
9
|
+
Let's create an admin-only command:
|
|
10
|
+
```python
|
|
11
|
+
@bot.command()
|
|
12
|
+
async def restricted(ctx):
|
|
13
|
+
await ctx.reply("You passed all checks!")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@restricted.check
|
|
17
|
+
async def is_admin(ctx):
|
|
18
|
+
admins = ["@alice:example.com", "@bob:example.com"]
|
|
19
|
+
return ctx.sender in admins
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
# Multiple Checks
|
|
23
|
+
You can add multiple checks to one command. ALL checks must pass:
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
@bot.command()
|
|
27
|
+
async def restricted(ctx):
|
|
28
|
+
await ctx.reply("You passed all checks!")
|
|
29
|
+
|
|
30
|
+
@restricted.check
|
|
31
|
+
async def check_one(ctx):
|
|
32
|
+
# Must be from a specific room
|
|
33
|
+
allowed_rooms = ["!room1:example.com", "!room2:example.com"]
|
|
34
|
+
return ctx.room_id in allowed_rooms
|
|
35
|
+
|
|
36
|
+
@restricted.check
|
|
37
|
+
async def check_two(ctx):
|
|
38
|
+
# Must not be banned
|
|
39
|
+
banned = ["@troublemaker:example.com"]
|
|
40
|
+
return ctx.sender not in banned
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Both checks must return `True` for the command to run.
|
|
44
|
+
|
|
45
|
+
# Global Checks (Bot-Level)
|
|
46
|
+
You can apply a check to _all_ commands with `@bot.check`:
|
|
47
|
+
```python
|
|
48
|
+
@bot.check
|
|
49
|
+
async def not_banned(ctx):
|
|
50
|
+
"""No banned users can run ANY commands"""
|
|
51
|
+
banned_users = ["@spammer:example.com", "@troll:example.com"]
|
|
52
|
+
return ctx.sender not in banned_users
|
|
53
|
+
```
|
|
54
|
+
Now this check runs before _every_ command on your bot.
|
|
55
|
+
|
|
56
|
+
# What is a Cooldown?
|
|
57
|
+
A cooldown prevents users from running a command too frequently. It's like a check, but specifically for rate limiting. When exceeded it raises a [`CooldownError`](../reference/errors.md).
|
|
58
|
+
|
|
59
|
+
### Adding a Cooldown
|
|
60
|
+
```python
|
|
61
|
+
@bot.command(
|
|
62
|
+
description="Searches for something",
|
|
63
|
+
cooldown=(3, 60.0) # 3 calls per 60 seconds
|
|
64
|
+
)
|
|
65
|
+
async def search(ctx, query: str):
|
|
66
|
+
# Simulate expensive operation
|
|
67
|
+
await ctx.reply(f"Searching for: {query}")
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Cooldown format:** `(rate, period)`
|
|
71
|
+
- `rate` (int): Number of times the command can be called
|
|
72
|
+
- `period` (float): Time window in seconds
|
|
73
|
+
|
|
74
|
+
**Example interpretations:**
|
|
75
|
+
- `(1, 10.0)` - Once every 10 seconds
|
|
76
|
+
- `(5, 60.0)` - 5 times per minute
|
|
77
|
+
- `(10, 3600.0)` - 10 times per hour
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
### Setting Cooldowns Programmatically
|
|
81
|
+
```python
|
|
82
|
+
@bot.command()
|
|
83
|
+
async def limited(ctx):
|
|
84
|
+
await ctx.reply("This command is rate-limited")
|
|
85
|
+
|
|
86
|
+
# Set cooldown after command creation
|
|
87
|
+
limited.set_cooldown(rate=2, period=30.0) # 2 times per 30 seconds
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Handling Cooldown Errors
|
|
91
|
+
When a user hits the cooldown limit, you can tell them how long to wait:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from matrix.errors import CooldownError
|
|
95
|
+
|
|
96
|
+
@bot.error(CooldownError)
|
|
97
|
+
async def handle_cooldown(error):
|
|
98
|
+
# error.retry tells you how many seconds until they can retry
|
|
99
|
+
wait_time = int(error.retry)
|
|
100
|
+
# You can send a message here if you have access to context
|
|
101
|
+
print(f"Cooldown hit! Wait {wait_time} seconds")
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# Hooks
|
|
106
|
+
```python
|
|
107
|
+
@command.before_invoke
|
|
108
|
+
async def before(ctx):
|
|
109
|
+
# Runs before command
|
|
110
|
+
|
|
111
|
+
@command.after_invoke
|
|
112
|
+
async def after(ctx):
|
|
113
|
+
# Runs after command succeeds
|
|
114
|
+
```
|