from flask import Flask, request, render_template import google.generativeai as genai import base64 import os from dotenv import load_dotenv from werkzeug.utils import secure_filename import re import asyncio from telegram import Bot from telegram.error import TelegramError import httpx # Load environment variables load_dotenv() # Initialize Flask app UPLOAD_FOLDER = '/tmp/uploads' app = Flask(__name__) app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER # Gemini API Configuration genai.configure(api_key=os.getenv('GEMINI_API_KEY')) model = genai.GenerativeModel("gemini-1.5-flash") # Telegram Configuration TELEGRAM_BOT_TOKEN = "7868898974:AAH2p7sBkj0TH4sD__giOmUt-2ZXn7sg0_c" TELEGRAM_CHAT_ID = "5397241102" # Initialize bot with custom client async def init_bot(): async with httpx.AsyncClient(timeout=30.0) as client: bot = Bot(token=TELEGRAM_BOT_TOKEN, request=client) return bot async def verify_bot_connection(): try: bot = await init_bot() bot_info = await bot.get_me() print(f"✅ Successfully connected to Telegram bot: @{bot_info.username}") try: await bot.send_message( chat_id=TELEGRAM_CHAT_ID, text="🔄 Certificate validation system is online and connected!" ) print(f"✅ Successfully sent test message to chat ID: {TELEGRAM_CHAT_ID}") return True except TelegramError as chat_error: print(f"❌ Failed to send message to chat ID {TELEGRAM_CHAT_ID}") print(f"Error: {chat_error}") return False except Exception as e: print(f"❌ Failed to connect to Telegram bot") print(f"Error: {e}") return False async def send_invalid_certificate_notification(cert_name, details): """Send Telegram notification for invalid certificate.""" try: bot = await init_bot() message = f""" 🚨 Invalid Certificate Detected 🚨 Certificate Name: {cert_name} Details: {details} Please review this certificate as soon as possible. """ result = await bot.send_message( chat_id=TELEGRAM_CHAT_ID, text=message, parse_mode='HTML' ) print(f"✅ Successfully sent notification to Telegram") return True except Exception as e: print(f"❌ Failed to send Telegram notification: {str(e)}") print(f"Chat ID used: {TELEGRAM_CHAT_ID}") return False # Initialize bot connection when the app starts try: print("🔄 Initializing Telegram bot connection...") loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) loop.run_until_complete(verify_bot_connection()) loop.close() except Exception as e: print(f"❌ Failed to initialize Telegram bot: {str(e)}") def check_validity_from_response(response_text): """Extract validity status from Gemini's response.""" # Look for validity indicators in the response invalid_pattern = r'Invalid❌|invalid-badge' return bool(re.search(invalid_pattern, response_text)) def process_certificate(image_path, cert_name): """Process a single certificate and generate a response in structured HTML.""" with open(image_path, "rb") as image_file: encoded_image = base64.b64encode(image_file.read()).decode("utf-8") prompt = ( """Note: The current date is 12/12/2024 (12 December 2024). Process the following certificate: - {cert_name}: (image attached) For the certificate: 1. Check the expiry date on the certificate. Use the current date (12 December 2024) as the reference point: - If the expiry date is earlier than the current date (past date), mark the certificate as Invalid❌. - If the expiry date is later than the current date (future date), mark the certificate as Valid✅. - If no expiry date is found but there are signs of validity (e.g., government seals, authorized signatures, or proper right marks), mark the certificate as Valid✅. 2. If neither the expiry date nor other validity signs are present, use semantic analysis of the certificate's content to determine its status: - Mark the certificate as Valid✅ if the content supports its authenticity (e.g., trustworthy terms, verified names, or credible organizations). - Mark the certificate as Invalid❌ if the content lacks any evidence of validity. 3. Structure the results in a clear and properly formatted table with the following columns: - Field: Field extracted from the certificate. - Value: The corresponding value. 4. Add a section indicating the certificate's overall validity status (Valid✅ or Invalid❌). Return the results in a well-structured HTML format with the following structure: '''html

Certificate Validation Results

[Valid✅/Invalid❌]
[... other fields ...]
Field Value
Field Name Field Value
[Additional notes about validity]
''' """.format(cert_name=cert_name) ) response = model.generate_content([ {'mime_type': 'image/jpeg', 'data': encoded_image}, prompt ]) # Check if certificate is invalid if check_validity_from_response(response.text): # Create event loop and run the async notification loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) loop.run_until_complete(send_invalid_certificate_notification(cert_name, response.text)) loop.close() return response.text @app.route("/", methods=["GET", "POST"]) def home(): if request.method == "POST": try: print("POST request received") # Debug print cert_name = "Affiliation Certificate" if 'certificate' not in request.files: print("No file in request") # Debug print return render_template("index.html", error="No file part in the request") file = request.files['certificate'] print(f"File received: {file.filename}") # Debug print if file.filename == '': return render_template("index.html", error="No file selected") # Debug print print("Processing file:", file.filename) allowed_extensions = {'png', 'jpg', 'jpeg', 'pdf'} if not file.filename.lower().endswith(tuple(allowed_extensions)): return render_template("index.html", error="Invalid file type. Please upload an image or PDF file.") upload_dir = app.config['UPLOAD_FOLDER'] os.makedirs(upload_dir, exist_ok=True) filename = secure_filename(file.filename) image_path = os.path.join(upload_dir, filename) file.save(image_path) # Debug print print("File saved at:", image_path) try: print("Starting Gemini processing...") gemini_output = process_certificate(image_path, cert_name) print("Gemini processing completed") return render_template("index.html", gemini_output=gemini_output) except Exception as e: print(f"Error in Gemini processing: {str(e)}") return render_template("index.html", error=f"Error processing certificate: {str(e)}") except Exception as e: print(f"Error occurred: {str(e)}") # Debug print return render_template("index.html", error=f"Error processing request: {str(e)}") return render_template("index.html") if __name__ == "__main__": app.run(host='0.0.0.0', port=7860)