1#!/usr/bin/env python
2# pylint: disable=unused-argument
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 InlineKeyboardButton, InlineKeyboardMarkup, Update, helpers
24from telegram.constants import ParseMode
25from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, filters
26
27# Enable logging
28logging.basicConfig(
29 format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
30)
31
32# set higher logging level for httpx to avoid all GET and POST requests being logged
33logging.getLogger("httpx").setLevel(logging.WARNING)
34
35logger = logging.getLogger(__name__)
36
37# Define constants that will allow us to reuse the deep-linking parameters.
38CHECK_THIS_OUT = "check-this-out"
39USING_ENTITIES = "using-entities-here"
40USING_KEYBOARD = "using-keyboard-here"
41SO_COOL = "so-cool"
42
43# Callback data to pass in 3rd level deep-linking
44KEYBOARD_CALLBACKDATA = "keyboard-callback-data"
45
46
47async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
48 """Send a deep-linked URL when the command /start is issued."""
49 bot = context.bot
50 url = helpers.create_deep_linked_url(bot.username, CHECK_THIS_OUT, group=True)
51 text = "Feel free to tell your friends about it:\n\n" + url
52 await update.message.reply_text(text)
53
54
55async def deep_linked_level_1(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
56 """Reached through the CHECK_THIS_OUT payload"""
57 bot = context.bot
58 url = helpers.create_deep_linked_url(bot.username, SO_COOL)
59 text = (
60 "Awesome, you just accessed hidden functionality! Now let's get back to the private chat."
61 )
62 keyboard = InlineKeyboardMarkup.from_button(
63 InlineKeyboardButton(text="Continue here!", url=url)
64 )
65 await update.message.reply_text(text, reply_markup=keyboard)
66
67
68async def deep_linked_level_2(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
69 """Reached through the SO_COOL payload"""
70 bot = context.bot
71 url = helpers.create_deep_linked_url(bot.username, USING_ENTITIES)
72 text = f'You can also mask the deep-linked URLs as links: <a href="{url}">▶️ CLICK HERE</a>.'
73 await update.message.reply_text(text, parse_mode=ParseMode.HTML, disable_web_page_preview=True)
74
75
76async def deep_linked_level_3(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
77 """Reached through the USING_ENTITIES payload"""
78 await update.message.reply_text(
79 "It is also possible to make deep-linking using InlineKeyboardButtons.",
80 reply_markup=InlineKeyboardMarkup(
81 [[InlineKeyboardButton(text="Like this!", callback_data=KEYBOARD_CALLBACKDATA)]]
82 ),
83 )
84
85
86async def deep_link_level_3_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
87 """Answers CallbackQuery with deeplinking url."""
88 bot = context.bot
89 url = helpers.create_deep_linked_url(bot.username, USING_KEYBOARD)
90 await update.callback_query.answer(url=url)
91
92
93async def deep_linked_level_4(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
94 """Reached through the USING_KEYBOARD payload"""
95 payload = context.args
96 await update.message.reply_text(
97 f"Congratulations! This is as deep as it gets 👏🏻\n\nThe payload was: {payload}"
98 )
99
100
101def main() -> None:
102 """Start the bot."""
103 # Create the Application and pass it your bot's token.
104 application = Application.builder().token("TOKEN").build()
105
106 # More info on what deep linking actually is (read this first if it's unclear to you):
107 # https://core.telegram.org/bots/features#deep-linking
108
109 # Register a deep-linking handler
110 application.add_handler(
111 CommandHandler("start", deep_linked_level_1, filters.Regex(CHECK_THIS_OUT))
112 )
113
114 # This one works with a textual link instead of an URL
115 application.add_handler(CommandHandler("start", deep_linked_level_2, filters.Regex(SO_COOL)))
116
117 # We can also pass on the deep-linking payload
118 application.add_handler(
119 CommandHandler("start", deep_linked_level_3, filters.Regex(USING_ENTITIES))
120 )
121
122 # Possible with inline keyboard buttons as well
123 application.add_handler(
124 CommandHandler("start", deep_linked_level_4, filters.Regex(USING_KEYBOARD))
125 )
126
127 # register callback handler for inline keyboard button
128 application.add_handler(
129 CallbackQueryHandler(deep_link_level_3_callback, pattern=KEYBOARD_CALLBACKDATA)
130 )
131
132 # Make sure the deep-linking handlers occur *before* the normal /start handler.
133 application.add_handler(CommandHandler("start", start))
134
135 # Run the bot until the user presses Ctrl-C
136 application.run_polling(allowed_updates=Update.ALL_TYPES)
137
138
139if __name__ == "__main__":
140 main()