diff --git a/examples/README.md b/examples/README.md index d3d0f7d6a..74806cb78 100644 --- a/examples/README.md +++ b/examples/README.md @@ -52,6 +52,12 @@ A basic example on how to set up a custom error handler. ### [`chatmemberbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/chatmemberbot.py) A basic example on how `(my_)chat_member` updates can be used. +### [`webappbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/webappbot.py) +A basic example of how [Telegram WebApps](https://core.telegram.org/bots/webapps) can be used. +Use in combination with [`webappbot.html`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/webappbot.html). +For your convenience, this file is hosted by the PTB team such that you don't need to host it yourself. +Uses the [`iro.js`](https://iro.js.org) JavaScript library to showcase a user interface that is hard to achieve with native Telegram functionality. + ### [`contexttypesbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/contexttypesbot.py) This example showcases how `telegram.ext.ContextTypes` can be used to customize the `context` argument of handler and job callbacks. diff --git a/examples/webappbot.html b/examples/webappbot.html new file mode 100644 index 000000000..1565ec34b --- /dev/null +++ b/examples/webappbot.html @@ -0,0 +1,39 @@ + + + + + + python-telegram-bot Example WebApp + + + + + +
+
+
+ + + \ No newline at end of file diff --git a/examples/webappbot.py b/examples/webappbot.py new file mode 100644 index 000000000..e2d47cc38 --- /dev/null +++ b/examples/webappbot.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# pylint: disable=unused-argument,wrong-import-position +# This program is dedicated to the public domain under the CC0 license. + +""" +Simple example of a Telegram WebApp which displays a color picker. +The static website for this website is hosted by the PTB team for your convenience. +Currently only showcases starting the WebApp via a KeyboardButton, as all other methods would +require a bot token. +""" +import json +import logging + +from telegram import __version__ as TG_VER + +try: + from telegram import __version_info__ +except ImportError: + __version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment] + +if __version_info__ < (20, 0, 0, "alpha", 1): + raise RuntimeError( + f"This example is not compatible with your current PTB version {TG_VER}. To view the " + f"{TG_VER} version of this example, " + f"visit https://github.com/python-telegram-bot/python-telegram-bot/tree/v{TG_VER}/examples" + ) +from telegram import KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove, Update, WebAppInfo +from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters + +# Enable logging +logging.basicConfig( + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO +) +logger = logging.getLogger(__name__) + + +# Define a `/start` command handler. +async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + """Send a message with a button that opens a the web app.""" + await update.message.reply_text( + "Please press the button below to choose a color via the WebApp.", + reply_markup=ReplyKeyboardMarkup.from_button( + KeyboardButton( + text="Open the color picker!", + web_app=WebAppInfo(url="https://python-telegram-bot.org/static/webappbot"), + ) + ), + ) + + +# Handle incoming WebAppData +async def web_app_data(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + """Print the received data and remove the button.""" + # Here we use `json.loads`, since the WebApp sends the data JSON serialized string + # (see webappbot.html) + data = json.loads(update.effective_message.web_app_data.data) + await update.message.reply_html( + text=f"You selected the color with the HEX value {data['hex']}. The " + f"corresponding RGB value is {tuple(data['rgb'].values())}.", + reply_markup=ReplyKeyboardRemove(), + ) + + +def main() -> None: + """Start the bot.""" + # Create the Application and pass it your bot's token. + application = Application.builder().token("TOKEN").build() + + application.add_handler(CommandHandler("start", start)) + application.add_handler(MessageHandler(filters.StatusUpdate.WEB_APP_DATA, web_app_data)) + + # Run the bot until the user presses Ctrl-C + application.run_polling() + + +if __name__ == "__main__": + main()