mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-11 18:01:04 +00:00
Update to Bot API 3.2. Teach your bot to handle stickers and sticker sets.
This commit is contained in:
parent
1413baf4b8
commit
146e876099
7 changed files with 187 additions and 34 deletions
|
|
@ -100,6 +100,12 @@ class Methods:
|
||||||
SEND_AUDIO = 'sendAudio'
|
SEND_AUDIO = 'sendAudio'
|
||||||
SEND_DOCUMENT = 'sendDocument'
|
SEND_DOCUMENT = 'sendDocument'
|
||||||
SEND_STICKER = 'sendSticker'
|
SEND_STICKER = 'sendSticker'
|
||||||
|
GET_STICKER_SET = 'getStickerSet'
|
||||||
|
UPLOAD_STICKER_FILE = 'uploadStickerFile'
|
||||||
|
CREATE_NEW_STICKER_SET = 'createNewStickerSet'
|
||||||
|
ADD_STICKER_TO_SET = 'addStickerToSet'
|
||||||
|
SET_STICKER_POSITION_IN_SET = 'setStickerPositionInSet'
|
||||||
|
DELETE_STICKER_FROM_SET = 'deleteStickerFromSet'
|
||||||
SEND_VIDEO = 'sendVideo'
|
SEND_VIDEO = 'sendVideo'
|
||||||
SEND_VOICE = 'sendVoice'
|
SEND_VOICE = 'sendVoice'
|
||||||
SEND_VIDEO_NOTE = 'sendVideoNote'
|
SEND_VIDEO_NOTE = 'sendVideoNote'
|
||||||
|
|
|
||||||
|
|
@ -111,30 +111,16 @@ class BaseBot:
|
||||||
finally:
|
finally:
|
||||||
self.destroy_temp_session(session)
|
self.destroy_temp_session(session)
|
||||||
|
|
||||||
async def _send_file(self, file_type, file, payload):
|
async def _send_file(self, file_type, method, file, payload):
|
||||||
methods = {
|
|
||||||
'photo': api.Methods.SEND_PHOTO,
|
|
||||||
'audio': api.Methods.SEND_AUDIO,
|
|
||||||
'document': api.Methods.SEND_DOCUMENT,
|
|
||||||
'sticker': api.Methods.SEND_STICKER,
|
|
||||||
'video': api.Methods.SEND_VIDEO,
|
|
||||||
'voice': api.Methods.SEND_VOICE,
|
|
||||||
'video_note': api.Methods.SEND_VIDEO_NOTE
|
|
||||||
}
|
|
||||||
|
|
||||||
method = methods[file_type]
|
|
||||||
if isinstance(file, str):
|
if isinstance(file, str):
|
||||||
payload[file_type] = file
|
payload[file_type] = file
|
||||||
req = self.request(method, payload)
|
req = self.request(method, payload)
|
||||||
elif isinstance(file, io.IOBase):
|
elif isinstance(file, io.IOBase):
|
||||||
data = {file_type: file.read()}
|
data = {file_type: file.read()}
|
||||||
req = self.request(api.Methods.SEND_PHOTO, payload, data)
|
req = self.request(method, payload, data)
|
||||||
elif isinstance(file, bytes):
|
|
||||||
data = {file_type: file}
|
|
||||||
req = self.request(api.Methods.SEND_PHOTO, payload, data)
|
|
||||||
else:
|
else:
|
||||||
data = {file_type: file}
|
data = {file_type: file}
|
||||||
req = self.request(api.Methods.SEND_PHOTO, payload, data)
|
req = self.request(method, payload, data)
|
||||||
|
|
||||||
return await req
|
return await req
|
||||||
|
|
||||||
|
|
@ -181,8 +167,8 @@ class BaseBot:
|
||||||
if reply_markup and isinstance(reply_markup, dict):
|
if reply_markup and isinstance(reply_markup, dict):
|
||||||
reply_markup = json.dumps(reply_markup)
|
reply_markup = json.dumps(reply_markup)
|
||||||
|
|
||||||
payload = generate_payload(**locals())
|
payload = generate_payload(**locals(), exclude=[_message_type])
|
||||||
return await self._send_file(_message_type, photo, payload)
|
return await self._send_file(_message_type, api.Methods.SEND_PHOTO, photo, payload)
|
||||||
|
|
||||||
async def send_audio(self, chat_id, audio, caption=None, duration=None, performer=None, title=None,
|
async def send_audio(self, chat_id, audio, caption=None, duration=None, performer=None, title=None,
|
||||||
disable_notification=None, reply_to_message_id=None, reply_markup=None) -> dict:
|
disable_notification=None, reply_to_message_id=None, reply_markup=None) -> dict:
|
||||||
|
|
@ -190,8 +176,8 @@ class BaseBot:
|
||||||
if reply_markup and isinstance(reply_markup, dict):
|
if reply_markup and isinstance(reply_markup, dict):
|
||||||
reply_markup = json.dumps(reply_markup)
|
reply_markup = json.dumps(reply_markup)
|
||||||
|
|
||||||
payload = generate_payload(**locals())
|
payload = generate_payload(**locals(), exclude=[_message_type])
|
||||||
return await self._send_file(_message_type, audio, payload)
|
return await self._send_file(_message_type, api.Methods.SEND_AUDIO, audio, payload)
|
||||||
|
|
||||||
async def send_document(self, chat_id, document, caption=None, disable_notification=None, reply_to_message_id=None,
|
async def send_document(self, chat_id, document, caption=None, disable_notification=None, reply_to_message_id=None,
|
||||||
reply_markup=None) -> dict:
|
reply_markup=None) -> dict:
|
||||||
|
|
@ -199,8 +185,8 @@ class BaseBot:
|
||||||
if reply_markup and isinstance(reply_markup, dict):
|
if reply_markup and isinstance(reply_markup, dict):
|
||||||
reply_markup = json.dumps(reply_markup)
|
reply_markup = json.dumps(reply_markup)
|
||||||
|
|
||||||
payload = generate_payload(**locals())
|
payload = generate_payload(**locals(), exclude=[_message_type])
|
||||||
return await self._send_file(_message_type, document, payload)
|
return await self._send_file(_message_type, api.Methods.SEND_DOCUMENT, document, payload)
|
||||||
|
|
||||||
async def send_sticker(self, chat_id, sticker, disable_notification=None, reply_to_message_id=None,
|
async def send_sticker(self, chat_id, sticker, disable_notification=None, reply_to_message_id=None,
|
||||||
reply_markup=None) -> dict:
|
reply_markup=None) -> dict:
|
||||||
|
|
@ -208,8 +194,43 @@ class BaseBot:
|
||||||
if reply_markup and isinstance(reply_markup, dict):
|
if reply_markup and isinstance(reply_markup, dict):
|
||||||
reply_markup = json.dumps(reply_markup)
|
reply_markup = json.dumps(reply_markup)
|
||||||
|
|
||||||
|
payload = generate_payload(**locals(), exclude=[_message_type])
|
||||||
|
return await self._send_file(_message_type, api.Methods.SEND_STICKER, sticker, payload)
|
||||||
|
|
||||||
|
async def get_sticker_set(self, name: str) -> dict:
|
||||||
payload = generate_payload(**locals())
|
payload = generate_payload(**locals())
|
||||||
return await self._send_file(_message_type, sticker, payload)
|
return await self.request(api.Methods.GET_STICKER_SET, payload)
|
||||||
|
|
||||||
|
async def upload_sticker_file(self, user_id, png_sticker) -> dict:
|
||||||
|
_message_type = 'png_sticker'
|
||||||
|
payload = generate_payload(**locals(), exclude=['png_sticker'])
|
||||||
|
return await self._send_file(_message_type, api.Methods.UPLOAD_STICKER_FILE, png_sticker, payload)
|
||||||
|
|
||||||
|
async def create_new_sticker_set(self, name: str, title: str, png_sticker, emojis: str, is_mask: bool = None,
|
||||||
|
mask_position: dict or str = None) -> bool:
|
||||||
|
_message_type = 'png_sticker'
|
||||||
|
if mask_position and isinstance(mask_position, dict):
|
||||||
|
mask_position = json.dumps(mask_position)
|
||||||
|
|
||||||
|
payload = generate_payload(**locals(), exclude=[_message_type])
|
||||||
|
return await self._send_file(_message_type, api.Methods.CREATE_NEW_STICKER_SET, png_sticker, payload)
|
||||||
|
|
||||||
|
async def add_sticker_to_set(self, user_id: int, name: str, png_sticker, emojis: str,
|
||||||
|
mask_position: str or dict) -> bool:
|
||||||
|
_message_type = 'png_sticker'
|
||||||
|
if mask_position and isinstance(mask_position, dict):
|
||||||
|
mask_position = json.dumps(mask_position)
|
||||||
|
payload = generate_payload(**locals(), exclude=[_message_type])
|
||||||
|
|
||||||
|
return await self._send_file(_message_type, api.Methods.ADD_STICKER_TO_SET, png_sticker, payload)
|
||||||
|
|
||||||
|
async def set_sticker_position_in_set(self, sticker: str, position: int) -> bool:
|
||||||
|
payload = generate_payload(**locals())
|
||||||
|
return await self.request(api.Methods.SET_STICKER_POSITION_IN_SET, payload)
|
||||||
|
|
||||||
|
async def delete_sticker_from_set(self, sticker: str) -> bool:
|
||||||
|
payload = generate_payload(**locals())
|
||||||
|
return await self.request(api.Methods.DELETE_STICKER_FROM_SET, payload)
|
||||||
|
|
||||||
async def send_video(self, chat_id, video, duration=None, width=None, height=None, caption=None,
|
async def send_video(self, chat_id, video, duration=None, width=None, height=None, caption=None,
|
||||||
disable_notification=None, reply_to_message_id=None, reply_markup=None) -> dict:
|
disable_notification=None, reply_to_message_id=None, reply_markup=None) -> dict:
|
||||||
|
|
@ -217,8 +238,8 @@ class BaseBot:
|
||||||
if reply_markup and isinstance(reply_markup, dict):
|
if reply_markup and isinstance(reply_markup, dict):
|
||||||
reply_markup = json.dumps(reply_markup)
|
reply_markup = json.dumps(reply_markup)
|
||||||
|
|
||||||
payload = generate_payload(**locals())
|
payload = generate_payload(**locals(), exclude=[_message_type])
|
||||||
return await self._send_file(_message_type, video, payload)
|
return await self._send_file(_message_type, api.Methods.SEND_VIDEO, video, payload)
|
||||||
|
|
||||||
async def send_voice(self, chat_id, voice, caption=None, duration=None, disable_notification=None,
|
async def send_voice(self, chat_id, voice, caption=None, duration=None, disable_notification=None,
|
||||||
reply_to_message_id=None, reply_markup=None) -> dict:
|
reply_to_message_id=None, reply_markup=None) -> dict:
|
||||||
|
|
@ -226,8 +247,8 @@ class BaseBot:
|
||||||
if reply_markup and isinstance(reply_markup, dict):
|
if reply_markup and isinstance(reply_markup, dict):
|
||||||
reply_markup = json.dumps(reply_markup)
|
reply_markup = json.dumps(reply_markup)
|
||||||
|
|
||||||
payload = generate_payload(**locals())
|
payload = generate_payload(**locals(), exclude=[_message_type])
|
||||||
return await self._send_file(_message_type, voice, payload)
|
return await self._send_file(_message_type, api.Methods.SEND_VOICE, voice, payload)
|
||||||
|
|
||||||
async def send_video_note(self, chat_id, video_note, duration=None, length=None, disable_notification=None,
|
async def send_video_note(self, chat_id, video_note, duration=None, length=None, disable_notification=None,
|
||||||
reply_to_message_id=None, reply_markup=None) -> dict:
|
reply_to_message_id=None, reply_markup=None) -> dict:
|
||||||
|
|
@ -235,8 +256,8 @@ class BaseBot:
|
||||||
if reply_markup and isinstance(reply_markup, dict):
|
if reply_markup and isinstance(reply_markup, dict):
|
||||||
reply_markup = json.dumps(reply_markup)
|
reply_markup = json.dumps(reply_markup)
|
||||||
|
|
||||||
payload = generate_payload(**locals())
|
payload = generate_payload(**locals(), exclude=[_message_type])
|
||||||
return await self._send_file(_message_type, video_note, payload)
|
return await self._send_file(_message_type, api.Methods.SEND_VIDEO_NOTE, video_note, payload)
|
||||||
|
|
||||||
async def send_location(self, chat_id, latitude, longitude, disable_notification=None, reply_to_message_id=None,
|
async def send_location(self, chat_id, latitude, longitude, disable_notification=None, reply_to_message_id=None,
|
||||||
reply_markup=None) -> dict:
|
reply_markup=None) -> dict:
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from .. import types
|
|
||||||
from .base import BaseBot
|
from .base import BaseBot
|
||||||
|
from .. import types
|
||||||
|
|
||||||
|
|
||||||
class Bot(BaseBot):
|
class Bot(BaseBot):
|
||||||
|
|
@ -246,6 +246,80 @@ class Bot(BaseBot):
|
||||||
reply_markup)
|
reply_markup)
|
||||||
return self.prepare_object(types.Message.de_json(message))
|
return self.prepare_object(types.Message.de_json(message))
|
||||||
|
|
||||||
|
async def get_sticker_set(self, name: str) -> types.StickerSet:
|
||||||
|
"""
|
||||||
|
Use this method to get a sticker set.
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
:return: :class:`aiogram.types.StickerSet`
|
||||||
|
"""
|
||||||
|
return self.prepare_object(types.StickerSet.deserialize(await super(Bot, self).get_sticker_set(name)))
|
||||||
|
|
||||||
|
async def upload_sticker_file(self, user_id: int, png_sticker) -> types.File:
|
||||||
|
"""
|
||||||
|
Use this method to upload a .png file with a sticker for later use in
|
||||||
|
createNewStickerSet and addStickerToSet methods (can be used multiple times).
|
||||||
|
|
||||||
|
:param user_id: int
|
||||||
|
:param png_sticker: InputFile
|
||||||
|
:return: :class:`aiogram.types.File`
|
||||||
|
"""
|
||||||
|
file = super(Bot, self).upload_sticker_file(user_id, png_sticker)
|
||||||
|
return self.prepare_object(types.File.deserialize(await file))
|
||||||
|
|
||||||
|
async def create_new_sticker_set(self, name: str, title: str, png_sticker, emojis: str, is_mask: bool = None,
|
||||||
|
mask_position: types.MaskPosition or dict or str = None) -> bool:
|
||||||
|
"""
|
||||||
|
Use this method to create new sticker set owned by a user. The bot will be able to edit the created sticker set.
|
||||||
|
|
||||||
|
:param name:
|
||||||
|
:param title:
|
||||||
|
:param png_sticker:
|
||||||
|
:param emojis:
|
||||||
|
:param is_mask:
|
||||||
|
:param mask_position:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if isinstance(mask_position, types.MaskPosition):
|
||||||
|
mask_position = json.dumps(mask_position.to_json())
|
||||||
|
|
||||||
|
return await super(Bot, self).create_new_sticker_set(name, title, png_sticker, emojis, is_mask, mask_position)
|
||||||
|
|
||||||
|
async def add_sticker_to_set(self, user_id: int, name: str, png_sticker, emojis: str,
|
||||||
|
mask_position: str or dict = None) -> bool:
|
||||||
|
"""
|
||||||
|
Use this method to add a new sticker to a set created by the bot.
|
||||||
|
|
||||||
|
:param user_id:
|
||||||
|
:param name:
|
||||||
|
:param png_sticker:
|
||||||
|
:param emojis:
|
||||||
|
:param mask_position:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if isinstance(mask_position, types.MaskPosition):
|
||||||
|
mask_position = json.dumps(mask_position.to_json())
|
||||||
|
return await super(Bot, self).add_sticker_to_set(user_id, name, png_sticker, emojis, mask_position)
|
||||||
|
|
||||||
|
async def set_sticker_position_in_set(self, sticker: str, position: int) -> bool:
|
||||||
|
"""
|
||||||
|
Use this method to move a sticker in a set created by the bot to a specific position.
|
||||||
|
|
||||||
|
:param sticker: str
|
||||||
|
:param position: int
|
||||||
|
:return: True on success.
|
||||||
|
"""
|
||||||
|
return await super(Bot, self).set_sticker_position_in_set(sticker, position)
|
||||||
|
|
||||||
|
async def delete_sticker_from_set(self, sticker: str) -> bool:
|
||||||
|
"""
|
||||||
|
Use this method to delete a sticker from a set created by the bot.
|
||||||
|
|
||||||
|
:param sticker: str
|
||||||
|
:return: True on success
|
||||||
|
"""
|
||||||
|
return await super(Bot, self).delete_sticker_from_set(sticker)
|
||||||
|
|
||||||
async def send_video(self, chat_id, video, duration=None, width=None, height=None, caption=None,
|
async def send_video(self, chat_id, video, duration=None, width=None, height=None, caption=None,
|
||||||
disable_notification=None, reply_to_message_id=None, reply_markup=None) -> types.Message:
|
disable_notification=None, reply_to_message_id=None, reply_markup=None) -> types.Message:
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ from .inline_query_result import InlineQueryResult, InlineQueryResultArticle, In
|
||||||
from .invoice import Invoice
|
from .invoice import Invoice
|
||||||
from .labeled_price import LabeledPrice
|
from .labeled_price import LabeledPrice
|
||||||
from .location import Location
|
from .location import Location
|
||||||
|
from .mask_position import MaskPosition
|
||||||
from .message import Message, ContentType, ParseMode
|
from .message import Message, ContentType, ParseMode
|
||||||
from .message_entity import MessageEntity
|
from .message_entity import MessageEntity
|
||||||
from .order_info import OrderInfo
|
from .order_info import OrderInfo
|
||||||
|
|
@ -34,6 +35,7 @@ from .shipping_address import ShippingAddress
|
||||||
from .shipping_option import ShippingOption
|
from .shipping_option import ShippingOption
|
||||||
from .shipping_query import ShippingQuery
|
from .shipping_query import ShippingQuery
|
||||||
from .sticker import Sticker
|
from .sticker import Sticker
|
||||||
|
from .sticker_set import StickerSet
|
||||||
from .successful_payment import SuccessfulPayment
|
from .successful_payment import SuccessfulPayment
|
||||||
from .update import Update
|
from .update import Update
|
||||||
from .user import User
|
from .user import User
|
||||||
|
|
@ -99,6 +101,7 @@ __all__ = [
|
||||||
'KeyboardButton',
|
'KeyboardButton',
|
||||||
'LabeledPrice',
|
'LabeledPrice',
|
||||||
'Location',
|
'Location',
|
||||||
|
'MaskPosition'
|
||||||
'Message',
|
'Message',
|
||||||
'MessageEntity',
|
'MessageEntity',
|
||||||
'OrderInfo',
|
'OrderInfo',
|
||||||
|
|
@ -111,6 +114,7 @@ __all__ = [
|
||||||
'ShippingOption',
|
'ShippingOption',
|
||||||
'ShippingQuery',
|
'ShippingQuery',
|
||||||
'Sticker',
|
'Sticker',
|
||||||
|
'StickerSet'
|
||||||
'SuccessfulPayment',
|
'SuccessfulPayment',
|
||||||
'Update',
|
'Update',
|
||||||
'User',
|
'User',
|
||||||
|
|
|
||||||
15
aiogram/types/mask_position.py
Normal file
15
aiogram/types/mask_position.py
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
from .base import Serializable
|
||||||
|
|
||||||
|
|
||||||
|
class MaskPosition(Serializable):
|
||||||
|
"""
|
||||||
|
This object describes the position on faces where a mask should be placed by default.
|
||||||
|
|
||||||
|
https://core.telegram.org/bots/api#maskposition
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, point, x_shift, y_shift, zoom):
|
||||||
|
self.point: str = point
|
||||||
|
self.x_shift: float = x_shift
|
||||||
|
self.y_shift: float = y_shift
|
||||||
|
self.zoom: float = zoom
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
from .base import Deserializable
|
from .base import Deserializable
|
||||||
from .photo_size import PhotoSize
|
from .photo_size import PhotoSize
|
||||||
|
from .mask_position import MaskPosition
|
||||||
|
|
||||||
|
|
||||||
class Sticker(Deserializable):
|
class Sticker(Deserializable):
|
||||||
|
|
@ -8,12 +9,15 @@ class Sticker(Deserializable):
|
||||||
|
|
||||||
https://core.telegram.org/bots/api#sticker
|
https://core.telegram.org/bots/api#sticker
|
||||||
"""
|
"""
|
||||||
def __init__(self, file_id, width, height, thumb, emoji, file_size):
|
|
||||||
|
def __init__(self, file_id, width, height, thumb, emoji, set_name, mask_position, file_size):
|
||||||
self.file_id: str = file_id
|
self.file_id: str = file_id
|
||||||
self.width: int = width
|
self.width: int = width
|
||||||
self.height: int = height
|
self.height: int = height
|
||||||
self.thumb: PhotoSize = thumb
|
self.thumb: PhotoSize = thumb
|
||||||
self.emoji: str = emoji
|
self.emoji: str = emoji
|
||||||
|
self.set_name: str = set_name
|
||||||
|
self.mask_position: MaskPosition = mask_position
|
||||||
self.file_size: int = file_size
|
self.file_size: int = file_size
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
@ -25,6 +29,8 @@ class Sticker(Deserializable):
|
||||||
height = raw_data.get('height')
|
height = raw_data.get('height')
|
||||||
thumb = PhotoSize.deserialize(raw_data.get('thumb'))
|
thumb = PhotoSize.deserialize(raw_data.get('thumb'))
|
||||||
emoji = raw_data.get('emoji')
|
emoji = raw_data.get('emoji')
|
||||||
|
set_name = raw_data.get('set_name')
|
||||||
|
mask_position = MaskPosition.deserialize(raw_data.get('mask_position'))
|
||||||
file_size = raw_data.get('file_size')
|
file_size = raw_data.get('file_size')
|
||||||
|
|
||||||
return Sticker(file_id, width, height, thumb, emoji, file_size)
|
return Sticker(file_id, width, height, thumb, emoji, set_name, mask_position, file_size)
|
||||||
|
|
|
||||||
27
aiogram/types/sticker_set.py
Normal file
27
aiogram/types/sticker_set.py
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
from .base import Deserializable
|
||||||
|
from .sticker import Sticker
|
||||||
|
|
||||||
|
|
||||||
|
class StickerSet(Deserializable):
|
||||||
|
"""
|
||||||
|
This object represents a sticker set.
|
||||||
|
|
||||||
|
https://core.telegram.org/bots/api#stickerset
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, name, title, is_mask, stickers):
|
||||||
|
self.name: str = name
|
||||||
|
self.title: str = title
|
||||||
|
self.is_mask: bool = is_mask
|
||||||
|
self.stickers: [Sticker] = stickers
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def de_json(cls, raw_data):
|
||||||
|
raw_data = cls.check_json(raw_data)
|
||||||
|
|
||||||
|
name = raw_data.get('name')
|
||||||
|
title = raw_data.get('title')
|
||||||
|
is_mask = raw_data.get('is_mask')
|
||||||
|
stickers = Sticker.deserialize(raw_data.get('stickers'))
|
||||||
|
|
||||||
|
return StickerSet(name, title, is_mask, stickers)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue