Documentation Improvements (#4573, #4565)

Co-authored-by: Snehashish Biswas <coderrx06@gmail.com>
Co-authored-by: poolitzer <github@poolitzer.eu>
This commit is contained in:
Bibo-Joshi 2024-12-01 11:47:38 +01:00 committed by GitHub
parent ef1685c436
commit ffe23be992
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 63 additions and 44 deletions

View file

@ -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>`_

View file

@ -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
@ -26,36 +26,36 @@ logging.getLogger("httpx").setLevel(logging.WARNING)
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,
@ -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,
@ -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)

View file

@ -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

View file

@ -36,10 +36,11 @@ RT = TypeVar("RT")
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>`
@ -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.