def send_to_sqs(self, action_id: str, action_type: str, value: str,\ message_type: Types, consultant_uuid = None): ''' Sends message to SQS - :param action_id: action id of message :param action_type: type of message :param value: value of message ''' if action_type == 'checkboxes': value = [{'value': x['value'].split(';')[1]} for x in value] if action_type == 'static_select': value = value['value'].split(';')[1] message_payload = { "action_id": action_id, "type": action_type, "value": value } if self.metadata is not None: if 'current_activity' in self.metadata and\ self.metadata['current_activity'] is not None: message_payload['customer'] = self.metadata['current_activity'] elif 'current_customer' in self.metadata and\ self.metadata['current_customer'] is not None: message_payload['customer'] = self.metadata['current_customer'] checkin = self.checkin_model.get(self.metadata['checkin_id']) message = write_message(checkin.consultant_uuid, message_type, checkin_id=checkin.uuid, device_id=self.payload['api_app_id'], trigger_id=self.payload['trigger_id'], payload=message_payload) else: message = write_message(consultant_uuid, message_type, checkin_id=None, device_id=self.payload['api_app_id'], trigger_id=self.payload['trigger_id'], payload=message_payload) slack_app_url = get_export('checkin-action-queue-url') send = self.sqs_client.send_message(QueueUrl=slack_app_url, MessageBody='Slack User Input', MessageAttributes=message, MessageGroupId='UserInput', MessageDeduplicationId=str( uuid.uuid4())) print("SEND TO SQS:", send) return send
def checkin(checkin_date: date, slack_id: str, sqs_client: Boto3SQS,\ consultant_model: PynamoDBConsultant): ''' Starts Checkin - :param sqs_client: AWS Event :param context: AWS Lambda context ''' checkin_action_url = os.environ['CHECKIN_ACTION_URL'] consultant = next(consultant_model.slack_id_index.query(slack_id), None) if consultant is not None: print(checkin_date) message = write_message(consultant.uuid, Types.Scheduled, checkin_date=str(checkin_date)) send_scheduled = sqs_client.send_message(QueueUrl=checkin_action_url, MessageBody='Scheduled', MessageAttributes=message, MessageDeduplicationId=str( uuid.uuid4()), MessageGroupId="Scheduled") print(send_scheduled) response_text = "The CheckIn for '{}' will be with you shortly".format( checkin_date) else: response_text = "Error: Consultant not found" return {"response_type": "ephemeral", "text": response_text}
def scheduled(message: Dict, unique_id: str, sns_client: Boto3SNS, stepfunctions_client: Boto3SFN, checkin_model: PynamoDBCheckIn)\ -> Tuple[Boto3SNS, Boto3SFN]: ''' Method for scheduled action. Saves "null" checkin in database and publish message to prediction queue. - :param message: The message from start "event" e.g. message will be received at 9am. :param unique_id: Unique id for checkin in database. :param sns_client: boto3 client for Simple Notification Server. :param stepfunctions_client: boto3 client for stepfunctions. :param checkin_model: PynamoDB CheckIn Model ''' prediction_arn = get_export('predict-topic-arn') times_up_machine = os.environ['TIMES_UP_MACHINE'] reminder = 'checkin-id' in message if not reminder: checkin_date = datetime.strptime(message['checkin-date'], '%Y-%m-%d').date() checkin = checkin_model(uuid=unique_id, consultant_uuid=message['consultant'], date=str(checkin_date), completed='False', predictions='[]', user_input='[]') # Write the checkin to the database checkin.save() # Send message to predict sns_pub = sns_client.publish( TopicArn=prediction_arn, Message='Ready for prediction', MessageAttributes=write_message( message['consultant'], Types.Predict, checkin_id=unique_id) ) print(sns_pub) # Start TimesUp start = stepfunctions_client.start_execution( stateMachineArn=times_up_machine, input=json.dumps(write_message( message['consultant'], Types.Slack if not reminder else Types.Slack_Reminder,\ checkin_id=unique_id if not reminder else message['checkin-id'])) ) print(start)
def scheduler_start_checkin(consultant: Dict, sqs_client: Boto3SQS, checkin_model: PynamoDBCheckIn, reminder=False) -> None: ''' Starts the scheduler - :param consultant: current consultant :param sqs_client: Boto3 SQS client :param checkin_model: PynamoDB Checkin Model :param reminder: is the scheduler a reminder ''' checkin_action_url = os.environ['CHECKIN_ACTION_URL'] scheduled = [] checkins = checkin_model.consultant_uuid_date_index.query(consultant.uuid,\ checkin_model.date <= str(datetime.today()), checkin_model.completed == 'False') for checkin in checkins: message = write_message(consultant.uuid, Types.Scheduled_Reminder,\ checkin_id=checkin.uuid) scheduled.append(create_scheduled(checkin.uuid, message)) if not reminder: checkin_date = date.today() if consultant.same_day_checkin is None or consultant.same_day_checkin == 'False': checkin_date = checkin_date - timedelta( max(1, (checkin_date.weekday() + 6) % 7 - 3)) message = write_message(consultant.uuid, Types.Scheduled,\ checkin_date=checkin_date.strftime("%Y-%m-%d")) scheduled.append(create_scheduled(consultant.slack_id, message)) if len(scheduled) > 0: for count in range((int(len(scheduled) / 10) + 1)): batch = scheduled[10 * (count):(10 * (count + 1))] if len(batch) > 0: send_scheduled = sqs_client.send_message_batch( QueueUrl=checkin_action_url, Entries=batch) print(send_scheduled)
def create_entrie(consultant: str, today: bool, checkin_id: str, consultants_model: PynamoDBConsultant, requests_client: Requests) -> Dict: ''' Creates an entrie for sending in message batch - :param consultant: consultant uuid :param today: is it today or yesterday true/false :param checkin_id: checkin uuid :param consultants_model: PynamoDB Consultants Model :param requests_client: Requests Client ''' payload = { "header": { "prediction-type": "hint", "posibility": 95 if today else 90, "source": "slack" }, "body": { "type": "standup", "message": "", } } entrie = { 'Id': "", 'MessageBody': 'Prediction', 'MessageAttributes': "", 'MessageDeduplicationId': str(uuid.uuid4()), 'MessageGroupId': "Prediction" } message = get_standups_for_consultant(consultant, today, consultants_model, requests_client) payload['body']['message'] = message entrie['Id'] = str(uuid.uuid4()).replace('-', '_') entrie['MessageAttributes'] = write_message(consultant, Types.Prediction, checkin_id=checkin_id, payload=payload) return entrie if message is not None else None
def create_entrie(consultant: str, checkin_id: str, online_status_model: PynamoDBOnlineStatuses) -> Dict: ''' Creates an entrie for sending in message batch - :param consultant: consultant uuid :param checkin_id: checkin uuid :param online_status_model: PynamoDB Online Statuses Model ''' payload = { "header": { "prediction-type": "duration", "posibility": 95, "source": "slack" }, "body": { "type": "start-end", "starttime": "", "endtime": "" } } entrie = { 'Id': "", 'MessageBody': 'Prediction', 'MessageAttributes': "", 'MessageDeduplicationId': str(uuid.uuid4()), 'MessageGroupId': "Prediction" } start_time, end_time = calculate_start_end_time(consultant, online_status_model) payload['body']['starttime'] = start_time['time'] payload['body']['endtime'] = end_time['time'] entrie['Id'] = str(uuid.uuid4()).replace('-', '_') entrie['MessageAttributes'] = write_message(consultant, Types.Prediction, checkin_id=checkin_id, payload=payload) return entrie
def make_prediction(event: Dict, context, sqs_client: Boto3SQS,\ customers_model: PynamoDBCustomers, checkin_model: PynamoDBCheckIn, contract_model: PynamoDBContract, \ weights_model: PynamoDBWeights) -> None: ''' Subscribes to SNS Topic to predict standup hints - :param event: AWS event :param context: AWS Lambda context :param sqs_client: Boto3 SQS client :param customers_model: Customer pynamodb :param checkin_model: CheckIn pynamodb :param contract_model: Contract pynamodb :param weights_model: Weights pynamodb ''' print("Request ID:", context) print("event", event) attributes = load_message(event['Records'][0]['Sns']['MessageAttributes'], True) if ('type' not in attributes) or (attributes['type'] != Types.Predict): print('Type not found') date = checkin_model.get(attributes['checkin-id']).date date_datetime = datetime.datetime.strptime(date, '%Y-%m-%d') customers = customers_model.scan() weights = weights_model.scan() checkins = list(checkin_model.scan(checkin_model.date.between(\ str(date_datetime - datetime.timedelta(days=3)),\ str(date_datetime - datetime.timedelta(days=1))) &\ (checkin_model.consultant_uuid == attributes['consultant'])&\ (checkin_model.completed == 'True'))) weights = { "default": next((x.value for x in weights if x.name == 'default'), 1), "active_contract": next((x.value for x in weights if x.name == 'active_contract'), 5), "active_consultant": next((x.value for x in weights if x.name ==\ 'active_contract_for_consultant'), 10), "yesterday": next((x.value for x in weights if x.name == 'yesterday'), 3), "two_days_ago": next((x.value for x in weights if x.name == 'two_days_ago'), 2), "email_sent": next((x.value for x in weights if x.name == 'email_sent'), 10), "email_received": next((x.value for x in weights if x.name == 'email_received'), 5) } entries = [] for customer in customers: print("Customer: ", customer) print("CustomerId: ", customer.uuid) weight = weights['default'] active_contracts = list(contract_model.scan((contract_model.customerId ==\ int(customer.registrationNo)) &\ (contract_model.active == 'True'))) if active_contracts: for contract in active_contracts: weight *= weights['active_contract'] consultant = list(filter(lambda x: x['uuid'] == attributes['consultant'],\ json.loads(contract.consultants))) if consultant: weight *= weights['active_consultant'] for checkin in checkins: weight = calc_weight(customer, checkin, date, date_datetime, weight, weights) entries.append(create_entrie(customer.uuid, weight)) send_entries = sqs_client.send_message( QueueUrl=os.environ['CHECKIN_ACTION_URL'], MessageBody='Prediction', MessageAttributes=write_message(attributes['consultant'], Types.Prediction, checkin_id=attributes['checkin-id'], payload=entries), MessageDeduplicationId=str(uuid.uuid4()).replace('-', '_'), MessageGroupId='Prediction') print(send_entries)