1#!/usr/bin/env python
2# pylint: disable=unused-argument, import-error
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! "
61 "Now let's get back to the private chat."
62 )
63 keyboard = InlineKeyboardMarkup.from_button(
64 InlineKeyboardButton(text="Continue here!", url=url)
65 )
66 await update.message.reply_text(text, reply_markup=keyboard)
67
68
69async def deep_linked_level_2(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
70 """Reached through the SO_COOL payload"""
71 bot = context.bot
72 url = helpers.create_deep_linked_url(bot.username, USING_ENTITIES)
73 text = f'You can also mask the deep-linked URLs as links: <a href="{url}">▶️ CLICK HERE</a>.'
74 await update.message.reply_text(text, parse_mode=ParseMode.HTML, disable_web_page_preview=True)
75
76
77async def deep_linked_level_3(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
78 """Reached through the USING_ENTITIES payload"""
79 await update.message.reply_text(
80 "It is also possible to make deep-linking using InlineKeyboardButtons.",
81 reply_markup=InlineKeyboardMarkup(
82 [[InlineKeyboardButton(text="Like this!", callback_data=KEYBOARD_CALLBACKDATA)]]
83 ),
84 )
85
86
87async def deep_link_level_3_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
88 """Answers CallbackQuery with deeplinking url."""
89 bot = context.bot
90 url = helpers.create_deep_linked_url(bot.username, USING_KEYBOARD)
91 await update.callback_query.answer(url=url)
92
93
94async def deep_linked_level_4(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
95 """Reached through the USING_KEYBOARD payload"""
96 payload = context.args
97 await update.message.reply_text(
98 f"Congratulations! This is as deep as it gets 👏🏻\n\nThe payload was: {payload}"
99 )
100
101
102def main() -> None:
103 """Start the bot."""
104 # Create the Application and pass it your bot's token.
105 application = Application.builder().token("TOKEN").build()
106
107 # More info on what deep linking actually is (read this first if it's unclear to you):
108 # https://core.telegram.org/bots/features#deep-linking
109
110 # Register a deep-linking handler
111 application.add_handler(
112 CommandHandler("start", deep_linked_level_1, filters.Regex(CHECK_THIS_OUT))
113 )
114
115 # This one works with a textual link instead of an URL
116 application.add_handler(CommandHandler("start", deep_linked_level_2, filters.Regex(SO_COOL)))
117
118 # We can also pass on the deep-linking payload
119 application.add_handler(
120 CommandHandler("start", deep_linked_level_3, filters.Regex(USING_ENTITIES))
121 )
122
123 # Possible with inline keyboard buttons as well
124 application.add_handler(
125 CommandHandler("start", deep_linked_level_4, filters.Regex(USING_KEYBOARD))
126 )
127
128 # register callback handler for inline keyboard button
129 application.add_handler(
130 CallbackQueryHandler(deep_link_level_3_callback, pattern=KEYBOARD_CALLBACKDATA)
131 )
132
133 # Make sure the deep-linking handlers occur *before* the normal /start handler.
134 application.add_handler(CommandHandler("start", start))
135
136 # Run the bot until the user presses Ctrl-C
137 application.run_polling(allowed_updates=Update.ALL_TYPES)
138
139
140if __name__ == "__main__":
141 main()