File size: 18,702 Bytes
81855eb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d9aab9b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
"""
CRM (Customer Relationship Management) System
Müşteri tanıma, segmentasyon ve kişiselleştirilmiş yanıtlar
"""
import json
import os
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Tuple
import re

class CustomerManager:
    def __init__(self, db_path: str = "customers.json"):
        self.db_path = db_path
        self.customers = self._load_database()
    
    def _load_database(self) -> Dict:
        """Müşteri veritabanını yükle"""
        if os.path.exists(self.db_path):
            try:
                with open(self.db_path, 'r', encoding='utf-8') as f:
                    return json.load(f)
            except:
                return {}
        return {}
    
    def _save_database(self):
        """Veritabanını kaydet"""
        with open(self.db_path, 'w', encoding='utf-8') as f:
            json.dump(self.customers, f, ensure_ascii=False, indent=2)
    
    def _extract_name_from_message(self, message: str) -> Optional[str]:
        """Mesajdan isim çıkarmaya çalış"""
        # "Ben Ahmet", "Benim adım Mehmet", "Merhaba ben Ali" gibi kalıplar
        patterns = [
            r"ben[im]?\s+ad[ıi]m?\s+(\w+)",
            r"ben\s+(\w+)",
            r"ad[ıi]m\s+(\w+)",
            r"(\w+)\s+diye",
        ]
        
        message_lower = message.lower()
        for pattern in patterns:
            match = re.search(pattern, message_lower)
            if match:
                name = match.group(1)
                # İlk harfi büyük yap
                return name.capitalize()
        return None
    
    def _detect_interests(self, message: str) -> List[str]:
        """Mesajdan ilgi alanlarını çıkar"""
        interests = []
        message_lower = message.lower()
        
        # Bisiklet kategorileri
        if any(word in message_lower for word in ["dağ", "mountain", "mtb"]):
            interests.append("mountain_bike")
        if any(word in message_lower for word in ["yol", "road", "yarış"]):
            interests.append("road_bike")
        if any(word in message_lower for word in ["şehir", "city", "urban"]):
            interests.append("city_bike")
        
        # Marka ve modeller
        if "trek" in message_lower:
            interests.append("trek")
        if "marlin" in message_lower:
            interests.append("marlin_series")
        if "fx" in message_lower:
            interests.append("fx_series")
        if "domane" in message_lower:
            interests.append("domane_series")
        if "madone" in message_lower:
            interests.append("madone_series")
        
        # Özellikler
        if any(word in message_lower for word in ["elektrik", "e-bike", "ebike"]):
            interests.append("e_bike")
        if any(word in message_lower for word in ["karbon", "carbon"]):
            interests.append("carbon")
        if any(word in message_lower for word in ["kadın", "women", "wsd"]):
            interests.append("women_specific")
        
        # Bütçe
        if any(word in message_lower for word in ["ucuz", "uygun fiyat", "ekonomik"]):
            interests.append("budget_friendly")
        if any(word in message_lower for word in ["premium", "high-end", "üst segment"]):
            interests.append("premium")
        
        return interests
    
    def _calculate_segment(self, customer: Dict) -> str:
        """Müşteri segmentini hesapla"""
        total_purchases = len(customer.get("purchases", []))
        total_spent = sum(p.get("price", 0) for p in customer.get("purchases", []))
        total_queries = customer.get("total_queries", 0)
        
        # Son aktivite kontrolü
        last_interaction = datetime.fromisoformat(customer.get("last_interaction", datetime.now().isoformat()))
        days_since_last = (datetime.now() - last_interaction).days
        
        # VIP kriterler
        if total_purchases >= 3 or total_spent >= 50000:
            return "VIP"
        
        # Potansiyel müşteri
        if total_queries >= 5 and total_purchases == 0:
            return "Potansiyel"
        
        # Kayıp riski
        if days_since_last > 30 and total_purchases > 0:
            return "Kayıp Riski"
        
        # Yeni müşteri (ilk 7 gün)
        first_seen = datetime.fromisoformat(customer.get("first_seen", datetime.now().isoformat()))
        if (datetime.now() - first_seen).days <= 7:
            return "Yeni"
        
        # Aktif müşteri
        if days_since_last <= 7:
            return "Aktif"
        
        # Standart
        return "Standart"
    
    def get_or_create_customer(self, phone: str, name: Optional[str] = None) -> Dict:
        """Müşteriyi getir veya yeni oluştur"""
        if phone in self.customers:
            # Var olan müşteri
            customer = self.customers[phone]
            customer["last_interaction"] = datetime.now().isoformat()
            
            # İsim güncellemesi
            if name and not customer.get("name"):
                customer["name"] = name
            
            # Segment güncelle
            customer["segment"] = self._calculate_segment(customer)
            
        else:
            # Yeni müşteri
            customer = {
                "phone": phone,
                "name": name,
                "first_seen": datetime.now().isoformat(),
                "last_interaction": datetime.now().isoformat(),
                "total_queries": 0,
                "purchases": [],
                "interests": [],
                "searched_products": [],
                "segment": "Yeni",
                "notes": [],
                "preferred_contact_time": None  # "morning", "afternoon", "evening"
            }
            self.customers[phone] = customer
        
        self._save_database()
        return customer
    
    def update_interaction(self, phone: str, message: str, product_searched: Optional[str] = None) -> Dict:
        """Müşteri etkileşimini güncelle"""
        customer = self.get_or_create_customer(phone)
        
        # Sorgu sayısını artır
        customer["total_queries"] = customer.get("total_queries", 0) + 1
        
        # İsim çıkarma denemesi
        if not customer.get("name"):
            extracted_name = self._extract_name_from_message(message)
            if extracted_name:
                customer["name"] = extracted_name
        
        # İlgi alanlarını güncelle
        new_interests = self._detect_interests(message)
        existing_interests = set(customer.get("interests", []))
        customer["interests"] = list(existing_interests.union(set(new_interests)))
        
        # Aranan ürünü kaydet
        if product_searched:
            searched_products = customer.get("searched_products", [])
            # Son 10 aramayı tut
            searched_products.append({
                "product": product_searched,
                "date": datetime.now().isoformat()
            })
            customer["searched_products"] = searched_products[-10:]
        
        # İletişim zamanı tercihi
        hour = datetime.now().hour
        if 6 <= hour < 12:
            time_pref = "morning"
        elif 12 <= hour < 18:
            time_pref = "afternoon"
        else:
            time_pref = "evening"
        
        # En çok hangi zaman diliminde yazıyor
        if not customer.get("preferred_contact_time"):
            customer["preferred_contact_time"] = time_pref
        
        # Segment güncelle
        customer["segment"] = self._calculate_segment(customer)
        
        # Son etkileşim zamanı
        customer["last_interaction"] = datetime.now().isoformat()
        
        self._save_database()
        return customer
    
    def add_purchase(self, phone: str, product: str, price: float) -> Dict:
        """Satın alma kaydı ekle"""
        customer = self.get_or_create_customer(phone)
        
        purchase = {
            "product": product,
            "price": price,
            "date": datetime.now().isoformat()
        }
        
        customer.setdefault("purchases", []).append(purchase)
        customer["segment"] = self._calculate_segment(customer)
        
        self._save_database()
        return customer
    
    def get_customer_context(self, phone: str) -> Dict:
        """Müşteri bağlamını getir"""
        customer = self.customers.get(phone, {})
        
        if not customer:
            return {
                "is_new": True,
                "greeting": "Merhaba! Trek bisikletleri hakkında size nasıl yardımcı olabilirim?"
            }
        
        context = {
            "is_new": False,
            "name": customer.get("name"),
            "segment": customer.get("segment", "Standart"),
            "total_queries": customer.get("total_queries", 0),
            "interests": customer.get("interests", []),
            "last_product": None,
            "days_since_last": 0,
            "greeting": ""
        }
        
        # Son aranan ürün
        searched_products = customer.get("searched_products", [])
        if searched_products:
            context["last_product"] = searched_products[-1]["product"]
            last_search_date = datetime.fromisoformat(searched_products[-1]["date"])
            context["days_since_last"] = (datetime.now() - last_search_date).days
        
        # Kişiselleştirilmiş selamlama oluştur
        context["greeting"] = self._generate_greeting(customer, context)
        
        return context
    
    def _generate_greeting(self, customer: Dict, context: Dict) -> str:
        """Kişiselleştirilmiş selamlama oluştur"""
        segment = customer.get("segment", "Standart")
        name = customer.get("name", "")
        
        # Saat bazlı selamlama
        hour = datetime.now().hour
        if 6 <= hour < 12:
            time_greeting = "Günaydın"
        elif 12 <= hour < 18:
            time_greeting = "İyi günler"
        else:
            time_greeting = "İyi akşamlar"
        
        # Segment bazlı selamlama
        if segment == "VIP":
            if name:
                greeting = f"{time_greeting} {name} Bey/Hanım! Değerli müşterimiz olarak size özel VIP avantajlarımız mevcut."
            else:
                greeting = f"{time_greeting}! Değerli müşterimize özel VIP avantajlarımız mevcut."
        
        elif segment == "Yeni":
            greeting = f"{time_greeting}! Trek bisikletleri dünyasına hoş geldiniz! Size nasıl yardımcı olabilirim?"
        
        elif segment == "Potansiyel":
            if context.get("last_product"):
                greeting = f"{time_greeting}! Daha önce sorduğunuz {context['last_product']} veya başka bir konuda size yardımcı olabilir miyim?"
            else:
                greeting = f"{time_greeting}! Bisiklet arayışınızda size nasıl yardımcı olabilirim?"
        
        elif segment == "Kayıp Riski":
            if name:
                greeting = f"{time_greeting} {name} Bey/Hanım! Sizi özledik! Size özel geri dönüş kampanyamız var."
            else:
                greeting = f"{time_greeting}! Sizi tekrar aramızda görmek güzel! Size özel fırsatlarımız var."
        
        elif segment == "Aktif":
            if name:
                greeting = f"{time_greeting} {name} Bey/Hanım! Tekrar hoş geldiniz!"
            else:
                greeting = f"{time_greeting}! Tekrar hoş geldiniz!"
            
            # Son aranan ürün varsa ekle
            if context.get("last_product") and context.get("days_since_last", 99) <= 3:
                greeting += f" {context['last_product']} hakkında bilgi almak ister misiniz?"
        
        else:  # Standart
            if name:
                greeting = f"{time_greeting} {name} Bey/Hanım! Size nasıl yardımcı olabilirim?"
            else:
                greeting = f"{time_greeting}! Size nasıl yardımcı olabilirim?"
        
        return greeting
    
    def get_analytics(self) -> Dict:
        """Analitik özet döndür"""
        total_customers = len(self.customers)
        segments = {}
        total_purchases = 0
        total_revenue = 0
        active_today = 0
        
        today = datetime.now().date()
        
        for customer in self.customers.values():
            # Segment dağılımı
            segment = customer.get("segment", "Standart")
            segments[segment] = segments.get(segment, 0) + 1
            
            # Satış istatistikleri
            purchases = customer.get("purchases", [])
            total_purchases += len(purchases)
            total_revenue += sum(p.get("price", 0) for p in purchases)
            
            # Bugün aktif olanlar
            last_interaction = datetime.fromisoformat(customer.get("last_interaction", "2020-01-01"))
            if last_interaction.date() == today:
                active_today += 1
        
        return {
            "total_customers": total_customers,
            "segments": segments,
            "total_purchases": total_purchases,
            "total_revenue": total_revenue,
            "active_today": active_today,
            "average_purchase_value": total_revenue / total_purchases if total_purchases > 0 else 0
        }
    
    def get_customer_list(self, segment: Optional[str] = None) -> List[Dict]:
        """Müşteri listesini getir"""
        customers = []
        
        for phone, customer in self.customers.items():
            if segment and customer.get("segment") != segment:
                continue
            
            customers.append({
                "phone": phone,
                "name": customer.get("name", "Bilinmiyor"),
                "segment": customer.get("segment", "Standart"),
                "total_queries": customer.get("total_queries", 0),
                "total_purchases": len(customer.get("purchases", [])),
                "last_interaction": customer.get("last_interaction"),
                "interests": customer.get("interests", [])
            })
        
        # Son etkileşime göre sırala
        customers.sort(key=lambda x: x["last_interaction"], reverse=True)
        return customers
    
    def should_ask_for_name(self, phone: str, message: str) -> Tuple[bool, Optional[str]]:
        """İsim sorulmalı mı kontrol et"""
        customer = self.customers.get(phone, {})
        
        # Zaten isim varsa sorma
        if customer.get("name"):
            return False, None
        
        queries = customer.get("total_queries", 0)
        message_lower = message.lower()
        
        # 1. Rezervasyon/satın alma anında (EN DOĞAL)
        reservation_keywords = ["rezerv", "ayırt", "satın al", "alabilir miyim", "almak istiyorum", 
                               "sipariş", "kargola", "gönder", "paket", "teslimat"]
        if any(keyword in message_lower for keyword in reservation_keywords):
            return True, "📝 Rezervasyon için adınızı alabilir miyim?"
        
        # 2. Mağaza ziyareti planı
        store_visit_keywords = ["mağazaya gel", "mağazaya uğra", "görmeye gel", "bakmaya gel", 
                               "test sürüşü", "denemek istiyorum"]
        if any(keyword in message_lower for keyword in store_visit_keywords):
            return True, "🏪 Mağazada size daha iyi yardımcı olabilmemiz için adınızı öğrenebilir miyim?"
        
        # 3. Telefon görüşmesi talebi
        phone_keywords = ["ara", "telefon", "görüş", "konuş", "iletişim"]
        if any(keyword in message_lower for keyword in phone_keywords):
            return True, "📞 Sizi arayabilmemiz için adınızı paylaşır mısınız?"
        
        # 4. Fiyat/ödeme görüşmesi (ciddi alıcı)
        payment_keywords = ["taksit", "ödeme", "kredi kartı", "havale", "eft", "nakit", "peşin"]
        if any(keyword in message_lower for keyword in payment_keywords):
            return True, "💳 Size özel ödeme seçenekleri sunabilmem için adınızı öğrenebilir miyim?"
        
        # 5. 3. mesajda nazikçe sor (sadece ürün sorguluyorsa)
        if queries == 2:  # 3. mesaj (0'dan başlıyor)
            # Sadece basit selamlaşma değilse
            greeting_only = ["merhaba", "selam", "günaydın", "iyi günler", "hey", "sa"]
            if not any(message_lower.strip() == greeting for greeting in greeting_only):
                return True, "Bu arada, size daha iyi hizmet verebilmem için adınızı öğrenebilir miyim? 😊"
        
        # 6. 5+ sorgudan sonra hala isim yoksa (potansiyel müşteri)
        if queries >= 5:
            return True, "✨ Sizin için özel tekliflerimiz olabilir. Adınızı paylaşır mısınız?"
        
        return False, None
    
    def extract_name_from_response(self, message: str) -> Optional[str]:
        """İsim sorulduktan sonra gelen yanıttan isim çıkar"""
        message_lower = message.lower().strip()
        
        # Direkt isim yanıtları
        if len(message_lower.split()) == 1:
            # Yaygın olmayan tek kelime yanıtları filtrele
            common_words = ["evet", "hayır", "tamam", "olur", "peki", "teşekkür", "teşekkürler",
                          "merhaba", "selam", "günaydın", "güle", "hoşçakal", "görüşürüz",
                          "sa", "as", "slm", "mrb", "ok", "okay", "yes", "no", "hi", "hello", "bye"]
            if message_lower not in common_words:
                # Tek kelime, muhtemelen isim
                name = message.capitalize()
                # Türkçe isim kontrolü (en az 2 karakter)
                if len(name) >= 2 and name.isalpha():
                    return name
        
        # "Benim adım X", "Ben X", "Adım X" kalıpları
        patterns = [
            r"(?:benim\s+)?ad[ıi]m?\s+(\w+)",
            r"ben\s+(\w+)",
            r"(\w+)\s+diye\s+hitap",
            r"bana\s+(\w+)\s+diyebilirsiniz",
            r"ismim\s+(\w+)",
            r"(\w+),?\s*teşekkür",  # "Ahmet, teşekkürler"
        ]
        
        for pattern in patterns:
            import re
            match = re.search(pattern, message_lower)
            if match:
                name = match.group(1).capitalize()
                if len(name) >= 2:
                    return name
        
        # İsim + Soyisim durumu (sadece ismi al)
        two_words = message.strip().split()
        if len(two_words) == 2:
            # Her ikisi de büyük harfle başlıyorsa
            if two_words[0][0].isupper() and two_words[1][0].isupper():
                return two_words[0]
        
        return None