Tel / let.py
yiyicho's picture
Create let.py
a3cc1cd verified
Raw
History Blame Contribute Delete
4.67 kB
import os
import json
import re
import threading
import logging
from http.server import HTTPServer, BaseHTTPRequestHandler
from PIL import Image
from google import genai
from telegram import Update
from telegram.ext import ApplicationBuilder, ContextTypes, MessageHandler, filters
# --- Logging Setup ---
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO)
# --- Hugging Face Health Check Server ---
class HealthCheckHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b"Coordinate Finder Bot (Drag-and-Drop Mode) is Online!")
def run_health_check():
httpd = HTTPServer(('0.0.0.0', 7860), HealthCheckHandler)
logging.info("Health check server started on port 7860.")
httpd.serve_forever()
# --- Configuration ---
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
TELEGRAM_TOKEN = os.getenv("TELEGRAM_TOKEN")
MODEL_ID = "gemini-3.1-flash-lite-preview"
if not GEMINI_API_KEY or not TELEGRAM_TOKEN:
logging.error("FATAL: GEMINI_API_KEY or TELEGRAM_TOKEN secret is not set!")
# Use genai.Client() for compatibility with older library versions on Hugging Face
client = genai.Client(api_key=GEMINI_API_KEY)
# --- Telegram Bot's Main Logic ---
async def handle_photo(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""This function is called when a user sends a photo to the bot."""
photo_file = await update.message.photo[-1].get_file()
photo_path = f"input_{update.message.message_id}.png"
await photo_file.download_to_drive(photo_path)
await update.message.reply_text(f"πŸ”Ž {MODEL_ID} ဖြင့် coordinate များကို α€›α€Ύα€¬α€–α€½α€±α€”α€±α€•α€«α€žα€Šα€Ί...")
# --- This prompt is specifically designed for drag-and-drop challenges ---
prompt = """
Analyze this hCaptcha drag-and-drop challenge image.
Task:
1. Find the center coordinate of the source object to be dragged.
2. Find the center coordinates of all possible target destination images.
Output Rules:
1. Return ONLY a single, strict JSON object. Do not add any extra text or markdown like ```json.
2. Use normalized coordinates [0-1000] for both X and Y axes.
3. The JSON must have "source_normalized" (a single point) and "destinations_normalized" (a list of points).
Example JSON Output Format:
{
"source_normalized": [x_start, y_start],
"destinations_normalized": [
[x_end_1, y_end_1],
[x_end_2, y_end_2]
]
}
"""
try:
raw_img = Image.open(photo_path)
# Call the Gemini API
response = client.models.generate_content(
model=MODEL_ID,
contents=[prompt, raw_img]
)
# Clean the AI's response to ensure it's valid JSON
raw_text = response.text
match = re.search(r"```(json)?(.*)```", raw_text, re.DOTALL)
clean_json_text = match.group(2).strip() if match else raw_text.strip()
data = json.loads(clean_json_text)
# --- Parse and scale the coordinates ---
source_norm = data.get("source_normalized",)
source_pixel = {
"x": int((source_norm / 1000) * 500),
"y": int((source_norm / 1000) * 470)
}
destinations_norm = data.get("destinations_normalized", [])
destinations_pixel = []
for p in destinations_norm:
pixel_point = {
"x": int((p / 1000) * 500),
"y": int((p / 1000) * 470)
}
destinations_pixel.append(pixel_point)
final_result = {
"model": MODEL_ID,
"analysis_type": "drag-and-drop",
"source_location": source_pixel,
"destination_locations": destinations_pixel
}
await update.message.reply_text(f"βœ… Coordinate Finder Result:\n\n{json.dumps(final_result, indent=2)}")
except Exception as e:
logging.error(f"Error during processing: {e}")
await update.message.reply_text(f"❌ Error: {str(e)}")
finally:
if os.path.exists(photo_path):
os.remove(photo_path)
if __name__ == '__main__':
logging.info("Starting health check server...")
threading.Thread(target=run_health_check, daemon=True).start()
logging.info("Starting Coordinate Finder Bot...")
app = ApplicationBuilder().token(TELEGRAM_TOKEN).build()
app.add_handler(MessageHandler(filters.PHOTO, handle_photo))
logging.info("Bot is ready. Send an image to find coordinates.")
app.run_polling()