django-telegram-app 0.1.1__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.
- django_telegram_app-0.1.1/.github/FUNDING.yml +1 -0
- django_telegram_app-0.1.1/.github/workflows/ci.yml +38 -0
- django_telegram_app-0.1.1/.github/workflows/release.yml +31 -0
- django_telegram_app-0.1.1/.gitignore +178 -0
- django_telegram_app-0.1.1/LICENSE +21 -0
- django_telegram_app-0.1.1/PKG-INFO +125 -0
- django_telegram_app-0.1.1/README.md +88 -0
- django_telegram_app-0.1.1/django_telegram_app/__init__.py +1 -0
- django_telegram_app-0.1.1/django_telegram_app/admin.py +52 -0
- django_telegram_app-0.1.1/django_telegram_app/apps.py +15 -0
- django_telegram_app-0.1.1/django_telegram_app/bot/__init__.py +58 -0
- django_telegram_app-0.1.1/django_telegram_app/bot/base.py +243 -0
- django_telegram_app-0.1.1/django_telegram_app/bot/bot.py +126 -0
- django_telegram_app-0.1.1/django_telegram_app/bot/testing/__init__.py +1 -0
- django_telegram_app-0.1.1/django_telegram_app/bot/testing/testcases.py +76 -0
- django_telegram_app-0.1.1/django_telegram_app/checks.py +83 -0
- django_telegram_app-0.1.1/django_telegram_app/conf.py +32 -0
- django_telegram_app-0.1.1/django_telegram_app/management/__init__.py +1 -0
- django_telegram_app-0.1.1/django_telegram_app/management/base.py +68 -0
- django_telegram_app-0.1.1/django_telegram_app/management/commands/__init__.py +1 -0
- django_telegram_app-0.1.1/django_telegram_app/management/commands/setwebhook.py +34 -0
- django_telegram_app-0.1.1/django_telegram_app/migrations/0001_initial.py +63 -0
- django_telegram_app-0.1.1/django_telegram_app/migrations/__init__.py +0 -0
- django_telegram_app-0.1.1/django_telegram_app/models.py +118 -0
- django_telegram_app-0.1.1/django_telegram_app/resolver.py +31 -0
- django_telegram_app-0.1.1/django_telegram_app/urls.py +10 -0
- django_telegram_app-0.1.1/django_telegram_app/views.py +31 -0
- django_telegram_app-0.1.1/django_telegram_app.egg-info/PKG-INFO +125 -0
- django_telegram_app-0.1.1/django_telegram_app.egg-info/SOURCES.txt +50 -0
- django_telegram_app-0.1.1/django_telegram_app.egg-info/dependency_links.txt +1 -0
- django_telegram_app-0.1.1/django_telegram_app.egg-info/requires.txt +10 -0
- django_telegram_app-0.1.1/django_telegram_app.egg-info/top_level.txt +1 -0
- django_telegram_app-0.1.1/docs/01-configuration.md +47 -0
- django_telegram_app-0.1.1/docs/02-bot-commands.md +50 -0
- django_telegram_app-0.1.1/docs/03-management-commands.md +30 -0
- django_telegram_app-0.1.1/pyproject.toml +70 -0
- django_telegram_app-0.1.1/runtests.py +25 -0
- django_telegram_app-0.1.1/setup.cfg +4 -0
- django_telegram_app-0.1.1/tests/__init__.py +1 -0
- django_telegram_app-0.1.1/tests/settings.py +53 -0
- django_telegram_app-0.1.1/tests/test_admin.py +44 -0
- django_telegram_app-0.1.1/tests/test_apps.py +16 -0
- django_telegram_app-0.1.1/tests/test_bot.py +209 -0
- django_telegram_app-0.1.1/tests/test_checks.py +66 -0
- django_telegram_app-0.1.1/tests/test_models.py +55 -0
- django_telegram_app-0.1.1/tests/test_resolver.py +40 -0
- django_telegram_app-0.1.1/tests/testapps/samplebot/__init__.py +1 -0
- django_telegram_app-0.1.1/tests/testapps/samplebot/apps.py +11 -0
- django_telegram_app-0.1.1/tests/testapps/samplebot/models.py +11 -0
- django_telegram_app-0.1.1/tests/testapps/samplebot/telegrambot/commands/echo.py +43 -0
- django_telegram_app-0.1.1/tests/testapps/samplebot/telegrambot/commands/poll.py +96 -0
- django_telegram_app-0.1.1/tests/urls.py +9 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
github: "shifqu"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: "CI Validation"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
validate-code:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.13"
|
|
18
|
+
cache: "pip"
|
|
19
|
+
|
|
20
|
+
- name: Install dependencies
|
|
21
|
+
run: |
|
|
22
|
+
python -m pip install --upgrade pip
|
|
23
|
+
pip install --editable .[dev]
|
|
24
|
+
|
|
25
|
+
- name: Lint
|
|
26
|
+
run: |
|
|
27
|
+
ruff check --fix django_telegram_app/ tests/
|
|
28
|
+
pylint django_telegram_app/ tests/
|
|
29
|
+
ruff format --check django_telegram_app/ tests/
|
|
30
|
+
pyright django_telegram_app/ tests/
|
|
31
|
+
|
|
32
|
+
- name: Tests with Coverage
|
|
33
|
+
run: |
|
|
34
|
+
coverage run -m runtests
|
|
35
|
+
|
|
36
|
+
- name: Coverage Report
|
|
37
|
+
run: |
|
|
38
|
+
coverage report --skip-covered --show-missing
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
id-token: write # REQUIRED for PyPI trusted publishing
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build-and-publish:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.13"
|
|
20
|
+
cache: "pip"
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: |
|
|
24
|
+
python -m pip install --upgrade pip
|
|
25
|
+
pip install --editable .[dev]
|
|
26
|
+
|
|
27
|
+
- name: Build sdist & wheel
|
|
28
|
+
run: python -Im build
|
|
29
|
+
|
|
30
|
+
- name: Publish to PyPI
|
|
31
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py,cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
#uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
#poetry.lock
|
|
109
|
+
|
|
110
|
+
# pdm
|
|
111
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
112
|
+
#pdm.lock
|
|
113
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
114
|
+
# in version control.
|
|
115
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
|
116
|
+
# .pdm.toml
|
|
117
|
+
# .pdm-python
|
|
118
|
+
# .pdm-build/
|
|
119
|
+
|
|
120
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
121
|
+
__pypackages__/
|
|
122
|
+
|
|
123
|
+
# Celery stuff
|
|
124
|
+
celerybeat-schedule
|
|
125
|
+
celerybeat.pid
|
|
126
|
+
|
|
127
|
+
# SageMath parsed files
|
|
128
|
+
*.sage.py
|
|
129
|
+
|
|
130
|
+
# Environments
|
|
131
|
+
.env
|
|
132
|
+
.dockerenv
|
|
133
|
+
.venv
|
|
134
|
+
env/
|
|
135
|
+
venv/
|
|
136
|
+
ENV/
|
|
137
|
+
env.bak/
|
|
138
|
+
venv.bak/
|
|
139
|
+
|
|
140
|
+
# Spyder project settings
|
|
141
|
+
.spyderproject
|
|
142
|
+
.spyproject
|
|
143
|
+
|
|
144
|
+
# Rope project settings
|
|
145
|
+
.ropeproject
|
|
146
|
+
|
|
147
|
+
# mkdocs documentation
|
|
148
|
+
/site
|
|
149
|
+
|
|
150
|
+
# mypy
|
|
151
|
+
.mypy_cache/
|
|
152
|
+
.dmypy.json
|
|
153
|
+
dmypy.json
|
|
154
|
+
|
|
155
|
+
# Pyre type checker
|
|
156
|
+
.pyre/
|
|
157
|
+
|
|
158
|
+
# pytype static type analyzer
|
|
159
|
+
.pytype/
|
|
160
|
+
|
|
161
|
+
# Cython debug symbols
|
|
162
|
+
cython_debug/
|
|
163
|
+
|
|
164
|
+
# PyCharm
|
|
165
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
166
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
167
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
168
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
169
|
+
#.idea/
|
|
170
|
+
|
|
171
|
+
# PyPI configuration file
|
|
172
|
+
.pypirc
|
|
173
|
+
|
|
174
|
+
# Ruff
|
|
175
|
+
.ruff_cache/
|
|
176
|
+
|
|
177
|
+
# Mac
|
|
178
|
+
.DS_Store
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 shifqu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: django-telegram-app
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: A Django app that integrates with Telegram to create bots.
|
|
5
|
+
Author-email: Sonny Valkeneers <sonny@softllama.net>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Environment :: Web Environment
|
|
8
|
+
Classifier: Framework :: Django
|
|
9
|
+
Classifier: Framework :: Django :: 5.2
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Internet
|
|
21
|
+
Classifier: Topic :: Communications :: Chat
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: django>=5.2
|
|
28
|
+
Requires-Dist: requests>=2.32
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: coverage>=7.11; extra == "dev"
|
|
31
|
+
Requires-Dist: django-types>=0.22; extra == "dev"
|
|
32
|
+
Requires-Dist: ruff>=0.14; extra == "dev"
|
|
33
|
+
Requires-Dist: pylint<4.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pyright>=1.1; extra == "dev"
|
|
35
|
+
Requires-Dist: build>=1.3; extra == "dev"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
# django-telegram-app
|
|
39
|
+
A Django app to integrate Telegram bots into your project.
|
|
40
|
+
|
|
41
|
+
Detailed documentation is in the [`docs/`](docs/) directory.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
[](https://github.com/astral-sh/ruff)
|
|
45
|
+
[](https://github.com/RobertCraigie/pyright-python)
|
|
47
|
+
[](https://github.com/pylint-dev/pylint)
|
|
49
|
+
[](https://docs.djangoproject.com/en/5.2/)
|
|
50
|
+
[](https://opensource.org/license/mit)
|
|
51
|
+
[](https://github.com/shifqu/django-telegram-app/actions/workflows/ci.yml)
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Features
|
|
56
|
+
|
|
57
|
+
- ✅ Command-based bot architecture with step-based flow
|
|
58
|
+
- ✅ Swappable `TelegramSettings` model
|
|
59
|
+
- ✅ Inline admin integration for linking Telegram settings to users
|
|
60
|
+
- ✅ Extensible: add commands per app via auto-discovery
|
|
61
|
+
- ✅ Built-in system checks for misconfiguration
|
|
62
|
+
- ✅ Django ORM integration (no direct API handling required)
|
|
63
|
+
- ✅ Easy to test (includes custom TelegramTestCase)
|
|
64
|
+
|
|
65
|
+
## Requirements (officially supported)
|
|
66
|
+
|
|
67
|
+
- Python **3.10+**
|
|
68
|
+
- Django **5.2+**
|
|
69
|
+
|
|
70
|
+
## Quick start
|
|
71
|
+
|
|
72
|
+
1. Install the package
|
|
73
|
+
```bash
|
|
74
|
+
pip install django-telegram-app
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
1. Add "django_telegram_app" to your INSTALLED_APPS setting like this:
|
|
78
|
+
```python
|
|
79
|
+
INSTALLED_APPS = [
|
|
80
|
+
...,
|
|
81
|
+
"django_telegram_app",
|
|
82
|
+
]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
2. Include the telegram URLconf in your project urls.py like this:
|
|
86
|
+
```python
|
|
87
|
+
...
|
|
88
|
+
from django_telegram_app.conf import settings as telegram_app_settings
|
|
89
|
+
...
|
|
90
|
+
path(telegram_app_settings.ROOT_URL, include("django_telegram_app.urls")),
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
3. Create your own commands in each app under `{appname}/telegrambot/commands/`. Refer to the documentation for more details on how to write custom commands.
|
|
94
|
+
|
|
95
|
+
4. Add the provided telegramsettings inline to your user-model like this:
|
|
96
|
+
```python
|
|
97
|
+
# user/admin.py
|
|
98
|
+
from django_telegram_app.admin import TelegramSettingInline
|
|
99
|
+
...
|
|
100
|
+
class CustomUserAdmin(UserAdmin):
|
|
101
|
+
...
|
|
102
|
+
inlines = [TelegramSettingInline]
|
|
103
|
+
# or add it to an existing entry
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
5. Configure the telegram settings. Refer to the documentation for all possible settings.
|
|
107
|
+
Minimal configuration is like this:
|
|
108
|
+
```python
|
|
109
|
+
# project/settings.py
|
|
110
|
+
...
|
|
111
|
+
TELEGRAM = {
|
|
112
|
+
"BOT_URL": "https://api.telegram.org/bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/"
|
|
113
|
+
}
|
|
114
|
+
...
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
6. Run `python manage.py migrate` to create the models.
|
|
118
|
+
|
|
119
|
+
7. Run `python manage.py setwebhook` to set the url on which you would like to receive telegram updates.
|
|
120
|
+
|
|
121
|
+
8. Start the development server and visit the admin to edit users and add/complete TelegramSettings there.
|
|
122
|
+
|
|
123
|
+
## License
|
|
124
|
+
|
|
125
|
+
This project is licensed under the MIT License — see the [`LICENSE`](LICENSE) file for details.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# django-telegram-app
|
|
2
|
+
A Django app to integrate Telegram bots into your project.
|
|
3
|
+
|
|
4
|
+
Detailed documentation is in the [`docs/`](docs/) directory.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
[](https://github.com/astral-sh/ruff)
|
|
8
|
+
[](https://github.com/RobertCraigie/pyright-python)
|
|
10
|
+
[](https://github.com/pylint-dev/pylint)
|
|
12
|
+
[](https://docs.djangoproject.com/en/5.2/)
|
|
13
|
+
[](https://opensource.org/license/mit)
|
|
14
|
+
[](https://github.com/shifqu/django-telegram-app/actions/workflows/ci.yml)
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
- ✅ Command-based bot architecture with step-based flow
|
|
21
|
+
- ✅ Swappable `TelegramSettings` model
|
|
22
|
+
- ✅ Inline admin integration for linking Telegram settings to users
|
|
23
|
+
- ✅ Extensible: add commands per app via auto-discovery
|
|
24
|
+
- ✅ Built-in system checks for misconfiguration
|
|
25
|
+
- ✅ Django ORM integration (no direct API handling required)
|
|
26
|
+
- ✅ Easy to test (includes custom TelegramTestCase)
|
|
27
|
+
|
|
28
|
+
## Requirements (officially supported)
|
|
29
|
+
|
|
30
|
+
- Python **3.10+**
|
|
31
|
+
- Django **5.2+**
|
|
32
|
+
|
|
33
|
+
## Quick start
|
|
34
|
+
|
|
35
|
+
1. Install the package
|
|
36
|
+
```bash
|
|
37
|
+
pip install django-telegram-app
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
1. Add "django_telegram_app" to your INSTALLED_APPS setting like this:
|
|
41
|
+
```python
|
|
42
|
+
INSTALLED_APPS = [
|
|
43
|
+
...,
|
|
44
|
+
"django_telegram_app",
|
|
45
|
+
]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
2. Include the telegram URLconf in your project urls.py like this:
|
|
49
|
+
```python
|
|
50
|
+
...
|
|
51
|
+
from django_telegram_app.conf import settings as telegram_app_settings
|
|
52
|
+
...
|
|
53
|
+
path(telegram_app_settings.ROOT_URL, include("django_telegram_app.urls")),
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
3. Create your own commands in each app under `{appname}/telegrambot/commands/`. Refer to the documentation for more details on how to write custom commands.
|
|
57
|
+
|
|
58
|
+
4. Add the provided telegramsettings inline to your user-model like this:
|
|
59
|
+
```python
|
|
60
|
+
# user/admin.py
|
|
61
|
+
from django_telegram_app.admin import TelegramSettingInline
|
|
62
|
+
...
|
|
63
|
+
class CustomUserAdmin(UserAdmin):
|
|
64
|
+
...
|
|
65
|
+
inlines = [TelegramSettingInline]
|
|
66
|
+
# or add it to an existing entry
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
5. Configure the telegram settings. Refer to the documentation for all possible settings.
|
|
70
|
+
Minimal configuration is like this:
|
|
71
|
+
```python
|
|
72
|
+
# project/settings.py
|
|
73
|
+
...
|
|
74
|
+
TELEGRAM = {
|
|
75
|
+
"BOT_URL": "https://api.telegram.org/bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/"
|
|
76
|
+
}
|
|
77
|
+
...
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
6. Run `python manage.py migrate` to create the models.
|
|
81
|
+
|
|
82
|
+
7. Run `python manage.py setwebhook` to set the url on which you would like to receive telegram updates.
|
|
83
|
+
|
|
84
|
+
8. Start the development server and visit the admin to edit users and add/complete TelegramSettings there.
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
This project is licensed under the MIT License — see the [`LICENSE`](LICENSE) file for details.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Telegram app."""
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""Telegram admin."""
|
|
2
|
+
|
|
3
|
+
from django.contrib import admin
|
|
4
|
+
|
|
5
|
+
from django_telegram_app.models import CallbackData, Message
|
|
6
|
+
from django_telegram_app.resolver import get_telegram_settings_model
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TelegramSettingInline(admin.TabularInline):
|
|
10
|
+
"""Represent a telegram setting inline in the admin."""
|
|
11
|
+
|
|
12
|
+
model = get_telegram_settings_model()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class CallbackDataAdmin(admin.ModelAdmin):
|
|
16
|
+
"""Represent the CallbackData admin."""
|
|
17
|
+
|
|
18
|
+
list_display = ("token", "data_truncated")
|
|
19
|
+
|
|
20
|
+
def has_add_permission(self, request): # noqa: ARG002 # pylint: disable=unused-argument
|
|
21
|
+
"""Do not allow to add callback_data."""
|
|
22
|
+
return False
|
|
23
|
+
|
|
24
|
+
def has_delete_permission(self, request, obj=None): # noqa: ARG002 # pylint: disable=unused-argument
|
|
25
|
+
"""Do not allow to delete callback_data."""
|
|
26
|
+
return False
|
|
27
|
+
|
|
28
|
+
def has_change_permission(self, request, obj=None): # noqa: ARG002 # pylint: disable=unused-argument
|
|
29
|
+
"""Do not allow to change callback_data."""
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class MessageAdmin(admin.ModelAdmin):
|
|
34
|
+
"""Represent the Message admin."""
|
|
35
|
+
|
|
36
|
+
list_display = ("update_id", "message_truncated", "error")
|
|
37
|
+
|
|
38
|
+
def has_add_permission(self, request): # noqa: ARG002 # pylint: disable=unused-argument
|
|
39
|
+
"""Do not allow to add messages."""
|
|
40
|
+
return False
|
|
41
|
+
|
|
42
|
+
def has_delete_permission(self, request, obj=None): # noqa: ARG002 # pylint: disable=unused-argument
|
|
43
|
+
"""Do not allow to delete messages."""
|
|
44
|
+
return False
|
|
45
|
+
|
|
46
|
+
def has_change_permission(self, request, obj=None): # noqa: ARG002 # pylint: disable=unused-argument
|
|
47
|
+
"""Do not allow to change messages."""
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
admin.site.register(CallbackData, CallbackDataAdmin)
|
|
52
|
+
admin.site.register(Message, MessageAdmin)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Telegram app configuration."""
|
|
2
|
+
|
|
3
|
+
from django.apps import AppConfig
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TelegramConfig(AppConfig):
|
|
7
|
+
"""Represent the telegram AppConfig."""
|
|
8
|
+
|
|
9
|
+
default_auto_field = "django.db.models.BigAutoField"
|
|
10
|
+
name = "django_telegram_app"
|
|
11
|
+
label = "django_telegram_app"
|
|
12
|
+
|
|
13
|
+
def ready(self):
|
|
14
|
+
"""Import checks."""
|
|
15
|
+
import django_telegram_app.checks # noqa: F401
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""Bot module for the Telegram app."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import functools
|
|
6
|
+
import pkgutil
|
|
7
|
+
from importlib import import_module
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
from django.apps import apps
|
|
12
|
+
from django.conf import settings
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from django_telegram_app.bot.base import BaseCommand
|
|
16
|
+
from django_telegram_app.models import AbstractTelegramSettings
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def find_commands(telegrambot_dir: Path):
|
|
20
|
+
"""Return a list of all the command names that are available for the provided telegrambot path."""
|
|
21
|
+
command_dir = telegrambot_dir / "commands"
|
|
22
|
+
return [name for _, name, is_pkg in pkgutil.iter_modules([command_dir]) if not is_pkg and not name.startswith("_")]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def load_command_class(app_name: str, name: str, settings: AbstractTelegramSettings) -> BaseCommand:
|
|
26
|
+
"""Return the Command class instance for the given command name and application name.
|
|
27
|
+
|
|
28
|
+
Allow all errors raised by the import process (ImportError, AttributeError) to propagate.
|
|
29
|
+
"""
|
|
30
|
+
module = import_module(f"{app_name}.telegrambot.commands.{name}")
|
|
31
|
+
return module.Command(settings)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@functools.cache
|
|
35
|
+
def get_commands():
|
|
36
|
+
"""Return a dictionary mapping command names to their callback applications.
|
|
37
|
+
|
|
38
|
+
Look for a telegrambot.commands package in each installed application -- if a commands package exists, register all
|
|
39
|
+
commands in that package.
|
|
40
|
+
|
|
41
|
+
All user-defined commands from the specified settings module are included.
|
|
42
|
+
|
|
43
|
+
The dictionary is in the format {command_name: app_name}. Key-value
|
|
44
|
+
pairs from this dictionary can then be used in calls to
|
|
45
|
+
load_command_class(app_name, command_name)
|
|
46
|
+
|
|
47
|
+
The dictionary is cached on the first call and reused on subsequent
|
|
48
|
+
calls.
|
|
49
|
+
"""
|
|
50
|
+
commands: dict[str, str] = {}
|
|
51
|
+
if not settings.configured:
|
|
52
|
+
return commands
|
|
53
|
+
|
|
54
|
+
for app_config in apps.get_app_configs():
|
|
55
|
+
path = Path(app_config.path) / "telegrambot"
|
|
56
|
+
commands.update({name: app_config.name for name in find_commands(path)})
|
|
57
|
+
|
|
58
|
+
return commands
|