# Telegram Notification Bot ๐ค
[](https://www.python.org/downloads/)
[](https://badge.fury.io/py/tg-notification-bot)
A modern, type-safe Python library for sending notifications through Telegram bots. Built with the latest aiogram 3.x
and Pydantic 2.x for maximum reliability and developer experience.
## โจ Features
- ๐ **Type Safety**: Full type annotations with mypy support
- ๐ **Modern**: Built on aiogram 3.x and Pydantic 2.x
- ๐ก๏ธ **Robust Error Handling**: Comprehensive exception handling with custom error types
- ๐ **Validation**: Input validation using Pydantic models
- ๐ฏ **Multiple Formats**: Send text, photos, and documents
- ๐ง **Flexible Configuration**: Support for various chat ID formats
- ๐ก **Multi-Chat Support**: Send messages to multiple chats simultaneously
- ๐ฆ **Concurrent Control**: Configurable concurrency limits for bulk operations
- ๐งช **Well Tested**: Comprehensive test suite with high coverage
- ๐ฆ **Zero Dependencies**: Only requires aiogram and pydantic
## ๐ Installation
```bash
uv pip install tg-notification-bot
```
For development:
```bash
# Using uv (recommended)
uv add --dev tg-notification-bot
```
## ๐ Quick Start
### Basic Usage
```python
import asyncio
from tg_notification_bot import TelegramNotificationBot
async def main():
  # Initialize with token and chat ID
  bot = TelegramNotificationBot("YOUR_BOT_TOKEN", "YOUR_CHAT_ID")
  # Send a simple message
  await bot.send_message("Hello, World! ๐")
  # Send a photo
  await bot.send_photo("path/to/photo.jpg", caption="Check this out!")
  # Send a document
  await bot.send_document("path/to/document.pdf", caption="Important file")
  # Don't forget to close the session
  await bot.close()
# Run the example
asyncio.run(main())
```
### Multi-Chat Support
#### Environment Variables for Multiple Chats
```bash
# .env file - Multiple chats separated by commas
TG_BOT_TOKEN=your_bot_token_here
TG_CHAT_ID=123456789,987654321,@channel_name
# Alternative variable name
TG_CHAT_IDS=123456789,987654321,@channel_name
```
```python
import asyncio
from tg_notification_bot import TelegramNotificationBot
async def main():
  # Automatically loads chat IDs from TG_CHAT_ID environment variable
  bot = TelegramNotificationBot("YOUR_BOT_TOKEN")
  # Send to all configured chats
  result = await bot.send_message_bulk("Hello to all chats! ๐")
  print(f"Sent to {result.successful_chats}/{result.total_chats} chats")
  print(f"Success rate: {result.success_rate:.1f}%")
  if result.failed_chats > 0:
    print(f"Failed chats: {result.failed_chat_ids}")
  await bot.close()
asyncio.run(main())
```
#### Programmatic Multi-Chat Configuration
```python
import asyncio
from tg_notification_bot import TelegramNotificationBot, NotificationConfig
async def main():
  # Configure multiple chats programmatically
  config = NotificationConfig(
    token="YOUR_BOT_TOKEN",
    chat_id=["123456789", "987654321", "@channel_name"],
    parse_mode="Markdown",
    disable_notification=True
  )
  bot = TelegramNotificationBot(config)
  # Send to all configured chats
  result = await bot.send_message_bulk("*Important* notification for all chats!")
  # Detailed results
  for send_result in result.results:
    if send_result.success:
      print(f"โ
 Sent to {send_result.chat_id}")
    else:
      print(f"โ Failed to send to {send_result.chat_id}: {send_result.error}")
  await bot.close()
asyncio.run(main())
```
#### Bulk Operations with Custom Chat Lists
```python
import asyncio
from tg_notification_bot import TelegramNotificationBot
async def main():
  bot = TelegramNotificationBot("YOUR_BOT_TOKEN", "default_chat_id")
  # Override chat list for specific operations
  emergency_chats = ["admin_chat", "ops_chat", "@alerts_channel"]
  async with bot:
    # Send to specific chat list
    result = await bot.send_message_bulk(
      "๐จ System Alert: Server is down!",
      chat_ids=emergency_chats,
      fail_silently=False,  # Raise exceptions on failure
      max_concurrent=5      # Limit concurrent sends
    )
    # Send photo to multiple chats
    photo_result = await bot.send_photo_bulk(
      "monitoring_dashboard.png",
      caption="Current system status",
      chat_ids=emergency_chats
    )
asyncio.run(main())
```
### Using Configuration Object
```python
import asyncio
from tg_notification_bot import TelegramNotificationBot, NotificationConfig
async def main():
  # Create configuration
  config = NotificationConfig(
    token="YOUR_BOT_TOKEN",
    chat_id="YOUR_CHAT_ID",
    parse_mode="Markdown",
    disable_notification=True
  )
  # Initialize bot with config
  bot = TelegramNotificationBot(config)
  await bot.send_message("*Bold text* with _italic_")
  await bot.close()
asyncio.run(main())
```
### Context Manager (Recommended)
```python
import asyncio
from tg_notification_bot import TelegramNotificationBot
async def main():
  async with TelegramNotificationBot("YOUR_BOT_TOKEN", "YOUR_CHAT_ID") as bot:
    await bot.send_message("Message sent safely! โ
")
    # Session automatically closed
asyncio.run(main())
```
## ๐ง Advanced Usage
### Structured Data with Pydantic Models
```python
import asyncio
from tg_notification_bot import (
  TelegramNotificationBot,
  MessageData,
  PhotoData,
  DocumentData
)
async def main():
  async with TelegramNotificationBot("YOUR_BOT_TOKEN", "YOUR_CHAT_ID") as bot:
    # Structured message
    message = MessageData(
      text="<b>Important</b> notification!",
      parse_mode="HTML",
      disable_notification=False
    )
    await bot.send_message(message)
    # Structured photo
    photo = PhotoData(
      photo="https://example.com/image.jpg",
      caption="Remote image",
      parse_mode="Markdown"
    )
    await bot.send_photo(photo)
asyncio.run(main())
```
### Handling Bulk Send Results
```python
import asyncio
from tg_notification_bot import TelegramNotificationBot, BulkSendResult
async def main():
  async with TelegramNotificationBot("YOUR_BOT_TOKEN", ["chat1", "chat2", "chat3"]) as bot:
    result: BulkSendResult = await bot.send_message_bulk("Test message")
    # Check overall results
    print(f"Success rate: {result.success_rate:.1f}%")
    print(f"Successful chats: {len(result.successful_chat_ids)}")
    print(f"Failed chats: {len(result.failed_chat_ids)}")
    # Process individual results
    for send_result in result.results:
      if send_result.success:
        print(f"โ
 {send_result.chat_id}")
      else:
        print(f"โ {send_result.chat_id}: {send_result.error}")
        # Access original exception if needed
        if send_result.exception:
          print(f"   Exception type: {type(send_result.exception).__name__}")
asyncio.run(main())
```
### File Handling
```python
import asyncio
from pathlib import Path
from io import BytesIO
from tg_notification_bot import TelegramNotificationBot
async def main():
  async with TelegramNotificationBot("YOUR_BOT_TOKEN", "YOUR_CHAT_ID") as bot:
    # Local file
    await bot.send_photo(Path("image.jpg"))
    # URL
    await bot.send_photo("https://example.com/photo.jpg")
    # File-like object
    buffer = BytesIO(b"fake image data")
    buffer.name = "generated.jpg"
    await bot.send_photo(buffer, caption="Generated image")
asyncio.run(main())
```
### Error Handling
```python
import asyncio
from tg_notification_bot import (
  TelegramNotificationBot,
  ChatNotFoundError,
  BotBlockedError,
  RateLimitError,
  TelegramNotificationError
)
async def main():
  async with TelegramNotificationBot("YOUR_BOT_TOKEN", "YOUR_CHAT_ID") as bot:
    try:
      await bot.send_message("Test message")
    except ChatNotFoundError as e:
      print(f"Chat not found: {e.chat_id}")
    except BotBlockedError as e:
      print(f"Bot blocked in chat: {e.chat_id}")
    except RateLimitError as e:
      print(f"Rate limited. Retry after: {e.retry_after} seconds")
    except TelegramNotificationError as e:
      print(f"General error: {e}")
asyncio.run(main())
```
## ๐ Configuration
### Environment Variables
```bash
# .env file
TG_BOT_TOKEN=your_bot_token_here
# Single chat
TG_CHAT_ID=your_chat_id_here
# Multiple chats (comma-separated)
TG_CHAT_ID=123456789,987654321,@channel_name
# Alternative for multiple chats
TG_CHAT_IDS=123456789,987654321,@channel_name
```
```python
import os
from tg_notification_bot import TelegramNotificationBot
# Load from environment
bot = TelegramNotificationBot(
  token=os.getenv("TG_BOT_TOKEN"),
  chat_id=os.getenv("TG_CHAT_ID")
)
```
### Chat ID Formats
The library supports various chat ID formats:
- `123456789` - User ID
- `-123456789` - Group chat ID
- `-100123456789` - Supergroup/channel ID
- `@username` - Public chat username
The bot automatically tries different formats if the initial one fails.
## ๐งช Testing
Run the test suite:
```bash
# Install development dependencies
uv sync --dev
# Run tests
uv run pytest
# Run tests with coverage
uv run pytest --cov=tg_notification_bot --cov-report=html
# Type checking
uv run mypy tg_notification_bot
# Linting and formatting with ruff
uv run ruff check tg_notification_bot
uv run ruff format --check tg_notification_bot
```
## ๐ API Reference
### Classes
#### `TelegramNotificationBot`
Main bot class for sending notifications.
**Constructor:**
- `TelegramNotificationBot(token: NotificationConfig | str, chat_id: str | int | List[str | int] = None)`
**Methods:**
##### Single Chat Methods
- `send_message(message: str | MessageData, chat_id: str | int = None) -> None`
- `send_photo(photo: str | Path | IO | PhotoData, caption: str = None, chat_id: str | int = None) -> None`
- `send_document(document: str | Path | IO | DocumentData, caption: str = None, chat_id: str | int = None) -> None`
##### Bulk Methods
- `send_message_bulk(message: str | MessageData, chat_ids: List[str | int] = None, fail_silently: bool = True, max_concurrent: int = 10) -> BulkSendResult`
- `send_photo_bulk(photo: str | Path | IO | PhotoData, caption: str = None, chat_ids: List[str | int] = None, fail_silently: bool = True, max_concurrent: int = 10) -> BulkSendResult`
- `send_document_bulk(document: str | Path | IO | DocumentData, caption: str = None, chat_ids: List[str | int] = None, fail_silently: bool = True, max_concurrent: int = 10) -> BulkSendResult`
##### Utility Methods
- `close() -> None`
#### `BulkSendResult`
Result object for bulk send operations.
**Properties:**
- `results: List[SendResult]` - Individual results for each chat
- `total_chats: int` - Total number of chats attempted
- `successful_chats: int` - Number of successful sends
- `failed_chats: int` - Number of failed sends
- `success_rate: float` - Success rate as percentage
- `successful_chat_ids: List[str]` - List of successful chat IDs
- `failed_chat_ids: List[str]` - List of failed chat IDs
#### `SendResult`
Result object for individual send operation.
**Properties:**
- `chat_id: str` - Chat ID where message was sent
- `success: bool` - Whether the operation was successful
- `error: Optional[str]` - Error message if failed
- `exception: Optional[Exception]` - Original exception if failed
## ๐ License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## ๐ Acknowledgments
- [aiogram](https://github.com/aiogram/aiogram) - Modern Telegram Bot API framework
- [pydantic](https://github.com/pydantic/pydantic) - Data validation using Python type hints
            
         
        Raw data
        
            {
    "_id": null,
    "home_page": null,
    "name": "tg-notification-bot",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "telegram, bot, notifications, aiogram, multi-chat, bulk-sending",
    "author": null,
    "author_email": "AI-Stratov <workistratov@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/1c/1e/786a80f6241d3ec30490d5b9f87a8338e441be72d1f5e239955613db499f/tg_notification_bot-1.0.0.tar.gz",
    "platform": null,
    "description": "# Telegram Notification Bot \ud83e\udd16\r\n\r\n[](https://www.python.org/downloads/)\r\n[](https://badge.fury.io/py/tg-notification-bot)\r\n\r\nA modern, type-safe Python library for sending notifications through Telegram bots. Built with the latest aiogram 3.x\r\nand Pydantic 2.x for maximum reliability and developer experience.\r\n\r\n## \u2728 Features\r\n\r\n- \ud83d\udd12 **Type Safety**: Full type annotations with mypy support\r\n- \ud83d\ude80 **Modern**: Built on aiogram 3.x and Pydantic 2.x\r\n- \ud83d\udee1\ufe0f **Robust Error Handling**: Comprehensive exception handling with custom error types\r\n- \ud83d\udcdd **Validation**: Input validation using Pydantic models\r\n- \ud83c\udfaf **Multiple Formats**: Send text, photos, and documents\r\n- \ud83d\udd27 **Flexible Configuration**: Support for various chat ID formats\r\n- \ud83d\udce1 **Multi-Chat Support**: Send messages to multiple chats simultaneously\r\n- \ud83d\udea6 **Concurrent Control**: Configurable concurrency limits for bulk operations\r\n- \ud83e\uddea **Well Tested**: Comprehensive test suite with high coverage\r\n- \ud83d\udce6 **Zero Dependencies**: Only requires aiogram and pydantic\r\n\r\n## \ud83d\ude80 Installation\r\n\r\n```bash\r\nuv pip install tg-notification-bot\r\n```\r\n\r\nFor development:\r\n\r\n```bash\r\n# Using uv (recommended)\r\nuv add --dev tg-notification-bot\r\n```\r\n\r\n## \ud83d\udcd6 Quick Start\r\n\r\n### Basic Usage\r\n\r\n```python\r\nimport asyncio\r\nfrom tg_notification_bot import TelegramNotificationBot\r\n\r\n\r\nasync def main():\r\n  # Initialize with token and chat ID\r\n  bot = TelegramNotificationBot(\"YOUR_BOT_TOKEN\", \"YOUR_CHAT_ID\")\r\n\r\n  # Send a simple message\r\n  await bot.send_message(\"Hello, World! \ud83c\udf0d\")\r\n\r\n  # Send a photo\r\n  await bot.send_photo(\"path/to/photo.jpg\", caption=\"Check this out!\")\r\n\r\n  # Send a document\r\n  await bot.send_document(\"path/to/document.pdf\", caption=\"Important file\")\r\n\r\n  # Don't forget to close the session\r\n  await bot.close()\r\n\r\n\r\n# Run the example\r\nasyncio.run(main())\r\n```\r\n\r\n### Multi-Chat Support\r\n\r\n#### Environment Variables for Multiple Chats\r\n\r\n```bash\r\n# .env file - Multiple chats separated by commas\r\nTG_BOT_TOKEN=your_bot_token_here\r\nTG_CHAT_ID=123456789,987654321,@channel_name\r\n\r\n# Alternative variable name\r\nTG_CHAT_IDS=123456789,987654321,@channel_name\r\n```\r\n\r\n```python\r\nimport asyncio\r\nfrom tg_notification_bot import TelegramNotificationBot\r\n\r\n\r\nasync def main():\r\n  # Automatically loads chat IDs from TG_CHAT_ID environment variable\r\n  bot = TelegramNotificationBot(\"YOUR_BOT_TOKEN\")\r\n\r\n  # Send to all configured chats\r\n  result = await bot.send_message_bulk(\"Hello to all chats! \ud83c\udf0d\")\r\n\r\n  print(f\"Sent to {result.successful_chats}/{result.total_chats} chats\")\r\n  print(f\"Success rate: {result.success_rate:.1f}%\")\r\n\r\n  if result.failed_chats > 0:\r\n    print(f\"Failed chats: {result.failed_chat_ids}\")\r\n\r\n  await bot.close()\r\n\r\n\r\nasyncio.run(main())\r\n```\r\n\r\n#### Programmatic Multi-Chat Configuration\r\n\r\n```python\r\nimport asyncio\r\nfrom tg_notification_bot import TelegramNotificationBot, NotificationConfig\r\n\r\n\r\nasync def main():\r\n  # Configure multiple chats programmatically\r\n  config = NotificationConfig(\r\n    token=\"YOUR_BOT_TOKEN\",\r\n    chat_id=[\"123456789\", \"987654321\", \"@channel_name\"],\r\n    parse_mode=\"Markdown\",\r\n    disable_notification=True\r\n  )\r\n\r\n  bot = TelegramNotificationBot(config)\r\n\r\n  # Send to all configured chats\r\n  result = await bot.send_message_bulk(\"*Important* notification for all chats!\")\r\n\r\n  # Detailed results\r\n  for send_result in result.results:\r\n    if send_result.success:\r\n      print(f\"\u2705 Sent to {send_result.chat_id}\")\r\n    else:\r\n      print(f\"\u274c Failed to send to {send_result.chat_id}: {send_result.error}\")\r\n\r\n  await bot.close()\r\n\r\n\r\nasyncio.run(main())\r\n```\r\n\r\n#### Bulk Operations with Custom Chat Lists\r\n\r\n```python\r\nimport asyncio\r\nfrom tg_notification_bot import TelegramNotificationBot\r\n\r\n\r\nasync def main():\r\n  bot = TelegramNotificationBot(\"YOUR_BOT_TOKEN\", \"default_chat_id\")\r\n\r\n  # Override chat list for specific operations\r\n  emergency_chats = [\"admin_chat\", \"ops_chat\", \"@alerts_channel\"]\r\n\r\n  async with bot:\r\n    # Send to specific chat list\r\n    result = await bot.send_message_bulk(\r\n      \"\ud83d\udea8 System Alert: Server is down!\",\r\n      chat_ids=emergency_chats,\r\n      fail_silently=False,  # Raise exceptions on failure\r\n      max_concurrent=5      # Limit concurrent sends\r\n    )\r\n\r\n    # Send photo to multiple chats\r\n    photo_result = await bot.send_photo_bulk(\r\n      \"monitoring_dashboard.png\",\r\n      caption=\"Current system status\",\r\n      chat_ids=emergency_chats\r\n    )\r\n\r\n\r\nasyncio.run(main())\r\n```\r\n\r\n### Using Configuration Object\r\n\r\n```python\r\nimport asyncio\r\n\r\nfrom tg_notification_bot import TelegramNotificationBot, NotificationConfig\r\n\r\n\r\nasync def main():\r\n  # Create configuration\r\n  config = NotificationConfig(\r\n    token=\"YOUR_BOT_TOKEN\",\r\n    chat_id=\"YOUR_CHAT_ID\",\r\n    parse_mode=\"Markdown\",\r\n    disable_notification=True\r\n  )\r\n\r\n  # Initialize bot with config\r\n  bot = TelegramNotificationBot(config)\r\n\r\n  await bot.send_message(\"*Bold text* with _italic_\")\r\n  await bot.close()\r\n\r\n\r\nasyncio.run(main())\r\n```\r\n\r\n### Context Manager (Recommended)\r\n\r\n```python\r\nimport asyncio\r\nfrom tg_notification_bot import TelegramNotificationBot\r\n\r\n\r\nasync def main():\r\n  async with TelegramNotificationBot(\"YOUR_BOT_TOKEN\", \"YOUR_CHAT_ID\") as bot:\r\n    await bot.send_message(\"Message sent safely! \u2705\")\r\n    # Session automatically closed\r\n\r\n\r\nasyncio.run(main())\r\n```\r\n\r\n## \ud83d\udd27 Advanced Usage\r\n\r\n### Structured Data with Pydantic Models\r\n\r\n```python\r\nimport asyncio\r\nfrom tg_notification_bot import (\r\n  TelegramNotificationBot,\r\n  MessageData,\r\n  PhotoData,\r\n  DocumentData\r\n)\r\n\r\n\r\nasync def main():\r\n  async with TelegramNotificationBot(\"YOUR_BOT_TOKEN\", \"YOUR_CHAT_ID\") as bot:\r\n    # Structured message\r\n    message = MessageData(\r\n      text=\"<b>Important</b> notification!\",\r\n      parse_mode=\"HTML\",\r\n      disable_notification=False\r\n    )\r\n    await bot.send_message(message)\r\n\r\n    # Structured photo\r\n    photo = PhotoData(\r\n      photo=\"https://example.com/image.jpg\",\r\n      caption=\"Remote image\",\r\n      parse_mode=\"Markdown\"\r\n    )\r\n    await bot.send_photo(photo)\r\n\r\n\r\nasyncio.run(main())\r\n```\r\n\r\n### Handling Bulk Send Results\r\n\r\n```python\r\nimport asyncio\r\nfrom tg_notification_bot import TelegramNotificationBot, BulkSendResult\r\n\r\n\r\nasync def main():\r\n  async with TelegramNotificationBot(\"YOUR_BOT_TOKEN\", [\"chat1\", \"chat2\", \"chat3\"]) as bot:\r\n    result: BulkSendResult = await bot.send_message_bulk(\"Test message\")\r\n\r\n    # Check overall results\r\n    print(f\"Success rate: {result.success_rate:.1f}%\")\r\n    print(f\"Successful chats: {len(result.successful_chat_ids)}\")\r\n    print(f\"Failed chats: {len(result.failed_chat_ids)}\")\r\n\r\n    # Process individual results\r\n    for send_result in result.results:\r\n      if send_result.success:\r\n        print(f\"\u2705 {send_result.chat_id}\")\r\n      else:\r\n        print(f\"\u274c {send_result.chat_id}: {send_result.error}\")\r\n        # Access original exception if needed\r\n        if send_result.exception:\r\n          print(f\"   Exception type: {type(send_result.exception).__name__}\")\r\n\r\n\r\nasyncio.run(main())\r\n```\r\n\r\n### File Handling\r\n\r\n```python\r\nimport asyncio\r\nfrom pathlib import Path\r\nfrom io import BytesIO\r\nfrom tg_notification_bot import TelegramNotificationBot\r\n\r\n\r\nasync def main():\r\n  async with TelegramNotificationBot(\"YOUR_BOT_TOKEN\", \"YOUR_CHAT_ID\") as bot:\r\n    # Local file\r\n    await bot.send_photo(Path(\"image.jpg\"))\r\n\r\n    # URL\r\n    await bot.send_photo(\"https://example.com/photo.jpg\")\r\n\r\n    # File-like object\r\n    buffer = BytesIO(b\"fake image data\")\r\n    buffer.name = \"generated.jpg\"\r\n    await bot.send_photo(buffer, caption=\"Generated image\")\r\n\r\n\r\nasyncio.run(main())\r\n```\r\n\r\n### Error Handling\r\n\r\n```python\r\nimport asyncio\r\nfrom tg_notification_bot import (\r\n  TelegramNotificationBot,\r\n  ChatNotFoundError,\r\n  BotBlockedError,\r\n  RateLimitError,\r\n  TelegramNotificationError\r\n)\r\n\r\n\r\nasync def main():\r\n  async with TelegramNotificationBot(\"YOUR_BOT_TOKEN\", \"YOUR_CHAT_ID\") as bot:\r\n    try:\r\n      await bot.send_message(\"Test message\")\r\n    except ChatNotFoundError as e:\r\n      print(f\"Chat not found: {e.chat_id}\")\r\n    except BotBlockedError as e:\r\n      print(f\"Bot blocked in chat: {e.chat_id}\")\r\n    except RateLimitError as e:\r\n      print(f\"Rate limited. Retry after: {e.retry_after} seconds\")\r\n    except TelegramNotificationError as e:\r\n      print(f\"General error: {e}\")\r\n\r\n\r\nasyncio.run(main())\r\n```\r\n\r\n## \ud83d\udd10 Configuration\r\n\r\n### Environment Variables\r\n\r\n```bash\r\n# .env file\r\nTG_BOT_TOKEN=your_bot_token_here\r\n\r\n# Single chat\r\nTG_CHAT_ID=your_chat_id_here\r\n\r\n# Multiple chats (comma-separated)\r\nTG_CHAT_ID=123456789,987654321,@channel_name\r\n\r\n# Alternative for multiple chats\r\nTG_CHAT_IDS=123456789,987654321,@channel_name\r\n```\r\n\r\n```python\r\nimport os\r\nfrom tg_notification_bot import TelegramNotificationBot\r\n\r\n# Load from environment\r\nbot = TelegramNotificationBot(\r\n  token=os.getenv(\"TG_BOT_TOKEN\"),\r\n  chat_id=os.getenv(\"TG_CHAT_ID\")\r\n)\r\n```\r\n\r\n### Chat ID Formats\r\n\r\nThe library supports various chat ID formats:\r\n\r\n- `123456789` - User ID\r\n- `-123456789` - Group chat ID\r\n- `-100123456789` - Supergroup/channel ID\r\n- `@username` - Public chat username\r\n\r\nThe bot automatically tries different formats if the initial one fails.\r\n\r\n## \ud83e\uddea Testing\r\n\r\nRun the test suite:\r\n\r\n```bash\r\n# Install development dependencies\r\nuv sync --dev\r\n\r\n# Run tests\r\nuv run pytest\r\n\r\n# Run tests with coverage\r\nuv run pytest --cov=tg_notification_bot --cov-report=html\r\n\r\n# Type checking\r\nuv run mypy tg_notification_bot\r\n\r\n# Linting and formatting with ruff\r\nuv run ruff check tg_notification_bot\r\nuv run ruff format --check tg_notification_bot\r\n```\r\n\r\n## \ud83d\udcdd API Reference\r\n\r\n### Classes\r\n\r\n#### `TelegramNotificationBot`\r\n\r\nMain bot class for sending notifications.\r\n\r\n**Constructor:**\r\n\r\n- `TelegramNotificationBot(token: NotificationConfig | str, chat_id: str | int | List[str | int] = None)`\r\n\r\n**Methods:**\r\n\r\n##### Single Chat Methods\r\n- `send_message(message: str | MessageData, chat_id: str | int = None) -> None`\r\n- `send_photo(photo: str | Path | IO | PhotoData, caption: str = None, chat_id: str | int = None) -> None`\r\n- `send_document(document: str | Path | IO | DocumentData, caption: str = None, chat_id: str | int = None) -> None`\r\n\r\n##### Bulk Methods\r\n- `send_message_bulk(message: str | MessageData, chat_ids: List[str | int] = None, fail_silently: bool = True, max_concurrent: int = 10) -> BulkSendResult`\r\n- `send_photo_bulk(photo: str | Path | IO | PhotoData, caption: str = None, chat_ids: List[str | int] = None, fail_silently: bool = True, max_concurrent: int = 10) -> BulkSendResult`\r\n- `send_document_bulk(document: str | Path | IO | DocumentData, caption: str = None, chat_ids: List[str | int] = None, fail_silently: bool = True, max_concurrent: int = 10) -> BulkSendResult`\r\n\r\n##### Utility Methods\r\n- `close() -> None`\r\n\r\n#### `BulkSendResult`\r\n\r\nResult object for bulk send operations.\r\n\r\n**Properties:**\r\n- `results: List[SendResult]` - Individual results for each chat\r\n- `total_chats: int` - Total number of chats attempted\r\n- `successful_chats: int` - Number of successful sends\r\n- `failed_chats: int` - Number of failed sends\r\n- `success_rate: float` - Success rate as percentage\r\n- `successful_chat_ids: List[str]` - List of successful chat IDs\r\n- `failed_chat_ids: List[str]` - List of failed chat IDs\r\n\r\n#### `SendResult`\r\n\r\nResult object for individual send operation.\r\n\r\n**Properties:**\r\n- `chat_id: str` - Chat ID where message was sent\r\n- `success: bool` - Whether the operation was successful\r\n- `error: Optional[str]` - Error message if failed\r\n- `exception: Optional[Exception]` - Original exception if failed\r\n\r\n## \ud83d\udcc4 License\r\n\r\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\r\n\r\n## \ud83d\ude4f Acknowledgments\r\n\r\n- [aiogram](https://github.com/aiogram/aiogram) - Modern Telegram Bot API framework\r\n- [pydantic](https://github.com/pydantic/pydantic) - Data validation using Python type hints\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Modern Telegram notification bot library for Python projects with multi-chat support",
    "version": "1.0.0",
    "project_urls": {
        "Documentation": "https://github.com/AI-Stratov/tg-notification-bot#readme",
        "Homepage": "https://github.com/AI-Stratov/tg-notification-bot",
        "Issues": "https://github.com/AI-Stratov/tg-notification-bot/issues",
        "Repository": "https://github.com/AI-Stratov/tg-notification-bot"
    },
    "split_keywords": [
        "telegram",
        " bot",
        " notifications",
        " aiogram",
        " multi-chat",
        " bulk-sending"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "768fcfad2375d1c8cb8ef4f0547cde7d517e10b6d5805dc4ac679785d197dbea",
                "md5": "cb6471b99f9b816bc260404943bacbc7",
                "sha256": "a4efea70d5ef304354c4a576d3e18bba3027c61aafc57ca2269cbb2c23e7b6b2"
            },
            "downloads": -1,
            "filename": "tg_notification_bot-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "cb6471b99f9b816bc260404943bacbc7",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 11215,
            "upload_time": "2025-09-12T16:15:26",
            "upload_time_iso_8601": "2025-09-12T16:15:26.781534Z",
            "url": "https://files.pythonhosted.org/packages/76/8f/cfad2375d1c8cb8ef4f0547cde7d517e10b6d5805dc4ac679785d197dbea/tg_notification_bot-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1c1e786a80f6241d3ec30490d5b9f87a8338e441be72d1f5e239955613db499f",
                "md5": "6a012c4abec9c7c2d748c96e3c24f4cc",
                "sha256": "d005bdc755cb9a37ed323b34401a7d390c1bab1d4c9d805ddbb0b4fc2fdf92a8"
            },
            "downloads": -1,
            "filename": "tg_notification_bot-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "6a012c4abec9c7c2d748c96e3c24f4cc",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 18150,
            "upload_time": "2025-09-12T16:15:27",
            "upload_time_iso_8601": "2025-09-12T16:15:27.726543Z",
            "url": "https://files.pythonhosted.org/packages/1c/1e/786a80f6241d3ec30490d5b9f87a8338e441be72d1f5e239955613db499f/tg_notification_bot-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-12 16:15:27",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "AI-Stratov",
    "github_project": "tg-notification-bot#readme",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "tg-notification-bot"
}