ChatbotRAG / scenario_handlers /post_event_feedback.py
minhvtt's picture
Upload 36 files
ffb5f88 verified
"""
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]}")