Skip to content

API 4.7 #1858

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Apr 10, 2020
Merged

API 4.7 #1858

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ make the development of bots easy and straightforward. These classes are contain
Telegram API support
====================

All types and methods of the Telegram Bot API **4.6** are supported.
All types and methods of the Telegram Bot API **4.7** are supported.

==========
Installing
Expand Down
6 changes: 6 additions & 0 deletions docs/source/telegram.botcommand.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
telegram.BotCommand
===================

.. autoclass:: telegram.BotCommand
:members:
:show-inheritance:
6 changes: 6 additions & 0 deletions docs/source/telegram.dice.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
telegram.Dice
=============

.. autoclass:: telegram.Dice
:members:
:show-inheritance:
2 changes: 2 additions & 0 deletions docs/source/telegram.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ telegram package
telegram.animation
telegram.audio
telegram.bot
telegram.botcommand
telegram.callbackquery
telegram.chat
telegram.chataction
Expand All @@ -17,6 +18,7 @@ telegram package
telegram.chatphoto
telegram.constants
telegram.contact
telegram.dice
telegram.document
telegram.error
telegram.file
Expand Down
5 changes: 4 additions & 1 deletion telegram/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"""A library that provides a Python interface to the Telegram Bot API"""

from .base import TelegramObject
from .botcommand import BotCommand
from .user import User
from .files.chatphoto import ChatPhoto
from .chat import Chat
Expand All @@ -36,6 +37,7 @@
from .files.venue import Venue
from .files.videonote import VideoNote
from .chataction import ChatAction
from .dice import Dice
from .userprofilephotos import UserProfilePhotos
from .keyboardbutton import KeyboardButton
from .keyboardbuttonpolltype import KeyboardButtonPollType
Expand Down Expand Up @@ -157,5 +159,6 @@
'InputMediaAudio', 'InputMediaDocument', 'TelegramDecryptionError',
'PassportElementErrorSelfie', 'PassportElementErrorTranslationFile',
'PassportElementErrorTranslationFiles', 'PassportElementErrorUnspecified', 'Poll',
'PollOption', 'PollAnswer', 'LoginUrl', 'KeyboardButton', 'KeyboardButtonPollType',
'PollOption', 'PollAnswer', 'LoginUrl', 'KeyboardButton', 'KeyboardButtonPollType', 'Dice',
'BotCommand'
]
247 changes: 226 additions & 21 deletions telegram/bot.py

Large diffs are not rendered by default.

46 changes: 46 additions & 0 deletions telegram/botcommand.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env python
# pylint: disable=R0903
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2020
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram Bot Command."""
from telegram import TelegramObject


class BotCommand(TelegramObject):
"""
This object represents a bot command.

Attributes:
command (:obj:`str`): Text of the command.
description (:obj:`str`): Description of the command.

Args:
command (:obj:`str`): Text of the command, 1-32 characters. Can contain only lowercase
English letters, digits and underscores.
description (:obj:`str`): Description of the command, 3-256 characters.
"""
def __init__(self, command, description, **kwargs):
self.command = command
self.description = description

@classmethod
def de_json(cls, data, bot):
if not data:
return None

return cls(**data)
43 changes: 43 additions & 0 deletions telegram/dice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env python
# pylint: disable=R0903
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2020
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram Dice."""
from telegram import TelegramObject


class Dice(TelegramObject):
"""
This object represents a dice with random value from 1 to 6. (The singular form of "dice" is
"die". However, PTB mimics the Telegram API, which uses the term "dice".)

Attributes:
value (:obj:`int`): Value of the dice.

Args:
value (:obj:`int`): Value of the dice, 1-6.
"""
def __init__(self, value, **kwargs):
self.value = value

@classmethod
def de_json(cls, data, bot):
if not data:
return None

return cls(**data)
48 changes: 47 additions & 1 deletion telegram/ext/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,10 @@ def filter(self, message):
...
MessageHandler(Filters.text(buttons), callback_method)

Note:
Dice messages don't have text. If you want to filter either text or dice messages, use
``Filters.text | Filters.dice``.

Args:
update (Iterable[:obj:`str`], optional): Which messages to allow. Only exact matches
are allowed. If not specified, will allow any text message.
Expand Down Expand Up @@ -427,7 +431,7 @@ class category(BaseFilter):
send media with wrong types that don't fit to this handler.

Example:
Filters.documents.category('audio/') returnes `True` for all types
Filters.documents.category('audio/') returns `True` for all types
of audio sent as file, for example 'audio/mpeg' or 'audio/x-wav'
"""

Expand Down Expand Up @@ -957,6 +961,48 @@ def filter(self, message):
poll = _Poll()
"""Messages that contain a :class:`telegram.Poll`."""

class _Dice(BaseFilter):
name = 'Filters.dice'

class _DiceValues(BaseFilter):

def __init__(self, values):
self.values = [values] if isinstance(values, int) else values
self.name = 'Filters.dice({})'.format(values)

def filter(self, message):
return bool(message.dice and message.dice.value in self.values)

def __call__(self, update):
if isinstance(update, Update):
return self.filter(update.effective_message)
else:
return self._DiceValues(update)

def filter(self, message):
return bool(message.dice)

dice = _Dice()
"""Dice Messages. If an integer or a list of integers is passed, it filters messages to only
allow those whose dice value is appearing in the given list.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
allow those whose dice value is appearing in the given list.
allow those with dice where the value is appearing in the given list.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this is slightly more accurate, the sentence feels kinda weird to me. And it should be clear from the context, that only dice messages are allowed. I'll not change for now. If this is important to you, you can PR for it ;)


Examples:
To allow any dice message, simply use
``MessageHandler(Filters.dice, callback_method)``.
To allow only dice with value 6, use
``MessageHandler(Filters.dice(6), callback_method)``.
To allow only dice with value 5 `or` 6, use
``MessageHandler(Filters.dice([5, 6]), callback_method)``.

Args:
update (:obj:`int` | List[:obj:`int`], optional): Which values to allow. If not
specified, will allow any dice message.

Note:
Dice messages don't have text. If you want to filter either text or dice messages, use
``Filters.text | Filters.dice``.
"""

class language(BaseFilter):
"""Filters messages to only allow those which are from users with a certain language code.

Expand Down
10 changes: 9 additions & 1 deletion telegram/files/sticker.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,22 +138,29 @@ class StickerSet(TelegramObject):
is_animated (:obj:`bool`): True, if the sticker set contains animated stickers.
contains_masks (:obj:`bool`): True, if the sticker set contains masks.
stickers (List[:class:`telegram.Sticker`]): List of all set stickers.
thumb (:class:`telegram.PhotoSize`): Optional. Sticker set thumbnail in the .WEBP or .TGS
format

Args:
name (:obj:`str`): Sticker set name.
title (:obj:`str`): Sticker set title.
is_animated (:obj:`bool`): True, if the sticker set contains animated stickers.
contains_masks (:obj:`bool`): True, if the sticker set contains masks.
stickers (List[:class:`telegram.Sticker`]): List of all set stickers.
thumb (:class:`telegram.PhotoSize`, optional): Sticker set thumbnail in the .WEBP or .TGS
format

"""

def __init__(self, name, title, is_animated, contains_masks, stickers, bot=None, **kwargs):
def __init__(self, name, title, is_animated, contains_masks, stickers, bot=None, thumb=None,
**kwargs):
self.name = name
self.title = title
self.is_animated = is_animated
self.contains_masks = contains_masks
self.stickers = stickers
# Optionals
self.thumb = thumb

self._id_attrs = (self.name,)

Expand All @@ -164,6 +171,7 @@ def de_json(data, bot):

data = super(StickerSet, StickerSet).de_json(data, bot)

data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)
data['stickers'] = Sticker.de_list(data.get('stickers'), bot)

return StickerSet(bot=bot, **data)
Expand Down
28 changes: 25 additions & 3 deletions telegram/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

from telegram import (Animation, Audio, Contact, Document, Chat, Location, PhotoSize, Sticker,
TelegramObject, User, Video, Voice, Venue, MessageEntity, Game, Invoice,
SuccessfulPayment, VideoNote, PassportData, Poll, InlineKeyboardMarkup)
SuccessfulPayment, VideoNote, PassportData, Poll, InlineKeyboardMarkup, Dice)
from telegram import ParseMode
from telegram.utils.helpers import escape_markdown, to_timestamp, from_timestamp

Expand Down Expand Up @@ -106,6 +106,7 @@ class Message(TelegramObject):
passport_data (:class:`telegram.PassportData`): Optional. Telegram Passport data.
poll (:class:`telegram.Poll`): Optional. Message is a native poll,
information about the poll.
dice (:class:`telegram.Dice`): Optional. Message is a dice.
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
to the message.
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
Expand Down Expand Up @@ -199,7 +200,7 @@ class Message(TelegramObject):
smaller than 52 bits, so a signed 64 bit integer or double-precision float type are
safe for storing this identifier.
pinned_message (:class:`telegram.message`, optional): Specified message was pinned. Note
that the Message object in this field will not contain further attr:`reply_to_message`
that the Message object in this field will not contain further :attr:`reply_to_message`
fields even if it is itself a reply.
invoice (:class:`telegram.Invoice`, optional): Message is an invoice for a payment,
information about the invoice.
Expand All @@ -214,6 +215,7 @@ class Message(TelegramObject):
passport_data (:class:`telegram.PassportData`, optional): Telegram Passport data.
poll (:class:`telegram.Poll`, optional): Message is a native poll,
information about the poll.
dice (:class:`telegram.Dice`, optional): Message is a dice with random value from 1 to 6.
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
to the message. login_url buttons are represented as ordinary url buttons.
default_quote (:obj:`bool`, optional): Default setting for the `quote` parameter of the
Expand All @@ -229,7 +231,7 @@ class Message(TelegramObject):
MESSAGE_TYPES = ['text', 'new_chat_members', 'left_chat_member', 'new_chat_title',
'new_chat_photo', 'delete_chat_photo', 'group_chat_created',
'supergroup_chat_created', 'channel_chat_created', 'migrate_to_chat_id',
'migrate_from_chat_id', 'pinned_message',
'migrate_from_chat_id', 'pinned_message', 'poll', 'dice',
'passport_data'] + ATTACHMENT_TYPES

def __init__(self,
Expand Down Expand Up @@ -282,6 +284,7 @@ def __init__(self,
reply_markup=None,
bot=None,
default_quote=None,
dice=None,
**kwargs):
# Required
self.message_id = int(message_id)
Expand Down Expand Up @@ -331,6 +334,7 @@ def __init__(self,
self.animation = animation
self.passport_data = passport_data
self.poll = poll
self.dice = dice
self.reply_markup = reply_markup
self.bot = bot
self.default_quote = default_quote
Expand Down Expand Up @@ -404,6 +408,7 @@ def de_json(cls, data, bot):
data['successful_payment'] = SuccessfulPayment.de_json(data.get('successful_payment'), bot)
data['passport_data'] = PassportData.de_json(data.get('passport_data'), bot)
data['poll'] = Poll.de_json(data.get('poll'), bot)
data['dice'] = Dice.de_json(data.get('dice'), bot)
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'), bot)

return cls(bot=bot, **data)
Expand Down Expand Up @@ -808,6 +813,23 @@ def reply_poll(self, *args, **kwargs):
self._quote(kwargs)
return self.bot.send_poll(self.chat_id, *args, **kwargs)

def reply_dice(self, *args, **kwargs):
"""Shortcut for::

bot.send_dice(update.message.chat_id, *args, **kwargs)

Keyword Args:
quote (:obj:`bool`, optional): If set to ``True``, the dice is sent as an actual reply
to this message. If ``reply_to_message_id`` is passed in ``kwargs``, this parameter
will be ignored. Default: ``True`` in group chats and ``False`` in private chats.

Returns:
:class:`telegram.Message`: On success, instance representing the message posted.

"""
self._quote(kwargs)
return self.bot.send_dice(self.chat_id, *args, **kwargs)

def forward(self, chat_id, *args, **kwargs):
"""Shortcut for::

Expand Down
Binary file added tests/data/sticker_set_thumb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/data/telegram_animated_sticker.tgs
Binary file not shown.
Loading