deeplinking.py

  1#!/usr/bin/env python
  2# pylint: disable=unused-argument, wrong-import-position
  3# This program is dedicated to the public domain under the CC0 license.
  4
  5"""Bot that explains Telegram's "Deep Linking Parameters" functionality.
  6
  7This program is dedicated to the public domain under the CC0 license.
  8
  9This Bot uses the Application class to handle the bot.
 10
 11First, a few handler functions are defined. Then, those functions are passed to
 12the Application and registered at their respective places.
 13Then, the bot is started and runs until we press Ctrl-C on the command line.
 14
 15Usage:
 16Deep Linking example. Send /start to get the link.
 17Press Ctrl-C on the command line or send a signal to the process to stop the
 18bot.
 19"""
 20
 21import logging
 22
 23from telegram import __version__ as TG_VER
 24
 25try:
 26    from telegram import __version_info__
 27except ImportError:
 28    __version_info__ = (0, 0, 0, 0, 0)  # type: ignore[assignment]
 29
 30if __version_info__ < (20, 0, 0, "alpha", 1):
 31    raise RuntimeError(
 32        f"This example is not compatible with your current PTB version {TG_VER}. To view the "
 33        f"{TG_VER} version of this example, "
 34        f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
 35    )
 36from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, helpers
 37from telegram.constants import ParseMode
 38from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, filters
 39
 40# Enable logging
 41logging.basicConfig(
 42    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
 43)
 44
 45logger = logging.getLogger(__name__)
 46
 47# Define constants that will allow us to reuse the deep-linking parameters.
 48CHECK_THIS_OUT = "check-this-out"
 49USING_ENTITIES = "using-entities-here"
 50USING_KEYBOARD = "using-keyboard-here"
 51SO_COOL = "so-cool"
 52
 53# Callback data to pass in 3rd level deep-linking
 54KEYBOARD_CALLBACKDATA = "keyboard-callback-data"
 55
 56
 57async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 58    """Send a deep-linked URL when the command /start is issued."""
 59    bot = context.bot
 60    url = helpers.create_deep_linked_url(bot.username, CHECK_THIS_OUT, group=True)
 61    text = "Feel free to tell your friends about it:\n\n" + url
 62    await update.message.reply_text(text)
 63
 64
 65async def deep_linked_level_1(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 66    """Reached through the CHECK_THIS_OUT payload"""
 67    bot = context.bot
 68    url = helpers.create_deep_linked_url(bot.username, SO_COOL)
 69    text = (
 70        "Awesome, you just accessed hidden functionality! "
 71        "Now let's get back to the private chat."
 72    )
 73    keyboard = InlineKeyboardMarkup.from_button(
 74        InlineKeyboardButton(text="Continue here!", url=url)
 75    )
 76    await update.message.reply_text(text, reply_markup=keyboard)
 77
 78
 79async def deep_linked_level_2(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 80    """Reached through the SO_COOL payload"""
 81    bot = context.bot
 82    url = helpers.create_deep_linked_url(bot.username, USING_ENTITIES)
 83    text = f'You can also mask the deep-linked URLs as links: <a href="{url}">▶️ CLICK HERE</a>.'
 84    await update.message.reply_text(text, parse_mode=ParseMode.HTML, disable_web_page_preview=True)
 85
 86
 87async def deep_linked_level_3(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 88    """Reached through the USING_ENTITIES payload"""
 89    await update.message.reply_text(
 90        "It is also possible to make deep-linking using InlineKeyboardButtons.",
 91        reply_markup=InlineKeyboardMarkup(
 92            [[InlineKeyboardButton(text="Like this!", callback_data=KEYBOARD_CALLBACKDATA)]]
 93        ),
 94    )
 95
 96
 97async def deep_link_level_3_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
 98    """Answers CallbackQuery with deeplinking url."""
 99    bot = context.bot
100    url = helpers.create_deep_linked_url(bot.username, USING_KEYBOARD)
101    await update.callback_query.answer(url=url)
102
103
104async def deep_linked_level_4(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
105    """Reached through the USING_KEYBOARD payload"""
106    payload = context.args
107    await update.message.reply_text(
108        f"Congratulations! This is as deep as it gets 👏🏻\n\nThe payload was: {payload}"
109    )
110
111
112def main() -> None:
113    """Start the bot."""
114    # Create the Application and pass it your bot's token.
115    application = Application.builder().token("TOKEN").build()
116
117    # More info on what deep linking actually is (read this first if it's unclear to you):
118    # https://core.telegram.org/bots/features#deep-linking
119
120    # Register a deep-linking handler
121    application.add_handler(
122        CommandHandler("start", deep_linked_level_1, filters.Regex(CHECK_THIS_OUT))
123    )
124
125    # This one works with a textual link instead of an URL
126    application.add_handler(CommandHandler("start", deep_linked_level_2, filters.Regex(SO_COOL)))
127
128    # We can also pass on the deep-linking payload
129    application.add_handler(
130        CommandHandler("start", deep_linked_level_3, filters.Regex(USING_ENTITIES))
131    )
132
133    # Possible with inline keyboard buttons as well
134    application.add_handler(
135        CommandHandler("start", deep_linked_level_4, filters.Regex(USING_KEYBOARD))
136    )
137
138    # register callback handler for inline keyboard button
139    application.add_handler(
140        CallbackQueryHandler(deep_link_level_3_callback, pattern=KEYBOARD_CALLBACKDATA)
141    )
142
143    # Make sure the deep-linking handlers occur *before* the normal /start handler.
144    application.add_handler(CommandHandler("start", start))
145
146    # Run the bot until the user presses Ctrl-C
147    application.run_polling()
148
149
150if __name__ == "__main__":
151    main()