def process_troublemaker(self): if super().is_number_in_db(): GuestAttendanceClient(self.guest).check_guest_in() # Number is in table, but this is a repeat troublemaker. if self.guest.name == "TROUBLEMAKER": return get_messaging_response(basic_troublemaker_response()) # For some reason they've gotten cold feet about sending their name to us, even # though they've done so in the past. else: return get_messaging_response( cheeky_troublemaker_response(self.guest.name)) else: is_member = self.member is not None new_guest = Guest.objects.create( phone=self.number, name=self.member.name if is_member else "TROUBLEMAKER", ) if is_member: new_guest.member = self.member new_guest.save() GuestAttendanceClient(new_guest).check_guest_in() if is_member: return get_messaging_response( member_troublemaker_response(self.member.first_name)) else: return get_messaging_response(basic_troublemaker_response())
def create_needshelp_guest_and_proceed(self): guest = Guest.objects.create(phone=self.phone, name="NEEDSHELP") guest.save() self.guest = guest self.raise_flag(GuestAttendanceClient(self.guest).check_guest_in()) return get_messaging_response(needshelp_guest_orientation_message())
def get_more_info_or_fwd_sms(self, message_body): if self.guest.name == "NEEDSHELP": # TODO: It's entirely possible for them to respond with something other than their name, meaning we'd set # their name to be something weird here. Is there a way we can validate? self.guest.name = message_body self.guest.save() self.twilio.notify_exec_and_sbs( needshelp_was_identified_message(message_body, self.guest.phone)) self.notify_slack( needshelp_was_identified_message(message_body, self.guest.phone)) return get_messaging_response( needshelp_identified_themselves_message(message_body)) else: self.twilio.notify_exec_and_sbs( message_from_guest_message(message_body, self.guest)) return get_messaging_response(successfully_forwarded_message())
def process_guest(self): # Account linking and setup. if self.is_number_in_db(): # We've established that there's a guest account in here. self.check_troublemaker_and_alias() else: self.add_to_database() GuestAttendanceClient(self.guest).check_guest_in() return get_messaging_response(welcome_to_event_message( self.guest.name))
def handle_request_for_help(self): self.logger.warning("Attemping to notify slack") self.notify_slack(generic_asked_for_help_slack_message(self.phone)) if self.guest is None: return self.create_needshelp_guest_and_proceed() attendance = EventAttendance.objects.filter( guest__id=self.guest.id, event__id=self.event[0].id).first() if not attendance.help_flag: attendance.help_flag = True attendance.help_flag_raised_at = get_current_time_mst() attendance.save() if self.guest.name == "TROUBLEMAKER": self.logger.warning("Troublemaker asking for emergency help.") self.guest.name = "NEEDSHELP" self.guest.save() self.twilio.notify_exec_and_sbs( troublemaker_asked_for_help_message(self.guest)) return get_messaging_response( needshelp_guest_orientation_message()) else: self.logger.warning( f"Guest name {self.guest.name} is asking for help.") self.notify_slack( f"Guest asking for help is named {self.guest.name}, phone is {self.guest.phone}." ) self.twilio.notify_exec_and_sbs( guest_asked_for_help_exec_sb_message(self.guest)) response_message = get_messaging_response( guest_asked_for_help_initial_message().strip()) self.logger.warning(f"Returning: {response_message}") return response_message
def create(self, request): """ Handles the SMS Requests POSTed In by Twilio """ logger.info(f"Received request: {request}") logger.info(f"Request body: {request.body}") headers = request.headers try: body = extract_twilio_body(request.body) except Exception as e: logger.error("Encountered error when parsing Twilio request body") return Response( { "improper_format": f"Was unable to parse Twilio data from your requests", "body": f"{request.body}", "headers": f"{headers}", "error_message": f"{e}", }, status=status.HTTP_400_BAD_REQUEST, ) # Twilio's verification will sporadically decide to fail. Who knows why or how. This code # enables a server setting to bypass verification checking as a bandaid. # TODO: Remove this bandaid and actually determine why verification is failing. Will probably need logging to go off. is_valid_message = verify_twilio_request(headers, body) # By default, we'll check all messages for authenticity. server_setting = server_setting_get_or_none("verify-twilio-requests") checking_message = bool( server_setting) if server_setting is not None else True logger.warning(f"Valid Twilio Signature? {is_valid_message}") logger.warning( f"For Body: {body}, Uri: {request.get_full_path()}, Signature: {headers['X-Twilio-Signature']}" ) if checking_message and not is_valid_message: return Response( { "signature_invalid": f"The signature included with the request is invalid. Who are you?", "body": f"{body}", "signature": f"{headers['X-Twilio-Signature']}", "uri": f"{request.get_full_path()}", }, status=status.HTTP_400_BAD_REQUEST, ) # Check for flag if help_flag_is_present(body["From"]): # For this flow, this is CRITICAL. In the event of an emergency coinciding with something breaking, we need # to provide some support still. try: emergency_response = EmergencyResponseClient( body["From"]).get_more_info_or_fwd_sms(body["Body"]) return HttpResponse( emergency_response, status=status.HTTP_200_OK, content_type="text/xml", ) except Exception as e: logger.error( "Error in EmergencyResponseClient, get_more_info_or_fwd_sms" ) logger.error(e) return HttpResponse( get_messaging_response(code_is_breaking_message()), status=status.HTTP_200_OK, content_type="text/xml", ) # Check if there's an event going on if len(get_active_event()) == 0: return HttpResponse( get_messaging_response(no_event_message()), status=status.HTTP_200_OK, content_type="text/xml", ) # Check if text is the default if text_is_default(body["Body"]): troublemaker_response = TroublemakerClient( body["From"]).process_troublemaker() return HttpResponse( troublemaker_response, status=status.HTTP_200_OK, content_type="text/xml", ) # Checking if the message says help me if text_is_help(body["Body"]): # For this flow, this is CRITICAL. In the event of an emergency coinciding with something breaking, we need # to provide some support still. try: return HttpResponse( EmergencyResponseClient( body["From"]).handle_request_for_help(), status=status.HTTP_200_OK, content_type="text/xml", ) except Exception as e: logger.error( "Error in EmergencyResponseClient, handle_request_for_help" ) logger.error(e) return HttpResponse( get_messaging_response(code_is_breaking_message()), status=status.HTTP_200_OK, content_type="text/xml", ) else: logger.warning( "All pre-message checks passed, continuing with add guest flow" ) add_guest_client_response = AddGuestClient( body["From"], body["Body"]).process_guest() return HttpResponse( add_guest_client_response, status=status.HTTP_200_OK, content_type="text/xml", )