|
|
import os |
|
|
import requests |
|
|
from datetime import datetime, date |
|
|
from fastapi import FastAPI, Request |
|
|
from fastapi.responses import JSONResponse, HTMLResponse |
|
|
from fastapi.middleware.cors import CORSMiddleware |
|
|
|
|
|
|
|
|
app = FastAPI(title="ZenkaAI") |
|
|
|
|
|
app.add_middleware( |
|
|
CORSMiddleware, |
|
|
allow_origins=["*"], |
|
|
allow_methods=["*"], |
|
|
allow_headers=["*"], |
|
|
) |
|
|
|
|
|
HF_TOKEN = os.getenv("HF_TOKEN", "") |
|
|
MODEL = "microsoft/DialoGPT-small" |
|
|
API_URL = f"https://api-inference.huggingface.co/models/{MODEL}" |
|
|
|
|
|
users_db = {} |
|
|
LIMIT = 30 |
|
|
SHOPIER = "https://shopier.com/42153760" |
|
|
|
|
|
|
|
|
def get_user(email): |
|
|
email = email.lower().strip() |
|
|
today = date.today().isoformat() |
|
|
|
|
|
if email not in users_db: |
|
|
users_db[email] = {"count": 0, "date": today} |
|
|
|
|
|
user = users_db[email] |
|
|
if user["date"] != today: |
|
|
user["count"] = 0 |
|
|
user["date"] = today |
|
|
|
|
|
return user |
|
|
|
|
|
def get_ai_response(message): |
|
|
if not HF_TOKEN: |
|
|
return "🤖 ZenkaAI: Hoşgeldiniz! Token ayarlanmamış." |
|
|
|
|
|
try: |
|
|
response = requests.post( |
|
|
API_URL, |
|
|
headers={"Authorization": f"Bearer {HF_TOKEN}"}, |
|
|
json={"inputs": f"Soru: {message}\nCevap:"}, |
|
|
timeout=15 |
|
|
) |
|
|
|
|
|
if response.status_code == 200: |
|
|
result = response.json() |
|
|
if isinstance(result, list) and result: |
|
|
text = result[0].get('generated_text', '') |
|
|
if text: |
|
|
return f"🤖 {text.split('Cevap:')[-1].strip()}" |
|
|
|
|
|
return "🤖 Size nasıl yardımcı olabilirim?" |
|
|
|
|
|
except: |
|
|
return "🤖 Teknik bir sorun oluştu." |
|
|
|
|
|
|
|
|
@app.get("/") |
|
|
async def home(): |
|
|
html = """ |
|
|
<!DOCTYPE html> |
|
|
<html> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>ZenkaAI - Türkçe AI</title> |
|
|
<style> |
|
|
body { |
|
|
font-family: Arial; |
|
|
margin: 0; |
|
|
padding: 20px; |
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
|
|
min-height: 100vh; |
|
|
} |
|
|
.container { |
|
|
max-width: 600px; |
|
|
margin: auto; |
|
|
background: white; |
|
|
padding: 25px; |
|
|
border-radius: 15px; |
|
|
box-shadow: 0 10px 30px rgba(0,0,0,0.3); |
|
|
} |
|
|
h1 { color: #4f46e5; text-align: center; } |
|
|
.chat-box { |
|
|
height: 350px; |
|
|
overflow-y: auto; |
|
|
border: 2px solid #e5e7eb; |
|
|
border-radius: 10px; |
|
|
padding: 15px; |
|
|
margin: 20px 0; |
|
|
background: #f9fafb; |
|
|
} |
|
|
.msg { |
|
|
margin: 10px 0; |
|
|
padding: 10px 15px; |
|
|
border-radius: 10px; |
|
|
max-width: 80%; |
|
|
} |
|
|
.user { background: #4f46e5; color: white; margin-left: auto; } |
|
|
.ai { background: white; border: 1px solid #e5e7eb; } |
|
|
input, textarea, button { |
|
|
width: 100%; |
|
|
padding: 12px; |
|
|
margin: 8px 0; |
|
|
border: 2px solid #ddd; |
|
|
border-radius: 10px; |
|
|
font-size: 16px; |
|
|
box-sizing: border-box; |
|
|
} |
|
|
button { |
|
|
background: #4f46e5; |
|
|
color: white; |
|
|
border: none; |
|
|
font-weight: bold; |
|
|
cursor: pointer; |
|
|
} |
|
|
.info { |
|
|
text-align: center; |
|
|
margin-top: 15px; |
|
|
color: #666; |
|
|
font-size: 14px; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<div class="container"> |
|
|
<h1>🤖 ZenkaAI</h1> |
|
|
<div style="padding:10px;background:#d1fae5;border-radius:8px;text-align:center;margin:15px 0;"> |
|
|
✅ Sistem Çalışıyor |
|
|
</div> |
|
|
|
|
|
<div class="chat-box" id="chatBox"> |
|
|
<div class="msg ai"> |
|
|
<strong>AI:</strong> Merhaba! Ben ZenkaAI. Size nasıl yardımcı olabilirim? |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<input type="email" id="email" placeholder="Email" value="test@example.com"> |
|
|
<textarea id="message" placeholder="Mesajınız..." rows="3"></textarea> |
|
|
<button onclick="sendMessage()">Gönder</button> |
|
|
|
|
|
<div class="info"> |
|
|
<p>Günlük limit: 30 sorgu • Premium: """ + SHOPIER + """</p> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
async function sendMessage() { |
|
|
const email = document.getElementById('email').value; |
|
|
const message = document.getElementById('message').value; |
|
|
|
|
|
if (!email || !message) { |
|
|
alert('Email ve mesaj gerekli!'); |
|
|
return; |
|
|
} |
|
|
|
|
|
// Kullanıcı mesajı |
|
|
const chatBox = document.getElementById('chatBox'); |
|
|
const userMsg = document.createElement('div'); |
|
|
userMsg.className = 'msg user'; |
|
|
userMsg.innerHTML = '<strong>Siz:</strong> ' + message; |
|
|
chatBox.appendChild(userMsg); |
|
|
|
|
|
document.getElementById('message').value = ''; |
|
|
|
|
|
try { |
|
|
const response = await fetch('/api/chat', { |
|
|
method: 'POST', |
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
body: JSON.stringify({email, message}) |
|
|
}); |
|
|
|
|
|
const data = await response.json(); |
|
|
|
|
|
// AI yanıtı |
|
|
const aiMsg = document.createElement('div'); |
|
|
aiMsg.className = 'msg ai'; |
|
|
aiMsg.innerHTML = '<strong>AI:</strong> ' + data.response; |
|
|
chatBox.appendChild(aiMsg); |
|
|
|
|
|
chatBox.scrollTop = chatBox.scrollHeight; |
|
|
|
|
|
} catch (error) { |
|
|
alert('Hata: ' + error.message); |
|
|
} |
|
|
} |
|
|
|
|
|
// Enter tuşu |
|
|
document.getElementById('message').addEventListener('keypress', function(e) { |
|
|
if (e.key === 'Enter' && !e.shiftKey) { |
|
|
e.preventDefault(); |
|
|
sendMessage(); |
|
|
} |
|
|
}); |
|
|
</script> |
|
|
</body> |
|
|
</html> |
|
|
""" |
|
|
return HTMLResponse(content=html) |
|
|
|
|
|
@app.get("/health") |
|
|
async def health(): |
|
|
return { |
|
|
"status": "ok", |
|
|
"service": "ZenkaAI", |
|
|
"time": datetime.now().isoformat(), |
|
|
"token": "var" if HF_TOKEN else "yok" |
|
|
} |
|
|
|
|
|
@app.post("/api/chat") |
|
|
async def chat(request: Request): |
|
|
try: |
|
|
data = await request.json() |
|
|
except: |
|
|
return JSONResponse({"error": "Geçersiz JSON"}, status_code=400) |
|
|
|
|
|
email = data.get("email", "").strip() |
|
|
message = data.get("message", "").strip() |
|
|
|
|
|
if not email or "@" not in email: |
|
|
return JSONResponse({"error": "Geçerli email gerekli"}, status_code=400) |
|
|
|
|
|
if not message: |
|
|
return JSONResponse({"error": "Mesaj boş olamaz"}, status_code=400) |
|
|
|
|
|
user = get_user(email) |
|
|
|
|
|
if user["count"] >= LIMIT: |
|
|
return JSONResponse({ |
|
|
"response": f"Günlük limit ({LIMIT}) doldu. Premium: {SHOPIER}", |
|
|
"status": "limit" |
|
|
}, status_code=429) |
|
|
|
|
|
response = get_ai_response(message) |
|
|
user["count"] += 1 |
|
|
|
|
|
return { |
|
|
"response": response, |
|
|
"status": "success", |
|
|
"remaining": LIMIT - user["count"], |
|
|
"used": user["count"] |
|
|
} |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
import uvicorn |
|
|
print("🚀 ZenkaAI Başlatılıyor...") |
|
|
print(f"🔑 Token: {'✅ Var' if HF_TOKEN else '⚠️ Yok'}") |
|
|
uvicorn.run(app, host="0.0.0.0", port=7860) |