Skip to content
Merged
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
60 changes: 58 additions & 2 deletions telegram/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2521,6 +2521,8 @@ def set_webhook(
max_connections: int = 40,
allowed_updates: List[str] = None,
api_kwargs: JSONDict = None,
ip_address: str = None,
drop_pending_updates: bool = None,
) -> bool:
"""
Use this method to specify a url and receive incoming updates via an outgoing webhook.
Expand All @@ -2541,6 +2543,8 @@ def set_webhook(
certificate (:obj:`filelike`): Upload your public key certificate so that the root
certificate in use can be checked. See our self-signed guide for details.
(https://goo.gl/rw7w6Y)
ip_address (:obj:`str`, optional): The fixed IP address which will be used to send
webhook requests instead of the IP address resolved through DNS.
max_connections (:obj:`int`, optional): Maximum allowed number of simultaneous HTTPS
connections to the webhook for update delivery, 1-100. Defaults to 40. Use lower
values to limit the load on your bot's server, and higher values to increase your
Expand All @@ -2553,6 +2557,8 @@ def set_webhook(
specified, the previous setting will be used. Please note that this parameter
doesn't affect updates created before the call to the set_webhook, so unwanted
updates may be received for a short period of time.
drop_pending_updates (:obj:`bool`, optional): Pass :obj:`True` to drop all pending
updates.
timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
the read timeout from the server (instead of the one specified during creation of
the connection pool).
Expand Down Expand Up @@ -2592,18 +2598,26 @@ def set_webhook(
data['max_connections'] = max_connections
if allowed_updates is not None:
data['allowed_updates'] = allowed_updates
if ip_address:
data['ip_address'] = ip_address
if drop_pending_updates:
data['drop_pending_updates'] = drop_pending_updates

result = self._post('setWebhook', data, timeout=timeout, api_kwargs=api_kwargs)

return result # type: ignore[return-value]

@log
def delete_webhook(self, timeout: float = None, api_kwargs: JSONDict = None) -> bool:
def delete_webhook(
self, timeout: float = None, api_kwargs: JSONDict = None, drop_pending_updates: bool = None
) -> bool:
"""
Use this method to remove webhook integration if you decide to switch back to
getUpdates. Requires no parameters.

Args:
drop_pending_updates(:obj:`bool`, optional): Pass :obj:`True`: to drop all pending
updates.
timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
the read timeout from the server (instead of the one specified during creation of
the connection pool).
Expand All @@ -2617,7 +2631,12 @@ def delete_webhook(self, timeout: float = None, api_kwargs: JSONDict = None) ->
:class:`telegram.TelegramError`

"""
result = self._post('deleteWebhook', None, timeout=timeout, api_kwargs=api_kwargs)
data = {}

if drop_pending_updates:
data['drop_pending_updates'] = drop_pending_updates

result = self._post('deleteWebhook', data, timeout=timeout, api_kwargs=api_kwargs)

return result # type: ignore[return-value]

Expand Down Expand Up @@ -4360,6 +4379,41 @@ def set_my_commands(

return result # type: ignore[return-value]

@log
def log_out(self) -> bool:
"""
Use this method to log out from the cloud Bot API server before launching the bot locally.
You *must* log out the bot before running it locally, otherwise there is no guarantee that
the bot will receive updates. After a successful call, you can immediately log in on a
local server, but will not be able to log in back to the cloud Bot API server for 10
minutes.

Returns:
:obj:`True`: On success

Raises:
:class:`telegram.TelegramError`

"""
return self._post('logOut') # type: ignore[return-value]

@log
def close(self) -> bool:
"""
Use this method to close the bot instance before moving it from one local server to
another. You need to delete the webhook before calling this method to ensure that the bot
isn't launched again after server restart. The method will return error 429 in the first
10 minutes after the bot is launched.

Returns:
:obj:`True`: On success

Raises:
:class:`telegram.TelegramError`

"""
return self._post('close') # type: ignore[return-value]

def to_dict(self) -> JSONDict:
data: JSONDict = {'id': self.id, 'username': self.username, 'first_name': self.first_name}

Expand Down Expand Up @@ -4509,3 +4563,5 @@ def to_dict(self) -> JSONDict:
"""Alias for :attr:`get_my_commands`"""
setMyCommands = set_my_commands
"""Alias for :attr:`set_my_commands`"""
logOut = log_out
"""Alias for :attr:`log_out`"""
11 changes: 9 additions & 2 deletions telegram/webhookinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ class WebhookInfo(TelegramObject):

Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`url`, :attr:`has_custom_certificate`,
:attr:`pending_update_count`, :attr:`last_error_date`, :attr:`last_error_message`,
:attr:`max_connections` and :attr:`allowed_updates` are equal.
:attr:`pending_update_count`, :attr:`ip_address`, :attr:`last_error_date`,
:attr:`last_error_message`, :attr:`max_connections` and :attr:`allowed_updates` are equal.

Attributes:
url (:obj:`str`): Webhook URL.
has_custom_certificate (:obj:`bool`): If a custom certificate was provided for webhook.
pending_update_count (:obj:`int`): Number of updates awaiting delivery.
ip_address (:obj:`str`): Optional. Currently used webhook IP address.
last_error_date (:obj:`int`): Optional. Unix time for the most recent error that happened.
last_error_message (:obj:`str`): Optional. Error message in human-readable format.
max_connections (:obj:`int`): Optional. Maximum allowed number of simultaneous HTTPS
Expand All @@ -49,6 +50,7 @@ class WebhookInfo(TelegramObject):
has_custom_certificate (:obj:`bool`): :obj:`True`, if a custom certificate was provided for
webhook certificate checks.
pending_update_count (:obj:`int`): Number of updates awaiting delivery.
ip_address (:obj:`str`, optional): Currently used webhook IP address.
last_error_date (:obj:`int`, optional): Unix time for the most recent error that happened
when trying to deliver an update via webhook.
last_error_message (:obj:`str`, optional): Error message in human-readable format for the
Expand All @@ -69,12 +71,16 @@ def __init__(
last_error_message: str = None,
max_connections: int = None,
allowed_updates: List[str] = None,
ip_address: str = None,
**_kwargs: Any,
):
# Required
self.url = url
self.has_custom_certificate = has_custom_certificate
self.pending_update_count = pending_update_count

# Optional
self.ip_address = ip_address
self.last_error_date = last_error_date
self.last_error_message = last_error_message
self.max_connections = max_connections
Expand All @@ -84,6 +90,7 @@ def __init__(
self.url,
self.has_custom_certificate,
self.pending_update_count,
self.ip_address,
self.last_error_date,
self.last_error_message,
self.max_connections,
Expand Down
38 changes: 37 additions & 1 deletion tests/test_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -922,7 +922,12 @@ def test_set_webhook_get_webhook_info_and_delete_webhook(self, bot):
url = 'https://python-telegram-bot.org/test/webhook'
max_connections = 7
allowed_updates = ['message']
bot.set_webhook(url, max_connections=max_connections, allowed_updates=allowed_updates)
bot.set_webhook(
url,
max_connections=max_connections,
allowed_updates=allowed_updates,
ip_address='127.0.0.1',
)
time.sleep(2)
live_info = bot.get_webhook_info()
time.sleep(6)
Expand All @@ -933,6 +938,19 @@ def test_set_webhook_get_webhook_info_and_delete_webhook(self, bot):
assert live_info.url == url
assert live_info.max_connections == max_connections
assert live_info.allowed_updates == allowed_updates
assert live_info.ip_address == '127.0.0.1'

@pytest.mark.parametrize('drop_pending_updates', [True, False])
def test_set_webhook_delete_webhook_drop_pending_updates(
self, bot, drop_pending_updates, monkeypatch
):
def assertion(url, data, *args, **kwargs):
return bool(data.get('drop_pending_updates')) == drop_pending_updates

monkeypatch.setattr(bot.request, 'post', assertion)

assert bot.set_webhook(drop_pending_updates=drop_pending_updates)
assert bot.delete_webhook(drop_pending_updates=drop_pending_updates)

@flaky(3, 1)
@pytest.mark.timeout(10)
Expand Down Expand Up @@ -1379,3 +1397,21 @@ def test_set_and_get_my_commands_strings(self, bot):
assert bc[0].description == 'descr1'
assert bc[1].command == 'cmd2'
assert bc[1].description == 'descr2'

def test_log_out(self, monkeypatch, bot):
# We don't actually make a request as to not break the test setup
def assertion(url, data, *args, **kwargs):
return data == {} and url.split('/')[-1] == 'logOut'

monkeypatch.setattr(bot.request, 'post', assertion)

assert bot.log_out()

def test_close(self, monkeypatch, bot):
# We don't actually make a request as to not break the test setup
def assertion(url, data, *args, **kwargs):
return data == {} and url.split('/')[-1] == 'close'

monkeypatch.setattr(bot.request, 'post', assertion)

assert bot.close()
3 changes: 3 additions & 0 deletions tests/test_webhookinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def webhook_info():
url=TestWebhookInfo.url,
has_custom_certificate=TestWebhookInfo.has_custom_certificate,
pending_update_count=TestWebhookInfo.pending_update_count,
ip_address=TestWebhookInfo.ip_address,
last_error_date=TestWebhookInfo.last_error_date,
max_connections=TestWebhookInfo.max_connections,
allowed_updates=TestWebhookInfo.allowed_updates,
Expand All @@ -39,6 +40,7 @@ class TestWebhookInfo(object):
url = "http://www.google.com"
has_custom_certificate = False
pending_update_count = 5
ip_address = '127.0.0.1'
last_error_date = time.time()
max_connections = 42
allowed_updates = ['type1', 'type2']
Expand All @@ -52,6 +54,7 @@ def test_to_dict(self, webhook_info):
assert webhook_info_dict['last_error_date'] == self.last_error_date
assert webhook_info_dict['max_connections'] == self.max_connections
assert webhook_info_dict['allowed_updates'] == self.allowed_updates
assert webhook_info_dict['ip_address'] == self.ip_address

def test_equality(self):
a = WebhookInfo(
Expand Down