Skip to content

Commit 33c0796

Browse files
committed
v0.1705 - query if token missing
1 parent ec3de24 commit 33c0796

File tree

4 files changed

+213
-41
lines changed

4 files changed

+213
-41
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ After launching the bot, you can interact with it via Telegram (message `@whatev
145145
- `/language` - set the model's transcription language (`auto` = autodetect); if you know the language spoken in the audio, setting the transcription language manually with this command may improve both transcription speed and accuracy.
146146

147147
## Changes
148+
- v0.1705 - Dockerized pre-builds; thanks to [jonmjr](https://github.com/jonmrjr) for assistance!
149+
- updated `src/utils/bot_token.py` to query for a bot token if it's not found from either env vars or from the file
150+
- can be useful when running the bot in Docker containers
151+
- this option can be set on/off in `config.ini` with `AskForTokenIfNotFound = True` (default is `true`)
148152
- v0.1704 - Token logic / `bot_token.py` updates; added `config.ini` preferences for reading the bot token
149153
- `preferenvforbottoken = True` is now on by default to prefer the environment variable entry for the bot token.
150154
- set to `false` to prefer `config/bot_token.txt` over the environment variable

config/config.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
preferenvforbottoken = True
55
# Set to True to allow falling back to the alternative token source if the preferred one fails.
66
AllowBotTokenFallback = True
7+
# Prompt the user for a Telegram Bot API token if it's not found; write it to `config/bot_token.txt`.
8+
AskForTokenIfNotFound = True
79

810
[GeneralSettings]
911
# Restart on connection failure

src/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# openai-whisper transcriber-bot for Telegram
44

55
# version of this program
6-
version_number = "0.1704"
6+
version_number = "0.1705"
77

88
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
99
# https://github.com/FlyingFathead/whisper-transcriber-telegram-bot/

src/utils/bot_token.py

Lines changed: 206 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# ~~~ Enhanced Read Telegram Bot Token with Configurable Fallback and Appropriate Logging ~~~
1+
# ~~~ Enhanced Read Telegram Bot Token with Configurable Fallback, Appropriate Logging, and Validity Check ~~~
22

33
import os
44
import configparser
@@ -39,26 +39,37 @@ def get_bot_token():
3939

4040
prefer_env = config.getboolean('DEFAULT', 'PreferEnvForBotToken', fallback=True)
4141
allow_fallback = config.getboolean('DEFAULT', 'AllowFallback', fallback=True)
42+
ask_for_token = config.getboolean('DEFAULT', 'AskForTokenIfNotFound', fallback=True)
43+
44+
invalid_tokens = [
45+
'YourTelegramBotToken',
46+
'123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11', # Example bot token from Telegram documentation
47+
'',
48+
None
49+
]
50+
51+
def is_valid_token(token):
52+
return token not in invalid_tokens and len(token.split(':')) == 2
4253

4354
# Define retrieval methods
4455
def retrieve_from_env():
4556
bot_token = os.getenv('TELEGRAM_BOT_TOKEN')
46-
if bot_token:
57+
if bot_token and is_valid_token(bot_token):
4758
logging.info("Bot token successfully retrieved from environment variable.")
4859
return bot_token
4960
else:
50-
logging.warning("TELEGRAM_BOT_TOKEN environment variable not set.")
61+
logging.warning("Invalid or unset TELEGRAM_BOT_TOKEN environment variable.")
5162
return None
5263

5364
def retrieve_from_file():
5465
if token_file_path.is_file():
5566
try:
5667
bot_token = token_file_path.read_text().strip()
57-
if bot_token:
68+
if bot_token and is_valid_token(bot_token):
5869
logging.info("Bot token successfully retrieved from bot_token.txt.")
5970
return bot_token
6071
else:
61-
logging.error("bot_token.txt is empty.")
72+
logging.error("Invalid or empty bot_token.txt.")
6273
return None
6374
except IOError as e:
6475
logging.error(f"Failed to read bot_token.txt. Details: {e}")
@@ -67,16 +78,39 @@ def retrieve_from_file():
6778
logging.error(f"bot_token.txt not found at {token_file_path}.")
6879
return None
6980

81+
def query_user_for_token():
82+
logging.info("No valid bot token found. Please obtain a Telegram bot token from @BotFather on Telegram and paste it below.")
83+
logging.info("Press Enter without typing anything to quit.")
84+
token = input("Your Telegram bot token: ").strip()
85+
if token and is_valid_token(token):
86+
# Save the token to bot_token.txt for future use
87+
try:
88+
token_file_path.write_text(token)
89+
logging.info(f"Bot token saved to {token_file_path}.")
90+
return token
91+
except IOError as e:
92+
logging.error(f"Failed to save bot token to bot_token.txt. Details: {e}")
93+
return None
94+
else:
95+
logging.error("No valid token entered. Exiting application.")
96+
sys.exit(1)
97+
7098
# Retrieval logic based on configuration
7199
if prefer_env:
72100
token = retrieve_from_env()
73101
if token:
74102
return token
75103
elif allow_fallback:
76-
logging.warning("Preferred environment variable not found. Attempting to retrieve bot token from bot_token.txt as fallback.")
104+
logging.warning("Preferred environment variable not found or invalid. Attempting to retrieve bot token from bot_token.txt as fallback.")
77105
token = retrieve_from_file()
78106
if token:
79107
return token
108+
elif ask_for_token:
109+
token = query_user_for_token()
110+
if token:
111+
return token
112+
else:
113+
raise BotTokenError("Failed to retrieve bot token from environment variable, token file, and user input.")
80114
else:
81115
raise BotTokenError("Failed to retrieve bot token from both environment variable and token file.")
82116
else:
@@ -90,10 +124,16 @@ def retrieve_from_file():
90124
if token:
91125
return token
92126
elif allow_fallback:
93-
logging.warning("bot_token.txt not found. Attempting to retrieve bot token from environment variable as fallback.")
127+
logging.warning("bot_token.txt not found or invalid. Attempting to retrieve bot token from environment variable as fallback.")
94128
token = retrieve_from_env()
95129
if token:
96130
return token
131+
elif ask_for_token:
132+
token = query_user_for_token()
133+
if token:
134+
return token
135+
else:
136+
raise BotTokenError("Failed to retrieve bot token from token file, environment variable, and user input.")
97137
else:
98138
raise BotTokenError("Failed to retrieve bot token from both token file and environment variable.")
99139
else:
@@ -122,49 +162,175 @@ def retrieve_from_file():
122162
sys.stderr.flush() # Ensure all stderr logs are flushed
123163
sys.exit(1)
124164

125-
# # // (old method)
126-
# # ~~~ read the telegram bot token ~~~
165+
# # ((newer method; no query))
166+
# # to be cleaned up, kept only for reference atm!
167+
# # ~~~ Enhanced Read Telegram Bot Token with Configurable Fallback and Appropriate Logging ~~~
127168

128169
# import os
129170
# import configparser
130-
# import sys
131171
# import logging
172+
# from pathlib import Path
173+
# import sys
174+
175+
# # Set up basic logging configuration
176+
# # logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
177+
# logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[logging.StreamHandler(sys.stdout)])
178+
179+
# class BotTokenError(Exception):
180+
# """Custom exception for bot token retrieval failures."""
181+
# pass
132182

133183
# def get_bot_token():
134-
# # Correctly ascend two levels to get the project root from bot_token.py in src/utils
135-
# base_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
136-
# config_path = os.path.join(base_dir, 'config', 'config.ini')
137-
# token_file_path = os.path.join(base_dir, 'config', 'bot_token.txt')
138-
139-
# logging.info(f"Debug: Base directory is {base_dir}")
140-
# logging.info(f"Debug: Config path is {config_path}")
141-
# logging.info(f"Debug: Token file path is {token_file_path}")
142-
143-
# # Check if the paths actually exist
144-
# if not os.path.exists(config_path):
145-
# print("Error: config.ini not found at the expected path.")
146-
# sys.exit(1)
184+
# try:
185+
# # Ascend two levels to get the project root from bot_token.py in src/utils
186+
# base_dir = Path(__file__).resolve().parents[2]
187+
# config_path = base_dir / 'config' / 'config.ini'
188+
# token_file_path = base_dir / 'config' / 'bot_token.txt'
147189

148-
# if not os.path.exists(token_file_path) and not os.getenv('TELEGRAM_BOT_TOKEN'):
149-
# print("Error: bot_token.txt not found at the expected path and TELEGRAM_BOT_TOKEN environment variable is not set.")
150-
# sys.exit(1)
190+
# logging.debug(f"Base directory: {base_dir}")
191+
# logging.debug(f"Config path: {config_path}")
192+
# logging.debug(f"Token file path: {token_file_path}")
193+
194+
# # Verify config.ini exists
195+
# if not config_path.is_file():
196+
# raise BotTokenError(f"config.ini not found at {config_path}.")
197+
198+
# # Read configuration
199+
# config = configparser.ConfigParser()
200+
# config.read(config_path)
201+
202+
# # Validate configuration
203+
# if 'DEFAULT' not in config:
204+
# raise BotTokenError("Missing 'DEFAULT' section in config.ini.")
151205

152-
# # Reading the config
153-
# config = configparser.ConfigParser()
154-
# config.read(config_path)
155-
# prefer_env = config.getboolean('DEFAULT', 'PreferEnvForBotToken', fallback=True)
206+
# prefer_env = config.getboolean('DEFAULT', 'PreferEnvForBotToken', fallback=True)
207+
# allow_fallback = config.getboolean('DEFAULT', 'AllowFallback', fallback=True)
156208

157-
# if prefer_env and os.getenv('TELEGRAM_BOT_TOKEN'):
158-
# return os.getenv('TELEGRAM_BOT_TOKEN')
209+
# # Define retrieval methods
210+
# def retrieve_from_env():
211+
# bot_token = os.getenv('TELEGRAM_BOT_TOKEN')
212+
# if bot_token:
213+
# logging.info("Bot token successfully retrieved from environment variable.")
214+
# return bot_token
215+
# else:
216+
# logging.warning("TELEGRAM_BOT_TOKEN environment variable not set.")
217+
# return None
159218

160-
# # Try to read the token from the file if the environment variable isn't preferred or set
219+
# def retrieve_from_file():
220+
# if token_file_path.is_file():
221+
# try:
222+
# bot_token = token_file_path.read_text().strip()
223+
# if bot_token:
224+
# logging.info("Bot token successfully retrieved from bot_token.txt.")
225+
# return bot_token
226+
# else:
227+
# logging.error("bot_token.txt is empty.")
228+
# return None
229+
# except IOError as e:
230+
# logging.error(f"Failed to read bot_token.txt. Details: {e}")
231+
# return None
232+
# else:
233+
# logging.error(f"bot_token.txt not found at {token_file_path}.")
234+
# return None
235+
236+
# # Retrieval logic based on configuration
237+
# if prefer_env:
238+
# token = retrieve_from_env()
239+
# if token:
240+
# return token
241+
# elif allow_fallback:
242+
# logging.warning("Preferred environment variable not found. Attempting to retrieve bot token from bot_token.txt as fallback.")
243+
# token = retrieve_from_file()
244+
# if token:
245+
# return token
246+
# else:
247+
# raise BotTokenError("Failed to retrieve bot token from both environment variable and token file.")
248+
# else:
249+
# logging.error("Environment variable not found and fallback is disabled.")
250+
# raise BotTokenError(
251+
# "Failed to retrieve bot token. "
252+
# "Please ensure the TELEGRAM_BOT_TOKEN environment variable is set, or allow fallback by enabling it in config.ini."
253+
# )
254+
# else:
255+
# token = retrieve_from_file()
256+
# if token:
257+
# return token
258+
# elif allow_fallback:
259+
# logging.warning("bot_token.txt not found. Attempting to retrieve bot token from environment variable as fallback.")
260+
# token = retrieve_from_env()
261+
# if token:
262+
# return token
263+
# else:
264+
# raise BotTokenError("Failed to retrieve bot token from both token file and environment variable.")
265+
# else:
266+
# logging.error("Token file not found and fallback is disabled.")
267+
# raise BotTokenError(
268+
# "Failed to retrieve bot token. "
269+
# "Please ensure bot_token.txt exists at the expected location, or allow fallback by enabling it in config.ini."
270+
# )
271+
272+
# except BotTokenError as e:
273+
# logging.error(f"BotTokenError: {e}")
274+
# sys.stderr.flush() # Ensure all stderr logs are flushed
275+
# sys.exit(1) # Explicitly exit on BotTokenError
276+
# except Exception as e:
277+
# logging.error(f"Unexpected error while retrieving bot token: {e}")
278+
# sys.stderr.flush() # Ensure all stderr logs are flushed
279+
# sys.exit(1) # Explicitly exit on unexpected errors
280+
281+
# # Example usage
282+
# if __name__ == "__main__":
161283
# try:
162-
# with open(token_file_path, 'r') as file:
163-
# return file.read().strip()
164-
# except FileNotFoundError:
165-
# print("Error: Failed to read bot_token.txt.")
284+
# token = get_bot_token()
285+
# logging.info("Bot token successfully retrieved.")
286+
# except Exception as e:
287+
# logging.critical("Failed to retrieve bot token. Exiting application.")
288+
# sys.stderr.flush() # Ensure all stderr logs are flushed
166289
# sys.exit(1)
167290

168-
# # Fallback error message
169-
# print("The bot token could not be determined.")
170-
# sys.exit(1)
291+
# # # // (old method)
292+
# # # ~~~ read the telegram bot token ~~~
293+
294+
# # import os
295+
# # import configparser
296+
# # import sys
297+
# # import logging
298+
299+
# # def get_bot_token():
300+
# # # Correctly ascend two levels to get the project root from bot_token.py in src/utils
301+
# # base_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
302+
# # config_path = os.path.join(base_dir, 'config', 'config.ini')
303+
# # token_file_path = os.path.join(base_dir, 'config', 'bot_token.txt')
304+
305+
# # logging.info(f"Debug: Base directory is {base_dir}")
306+
# # logging.info(f"Debug: Config path is {config_path}")
307+
# # logging.info(f"Debug: Token file path is {token_file_path}")
308+
309+
# # # Check if the paths actually exist
310+
# # if not os.path.exists(config_path):
311+
# # print("Error: config.ini not found at the expected path.")
312+
# # sys.exit(1)
313+
314+
# # if not os.path.exists(token_file_path) and not os.getenv('TELEGRAM_BOT_TOKEN'):
315+
# # print("Error: bot_token.txt not found at the expected path and TELEGRAM_BOT_TOKEN environment variable is not set.")
316+
# # sys.exit(1)
317+
318+
# # # Reading the config
319+
# # config = configparser.ConfigParser()
320+
# # config.read(config_path)
321+
# # prefer_env = config.getboolean('DEFAULT', 'PreferEnvForBotToken', fallback=True)
322+
323+
# # if prefer_env and os.getenv('TELEGRAM_BOT_TOKEN'):
324+
# # return os.getenv('TELEGRAM_BOT_TOKEN')
325+
326+
# # # Try to read the token from the file if the environment variable isn't preferred or set
327+
# # try:
328+
# # with open(token_file_path, 'r') as file:
329+
# # return file.read().strip()
330+
# # except FileNotFoundError:
331+
# # print("Error: Failed to read bot_token.txt.")
332+
# # sys.exit(1)
333+
334+
# # # Fallback error message
335+
# # print("The bot token could not be determined.")
336+
# # sys.exit(1)

0 commit comments

Comments
 (0)