Spaces:
Running
Running
| """ | |
| 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]}") | |