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