Metadata-Version: 2.1
Name: tgpromo
Version: 0.1.0
Summary: Asynchronous SDK for integrating with the tgpromo.org API
Home-page: https://tgpromo.org
License: MIT
Keywords: telegram,tgpromo,advertising,async,sdk,api,marketing
Author: tgpromo
Author-email: contact@tgpromo.org
Requires-Python: >=3.8,<4.0
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
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
Requires-Dist: httpx (>=0.28.1,<0.29.0)
Requires-Dist: pydantic (>=2.10.6,<3.0.0)
Project-URL: Repository, https://github.com/tgpromo/tgpromo-python
Description-Content-Type: text/markdown

# tgpromo

An asynchronous Python SDK for integrating your Telegram bot or service with the [tgpromo.org](https://tgpromo.org) advertising platform.

- 🚀 Supports Python 3.8 and above  
- 🔐 Safe by design — robust error handling and health checks  
- ⚡️ Minimal integration — just one method call to show ads

---

## 🔗 Useful Links

- **Website:** [tgpromo.org](https://tgpromo.org)
- **API Base URL:** https://api.tgpromo.org  
- **Swagger / OpenAPI docs:** https://docs.api.tgpromo.org  
- **Telegram Mini-App (bot):** [@tgpromo_bot](https://t.me/tgpromo_bot)  
- **Telegram Channel:** [@tgpromo](https://t.me/tgpromo)

---

## 📦 Installation

```bash
pip install tgpromo
```

---

## ⚙️ Quick Start
To integrate your bot with tgpromo, simply call the ad impression method each time you receive a message from a user and want to show an ad.

This is the only required step — the method returns a flag indicating whether the impression was successfully sent.

If your bot responds quickly, you can show the ad **after** sending your reply.


```python
import asyncio
from tgpromo import PartnerClient, TGPromoException

async def main():
    client = PartnerClient(token='YOUR_PARTNER_API_TOKEN')

    try:
        result = await client.ads.impressions.send(
            user_id=123,
            message_id=456
        )
        print('Impression sent: ', result.impression_sent)
    except TGPromoException as e:
        print('Impression send error: ', e)
        
    # Clean up client when done
    await client.aclose()

if __name__ == '__main__':
    asyncio.run(main())
```

## 🤖 Example with aiogram
This example uses aiogram v3. It sends an ad impression when the /start command is received.

You can also show ads after any user interaction — for example, after completing a task or sending a message.

```python
import asyncio
from os import getenv

from aiogram import Bot, Dispatcher, html
from aiogram.client.default import DefaultBotProperties
from aiogram.enums import ParseMode
from aiogram.filters import CommandStart
from aiogram.types import Message
from tgpromo import PartnerClient, TGPromoException


# Bot token can be obtained via https://t.me/BotFather
BOT_TOKEN = getenv('BOT_TOKEN')

# Partner API token is available in the bot management panel (https://tgpromo.org or https://t.me/tgpromo_bot)
TGPROMO_PARTNER_API_TOKEN = getenv('TGPROMO_PARTNER_API_TOKEN')

dp = Dispatcher()
partner_client = PartnerClient(TGPROMO_PARTNER_API_TOKEN)


@dp.message(CommandStart())
async def command_start_handler(message: Message) -> None:
    """
    Handle the /start command and attempt to send an ad impression.
    """
    try:
        result = await partner_client.ads.impressions.send(
            user_id=message.from_user.id,
            message_id=message.message_id
        )

        if not result.impression_sent:
            print('Impression not sent - try another network or your own ad ;)')
    except TGPromoException as e:
        print('Impression send error: ', e)

    await message.answer(f'Hello, {html.bold(message.from_user.full_name)}!')


async def main() -> None:
    bot = Bot(token=BOT_TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML))
    await dp.start_polling(bot)


if __name__ == '__main__':
    asyncio.run(main())
```

---

## 🔒 Safety & Resilience Features
- Your service remains stable even if the tgpromo API becomes temporarily unreachable
- API requests are automatically paused during network outages or server errors
- Availability is automatically restored once API connectivity returns
- Raises `TGPromoException` for general errors, and `PartnerAPIException` for partner-specific issues

---

## 📝 License

This project is licensed under the MIT License – see the [LICENSE](./LICENSE) file for details.
