Metadata-Version: 2.4
Name: toptl-ptb
Version: 0.1.0
Summary: python-telegram-bot plugin for TOP.TL — autopost bot stats, gate commands behind votes, handle vote webhooks.
Project-URL: Homepage, https://top.tl
Project-URL: Documentation, https://top.tl/developers
Project-URL: Repository, https://github.com/top-tl/ptb
Project-URL: Issues, https://github.com/top-tl/ptb/issues
Author-email: "TOP.TL" <hello@top.tl>
License: MIT
License-File: LICENSE
Keywords: bot,plugin,ptb,python-telegram-bot,stats,telegram,top.tl,toptl,votes
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Communications :: Chat
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: python-telegram-bot>=21.0
Requires-Dist: toptl>=0.1.1
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Requires-Dist: twine>=5.0; extra == 'dev'
Description-Content-Type: text/markdown

# toptl-ptb

[![PyPI version](https://img.shields.io/pypi/v/toptl-ptb.svg?label=pypi&color=3775a9)](https://pypi.org/project/toptl-ptb/)
[![Python versions](https://img.shields.io/pypi/pyversions/toptl-ptb.svg?color=3776ab)](https://pypi.org/project/toptl-ptb/)
[![Downloads](https://img.shields.io/pypi/dm/toptl-ptb.svg?color=blue)](https://pypi.org/project/toptl-ptb/)
[![License](https://img.shields.io/pypi/l/toptl-ptb.svg?color=green)](https://github.com/top-tl/ptb/blob/main/LICENSE)
[![python-telegram-bot](https://img.shields.io/badge/python--telegram--bot-21%2B-26a5e4)](https://github.com/python-telegram-bot/python-telegram-bot)
[![TOP.TL](https://img.shields.io/badge/top.tl-developers-2ec4b6)](https://top.tl/developers)

Official [TOP.TL](https://top.tl) plugin for **python-telegram-bot**. One call wires up autoposted bot stats, vote-gated commands, and webhook helpers — all on top of the [`toptl`](https://pypi.org/project/toptl/) SDK.

## Install

```bash
pip install toptl-ptb
```

Python 3.9+. Pulls in `toptl>=0.1.1` and `python-telegram-bot>=21.0`.

## Quick start

```python
from telegram.ext import ApplicationBuilder, CommandHandler
from toptl import AsyncTopTL
from toptl_ptb import setup_toptl, vote_required

app = ApplicationBuilder().token("BOT_TOKEN").build()
client = AsyncTopTL("toptl_xxx")

# One line installs the tracker + autoposter on the Application.
plugin = setup_toptl(app, client, "mybot")

@vote_required(plugin, vote_url="https://top.tl/mybot")
async def premium(update, context):
    await update.message.reply_text("Thanks for voting!")

app.add_handler(CommandHandler("premium", premium))
app.run_polling()
```

`setup_toptl` does three things:

1. Adds a low-priority `TypeHandler` that records unique user / group / channel IDs from every update.
2. Schedules a `JobQueue` task that flushes those counts to TOP.TL every 30 min — only when they changed, so you're not burning API quota on idle minutes.
3. Returns a `TopTLPlugin` handle you use for vote checks and manual flushes.

## Vote gating

The `@vote_required(plugin)` decorator short-circuits the handler and replies with a prompt when the user hasn't voted:

```python
@vote_required(plugin, message="Vote to unlock this: https://top.tl/mybot")
async def premium(update, context):
    ...
```

For checks inside existing logic:

```python
if await plugin.has_voted(update.effective_user.id):
    ...
```

Both paths fail-open — network errors never block your handler, they just count as "not voted" and log at ERROR level.

## Tuning the autoposter

```python
plugin = setup_toptl(
    app, client, "mybot",
    interval_seconds=15 * 60,   # flush every 15 min instead of 30
    first_seconds=5,            # first flush 5s after startup
    handler_group=-1,           # override the default -100 group
)
```

To flush manually — for example from a graceful-shutdown hook:

```python
async def post_shutdown(application):
    await plugin.post_now()
    await client.aclose()

app.post_shutdown = post_shutdown
```

## Requirements

- `python-telegram-bot[job-queue]>=21.0` — the `[job-queue]` extra enables the autoposter. Without it you can still call `plugin.post_now()` from your own schedule (e.g. an existing `apscheduler`).
- Python 3.9 or newer.

## License

MIT.

---

Part of the [TOP.TL developer ecosystem](https://top.tl/developers). Issues and contributions: [`top-tl/ptb`](https://github.com/top-tl/ptb).
