allow user to be added via id

This commit is contained in:
2026-05-11 11:34:38 +01:00
parent 5b434abd06
commit 7a2db35495
8 changed files with 170 additions and 9 deletions

69
bot.py
View File

@@ -13,7 +13,7 @@ from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, fil
# Import your existing logic
from agent import parse_page
from database import upload_entry
from database import add_telegram_user_id, get_telegram_user_ids, upload_entry
from scraper import get_clean_content as _get_clean_content
@@ -45,12 +45,12 @@ TOKEN = os.getenv("TG_TOKEN")
_allowed_env = os.getenv("ALLOWED_USERS", "")
if _allowed_env:
try:
ALLOWED_IDS = [int(x.strip()) for x in _allowed_env.split(',') if x.strip()]
ALLOWED_IDS = {int(x.strip()) for x in _allowed_env.split(',') if x.strip()}
except Exception:
logging.warning("Failed to parse ALLOWED_USERS from .env; defaulting to empty list")
ALLOWED_IDS = []
ALLOWED_IDS = set()
else:
ALLOWED_IDS = []
ALLOWED_IDS = set()
if not TOKEN:
logging.warning("TG_TOKEN not set in .env; bot will not start without a token")
@@ -95,6 +95,17 @@ def retry(max_attempts=3, backoff_factor=2, initial_delay=1):
task_queue = asyncio.Queue()
def is_authorized_user(user_id: int) -> bool:
if user_id in ALLOWED_IDS:
return True
try:
return user_id in set(get_telegram_user_ids())
except Exception as exc:
logging.warning("Failed to fetch Telegram access list: %s", exc)
return False
def is_http_url(text: str) -> bool:
return bool(re.match(r'^https?://\S+$', text.strip()))
@@ -188,19 +199,56 @@ async def process_link(update, context, source_value, entry_type="opportunity",
# --- Handlers ---
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
if update.effective_user.id not in ALLOWED_IDS:
if not is_authorized_user(update.effective_user.id):
return
await update.message.reply_text(
"Welcome! I can extract arts opportunities and events.\n\n"
"📋 **Commands:**\n"
"/add <id> - Allow a Telegram user ID access\n"
"/op <url> - Extract an opportunity\n"
"/ev <url> - Extract an event\n\n"
"You can also send a URL directly and I will ask whether to process it as an event or opportunity."
)
async def handle_add_user(update: Update, context: ContextTypes.DEFAULT_TYPE):
requester_id = update.effective_user.id
if not is_authorized_user(requester_id):
await update.message.reply_text("Unauthorized. User ID needs to be added!")
return
if not context.args:
await update.message.reply_text("Usage: /add <telegram_user_id>")
return
raw_user_id = context.args[0].strip()
try:
user_id = int(raw_user_id)
except ValueError:
await update.message.reply_text("Please provide a valid numeric Telegram user ID. Usage: /add <telegram_user_id>")
return
if user_id in ALLOWED_IDS:
await update.message.reply_text(f"{user_id} already has access.")
return
try:
existing_ids = set(get_telegram_user_ids())
if user_id in existing_ids:
ALLOWED_IDS.add(user_id)
await update.message.reply_text(f"{user_id} already has access.")
return
add_telegram_user_id(user_id)
ALLOWED_IDS.add(user_id)
await update.message.reply_text(f"Added {user_id} to Telegram access.")
except Exception as exc:
logging.exception("Failed to add Telegram user ID %s", user_id)
await update.message.reply_text(f"Failed to add {user_id}: {exc}")
async def handle_opportunity(update: Update, context: ContextTypes.DEFAULT_TYPE):
user_id = update.effective_user.id
if user_id not in ALLOWED_IDS:
if not is_authorized_user(user_id):
await update.message.reply_text("Unauthorized. User ID needs to be added!")
return
@@ -220,7 +268,7 @@ async def handle_opportunity(update: Update, context: ContextTypes.DEFAULT_TYPE)
async def handle_event(update: Update, context: ContextTypes.DEFAULT_TYPE):
user_id = update.effective_user.id
if user_id not in ALLOWED_IDS:
if not is_authorized_user(user_id):
await update.message.reply_text("Unauthorized. User ID needs to be added!")
return
@@ -239,7 +287,7 @@ async def handle_event(update: Update, context: ContextTypes.DEFAULT_TYPE):
await task_queue.put((update, context, input_text, "event", source_kind))
async def handle_followup_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
if update.effective_user.id not in ALLOWED_IDS:
if not is_authorized_user(update.effective_user.id):
return
if not context.user_data.get('awaiting_save_url'):
@@ -279,6 +327,10 @@ async def button_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
query = update.callback_query
await query.answer()
if not is_authorized_user(query.from_user.id):
await query.edit_message_text("Unauthorized. User ID needs to be added!")
return
if query.data.startswith('choose_type:'):
pending_url = context.user_data.get('pending_url_to_process')
if not pending_url:
@@ -325,6 +377,7 @@ async def _main():
application = ApplicationBuilder().token(TOKEN).build()
application.add_handler(CommandHandler("start", start))
application.add_handler(CommandHandler("add", handle_add_user))
application.add_handler(CommandHandler("op", handle_opportunity))
application.add_handler(CommandHandler("ev", handle_event))
application.add_handler(MessageHandler(filters.TEXT & (~filters.COMMAND), handle_followup_text))