BF-WAB / intent_analyzer.py
SamiKoen's picture
Add GPT-5 Powered Intent Analysis for Smart Store Notifications
076bb5b
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
GPT-5 Powered Intent Analyzer
Müşteri mesajlarından niyeti anlar ve aksiyonları belirler
"""
import os
import json
import requests
import logging
from typing import Dict, Optional, List, Tuple
logger = logging.getLogger(__name__)
# OpenAI API
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
API_URL = "https://api.openai.com/v1/chat/completions"
def analyze_customer_intent(
message: str,
context: Optional[Dict] = None
) -> Dict:
"""
GPT-5 ile müşteri niyetini analiz et
Args:
message: Müşteri mesajı
context: Sohbet bağlamı (varsa)
Returns:
{
"intents": ["reserve", "price", "stock", "info"],
"product": "FX 2",
"confidence": 0.95,
"store": "caddebostan", # Eğer belirtildiyse
"urgency": "high/medium/low",
"customer_mood": "positive/neutral/negative",
"suggested_action": "notify_store/answer_directly/both",
"notification_message": "Özel mesaj"
}
"""
if not OPENAI_API_KEY:
logger.error("OpenAI API key missing")
return {"intents": [], "confidence": 0}
# Sistem promptu
system_prompt = """Sen bir müşteri niyet analiz uzmanısın. Trek bisiklet mağazası için müşteri mesajlarını analiz ediyorsun.
GÖREV: Müşteri mesajını analiz et ve JSON formatında döndür.
NİYET TİPLERİ:
- "reserve": Ürünü ayırtmak, rezerve etmek, tutmak istiyor
- "price": Fiyat bilgisi istiyor
- "stock": Stok durumu soruyor
- "info": Genel bilgi istiyor
- "complaint": Şikayet ediyor
- "order": Sipariş vermek istiyor
- "test_ride": Test sürüşü istiyor
- "service": Servis/tamir istiyor
- "none": Belirgin bir niyet yok
ÖRNEK CÜMLELER:
- "bu bisikleti ayırtabilir misiniz" → reserve
- "yarın gelip alabilirim" → reserve
- "benim için tutun" → reserve
- "fiyatı nedir" → price
- "kaç para" → price
- "var mı" → stock
- "stokta mı" → stock
- "özellikleri nelerdir" → info
- "test edebilir miyim" → test_ride
ACİLİYET:
- high: Hemen aksiyon gerekiyor (ayırtma, hemen alma isteği)
- medium: Normal takip yeterli
- low: Bilgi amaçlı
JSON FORMATI:
{
"intents": ["reserve", "price"], // Birden fazla olabilir
"product": "FX 2", // Eğer üründen bahsediyorsa
"confidence": 0.95, // 0-1 arası güven skoru
"store": null, // Mağaza adı varsa
"urgency": "high",
"customer_mood": "positive",
"suggested_action": "notify_store", // notify_store, answer_directly, both, none
"notification_required": true,
"notification_reason": "Müşteri FX 2'yi ayırtmak istiyor"
}"""
# Bağlam varsa ekle
context_info = ""
if context:
if context.get("current_category"):
context_info = f"\nSON KONUŞULAN ÜRÜN: {context['current_category']}"
if context.get("messages"):
last_msg = context["messages"][-1] if context["messages"] else None
if last_msg:
context_info += f"\nÖNCEKİ MESAJ: {last_msg.get('user', '')}"
# GPT-5'e gönder
try:
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": f"Müşteri mesajı: \"{message}\"{context_info}\n\nJSON formatında analiz et:"}
]
payload = {
"model": "gpt-5-chat-latest",
"messages": messages,
"temperature": 0,
"max_tokens": 300,
"response_format": {"type": "json_object"} # JSON garantisi
}
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {OPENAI_API_KEY}"
}
response = requests.post(API_URL, headers=headers, json=payload, timeout=10)
if response.status_code == 200:
result = response.json()
analysis = json.loads(result['choices'][0]['message']['content'])
logger.info(f"🧠 Intent Analysis: {analysis}")
return analysis
else:
logger.error(f"GPT-5 API error: {response.status_code}")
return {"intents": [], "confidence": 0}
except Exception as e:
logger.error(f"Intent analysis error: {e}")
return {"intents": [], "confidence": 0}
def should_notify_store(analysis: Dict) -> Tuple[bool, str]:
"""
Mağazaya bildirim gönderilmeli mi?
Returns:
(should_notify, reason)
"""
# Yüksek güvenle rezervasyon talebi
if "reserve" in analysis.get("intents", []) and analysis.get("confidence", 0) > 0.7:
return True, "Müşteri ürünü ayırtmak istiyor"
# Acil stok sorusu
if "stock" in analysis.get("intents", []) and analysis.get("urgency") == "high":
return True, "Müşteri acil stok bilgisi istiyor"
# Test sürüşü talebi
if "test_ride" in analysis.get("intents", []):
return True, "Müşteri test sürüşü talep ediyor"
# Sipariş vermek istiyor
if "order" in analysis.get("intents", []) and analysis.get("confidence", 0) > 0.8:
return True, "Müşteri sipariş vermek istiyor"
# Şikayet varsa
if "complaint" in analysis.get("intents", []):
return True, "Müşteri şikayette bulunuyor"
# GPT öneriyorsa
if analysis.get("suggested_action") in ["notify_store", "both"]:
return True, analysis.get("notification_reason", "GPT-5 bildirim öneriyor")
return False, ""
def get_smart_notification_message(
analysis: Dict,
customer_phone: str,
original_message: str
) -> str:
"""
Analiz sonucuna göre akıllı bildirim mesajı oluştur
"""
intents = analysis.get("intents", [])
product = analysis.get("product", "Belirtilmemiş")
urgency = analysis.get("urgency", "medium")
mood = analysis.get("customer_mood", "neutral")
# Emoji seçimi
if "reserve" in intents:
emoji = "🔔"
title = "AYIRTMA TALEBİ"
elif "price" in intents:
emoji = "💰"
title = "FİYAT SORUSU"
elif "stock" in intents:
emoji = "📦"
title = "STOK SORUSU"
elif "test_ride" in intents:
emoji = "🚴"
title = "TEST SÜRÜŞÜ TALEBİ"
elif "complaint" in intents:
emoji = "⚠️"
title = "ŞİKAYET"
elif "order" in intents:
emoji = "🛒"
title = "SİPARİŞ TALEBİ"
else:
emoji = "ℹ️"
title = "MÜŞTERİ TALEBİ"
# Aciliyet vurgusu
if urgency == "high":
title = f"🚨 ACİL - {title}"
# Mesaj oluştur
from datetime import datetime
now = datetime.now()
date_str = now.strftime("%d.%m.%Y %H:%M")
message_parts = [
f"{emoji} **{title}**",
f"📅 {date_str}",
"",
f"👤 **Müşteri:** {customer_phone.replace('whatsapp:', '')}",
f"🚲 **Ürün:** {product}",
f"💬 **Mesaj:** \"{original_message}\"",
"",
"📊 **AI Analizi:**"
]
# Niyet listesi
intent_map = {
"reserve": "✓ Ayırtma isteği",
"price": "✓ Fiyat bilgisi",
"stock": "✓ Stok durumu",
"test_ride": "✓ Test sürüşü",
"order": "✓ Sipariş",
"complaint": "✓ Şikayet",
"info": "✓ Bilgi talebi"
}
for intent in intents:
if intent in intent_map:
message_parts.append(f" {intent_map[intent]}")
# Müşteri durumu
mood_map = {
"positive": "😊 Pozitif",
"neutral": "😐 Nötr",
"negative": "😟 Negatif"
}
message_parts.append(f" Müşteri Durumu: {mood_map.get(mood, mood)}")
message_parts.append(f" Aciliyet: {'🔴 Yüksek' if urgency == 'high' else '🟡 Orta' if urgency == 'medium' else '🟢 Düşük'}")
# Önerilen aksiyon
message_parts.extend([
"",
"✅ **Önerilen Aksiyon:**"
])
if "reserve" in intents:
message_parts.extend([
"1. Stok kontrolü yapın",
"2. Müşteriyi hemen arayın",
"3. Ödeme ve teslimat planı belirleyin"
])
elif "test_ride" in intents:
message_parts.extend([
"1. Test bisikleti hazırlığı",
"2. Randevu ayarlayın",
"3. Kimlik ve güvenlik prosedürü"
])
elif "complaint" in intents:
message_parts.extend([
"1. Müşteriyi hemen arayın",
"2. Sorunu dinleyin",
"3. Çözüm önerisi sunun"
])
else:
message_parts.append("Müşteri ile iletişime geçin")
message_parts.extend([
"",
"---",
"Trek AI Assistant"
])
return "\n".join(message_parts)
# Test fonksiyonu
def test_intent_analysis():
"""Test senaryoları"""
test_messages = [
"FX 2'yi ayırtabilir misiniz?",
"Marlin 5'in fiyatı ne kadar?",
"Stokta var mı?",
"Yarın gelip alabilirim",
"Test sürüşü yapabilir miyim?",
"Bisikletim bozuldu",
"Teşekkürler",
"Merhaba",
"Sipariş vermek istiyorum"
]
print("\n" + "="*60)
print("INTENT ANALYSIS TEST")
print("="*60)
for msg in test_messages:
print(f"\n📝 Mesaj: \"{msg}\"")
analysis = analyze_customer_intent(msg)
if analysis.get("intents"):
print(f"🎯 Niyetler: {', '.join(analysis['intents'])}")
print(f"📊 Güven: {analysis.get('confidence', 0):.2%}")
print(f"🚨 Aciliyet: {analysis.get('urgency', 'unknown')}")
should_notify, reason = should_notify_store(analysis)
print(f"🔔 Bildirim: {'EVET' if should_notify else 'HAYIR'}")
if reason:
print(f" Sebep: {reason}")
else:
print("❌ Niyet tespit edilemedi")
print("\n" + "="*60)
if __name__ == "__main__":
test_intent_analysis()