ChatbotRAG / scenario_handlers /post_event_feedback.py
minhvtt's picture
Upload 36 files
ffb5f88 verified
raw
history blame
6.67 kB
"""
Post Event Feedback Scenario Handler
Collects feedback after user attends an event
"""
from typing import Dict, Any
from .base_handler import BaseScenarioHandler
class PostEventFeedbackHandler(BaseScenarioHandler):
"""
Handle post-event feedback flow
Requires initial_data: {event_name, event_date, event_id}
Steps:
1. Ask for rating (1-5 stars)
2. Ask what they liked most
3. Ask for improvement suggestions
4. Thank + ask if want similar events
5. Collect email for future events
"""
def start(self, initial_data: Dict = None) -> Dict[str, Any]:
"""Start feedback flow with event context"""
initial_data = initial_data or {}
event_name = initial_data.get('event_name', 'sự kiện')
return {
"message": f"Cảm ơn bạn đã tham dự *{event_name}* hôm qua! 🎉\n\nBạn thấy trải nghiệm như thế nào? (1-5 sao)",
"new_state": {
"active_scenario": "post_event_feedback",
"scenario_step": 1,
"scenario_data": initial_data
}
}
def next_step(self, current_step: int, user_input: str, scenario_data: Dict) -> Dict[str, Any]:
"""Process feedback and advance"""
expected_type = self._get_expected_type(current_step)
unexpected = self.handle_unexpected_input(user_input, expected_type, current_step)
if unexpected:
return unexpected
# STEP 1: Collect rating
if current_step == 1:
rating = self._extract_rating(user_input)
scenario_data['rating'] = rating
if rating >= 4:
msg = "Tuyệt vời! 🎉 Bạn thích điểm gì nhất về event?"
else:
msg = "Cảm ơn feedback! Bạn thấy event cần cải thiện điểm nào?"
return {
"message": msg,
"new_state": {
"active_scenario": "post_event_feedback",
"scenario_step": 2,
"scenario_data": scenario_data
},
"scenario_active": True
}
# STEP 2: What they liked/disliked
elif current_step == 2:
scenario_data['feedback_text'] = user_input
return {
"message": "Cảm ơn bạn nhiều! Feedback này giúp chúng mình rất nhiều 💙\n\nBạn muốn nhận thông tin về các event tương tự không?",
"new_state": {
"active_scenario": "post_event_feedback",
"scenario_step": 4,
"scenario_data": scenario_data
},
"scenario_active": True
}
# STEP 4: Want similar events?
elif current_step == 4:
choice = self._detect_yes_no(user_input)
if choice == 'yes':
return {
"message": "Tuyệt! Cho mình xin email để gửi thông tin event sắp tới nhé?",
"new_state": {
"active_scenario": "post_event_feedback",
"scenario_step": 5,
"scenario_data": scenario_data
},
"scenario_active": True
}
else:
# Save feedback without email
self._save_feedback(scenario_data)
return {
"message": "Okie! Cảm ơn bạn đã dành thời gian góp ý 🙏",
"new_state": None,
"scenario_active": False,
"end_scenario": True
}
# STEP 5: Collect email
elif current_step == 5:
email = user_input.strip()
if not self._validate_email(email):
return {
"message": "Email này có vẻ không đúng. Bạn nhập lại giúp mình nhé?",
"new_state": None,
"scenario_active": True
}
scenario_data['email'] = email
# Save feedback + email
self._save_feedback(scenario_data)
# Save lead
try:
self.lead_storage.save_lead(
event_name=scenario_data.get('event_name'),
email=email,
interests={"wants_similar_events": True},
session_id=scenario_data.get('session_id')
)
print(f"📧 Feedback + lead saved: {email}")
except Exception as e:
print(f"⚠️ Error saving lead: {e}")
return {
"message": "Cảm ơn bạn! Mình sẽ gửi thông tin event mới cho bạn sớm nhất ✨",
"new_state": None,
"scenario_active": False,
"end_scenario": True
}
# Fallback
return {
"message": "Cảm ơn bạn! Hẹn gặp lại ✨",
"new_state": None,
"scenario_active": False,
"end_scenario": True
}
def _get_expected_type(self, step: int) -> str:
"""Get expected input type"""
type_map = {
1: 'rating',
2: 'text',
4: 'choice',
5: 'email'
}
return type_map.get(step, 'text')
def _extract_rating(self, user_input: str) -> int:
"""Extract rating from user input"""
import re
# Look for numbers 1-5
match = re.search(r'[1-5]', user_input)
if match:
return int(match.group())
# Default to 3 if can't extract
return 3
def _detect_yes_no(self, user_input: str) -> str:
"""Detect yes/no"""
input_lower = user_input.lower()
return 'yes' if any(k in input_lower for k in ['có', 'yes', 'ok', 'được', 'ừ']) else 'no'
def _save_feedback(self, scenario_data: Dict):
"""Save feedback to database (placeholder)"""
# TODO: Implement actual feedback storage
print(f"💾 Feedback saved: {scenario_data.get('rating')} stars - {scenario_data.get('feedback_text', '')[:50]}")