From 40da6892c0b15c2e95a7b2db85247a7a5c4f9799 Mon Sep 17 00:00:00 2001 From: Tahiru Abdullai Date: Tue, 10 Dec 2024 10:34:00 +0000 Subject: [PATCH] Refactor: Update email tagging in nudges and add new report functionality - Modified `generate_email_tag` function to include a development mode tag when not in production. - Updated email tagging in `cadmin_events_nudge.py`, `cadmin_testimonial_nudge.py`, and `user_event_nudge.py` to use constants from `type_constants.py`. - Introduced `postmark_nudge_report.py` to generate and send CSV reports for nudge statistics using Postmark API. --- src/api/utils/api_utils.py | 11 +- src/task_queue/nudges/cadmin_events_nudge.py | 4 +- .../nudges/cadmin_testimonial_nudge.py | 4 +- .../nudges/postmark_nudge_report.py | 107 ++++++++++++++++++ src/task_queue/nudges/user_event_nudge.py | 3 +- src/task_queue/type_constants.py | 5 + 6 files changed, 125 insertions(+), 9 deletions(-) diff --git a/src/api/utils/api_utils.py b/src/api/utils/api_utils.py index b3beb4e74..0f30c063c 100644 --- a/src/api/utils/api_utils.py +++ b/src/api/utils/api_utils.py @@ -4,6 +4,7 @@ from math import atan2, cos, radians, sin, sqrt from django.utils.text import slugify +from _main_.settings import IS_PROD from _main_.utils.constants import COMMUNITY_URL_ROOT, DEFAULT_SOURCE_LANGUAGE_CODE from _main_.utils.utils import load_json from apps__campaigns.models import CallToAction, Section @@ -401,8 +402,8 @@ def create_unique_slug(title, model, field_name="slug", user_defined_slug=None): return f"{slug}-{timestamp}".lower() -def generate_email_tag(name, email_type): - return f"{name}__{email_type}" - - - +def generate_email_tag(subdomain, nudge_name): + tag = f"{subdomain}||{nudge_name}" + if not IS_PROD: + return tag+ "##DEV_MODE" + return tag \ No newline at end of file diff --git a/src/task_queue/nudges/cadmin_events_nudge.py b/src/task_queue/nudges/cadmin_events_nudge.py index bffd6b2b0..f776c0072 100644 --- a/src/task_queue/nudges/cadmin_events_nudge.py +++ b/src/task_queue/nudges/cadmin_events_nudge.py @@ -12,6 +12,7 @@ from task_queue.helpers import get_event_location from task_queue.nudges.nudge_utils import get_admin_email_list, update_last_notification_dates from _main_.utils.massenergize_logger import log +from task_queue.type_constants import CADMIN_EVENTS_NUDGE @@ -170,9 +171,8 @@ def send_events_report(name, email, event_list, com) -> bool: data["change_preference_link"] = change_preference_link data["events"] = event_list - tag = generate_email_tag(com.subdomain, "CadminEventsNudge") + tag = generate_email_tag(com.subdomain, CADMIN_EVENTS_NUDGE) - # sent from MassEnergize to cadmins send_massenergize_email_with_attachments(WEEKLY_EVENTS_NUDGE_TEMPLATE, data, [email], None, None, None, tag) return True except Exception as e: diff --git a/src/task_queue/nudges/cadmin_testimonial_nudge.py b/src/task_queue/nudges/cadmin_testimonial_nudge.py index 5585c4841..40efbc234 100644 --- a/src/task_queue/nudges/cadmin_testimonial_nudge.py +++ b/src/task_queue/nudges/cadmin_testimonial_nudge.py @@ -13,6 +13,8 @@ from django.db.models import Q from django.utils import timezone +from task_queue.type_constants import CADMIN_TESTIMONIALS_NUDGE + TESTIMONIAL_NUDGE_KEY = "cadmin_testimonial_nudge" @@ -80,7 +82,7 @@ def send_nudge(data, community, admin): cred = encode_data_for_URL({"email": email, "login_method": login_method}) data["change_preference_link"] = f"{ADMIN_URL_ROOT}/admin/profile/preferences/?cred={cred}" - tag = generate_email_tag(community.subdomain, "CadminTestimonialsNudge") + tag = generate_email_tag(community.subdomain, CADMIN_TESTIMONIALS_NUDGE) send_massenergize_email_with_attachments(CADMIN_TESTIMONIAL_NUDGE_TEMPLATE, data, [email], None, None, get_sender_email(community.id), tag) diff --git a/src/task_queue/nudges/postmark_nudge_report.py b/src/task_queue/nudges/postmark_nudge_report.py index e69de29bb..39a8007d1 100644 --- a/src/task_queue/nudges/postmark_nudge_report.py +++ b/src/task_queue/nudges/postmark_nudge_report.py @@ -0,0 +1,107 @@ +import csv +import os +from django.http import HttpResponse +import requests +from _main_.settings import POSTMARK_ACCOUNT_TOKEN, POSTMARK_EMAIL_SERVER_TOKEN +from _main_.utils.emailer.send_email import send_massenergize_email_with_attachments +from _main_.utils.utils import is_test_mode +from django.utils import timezone + +from api.utils.api_utils import generate_email_tag +from api.utils.constants import DATA_DOWNLOAD_TEMPLATE +from database.models import Community +from task_queue.type_constants import CADMIN_EVENTS_NUDGE, CADMIN_TESTIMONIALS_NUDGE, USER_EVENTS_NUDGE + + +def get_stats_from_postmark(tag, start, end): + + + url = f"https://api.postmarkapp.com/stats/outbound?fromdate={start}&todate={end}" + if is_test_mode(): + return + headers = {"Accept": "application/json","X-Postmark-Server-Token": POSTMARK_EMAIL_SERVER_TOKEN} + response = requests.get(url, headers=headers) + return response + + + +def main(period=250): + ''' + 2. number of requests to change communication preference per nudge per community + date: 2024-01-31 yyyy-mm-dd + ''' + if not isinstance(period, int): + period = 30 + + today = timezone.now().date() + start_date = today - timezone.timedelta(days=period) + + communities = Community.objects.filter(is_published=True, is_deleted=False, subdomain="wayland") + + for com in communities: + cadmin_event_nudge_tag = generate_email_tag(com.subdomain, CADMIN_EVENTS_NUDGE) + cadmin_testimonials_nudge_tag = generate_email_tag(com.subdomain, CADMIN_TESTIMONIALS_NUDGE) + user_event_nudge_tag = generate_email_tag(com.subdomain, USER_EVENTS_NUDGE) + + cadmin_event_nudge_res = get_stats_from_postmark(cadmin_event_nudge_tag, start_date, today) + cadmin_testimonials_nudge_res = get_stats_from_postmark(cadmin_testimonials_nudge_tag, start_date, today) + user_event_nudge_res = get_stats_from_postmark(user_event_nudge_tag, start_date, today) + + rows = [ + ["Nudge", "Total Sent", "Number of emails opened by unique users","Number of delivery failures (bounces)", "Number of spam complaints", "Number of clicks on content in emails", "Number of actual unsubscribes", "change communication preferences"], + ["Community Admin Events Nudge", + cadmin_event_nudge_res.json()["Sent"], + cadmin_event_nudge_res.json()["UniqueOpens"], + cadmin_event_nudge_res.json()["Bounced"], + cadmin_event_nudge_res.json()["SpamComplaints"], + cadmin_event_nudge_res.json()["TotalClicks"], + 0, + 0], + ["Community Admin Testimonials Nudge", + cadmin_testimonials_nudge_res.json()["Sent"], + cadmin_testimonials_nudge_res.json()["UniqueOpens"], + cadmin_testimonials_nudge_res.json()["Bounced"], + cadmin_testimonials_nudge_res.json()["SpamComplaints"], + cadmin_testimonials_nudge_res.json()["TotalClicks"], + 0, + 0], + ["User Events Nudge", + user_event_nudge_res.json()["Sent"], + user_event_nudge_res.json()["UniqueOpens"], + user_event_nudge_res.json()["Bounced"], + user_event_nudge_res.json()["SpamComplaints"], + user_event_nudge_res.json()["TotalClicks"], + 0, + 0] + ] + + response = HttpResponse(content_type="text/csv") + writer = csv.writer(response) + for row in rows: + writer.writerow(row) + + # Format filename + filename = f"{com.name} Nudge Report {start_date.strftime('%B %d, %Y')} to {today.strftime('%B %d, %Y')}.csv" + + # Send email with CSV attachment + temp_data = { + 'data_type': 'Nudge Report', + 'name': 'Admin' + } + + send_massenergize_email_with_attachments( + DATA_DOWNLOAD_TEMPLATE, + temp_data, + ["abdullai.tahiru@gmail.com"], + response.content, + filename, + None + ) + + + + + +''' +from task_queue.nudges.postmark_nudge_report import main +''' \ No newline at end of file diff --git a/src/task_queue/nudges/user_event_nudge.py b/src/task_queue/nudges/user_event_nudge.py index 68c32570e..7bb2e8d63 100644 --- a/src/task_queue/nudges/user_event_nudge.py +++ b/src/task_queue/nudges/user_event_nudge.py @@ -17,6 +17,7 @@ from task_queue.helpers import get_event_location from task_queue.nudges.nudge_utils import USER_PREFERENCE_DEFAULTS, WEEKLY, BI_WEEKLY, MONTHLY, DAILY, DEFAULT_EVENT_SETTINGS, LIMIT, EASTERN_TIME_ZONE +from task_queue.type_constants import USER_EVENTS_NUDGE @@ -234,7 +235,7 @@ def send_events_report_email(name, email, event_list, comm, login_method=""): data["cadmin_email"] = comm.owner_email if comm.owner_email else "" data["community"] = comm.name from_email = get_sender_email(comm.id) - tag = generate_email_tag(comm.subdomain, "UserEventsNudge") + tag = generate_email_tag(comm.subdomain, USER_EVENTS_NUDGE) send_massenergize_email_with_attachments(USER_EVENTS_NUDGE_TEMPLATE, data, [email], None, None, from_email, tag) print("Email sent to " + email) return True diff --git a/src/task_queue/type_constants.py b/src/task_queue/type_constants.py index 344db4fe4..c3a660b8d 100644 --- a/src/task_queue/type_constants.py +++ b/src/task_queue/type_constants.py @@ -41,3 +41,8 @@ class TaskStatus(TypeConstants): "ONE_OFF":'ONE_OFF', "EVERY_WEEK":'EVERY_WEEK' } + + +USER_EVENTS_NUDGE = "user_event_nudge" +CADMIN_EVENTS_NUDGE = "community_admin_events_nudge" +CADMIN_TESTIMONIALS_NUDGE = "community_admin_testimonials_nudge" \ No newline at end of file