Aiogram
Is a pretty simple and fully asynchronous framework for Telegram Bot API written in Python 3.7 with asyncio and aiohttp.
Categories
- Aiogram:Examples:InferenceServerProxy - 추론 서버를 연결하는 프록시 Bot
Simple example
"""
This is a echo bot.
It echoes any incoming text messages.
"""
import logging
from aiogram import Bot, Dispatcher, executor, types
API_TOKEN = 'BOT TOKEN HERE'
# Configure logging
logging.basicConfig(level=logging.INFO)
# Initialize bot and dispatcher
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
@dp.message_handler(commands=['start', 'help'])
async def send_welcome(message: types.Message):
"""
This handler will be called when user sends `/start` or `/help` command
"""
await message.reply("Hi!\nI'm EchoBot!\nPowered by aiogram.")
@dp.message_handler()
async def echo(message: types.Message):
# old style:
# await bot.send_message(message.chat.id, message.text)
await message.answer(message.text)
if __name__ == '__main__':
executor.start_polling(dp, skip_updates=True)
Photo 다운로드
def get_max_size_photo(photo: List[PhotoSize]) -> PhotoSize:
if not photo:
raise IndexError("Empty photo")
max_file_size = max(map(lambda x: x.file_size, photo))
return list(filter(lambda x: x.file_size == max_file_size, photo))[0]
@dp.message_handler(content_types=["photo"])
async def on_photo(self, message: Message):
photo = get_max_size_photo(message.photo)
buffer = BytesIO()
await photo.download(destination_file=buffer)
data = buffer.getbuffer()
file_id 로 다운받기
- How to download file? - aiogram 3.5.0 documentation
- python - How to save photo from Telegram Bot (Aiogram) to PostgreSQL database? - Stack Overflow
- Download a file from Telegram using aiogram bot-framework in Python - Stack Overflow
Example:
file_info = await bot.get_file(photo[len(photo) - 1].file_id)
new_photo = (await bot.download_file(file_info.file_path)).read()
파일 업로드
By first step you will need to import InputFile wrapper:
from aiogram.types import FSInputFile
...
cat = FSInputFile("cat.png")
agenda = FSInputFile("my-document.pdf", filename="agenda-2019-11-19.pdf")
Upload from buffer
Files can be also passed from buffer (For example you generate image using Pillow and you want to send it to Telegram):
Import wrapper:
from aiogram.types import BufferedInputFile
...
text_file = BufferedInputFile(b"Hello, world!", filename="file.txt")
Magic filters
- Magic filters - aiogram 3.4.1 documentation
-
aiogram.util.magic_filter.MagicFilter
를 사용하거나aiogram.F
를 사용하면 된다.
Exists or not None:
Equals:
F.text == 'hello' # lambda message: message.text == 'hello'
F.from_user.id == 42 # lambda message: message.from_user.id == 42
F.text != 'spam' # lambda message: message.text != 'spam'
Is one of:
F.from_user.id.in_({42, 1000, 123123}) # lambda query: query.from_user.id in {42, 1000, 123123}
F.data.in_({'foo', 'bar', 'baz'}) # lambda query: query.data in {'foo', 'bar', 'baz'}
Contains:
String startswith/endswith:
F.text.startswith('foo') # lambda message: message.text.startswith('foo')
F.text.endswith('bar') # lambda message: message.text.startswith('bar')
Regexp:
Custom function:
F.chat.func(lambda chat: chat.id == -42) # lambda message: (lambda chat: chat.id == -42)(message.chat)
Inverting result:
~F.text # lambda message: not message.text
~F.text.startswith('spam') # lambda message: not message.text.startswith('spam')
Combining:
(F.from_user.id == 42) & (F.text == 'admin')
F.text.startswith('a') | F.text.endswith('b')
(F.from_user.id.in_({42, 777, 911})) & (F.text.startswith('!') | F.text.startswith('/')) & F.text.contains('ban')
Usage in aiogram:
@router.message(F.text == 'hello')
@router.inline_query(F.data == 'button:1')
@router.message(F.text.startswith('foo'))
@router.message(F.content_type.in_({'text', 'sticker'}))
@router.message(F.text.regexp(r'\d+'))
Custom filter example
For example if you need to make simple text filter:
from aiogram import Router
from aiogram.filters import Filter
from aiogram.types import Message
router = Router()
class MyFilter(Filter):
def __init__(self, my_text: str) -> None:
self.my_text = my_text
async def __call__(self, message: Message) -> bool:
return message.text == self.my_text
@router.message(MyFilter("hello"))
async def my_handler(message: Message):
...
Combining Filters
and_f(F.text.startswith("show"), F.text.endswith("example"))
or_f(F.text(text="hi"), CommandStart())
invert_f(IsAdmin())
and_f(<A>, or_f(<B>, <C>))
Middleware example
from aiogram import BaseMiddleware
from aiogram.types import Message
class CounterMiddleware(BaseMiddleware):
def __init__(self) -> None:
self.counter = 0
async def __call__(
self,
handler: Callable[[Message, Dict[str, Any]], Awaitable[Any]],
event: Message,
data: Dict[str, Any]
) -> Any:
self.counter += 1
data['counter'] = self.counter
return await handler(event, data)
and then
유한 상태 머신
- python - AIOGram get all message photos - Stack Overflow
- Finite state machine example — aiogram 2.25.1 documentation
질문을 주고 받는 상태를 기록할 수 있다.