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"""
6Simple Bot to print/download all incoming passport data
7
8See https://telegram.org/blog/passport for info about what telegram passport is.
9
10See https://github.com/python-telegram-bot/python-telegram-bot/wiki/Telegram-Passport
11 for how to use Telegram Passport properly with python-telegram-bot.
12
13Note:
14To use Telegram Passport, you must install PTB via
15`pip install "python-telegram-bot[passport]"`
16"""
17import logging
18from pathlib import Path
19
20from telegram import __version__ as TG_VER
21
22try:
23 from telegram import __version_info__
24except ImportError:
25 __version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
26
27if __version_info__ < (20, 0, 0, "alpha", 5):
28 raise RuntimeError(
29 f"This example is not compatible with your current PTB version {TG_VER}. To view the "
30 f"{TG_VER} version of this example, "
31 f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
32 )
33from telegram import Update
34from telegram.ext import Application, ContextTypes, MessageHandler, filters
35
36# Enable logging
37
38logging.basicConfig(
39 format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
40)
41
42# set higher logging level for httpx to avoid all GET and POST requests being logged
43logging.getLogger("httpx").setLevel(logging.WARNING)
44
45logger = logging.getLogger(__name__)
46
47
48async def msg(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
49 """Downloads and prints the received passport data."""
50 # Retrieve passport data
51 passport_data = update.message.passport_data
52 # If our nonce doesn't match what we think, this Update did not originate from us
53 # Ideally you would randomize the nonce on the server
54 if passport_data.decrypted_credentials.nonce != "thisisatest":
55 return
56
57 # Print the decrypted credential data
58 # For all elements
59 # Print their decrypted data
60 # Files will be downloaded to current directory
61 for data in passport_data.decrypted_data: # This is where the data gets decrypted
62 if data.type == "phone_number":
63 print("Phone: ", data.phone_number)
64 elif data.type == "email":
65 print("Email: ", data.email)
66 if data.type in (
67 "personal_details",
68 "passport",
69 "driver_license",
70 "identity_card",
71 "internal_passport",
72 "address",
73 ):
74 print(data.type, data.data)
75 if data.type in (
76 "utility_bill",
77 "bank_statement",
78 "rental_agreement",
79 "passport_registration",
80 "temporary_registration",
81 ):
82 print(data.type, len(data.files), "files")
83 for file in data.files:
84 actual_file = await file.get_file()
85 print(actual_file)
86 await actual_file.download_to_drive()
87 if (
88 data.type in ("passport", "driver_license", "identity_card", "internal_passport")
89 and data.front_side
90 ):
91 front_file = await data.front_side.get_file()
92 print(data.type, front_file)
93 await front_file.download_to_drive()
94 if data.type in ("driver_license" and "identity_card") and data.reverse_side:
95 reverse_file = await data.reverse_side.get_file()
96 print(data.type, reverse_file)
97 await reverse_file.download_to_drive()
98 if (
99 data.type in ("passport", "driver_license", "identity_card", "internal_passport")
100 and data.selfie
101 ):
102 selfie_file = await data.selfie.get_file()
103 print(data.type, selfie_file)
104 await selfie_file.download_to_drive()
105 if data.translation and data.type in (
106 "passport",
107 "driver_license",
108 "identity_card",
109 "internal_passport",
110 "utility_bill",
111 "bank_statement",
112 "rental_agreement",
113 "passport_registration",
114 "temporary_registration",
115 ):
116 print(data.type, len(data.translation), "translation")
117 for file in data.translation:
118 actual_file = await file.get_file()
119 print(actual_file)
120 await actual_file.download_to_drive()
121
122
123def main() -> None:
124 """Start the bot."""
125 # Create the Application and pass it your token and private key
126 private_key = Path("private.key")
127 application = (
128 Application.builder().token("TOKEN").private_key(private_key.read_bytes()).build()
129 )
130
131 # On messages that include passport data call msg
132 application.add_handler(MessageHandler(filters.PASSPORT_DATA, msg))
133
134 # Run the bot until the user presses Ctrl-C
135 application.run_polling(allowed_updates=Update.ALL_TYPES)
136
137
138if __name__ == "__main__":
139 main()