tclookup / main.py
Bhatiasab's picture
Update main.py
0826878 verified
Raw
History Blame Contribute Delete
5.04 kB
import os
import re
import asyncio
import uvicorn
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from telethon import TelegramClient
from contextlib import asynccontextmanager
# --- CONFIG ---
API_ID = 21934109
API_HASH = 'e7e8c554b9ff88d180983996c33bdf27'
BOT_USERNAME = '@TruecallerInfoLookupBot'
# Dynamically bind to Hugging Face's required routing port (defaults to 7860)
PORT = int(os.environ.get("PORT", 7860))
# Cache profile ID to prevent hitting rate limits
state = {"my_id": None}
# --- INITIALIZE THE CLEAN CLIENT ---
# We point directly to the standard connection layer since Hugging Face supports it natively
client = TelegramClient('/code/lookup_session', API_ID, API_HASH)
def parse_to_json(text: str) -> dict:
"""Parses the bot text into a structured dictionary."""
e_match = re.search(r'Eyecon.*?Name:\s*`?(.*?)`?(?:\n|$)', text, re.IGNORECASE | re.DOTALL)
c_match = re.search(r'CALLAPP.*?Name:\s*`?(.*?)`?(?:\n|$)', text, re.IGNORECASE | re.DOTALL)
name1 = e_match.group(1).strip() if e_match else None
name2 = c_match.group(1).strip() if c_match else None
data = {}
if name1:
data["name1"] = name1
if name2:
data["name2"] = name2
if not name1 and not name2:
fallback = re.search(r'Name:\s*`?(.*?)`?(?:\n|$)', text, re.IGNORECASE)
if fallback:
data["name1"] = fallback.group(1).strip()
carrier_match = re.search(r'Carrier:\s*`?(.*?)`?(?:\n|$)', text, re.IGNORECASE)
location_match = re.search(r'Location:\s*`?(.*?)`?(?:\n|$)', text, re.IGNORECASE)
data["carrier"] = carrier_match.group(1).strip() if carrier_match else "N/A"
data["location"] = location_match.group(1).strip() if location_match else "N/A"
data["full_text"] = text
return data
# --- NATIVE FASTAPI ASYNC LIFECYCLE ---
@asynccontextmanager
async def lifespan(app: FastAPI):
session_path = "/code/lookup_session.session"
print(f"[STARTUP] Looking for session file at: {session_path}")
try:
print("[STARTUP] Connecting directly to Telegram Network...")
await client.connect()
except Exception as e:
print(f"\n[CRITICAL] Connection failed: {e}\n")
raise e
if not await client.is_user_authorized():
print("!!! NOT LOGGED IN. Please verify your 'lookup_session.session' file !!!")
else:
print("Telethon Connected and Authorized.")
me = await client.get_me()
state["my_id"] = me.id
yield
print("[SHUTDOWN] Disconnecting Telegram Client...")
await client.disconnect()
app = FastAPI(lifespan=lifespan)
# --- CORS CONFIGURATION ---
app.add_middleware(
CORSMiddleware,
allow_origins=["https://crm.gudmed.in"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# --- HEALTH CHECK ROUTE (Keeps Hugging Face Routing Live) ---
@app.get("/")
async def root_index():
return {"status": "healthy", "service": "Telegram Truecaller Polling API"}
# --- PRIMARY LOOKUP ENDPOINT ---
@app.get("/lookup")
async def lookup(phone: str):
# Take last 10 digits
clean_phone = str(phone)[-10:].strip()
if not state["my_id"]:
raise HTTPException(status_code=503, detail="Telegram client not authorized or fully connected.")
try:
print(f"[API] Sending search payload for target: +91{clean_phone}")
# 1. Send the number to the bot
await client.send_message(BOT_USERNAME, f'+91{clean_phone}')
# 2. Polling logic (Checks every 0.5s for 40 attempts -> 20 seconds total)
for i in range(40):
await asyncio.sleep(0.5)
# Fetch latest 3 messages to bypass ads or temporary indicators
messages = await client.get_messages(BOT_USERNAME, limit=3)
for m in messages:
# Confirm message came from the bot, not your own account
if m.sender_id != state["my_id"]:
# Ignore working status frames
if not m.text or any(x in m.text for x in ["Searching", "Please wait", "Typing"]):
continue
# Target confirmation check
if clean_phone in m.text:
print(f"[API] Target found on polling loop step {i}! Processing...")
return {
"status": "success",
"phone": clean_phone,
"data": parse_to_json(m.text)
}
raise HTTPException(status_code=504, detail="Timeout: Bot didn't respond with correct number in time.")
except HTTPException:
raise
except Exception as e:
print(f"Lookup Error: {e}")
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=PORT, loop="asyncio")