Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Documentation Improvements #4573

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 4 commits into from
Dec 1, 2024
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
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ The following wonderful people contributed directly or indirectly to this projec
- `Rahiel Kasim <https://github.com/rahiel>`_
- `Riko Naka <https://github.com/rikonaka>`_
- `Rizlas <https://github.com/rizlas>`_
- `Snehashish Biswas <https://github.com/Snehashish06>`_
- `Sahil Sharma <https://github.com/sahilsharma811>`_
- `Sam Mosleh <https://github.com/sam-mosleh>`_
- `Sascha <https://github.com/saschalalala>`_
Expand Down
79 changes: 39 additions & 40 deletions examples/paymentbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# pylint: disable=unused-argument
# This program is dedicated to the public domain under the CC0 license.

"""Basic example for a bot that can receive payment from user."""
"""Basic example for a bot that can receive payments from users."""

import logging

Expand All @@ -26,36 +26,36 @@

logger = logging.getLogger(__name__)

# Insert the token from your payment provider.
# In order to get a provider_token see https://core.telegram.org/bots/payments#getting-a-token
PAYMENT_PROVIDER_TOKEN = "PAYMENT_PROVIDER_TOKEN"


async def start_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Displays info on how to use the bot."""
"""Provides instructions on how to use the bot."""
msg = (
"Use /shipping to get an invoice for shipping-payment, or /noshipping for an "
"Use /shipping to receive an invoice with shipping included, or /noshipping for an "
"invoice without shipping."
)

await update.message.reply_text(msg)


async def start_with_shipping_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Sends an invoice with shipping-payment."""
"""Sends an invoice which triggers a shipping query."""
chat_id = update.message.chat_id
title = "Payment Example"
description = "Payment Example using python-telegram-bot"
# select a payload just for you to recognize its the donation from your bot
description = "Example of a payment process using the python-telegram-bot library."
# Unique payload to identify this payment request as being from your bot
payload = "Custom-Payload"
# In order to get a provider_token see https://core.telegram.org/bots/payments#getting-a-token
# Set up the currency.
# List of supported currencies: https://core.telegram.org/bots/payments#supported-currencies
currency = "USD"
# price in dollars
# Price in dollars
price = 1
# price * 100 so as to include 2 decimal points
# check https://core.telegram.org/bots/payments#supported-currencies for more details
# Convert price to cents from dollars.
prices = [LabeledPrice("Test", price * 100)]

# optionally pass need_name=True, need_phone_number=True,
# need_email=True, need_shipping_address=True, is_flexible=True
# Optional parameters like need_shipping_address and is_flexible trigger extra user prompts
# https://docs.python-telegram-bot.org/en/stable/telegram.bot.html#telegram.Bot.send_invoice
await context.bot.send_invoice(
chat_id,
title,
Expand All @@ -75,17 +75,16 @@ async def start_with_shipping_callback(update: Update, context: ContextTypes.DEF
async def start_without_shipping_callback(
update: Update, context: ContextTypes.DEFAULT_TYPE
) -> None:
"""Sends an invoice without shipping-payment."""
"""Sends an invoice without requiring shipping details."""
chat_id = update.message.chat_id
title = "Payment Example"
description = "Payment Example using python-telegram-bot"
# select a payload just for you to recognize its the donation from your bot
description = "Example of a payment process using the python-telegram-bot library."
# Unique payload to identify this payment request as being from your bot
payload = "Custom-Payload"
# In order to get a provider_token see https://core.telegram.org/bots/payments#getting-a-token
currency = "USD"
# price in dollars
# Price in dollars
price = 1
# price * 100 so as to include 2 decimal points
# Convert price to cents from dollars.
prices = [LabeledPrice("Test", price * 100)]

# optionally pass need_name=True, need_phone_number=True,
Expand All @@ -96,65 +95,65 @@ async def start_without_shipping_callback(


async def shipping_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Answers the ShippingQuery with ShippingOptions"""
"""Handles the ShippingQuery with available shipping options."""
query = update.shipping_query
# check the payload, is this from your bot?
# Verify if the payload matches, ensure it's from your bot
if query.invoice_payload != "Custom-Payload":
# answer False pre_checkout_query
# If not, respond with an error
await query.answer(ok=False, error_message="Something went wrong...")
return

# First option has a single LabeledPrice
# Define available shipping options
# First option with a single price entry
options = [ShippingOption("1", "Shipping Option A", [LabeledPrice("A", 100)])]
# second option has an array of LabeledPrice objects
# Second option with multiple price entries
price_list = [LabeledPrice("B1", 150), LabeledPrice("B2", 200)]
options.append(ShippingOption("2", "Shipping Option B", price_list))
await query.answer(ok=True, shipping_options=options)


# after (optional) shipping, it's the pre-checkout
# After (optional) shipping, process the pre-checkout step
async def precheckout_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Answers the PreQecheckoutQuery"""
"""Responds to the PreCheckoutQuery as the final confirmation for checkout."""
query = update.pre_checkout_query
# check the payload, is this from your bot?
# Verify if the payload matches, ensure it's from your bot
if query.invoice_payload != "Custom-Payload":
# answer False pre_checkout_query
# If not, respond with an error
await query.answer(ok=False, error_message="Something went wrong...")
else:
await query.answer(ok=True)


# finally, after contacting the payment provider...
# Final callback after successful payment
async def successful_payment_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Confirms the successful payment."""
# do something after successfully receiving payment?
await update.message.reply_text("Thank you for your payment!")
"""Acknowledges successful payment and thanks the user."""
await update.message.reply_text("Thank you for your payment.")


def main() -> None:
"""Run the bot."""
"""Starts the bot and sets up handlers."""
# Create the Application and pass it your bot's token.
application = Application.builder().token("TOKEN").build()

# simple start function
# Start command to display usage instructions
application.add_handler(CommandHandler("start", start_callback))

# Add command handler to start the payment invoice
# Command handlers for starting the payment process
application.add_handler(CommandHandler("shipping", start_with_shipping_callback))
application.add_handler(CommandHandler("noshipping", start_without_shipping_callback))

# Optional handler if your product requires shipping
# Handler for shipping query (if product requires shipping)
application.add_handler(ShippingQueryHandler(shipping_callback))

# Pre-checkout handler to final check
# Pre-checkout handler for verifying payment details.
application.add_handler(PreCheckoutQueryHandler(precheckout_callback))

# Success! Notify your user!
# Handler for successful payment. Notify the user that the payment was successful.
application.add_handler(
MessageHandler(filters.SUCCESSFUL_PAYMENT, successful_payment_callback)
)

# Run the bot until the user presses Ctrl-C
# Start polling for updates until interrupted (CTRL+C)
application.run_polling(allowed_updates=Update.ALL_TYPES)


Expand Down
13 changes: 13 additions & 0 deletions telegram/ext/_aioratelimiter.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,19 @@ class AIORateLimiter(BaseRateLimiter[int]):
necessary in some cases, e.g. the bot may hit a rate limit in one group but might still
be allowed to send messages in another group.

Tip:
With `Bot API 7.1 <https://core.telegram.org/bots/api-changelog#october-31-2024>`_
(PTB v27.1), Telegram introduced the parameter
:paramref:`~telegram.Bot.send_message.allow_paid_broadcast`.
This allows bots to send up to
:tg-const:`telegram.constants.FloodLimit.PAID_MESSAGES_PER_SECOND` messages per second by
paying a fee in Telegram Stars.

.. caution::
This class currently doesn't take the
:paramref:`~telegram.Bot.send_message.allow_paid_broadcast` parameter into account.
This means that the rate limiting is applied just like for any other message.

Note:
This class is to be understood as minimal effort reference implementation.
If you would like to handle rate limiting in a more sophisticated, fine-tuned way, we
Expand Down
14 changes: 10 additions & 4 deletions telegram/ext/_handlers/commandhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@
class CommandHandler(BaseHandler[Update, CCT, RT]):
"""Handler class to handle Telegram commands.

Commands are Telegram messages that start with ``/``, optionally followed by an ``@`` and the
bot's name and/or some additional text. The handler will add a :obj:`list` to the
:class:`CallbackContext` named :attr:`CallbackContext.args`. It will contain a list of strings,
which is the text following the command split on single or consecutive whitespace characters.
Commands are Telegram messages that start with a :attr:`telegram.MessageEntity.BOT_COMMAND`
(so with ``/``, optionally followed by an ``@`` and the bot's name and/or some additional
text). The handler will add a :obj:`list` to the :class:`CallbackContext` named
:attr:`CallbackContext.args`. It will contain a list of strings, which is the text following
the command split on single or consecutive whitespace characters.

By default, the handler listens to messages as well as edited messages. To change this behavior
use :attr:`~filters.UpdateType.EDITED_MESSAGE <telegram.ext.filters.UpdateType.EDITED_MESSAGE>`
Expand All @@ -53,6 +54,11 @@ class CommandHandler(BaseHandler[Update, CCT, RT]):
:attr:`telegram.ext.filters.CAPTION` and :class:`telegram.ext.filters.Regex`) to handle
those messages.

Note:
If you want to support a different entity in the beginning, e.g. if a command message is
wrapped in a :attr:`telegram.MessageEntity.CODE`, use the
:class:`telegram.ext.PrefixHandler`.

Warning:
When setting :paramref:`block` to :obj:`False`, you cannot rely on adding custom
attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info.
Expand Down