def execute_operation( self, user, workflow: Optional[models.Workflow] = None, action: Optional[models.Action] = None, payload: Optional[Dict] = None, log_item: Optional[models.Log] = None, ): """Send the personalized JSON objects to the given URL.""" if log_item is None: log_item = action.log(user, self.log_event, **payload) action_evals = evaluate_action( action, column_name=action.workflow.columns.get( pk=payload['item_column']).name, exclude_values=payload.get('exclude_values', []), ) # Create the headers to use for all requests headers = { 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Authorization': 'Bearer {0}'.format(payload['token']), } # Iterate over all json objects to create the strings and check for # correctness for json_string, _ in action_evals: _send_and_log_json(user, action, json.loads(json_string), headers) action.last_executed_log = log_item action.save(update_fields=['last_executed_log']) # Update excluded items in payload self._update_excluded_items( payload, [column_value for __, column_value in action_evals])
def execute_operation( self, user, workflow: Optional[models.Workflow] = None, action: Optional[models.Action] = None, payload: Optional[Dict] = None, log_item: Optional[models.Log] = None, ): """Send CANVAS emails with the action content evaluated for each row. Performs the submission of the emails for the given action and with the given subject. The subject will be evaluated also with respect to the rows, attributes, and conditions. :param user: User object that executed the action :param workflow: Workflow being processed :param action: Action from where to take the messages :param log_item: Log object to store results :param payload: Dictionary with all the parameters :return: Nothing """ # Evaluate the action string, evaluate the subject, and get the value # of the email column. if log_item is None: log_item = action.log(user, self.log_event, **payload) item_column = action.workflow.columns.get(pk=payload['item_column']) action_evals = evaluate_action( action, extra_string=payload['subject'], column_name=item_column.name, exclude_values=payload.get('exclude_values', [])) # Get the oauth info target_url = payload['target_url'] oauth_info = settings.CANVAS_INFO_DICT.get(target_url) if not oauth_info: raise Exception(_('Unable to find OAuth Information Record')) # Get the token user_token = models.OAuthUserToken.objects.filter( user=user, instance_name=target_url, ).first() if not user_token: # There is no token, execution cannot proceed raise Exception(_('Incorrect execution due to absence of token')) # Create the headers to use for all requests headers = { 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Authorization': 'Bearer {0}'.format(user_token.access_token), } # Create the context for the log events context = {'action': action.id} # Send the objects to the given URL idx = 1 burst = oauth_info['aux_params'].get('burst') burst_pause = oauth_info['aux_params'].get('pause', 0) domain = oauth_info['domain_port'] conversation_url = oauth_info['conversation_url'].format(domain) to_emails = [] for msg_body, msg_subject, msg_to in action_evals: # JSON object to send. Taken from method.conversations.create in # https://canvas.instructure.com/doc/api/conversations.html canvas_email_payload = { 'recipients[]': int(msg_to), 'body': msg_body, 'subject': msg_subject, 'force_new': True, } # Manage the bursts _do_burst_pause(burst, burst_pause, idx) # Index to detect bursts idx += 1 # Send the email result_msg, response_status = _send_single_canvas_message( conversation_url, canvas_email_payload, headers, oauth_info, ) if settings.ONTASK_TESTING: # Print the sent JSON LOGGER.info( 'SEND JSON(%s): %s', target_url, json.dumps(canvas_email_payload)) result_msg = 'SENT TO LOGGER' response_status = 200 # Log message sent context['subject'] = canvas_email_payload['subject'] context['body'] = canvas_email_payload['body'] context['from_email'] = user.email context['to_email'] = canvas_email_payload['recipients[]'] context['email_sent_datetime'] = str( datetime.datetime.now(pytz.timezone(settings.TIME_ZONE))) context['response_status'] = response_status context['result_msg'] = result_msg action.log( user, models.Log.ACTION_CANVAS_EMAIL_SENT, **context) to_emails.append(msg_to) action.last_executed_log = log_item action.save(update_fields=['last_executed_log']) # Update excluded items in payload self._update_excluded_items(payload, to_emails)