1import asyncio
2import logging
3
4from aiogram import Bot, Dispatcher, types
5from aiogram.utils import exceptions, executor
6
7API_TOKEN = 'BOT TOKEN HERE'
8
9logging.basicConfig(level=logging.INFO)
10log = logging.getLogger('broadcast')
11
12bot = Bot(token=API_TOKEN, parse_mode=types.ParseMode.HTML)
13dp = Dispatcher(bot)
14
15
16def get_users():
17 """
18 Return users list
19
20 In this example returns some random ID's
21 """
22 yield from (61043901, 78238238, 78378343, 98765431, 12345678)
23
24
25async def send_message(user_id: int, text: str, disable_notification: bool = False) -> bool:
26 """
27 Safe messages sender
28
29 :param user_id:
30 :param text:
31 :param disable_notification:
32 :return:
33 """
34 try:
35 await bot.send_message(user_id, text, disable_notification=disable_notification)
36 except exceptions.BotBlocked:
37 log.error(f"Target [ID:{user_id}]: blocked by user")
38 except exceptions.ChatNotFound:
39 log.error(f"Target [ID:{user_id}]: invalid user ID")
40 except exceptions.RetryAfter as e:
41 log.error(f"Target [ID:{user_id}]: Flood limit is exceeded. Sleep {e.timeout} seconds.")
42 await asyncio.sleep(e.timeout)
43 return await send_message(user_id, text) # Recursive call
44 except exceptions.UserDeactivated:
45 log.error(f"Target [ID:{user_id}]: user is deactivated")
46 except exceptions.TelegramAPIError:
47 log.exception(f"Target [ID:{user_id}]: failed")
48 else:
49 log.info(f"Target [ID:{user_id}]: success")
50 return True
51 return False
52
53
54async def broadcaster() -> int:
55 """
56 Simple broadcaster
57
58 :return: Count of messages
59 """
60 count = 0
61 try:
62 for user_id in get_users():
63 if await send_message(user_id, '<b>Hello!</b>'):
64 count += 1
65 await asyncio.sleep(.05) # 20 messages per second (Limit: 30 messages per second)
66 finally:
67 log.info(f"{count} messages successful sent.")
68
69 return count
70
71
72if __name__ == '__main__':
73 # Execute broadcaster
74 executor.start(dp, broadcaster())