diff --git a/examples/broadcast_example.py b/examples/broadcast_example.py new file mode 100644 index 00000000..468da916 --- /dev/null +++ b/examples/broadcast_example.py @@ -0,0 +1,72 @@ +import asyncio +import logging + +from aiogram import Bot, Dispatcher, types +from aiogram.utils import exceptions, executor + +API_TOKEN = 'BOT TOKEN HERE' + +logging.basicConfig(level=logging.INFO) +log = logging.getLogger('broadcast') + +loop = asyncio.get_event_loop() +bot = Bot(token=API_TOKEN, loop=loop, parse_mode=types.ParseMode.HTML) +dp = Dispatcher(bot, loop=loop) + + +def get_users(): + """ + Return users list + + In this example returns some random ID's + """ + yield from (61043901, 78238238, 78378343, 98765431, 12345678) + + +async def send_message(user_id: int, text: str) -> bool: + """ + Safe messages sender + + :param user_id: + :param text: + :return: + """ + try: + await bot.send_message(user_id, 'Hello, World!') + except exceptions.BotBlocked: + log.error(f"Target [ID:{user_id}]: blocked by user") + except exceptions.ChatNotFound: + log.error(f"Target [ID:{user_id}]: invalid user ID") + except exceptions.RetryAfter as e: + log.error(f"Target [ID:{user_id}]: Flood limit is exceeded. Sleep {e.timeout} seconds.") + await asyncio.sleep(e.timeout) + return await send_message(user_id, text) # Recursive call + except exceptions.TelegramAPIError: + log.exception(f"Target [ID:{user_id}]: failed") + else: + log.info(f"Target [ID:{user_id}]: success") + return True + return False + + +async def broadcaster() -> int: + """ + Simple broadcaster + + :return: Count of messages + """ + count = 0 + try: + for user_id in get_users(): + if await send_message(user_id, 'Hello!'): + count += 1 + await asyncio.sleep(.05) # 20 messages per second (Limit: 30 messages per second) + finally: + log.info(f"{count} messages successful sent.") + + return count + + +if __name__ == '__main__': + # Execute broadcaster + executor.start(dp, broadcaster())