"""Email logic.""" import json from botocore.exceptions import ClientError from podcast import config from podcast.connectors import sqs from podcast.logic import url from podcast.models import ad_action as ad_action_model from podcast.models import ad_action_comment as ad_action_comment_model from podcast.models import campaign as campaign_model from podcast.models import episode as episode_model from podcast.models import order as order_model from podcast.models import podcast as podcast_model from podcast.models import user as user_model from podcast.models import user_podcast_settings as user_podcast_settings_model from podcast.utils.exc import OwsError def send_podcast_spike_email(user, data): """Send an email when a spike happens.""" _send_message(user, { 'subject': '[Spike Detected] {} trending episodes on your show'.format(len(data['episode_spikes'])), 'to': [user['email']], 'template': 'podcast_episode_spike', 'variables': data }, _get_settings_info(user['id'], 'spike_notifications')) def send_transcription_finished(transcription): """Send an email when a transcription finishes.""" user = user_model.get_user_by_id(transcription.created_by) episode = episode_model.get_episode_by_id(transcription.episode_id) podcast = podcast_model.get_podcast_by_id(episode['podcast_id']) _send_message(user, { 'subject': '[{podcast_name} - Update] Audio Transcription for an episode is complete', 'subject_variables': {'podcast_name': podcast['title']}, 'to': [user['email']], 'template': 'transcription_finished', 'variables': { 'name': user['name'], 'podcast_name': podcast['title'], 'episode_name': episode['title'], 'transcription_url': url.edit_transcription_via_email(episode['podcast_id'], episode['id']), }, }, _get_settings_info(user['id'], 'transcription_notifications')) def send_ad_due_tomorrow(ad_action): """Send an email when an ad is due tomorrow. Args: ad_action (dict): an ad action """ assignees, reporter, updated_by = _get_ad_action_users(ad_action) campaigns = campaign_model.get_campaigns_by_megaphone_ids([ad_action['campaign_id']]) order = order_model.get_order_by_megaphone_id(ad_action['order_id']) if len(campaigns): variables = { 'reporter_name': reporter['name'] if reporter else 'Deleted User', 'campaign_name': campaigns[0]['name'], 'order_name': order['name'], 'roll_type': ad_action['roll_type'] } for assignee in assignees: variables['name'] = assignee['name'] variables['host_read_ads_url'] = url.host_read_ads_via_email(assignee['organization']) _send_message(assignee, { 'subject': '[Host-Read Ad] A request is due in 24 hours', 'to': [assignee['email']], 'template': 'host_read_ad_due_tomorrow', 'variables': variables, }, _get_settings_info(assignee['id'], 'ad_notifications')) if reporter: variables['name'] = reporter['name'] variables['host_read_ads_url'] = url.host_read_ads_via_email(reporter['organization']) _send_message(reporter, { 'subject': '[Host-Read Ad] A request is due in 24 hours', 'to': [reporter['email']], 'template': 'host_read_ad_due_tomorrow', 'variables': variables, }, _get_settings_info(reporter['id'], 'ad_notifications')) else: raise OwsError.not_found() def send_ad_past_due(ad_action): """Send an email when an ad is overdue. Args: ad_action (dict): an ad action """ assignees, reporter, updated_by = _get_ad_action_users(ad_action) for assignee in assignees: _send_message(assignee, { 'subject': "[Host-Read Ad] A request is past it's due date", 'to': [assignee['email']], 'template': 'host_read_ad_past_due', 'variables': { 'name': assignee['name'], 'reporter_name': reporter['name'] if reporter else 'Deleted User', 'host_read_ads_url': url.host_read_ads_via_email(assignee['organization']), }, }, _get_settings_info(assignee['id'], 'ad_notifications')) def send_ad_action_assigned_to_me(ad_action): """Send an email when an ad action is assigned. Args: ad_action (dict): an ad action """ assignees, reporter, updated_by = _get_ad_action_users(ad_action) for assignee in assignees: _send_message(assignee, { 'subject': '[Host-Read Ad] A request has been assigned to you', 'to': [assignee['email']], 'template': 'host_read_ad_assigned', 'variables': { 'name': assignee['name'], 'reporter_name': reporter['name'] if reporter else 'Deleted User', 'due_date': ad_action['due_date'].strftime('%m/%d/%Y'), 'host_read_ads_url': url.host_read_ads_via_email(assignee['organization']), }, }, 'ad_notifications') def send_ad_action_submitted(ad_action): """Send an email when an ad action is submitted. Args: ad_action (dict): an ad action """ assignees, reporter, updated_by = _get_ad_action_users(ad_action) if reporter: subject_append_text = ' - please approve' if ad_action['requires_approval'] else '' _send_message(reporter, { 'subject': '[Host-Read Ad] Audio has been uploaded{}'.format(subject_append_text), 'to': [reporter['email']], 'template': 'host_read_ad_submitted', 'variables': { 'assignee_name': updated_by['name'] if updated_by else 'Deleted User', 'reporter_name': reporter['name'], 'ad_read_title': ad_action['title'], 'requires_approval': ad_action['requires_approval'], 'host_read_ads_url': url.host_read_ads_via_email(reporter['organization']), }, }, _get_settings_info(reporter['id'], 'ad_notifications')) def send_ad_action_approved(ad_action): """Send an email when an ad action is approved. Args: ad_action (dict): an ad action """ assignees, reporter, updated_by = _get_ad_action_users(ad_action) for assignee in assignees: _send_message(assignee, { 'subject': '[Host-Read Ad] Your upload was approved', 'to': [assignee['email']], 'template': 'host_read_ad_approved', 'variables': { 'name': assignee['name'], 'reporter_name': reporter['name'] if reporter else 'Deleted User', 'ad_read_title': ad_action['title'] }, }, _get_settings_info(assignee['id'], 'ad_notifications')) def send_ad_action_rejected(ad_action): """Send an email when an ad action is rejected. Args: ad_action (dict): an ad action """ assignees, reporter, updated_by = _get_ad_action_users(ad_action) for assignee in assignees: _send_message(assignee, { 'subject': '[Host-Read Ad] Your upload was rejected', 'to': [assignee['email']], 'template': 'host_read_ad_rejected', 'variables': { 'name': assignee['name'], 'reporter_name': reporter['name'] if reporter else 'Deleted User', 'host_read_ads_url': url.host_read_ads_via_email(assignee['organization']), 'ad_read_title': ad_action['title'], 'ad_read_rejection': ad_action['rejection_reason'], 'due_date': ad_action['due_date'].strftime('%m/%d/%Y') }, }, _get_settings_info(assignee['id'], 'ad_notifications')) def send_ad_action_assigned_to_me_deleted(ad_action): """Send an email when an ad action assigned to user is deleted. Args: ad_action (dict): an ad action """ assignees, reporter, updated_by = _get_ad_action_users(ad_action) for assignee in assignees: _send_message(assignee, { 'subject': '[Host-Read Ad] Your ad request has been deleted', 'to': [assignee['email']], 'template': 'host_read_ad_deleted', 'variables': { 'name': assignee['name'], 'reporter_name': reporter['name'] if reporter else 'Deleted User', 'deleted_by': updated_by['name'] if updated_by else 'Deleted User' }, }, 'ad_notifications') def send_assignees_updated_on_ad_action_assigned_to_me(ad_action): """Send an email when an assignees are updated on an assigned ad action. Args: ad_action (dict): an ad action """ assignees, reporter, updated_by = _get_ad_action_users(ad_action) assignees_names = [assignee['name'] if assignee else 'Deleted User' for assignee in assignees] for assignee in assignees: _send_message(assignee, { 'subject': '[Host-Read Ad] Your requests assignees have been updated', 'to': [assignee['email']], 'template': 'host_read_ad_assignees_updated', 'variables': { 'name': assignee['name'], 'assignees_names': assignees_names, 'reporter_name': reporter['name'] if reporter else 'Deleted User', 'due_date': ad_action['due_date'].strftime('%m/%d/%Y'), 'host_read_ads_url': url.host_read_ads_via_email(assignee['organization']), }, }, 'ad_notifications') def send_due_date_updated_on_ad_action_assigned_to_me(ad_action): """Send an email when an due date is updated on an assigned ad action. Args: ad_action (dict): an ad action """ assignees, reporter, updated_by = _get_ad_action_users(ad_action) for assignee in assignees: _send_message(assignee, { 'subject': '[Host-Read Ad] Your requests due date has been updated', 'to': [assignee['email']], 'template': 'host_read_ad_due_date_updated', 'variables': { 'name': assignee['name'], 'reporter_name': reporter['name'] if reporter else 'Deleted User', 'due_date': ad_action['due_date'].strftime('%m/%d/%Y'), 'host_read_ads_url': url.host_read_ads_via_email(assignee['organization']), }, }, 'ad_notifications') def send_script_updated_on_ad_action_assigned_to_me(ad_action): """Send an email when an script is updated on an assigned ad action. Args: ad_action (dict): an ad action """ assignees, reporter, updated_by = _get_ad_action_users(ad_action) for assignee in assignees: _send_message(assignee, { 'subject': '[Host-Read Ad] A new script has been uploaded', 'to': [assignee['email']], 'template': 'host_read_ad_script_updated', 'variables': { 'name': assignee['name'], 'reporter_name': reporter['name'] if reporter else 'Deleted User', 'due_date': ad_action['due_date'].strftime('%m/%d/%Y'), 'host_read_ads_url': url.host_read_ads_via_email(assignee['organization']), }, }, 'ad_notifications') def send_new_ad_action_comment(ad_action_id, ad_action_new_comment, current_user_id): """Send an email when new comment is added on ad action. Args: ad_action_id (int): an ad action id ad_action_new_comment (dict): an ad action comment """ ad_action = ad_action_model.get_ad_action_no_assets(ad_action_id) participants, commentor = _get_ad_action_participants(ad_action, ad_action_new_comment, current_user_id) for participant in participants: _send_message(participant, { 'subject': '[Host-Read Ad] New comment on ad request: {}'.format(ad_action['title']), 'to': [participant['email']], 'template': 'host_read_ad_new_comment', 'variables': { 'name': participant['name'], 'host_read_ad_name': ad_action['title'], 'host_read_ad_commentor': commentor['name'] if commentor else 'Deleted participant', 'host_read_ad_comment': ad_action_new_comment['comment'], 'host_read_ads_url': url.host_read_ads_via_email(participant['organization']), }, }, 'ad_notifications') def send_episode_scheduled(episode): """Send an email when an episode is scheduled. Args: episode (dict): an episode """ podcast = podcast_model.get_podcast_by_id(episode['podcast_id'], True) for user_obj in podcast.favorited_users: user = user_obj.to_dict() _send_message(user, { 'subject': '[{podcast_name} - Update] An Episode is scheduled to go live', 'subject_variables': {'podcast_name': podcast.title}, 'to': [user['email']], 'template': 'favorite_podcast_episode_scheduled', 'variables': { 'name': user['name'], 'episode_name': episode['title'], 'podcast_name': podcast.title, 'edit_episode_url': url.edit_episode_via_email(episode['podcast_id'], episode['id']), 'published_date': episode['published_date'].strftime('%m/%d/%Y %-I:%M%p UTC') }, }, _get_settings_info(user['id'], 'podcast_notifications')) def send_episode_live(episode, podcast, user): """Send an email when an episode has gone live.""" _send_message(user, { 'subject': '[{podcast_name} - Update] An Episode is published', 'subject_variables': {'podcast_name': podcast['title']}, 'to': [user['email']], 'template': 'favorite_podcast_episode_live', 'variables': { 'name': user['name'], 'episode_name': episode['title'], 'podcast_name': podcast['title'], 'published_date': episode['published_date'].strftime('%m/%d/%Y %-I:%M%p UTC') }, }, _get_settings_info(user['id'], 'podcast_notifications')) def send_episode_live_tomorrow(episode, podcast, user): """Send an email when an episode will go live tomorrow.""" _send_message(user, { 'subject': '[{podcast_name} - Update] An Episode is scheduled to go live tomorrow', 'subject_variables': {'podcast_name': podcast['title']}, 'to': [user['email']], 'template': 'favorite_podcast_episode_live_tomorrow', 'variables': { 'name': user['name'], 'episode_name': episode['title'], 'podcast_name': podcast['title'], 'published_date': episode['published_date'].strftime('%-I:%M%p UTC'), 'edit_episode_url': url.edit_episode_via_email(episode['podcast_id'], episode['id']), }, }, _get_settings_info(user['id'], 'podcast_notifications')) def _send_message(user, message, send_message): if not send_message: return message['type'] = 'GeneralNotification' message['sender'] = _get_sender(user) message['lang'] = user['language'] message['user_id'] = user['id'] message['variables']['organization'] = user['organization'] message['variables']['unsubscribe_url'] = url.settings_via_email() _send_sqs(message) def _send_sqs(message): """Send an email message. Args: user (dict): user to send the message to. message (dict): sqs message body Returns: Response: Response with success or error. """ try: sqs_client = sqs.get_sqs_client() return sqs_client.send_message( QueueUrl=config.DAEMON_NOTIFICATIONS_QUEUE_URL, MessageBody=json.dumps(message), DelaySeconds=0) except ClientError as e: error_message = 'Error sending messages {queue}: {message}'.format( queue=config.DAEMON_NOTIFICATIONS_QUEUE_URL, message=message) raise OwsError.from_boto3_client_error(e, error_message) def _get_sender(user): if config.IS_DEV: return 'ratoui@dev.theorchard.io' if user['organization'] == 'sme': return '"Sony Music Podcasts" ' return '"The Orchard Podcasts" ' def _get_ad_action_users(ad_action): ids = [*ad_action['assignee_ids'], ad_action['created_by'], ad_action['updated_by']] users = user_model.get_users_by_ids(ids, is_only_users=True)['items'] assignees = [x for x in users if x['id'] in ad_action['assignee_ids']] reporter = next((x for x in users if x['id'] == ad_action['created_by']), None) updated_by = next((x for x in users if x['id'] == ad_action['updated_by']), None) return [assignees, reporter, updated_by] def _get_ad_action_participants(ad_action, ad_action_new_comment, current_user_id): """Return all the users who are related to the ad action excluding the commentor. Users includes producers and reporter of the ad action. Also, anyone who has previously commented on the ad action. """ comments = ad_action_comment_model.get_ad_action_comments(ad_action['id'], 9999, 0)['items'] commentors_ids = [comment['created_by'] for comment in comments] ad_action_participant_ids = list(set((*ad_action['assignee_ids'], ad_action['created_by'], *commentors_ids))) participants = user_model.get_users_by_ids(ad_action_participant_ids, is_only_users=True)['items'] ad_action_participant_ids.remove(current_user_id) ad_action_participants = [x for x in participants if x['id'] in ad_action_participant_ids] commentor = next((x for x in participants if x['id'] == ad_action_new_comment['created_by']), None) return (ad_action_participants, commentor) def _get_settings_info(user_id, notification_type): return user_podcast_settings_model.get_user_settings(user_id)[notification_type]