Did some modifications...

This commit is contained in:
Joan
2025-10-29 11:14:34 +01:00
parent 8bcf8c8819
commit c012f03cb4
8 changed files with 420 additions and 168 deletions

View File

@@ -1,3 +1,4 @@
import datetime
import logging
import requests
from database import * # Import all DB functions
@@ -389,9 +390,9 @@ def format_last_participants_list(participants_list: list) -> str:
if numbers_str:
num_list = numbers_str.split(',')
if len(num_list) == 1:
line = f" - {user_name}, con la papeleta: {num_list[0]}"
line = f" - {user_name}, con la participación: {num_list[0]}"
else:
line = f" - {user_name}, con las papeletas: {', '.join(num_list)}"
line = f" - {user_name}, con las participaciones: {', '.join(num_list)}"
formatted_lines.append(line)
return "\n".join(formatted_lines) # Add a trailing newline
@@ -482,3 +483,245 @@ def get_paypal_amounts_for_invoice(invoice_id):
net_amount = float(breakdown.get("net_amount", {}).get("value", gross_amount))
return gross_amount, net_amount, fee_amount
def is_vip_member_of_homelabs(user_id):
"""Checks if a Telegram user ID is a VIP member of HomeLabs via the Homelabs API."""
if not HOMELABS_API_TOKEN or not HOMELABS_API_URL:
logger.warning("Homelabs API configuration is missing.")
return False # If not configured, treat as non-member
url = f"{HOMELABS_API_URL}/users/{user_id}"
headers = {
"X-API-Key": HOMELABS_API_TOKEN,
"Accept": "application/json",
}
try:
response = requests.get(url, headers=headers, timeout=5)
if response.status_code == 200:
data = response.json()
if data.get("is_lifetime") == True:
return True
if data.get("member_until") >= datetime.datetime.now(datetime.timezone.utc).date().isoformat():
return True
return False
elif response.status_code == 404:
return False # User not found, hence not a member
else:
logger.error(f"Unexpected response from Homelabs API: {response.status_code} - {response.text}")
return False
except requests.RequestException as e:
logger.error(f"Error connecting to Homelabs API: {e}")
return False
def send_raffle_update_image(raffle_id, current_user_name=None, numbers=None, bot_token=None):
"""
Sends or updates the raffle table image to the appropriate channel.
Can be used for payment confirmations or manual updates from admin.
Args:
raffle_id: The ID of the raffle
current_user_name: Name of the user who just joined (optional, for payment updates)
numbers: List of numbers the user selected (optional, for payment updates)
bot_token: Telegram bot token for API calls
Returns:
bool: True if successful, False otherwise
"""
try:
# Import here to avoid circular imports
import json
if not bot_token:
bot_token = BOT_TOKEN
TELEGRAM_API_URL = f"https://api.telegram.org/bot{bot_token}"
# Generate table image
if not generate_table_image(raffle_id):
logger.error(f"Failed to generate raffle table image for {raffle_id}")
return False
image_path = f"/app/data/raffles/raffle_table_{raffle_id}.png"
# Get raffle details
raffle_details = get_raffle(raffle_id)
if not raffle_details:
logger.error(f"Could not fetch raffle details for ID {raffle_id}")
return False
raffle_name = raffle_details['name']
raffle_description_for_announce = raffle_details['description'][:350]
channel_id_to_announce = raffle_details['channel_id']
original_price_per_number = raffle_details['price']
remaining_numbers_amount = get_remaining_numbers_amount(raffle_id)
# Determine keyboard and caption based on remaining numbers
keyboard = None
if remaining_numbers_amount == 0:
# Raffle is complete
main_announcement = f"🎯🏆🎯 <b>Sorteo '{raffle_name}' terminado</b> 🎯🏆🎯\n\n"
main_announcement += f"{raffle_description_for_announce}\n\n"
main_announcement += f"🌍 Envío internacional: {'Sí ✅' if raffle_details['international_shipping'] else 'No ❌'}\n"
main_announcement += f"💵 <b>Donación mínima:</b> {original_price_per_number}\n"
main_announcement += f"📜 <b>Normas y condiciones:</b> {TYC_DOCUMENT_URL}"
# Update main message to remove participate button
main_message_id = get_main_message_id(raffle_id)
if main_message_id:
requests.post(f"{TELEGRAM_API_URL}/editMessageCaption", json={
"chat_id": channel_id_to_announce,
"message_id": main_message_id,
"caption": main_announcement,
"reply_markup": None,
"parse_mode": "HTML"
})
else:
# Raffle still in progress
url = f"https://t.me/{BOT_NAME}?start=join_{raffle_id}"
keyboard = {
"inline_keyboard": [
[
{"text": "✅ ¡Participar Ahora! ✅", "url": url}
]
]
}
main_announcement = f"🏆 Sorteo '{raffle_name}' en progreso 🏆\n\n"
main_announcement += f"{raffle_description_for_announce}\n\n"
main_announcement += f"🌍 Envío internacional: {'Sí ✅' if raffle_details['international_shipping'] else 'No ❌'}\n"
main_announcement += f"💵 <b>Donación mínima:</b> {original_price_per_number}\n"
main_announcement += f"🗒️ Quedan {remaining_numbers_amount} participaciones disponibles. ¡Date prisa! 🗒️\n\n"
main_announcement += f"📜 <b>Normas y condiciones:</b> {TYC_DOCUMENT_URL}"
# Update main message
main_message_id = get_main_message_id(raffle_id)
if main_message_id:
requests.post(f"{TELEGRAM_API_URL}/editMessageCaption", json={
"chat_id": channel_id_to_announce,
"message_id": main_message_id,
"caption": main_announcement,
"reply_markup": keyboard,
"parse_mode": "HTML"
})
# Build caption for update message
caption = ""
# Add participant info if provided (for payment confirmations)
if current_user_name and numbers:
escaped_current_user_name = current_user_name
numbers_text = ""
if len(numbers) > 1:
numbers_text = f"con las participaciones: {', '.join(numbers)}"
else:
numbers_text = f"con la participación: {', '.join(numbers)}"
new_participant_line = f"🗳️ @{escaped_current_user_name} se ha unido al sorteo {numbers_text}. ¡Mucha suerte! 🗳️"
caption += f"{new_participant_line}\n\n"
# Add last participants
last_other_participants = get_last_n_other_participants(raffle_id, n=4)
last_participants_text = format_last_participants_list(last_other_participants)
caption += f"{last_participants_text}\n\n"
# Add remaining numbers info
remaining_numbers_text = ""
if remaining_numbers_amount > 10:
remaining_numbers_text = f"🗒️ Todavía hay {remaining_numbers_amount} participaciones disponibles. 🗒️"
elif remaining_numbers_amount == 1:
remaining_numbers = get_remaining_numbers(raffle_id)
remaining_numbers_text = f"⏰⏰⏰ ¡Última participación! ⏰⏰⏰\n\n"
remaining_numbers_text += f"Queda la participación: {remaining_numbers[0]}"
elif remaining_numbers_amount == 0:
remaining_numbers_text = "⌛ ¡Ya no hay participaciones! ⌛\n\n"
remaining_numbers_text += "¡El resultado del sorteo se dará a conocer a las 21:45h!"
else:
remaining_numbers = get_remaining_numbers(raffle_id)
remaining_numbers_text = f"🔔🔔🔔 ¡Últimas {remaining_numbers_amount} participaciones disponibles! 🔔🔔🔔\n\n"
remaining_numbers_text += f"Quedan las participaciones: {', '.join(remaining_numbers)}"
caption += f"{remaining_numbers_text}\n\n"
# Add raffle description and details
caption += (
f"{raffle_description_for_announce}\n\n"
f"🔎 Ver detalles: https://t.me/{REVERSE_CHANNELS.get(channel_id_to_announce)}/{get_main_message_id(raffle_id)}\n\n"
f"🌍 Envío internacional: {'Sí ✅' if raffle_details['international_shipping'] else 'No ❌'}\n"
f"💵 Donación mínima: {original_price_per_number}\n\n"
f"📜 Normas y condiciones: {TYC_DOCUMENT_URL} \n\n"
)
# Send or update the image message
update_message_id = get_update_message_id(raffle_id)
sent_or_edited_message_id = None
if update_message_id:
logger.info(f"Attempting to delete old message {update_message_id} and send new one in channel {channel_id_to_announce}")
# Try deleting old message first
try:
delete_payload = {'chat_id': channel_id_to_announce, 'message_id': update_message_id}
delete_response = requests.post(f"{TELEGRAM_API_URL}/deleteMessage", data=delete_payload)
if delete_response.status_code == 200:
logger.info(f"Successfully deleted old message {update_message_id} in channel {channel_id_to_announce}")
else:
logger.warning(f"Failed to delete old message {update_message_id} in channel {channel_id_to_announce}: {delete_response.text}")
except Exception as e_del:
logger.warning(f"Error deleting old message {update_message_id}: {e_del}")
# Always send new photo after delete attempt
files = {'photo': open(image_path, 'rb')}
data = {
'chat_id': channel_id_to_announce,
'caption': caption,
'parse_mode': 'HTML'
}
if keyboard:
data['reply_markup'] = json.dumps(keyboard)
try:
response = requests.post(f"{TELEGRAM_API_URL}/sendPhoto", data=data, files=files)
response.raise_for_status()
logger.info(f"Sent new photo to channel {channel_id_to_announce}")
message_data = response.json().get('result')
if message_data and 'message_id' in message_data:
sent_or_edited_message_id = message_data['message_id']
except requests.exceptions.RequestException as e:
logger.error(f"Error sending new photo to channel {channel_id_to_announce}: {e}")
return False
finally:
files['photo'].close()
else:
# No previous message, send new
logger.info(f"No previous message found for raffle {raffle_id} in channel {channel_id_to_announce}. Sending new.")
files = {'photo': open(image_path, 'rb')}
data = {
'chat_id': channel_id_to_announce,
'caption': caption,
'parse_mode': 'HTML'
}
if keyboard:
data['reply_markup'] = json.dumps(keyboard)
try:
response = requests.post(f"{TELEGRAM_API_URL}/sendPhoto", data=data, files=files)
response.raise_for_status()
logger.info(f"Sent photo to channel {channel_id_to_announce}")
message_data = response.json().get('result')
if message_data and 'message_id' in message_data:
sent_or_edited_message_id = message_data['message_id']
except requests.exceptions.RequestException as e:
logger.error(f"Error sending photo to channel {channel_id_to_announce}: {e}")
return False
finally:
files['photo'].close()
# Store the new message ID for future updates
if sent_or_edited_message_id:
store_update_message_id(raffle_id, sent_or_edited_message_id)
return True
except Exception as e:
logger.error(f"Error in send_raffle_update_image for raffle {raffle_id}: {e}")
return False