Skip to content

Commit 72dbfc6

Browse files
committed
feat: update course deadline email cadence and templates
1 parent ab250b5 commit 72dbfc6

5 files changed

Lines changed: 165 additions & 60 deletions

File tree

course_discovery/apps/course_metadata/emails.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -453,10 +453,11 @@ def send_course_deadline_email(course, course_run, recipients, deadline_email_va
453453
html_template = 'course_metadata/email/course_deadline.html'
454454
template = get_template(html_template)
455455
subject_lookup = {
456-
"three_months_reminder": f"Reminder: {course.title} ends in 3 months",
457-
"one_month_reminder": f"Reminder: {course.title} ends in 1 month",
458-
"seven_days_reminder": f"Reminder: {course.title} ends in 7 days",
459-
"course_ended": f"Reminder: {course.title} has ended",
456+
"two_months_reminder": f"Course Availability Reminder: {course.title} Ends in 60 Days",
457+
"one_month_reminder": f"Course Availability Reminder: {course.title} Ends in 30 Days",
458+
"fifteen_days_reminder": f"Course Availability Reminder: {course.title} Ends in 15 Days",
459+
"seven_days_reminder": f"Course Availability Reminder: {course.title} Ends in 7 Days",
460+
"course_ended": f"Reminder: {course.title} has Ended",
460461
}
461462

462463
subject = subject_lookup.get(deadline_email_variant, f"Reminder: {course.title} deadline is approaching")
@@ -467,8 +468,9 @@ def send_course_deadline_email(course, course_run, recipients, deadline_email_va
467468
"course_key": course.key,
468469
"course_end_date": (course_run.end.strftime("%m/%d/%Y") if course_run.end else None),
469470
"days_to_expire": (
470-
"90 days" if deadline_email_variant == "three_months_reminder"
471+
"60 days" if deadline_email_variant == "two_months_reminder"
471472
else "30 days" if deadline_email_variant == "one_month_reminder"
473+
else "15 days" if deadline_email_variant == "fifteen_days_reminder"
472474
else "7 days" if deadline_email_variant == "seven_days_reminder"
473475
else "course_ended"
474476
),

course_discovery/apps/course_metadata/management/commands/send_course_deadline_emails.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from course_discovery.apps.publisher.choices import InternalUserRole
2020
from course_discovery.apps.publisher.models import OrganizationUserRole
2121

22-
EMAIL_DELTA_DAYS = [90, 30, 7, -1]
22+
EMAIL_DELTA_DAYS = [60, 30, 15, 7, -1]
2323
LAST_RUN_END_DELTA = -1
2424

2525
logger = logging.getLogger(__name__)
@@ -29,8 +29,9 @@ class Command(BaseCommand):
2929
help = 'Send course deadline emails to Project Coordinators and Course Editors.'
3030

3131
DEADLINE_VARIANTS = {
32-
90: "three_months_reminder",
32+
60: "two_months_reminder",
3333
30: "one_month_reminder",
34+
15: "fifteen_days_reminder",
3435
7: "seven_days_reminder",
3536
-1: "course_ended",
3637
}

course_discovery/apps/course_metadata/management/commands/tests/test_send_course_deadline_emails.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,9 @@ def test_with_no_course_run_with_end_date_within_range(self):
110110
)
111111

112112
@ddt.data(
113-
(90, "three_months_reminder"),
113+
(60, "two_months_reminder"),
114114
(30, "one_month_reminder"),
115+
(15, "fifteen_days_reminder"),
115116
(7, "seven_days_reminder"),
116117
(-1, "course_ended"),
117118
)
@@ -122,7 +123,7 @@ def test_with_course_run_with_end_date_within_range(
122123
):
123124
"""
124125
Test that the command sends emails when there are advertised course runs with end dates within
125-
the specified range (90, 30, 7, -1 days).
126+
the specified range (60, 30, 15, 7, -1 days).
126127
"""
127128
self.non_draft_course_run.end = timezone.now() + timedelta(days=days_until_end)
128129
self.non_draft_course_run.save()

course_discovery/apps/course_metadata/templates/course_metadata/email/course_deadline.html

Lines changed: 106 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,123 @@
33
{% load django_markup %}
44

55
{% block body %}
6+
67
<p>
78
{% trans "Hi Course Team," %}
89
</p>
910

11+
{% if days_to_expire == '60 days' or days_to_expire == '30 days' or days_to_expire == '15 days' %}
12+
13+
<p>
14+
{% blocktrans with course_name=course_name course_key=course_key course_end_date=course_end_date days=days_to_expire %}
15+
This is an automated reminder that the course "{{ course_name }}" ({{ course_key }}) is scheduled to end in {{ days }} on {{ course_end_date }}.
16+
{% endblocktrans %}
17+
</p>
18+
19+
<p>
20+
{% trans "If no action is taken, the course will be automatically archived after this date. If you decide not to extend the course or create a new run at this time, please inform your dedicated Project Coordinator and share your plans. This helps ensure our internal teams remain aligned and can support you effectively." %}
21+
</p>
22+
23+
<p>
24+
{% trans "To ensure a smooth experience for our edX Learners, please take one of the following actions:" %}
25+
</p>
26+
27+
<ul>
28+
<li>
29+
<strong>{% trans "Create a New Course Run:" %}</strong>
30+
{% trans "Planning to update the content or offer the course to a new cohort? We recommend setting up a new course run in Publisher." %}
31+
{% trans "You can get started" %}
32+
<a href="{{ publisher_url }}courses/{{ course_uuid }}"> {% trans "here" %} </a>.
33+
</li>
34+
35+
<li>
36+
<strong>{% trans "Extend the Course End Date:" %}</strong>
37+
{% trans "If the content is still relevant, you can extend the course end date in Studio." %}
38+
{% trans "Simply visit the Schedule and Details tab" %}
39+
<a href="{{ course_schedule_settings_url }}"> {% trans "here" %} </a>.
40+
</li>
41+
</ul>
42+
43+
{% elif days_to_expire == '7 days' %}
44+
45+
<p>
46+
{% blocktrans with course_name=course_name course_key=course_key course_end_date=course_end_date %}
47+
Our records indicate that the course "{{ course_name }}" (Course Key: {{ course_key }}) is scheduled to end in 7 days on {{ course_end_date }}. Despite previous reminders, we’ve noticed that no action has been taken yet.
48+
{% endblocktrans %}
49+
</p>
50+
51+
<p>
52+
<strong>{% trans "Important:" %}</strong>
53+
{% trans "If no action is taken, the course will be automatically archived after the current end date. If you choose not to extend or create a new course run at this time, you must inform your dedicated Project Coordinator with your reasons. This will ensure our internal teams are properly informed about your plans." %}
54+
</p>
55+
1056
<p>
11-
{% if days_to_expire == '90 days' or days_to_expire == '30 days' or days_to_expire == '7 days' %}
12-
{% blocktrans with course_name=course_name course_key=course_key course_end_date=course_end_date days=days_to_expire %}
13-
This is an automated reminder that the course "{{ course_name }}" (Course Key: {{ course_key }}) is scheduled to end in {{ days }} on {{ course_end_date }}.
14-
{% endblocktrans %}
15-
<p>
16-
{% trans "To ensure uninterrupted learner access and enrollment, please take one of the following actions:" %}
17-
</p>
18-
{% elif days_to_expire == 'course_ended' %}
19-
{% blocktrans with course_name=course_name course_key=course_key course_end_date=course_end_date %}
20-
This is an automated reminder that the course "{{ course_name }}" (Course Key: {{ course_key }}) has officially ended as of {{ course_end_date }}.
21-
{% endblocktrans %}
22-
<p>
23-
{% trans "If this was intentional, no action is needed. However, if this course was meant to remain available, you have two options to restore access:" %}
24-
</p>
25-
{% endif %}
57+
{% trans "To prevent disruption to learner access, please choose one of the following options:" %}
2658
</p>
2759

2860
<ul>
29-
<li>{% trans "Extend the current course run’s end date if the same course is meant to remain available." %}</li>
30-
<li>
31-
{% trans "Create a new course run if you are planning to offer this course again with updated content, pacing, or a new cohort of learners." %}
32-
<a href="{{ publisher_url }}courses/{{ course_uuid }}"> {% trans "Visit the Course in Publisher" %} </a>
33-
</li>
61+
<li>
62+
<strong>{% trans "Create a New Course Run:" %}</strong>
63+
{% trans "Planning to update the content or offer the course to a new cohort? We recommend setting up a new course run in Publisher." %}
64+
{% trans "You can get started" %}
65+
<a href="{{ publisher_url }}courses/{{ course_uuid }}"> {% trans "here" %} </a>.
66+
</li>
67+
68+
<li>
69+
<strong>{% trans "Extend the Course End Date:" %}</strong>
70+
{% trans "If the content is still relevant, you can extend the course end date in Studio." %}
71+
{% trans "Simply visit the Schedule and Details tab" %}
72+
<a href="{{ course_schedule_settings_url }}"> {% trans "here" %} </a>.
73+
</li>
74+
</ul>
75+
76+
{% elif days_to_expire == 'course_ended' %}
77+
78+
<p>
79+
{% blocktrans with course_name=course_name course_key=course_key course_end_date=course_end_date %}
80+
Our records show that the course "{{ course_name }}" (Course Key: {{ course_key }}) officially ended on {{ course_end_date }} and has now entered the archived state. Despite our previous reminders, it appears no action has been taken yet.
81+
{% endblocktrans %}
82+
</p>
83+
84+
<p>
85+
<strong>{% trans "Important:" %}</strong>
86+
{% trans "If you decide not to extend the course or create a new course run at this time, you must inform your dedicated Project Coordinator with the reasons behind this. This will help ensure our internal teams are fully updated on your plans for the course." %}
87+
</p>
88+
89+
<p>
90+
{% trans "If you wish to keep this course active, please choose one of the following options:" %}
91+
</p>
92+
93+
<ul>
94+
<li>
95+
<strong>{% trans "Create a New Course Run:" %}</strong>
96+
{% trans "Planning to update the content or offer the course to a new cohort? We recommend setting up a new course run in Publisher." %}
97+
{% trans "You can get started" %}
98+
<a href="{{ publisher_url }}courses/{{ course_uuid }}"> {% trans "here" %} </a>.
99+
</li>
100+
101+
<li>
102+
<strong>{% trans "Extend the Course End Date:" %}</strong>
103+
{% trans "If the content is still relevant, you can extend the course end date in Studio." %}
104+
{% trans "Simply visit the Schedule and Details tab" %}
105+
<a href="{{ course_schedule_settings_url }}"> {% trans "here" %} </a>.
106+
</li>
34107
</ul>
35108

109+
{% endif %}
110+
111+
<p>
112+
<strong>{% trans "NOTE:" %}</strong>
113+
{% trans "This email address isn’t monitored for replies. If you have any questions or need assistance, please reach out to your dedicated Project Coordinator." %}
114+
</p>
115+
116+
<p>
117+
{% trans "Thank you for your attention to this—looking forward to your updates!" %}
118+
</p>
119+
36120
<p>
37-
{% trans "You can review and modify the course end settings here:" %}
38-
<a href="{{ course_schedule_settings_url }}">{{ course_schedule_settings_url }}</a>
39-
<br/>
40-
{% if days_to_expire == 'course_ended' %}
41-
{% blocktrans with partner_marketing_site_url=partner_marketing_site_url %}
42-
If no action is taken, the course will no longer be available for enrollment or access by learners on
43-
<a href="{{ partner_marketing_site_url }}">{{ partner_marketing_site_url }}</a> after the end date.
44-
{% endblocktrans %}
45-
<br/>
46-
{% endif %}
47-
{% trans "Thanks" %}
121+
{% trans "Best," %}<br/>
122+
{% trans "edX Operational Team" %}
48123
</p>
49124

50-
<!-- End Message Body -->
51125
{% endblock body %}

course_discovery/apps/course_metadata/templates/course_metadata/email/course_deadline.txt

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,60 @@
22

33
{% trans "Hi Course Team," %}
44

5-
{% if days_to_expire == '90 days' or days_to_expire == '30 days' or days_to_expire == '7 days' %}
5+
{% if days_to_expire == '60 days' or days_to_expire == '30 days' or days_to_expire == '15 days' %}
66
{% blocktrans with course_name=course_name course_key=course_key course_end_date=course_end_date days=days_to_expire %}
7-
This is an automated reminder that the course "{{ course_name }}" (Course Key: {{ course_key }}) is scheduled to end in {{ days }} on {{ course_end_date }}.
7+
This is an automated reminder that the course "{{ course_name }}" ({{ course_key }}) is scheduled to end in {{ days }} on {{ course_end_date }}.
88
{% endblocktrans %}
9-
{% elif days_to_expire == 'course_ended' %}
9+
10+
{% trans "If no action is taken, the course will be automatically archived after this date. If you decide not to extend the course or create a new run at this time, please inform your dedicated Project Coordinator and share your plans. This helps ensure our internal teams remain aligned and can support you effectively." %}
11+
12+
{% trans "To ensure a smooth experience for our edX Learners, please take one of the following actions:" %}
13+
14+
- {% trans "Create a New Course Run:" %}
15+
{% trans "Planning to update the content or offer the course to a new cohort? We recommend setting up a new course run in Publisher." %}
16+
{% trans "You can get started here:" %} {{ publisher_url }}courses/{{ course_uuid }}
17+
18+
- {% trans "Extend the Course End Date:" %}
19+
{% trans "If the content is still relevant, you can extend the course end date in Studio." %}
20+
{% trans "Simply visit the Schedule and Details tab here:" %} {{ course_schedule_settings_url }}
21+
22+
{% elif days_to_expire == '7 days' %}
23+
1024
{% blocktrans with course_name=course_name course_key=course_key course_end_date=course_end_date %}
11-
This is an automated reminder that the course "{{ course_name }}" (Course Key: {{ course_key }}) has officially ended as of {{ course_end_date }}.
25+
Our records indicate that the course "{{ course_name }}" (Course Key: {{ course_key }}) is scheduled to end in 7 days on {{ course_end_date }}. Despite previous reminders, we’ve noticed that no action has been taken yet.
1226
{% endblocktrans %}
13-
{% endif %}
1427

15-
{% if days_to_expire == '90 days' or days_to_expire == '30 days' or days_to_expire == '7 days' %}
16-
{% trans "To ensure uninterrupted learner access and enrollment, please take one of the following actions:" %}
17-
{% elif days_to_expire == 'course_ended' %}
18-
{% trans "If this was intentional, no action is needed. However, if this course was meant to remain available, you have two options to restore access:" %}
19-
{% endif %}
28+
{% trans "Important: If no action is taken, the course will be automatically archived after the current end date. If you choose not to extend or create a new course run at this time, you must inform your dedicated Project Coordinator with your reasons. This will ensure our internal teams are properly informed about your plans." %}
29+
30+
{% trans "To prevent disruption to learner access, please choose one of the following options:" %}
2031

21-
- {% trans "Extend the current course run’s end date if the same course is meant to remain available." %}
22-
- {% trans "Create a new course run if you are planning to offer this course again with updated content, pacing, or a new cohort of learners." %}
23-
{% trans "Visit the Course in Publisher:" %} {{ publisher_url }}courses/{{ course_uuid }}
32+
- {% trans "Create a New Course Run:" %}
33+
{{ publisher_url }}courses/{{ course_uuid }}
2434

25-
{% trans "You can review and modify the course end settings here:" %}
26-
{{ course_schedule_settings_url }}
35+
- {% trans "Extend the Course End Date:" %}
36+
{{ course_schedule_settings_url }}
2737

28-
{% if days_to_expire == 'course_ended' %}
29-
{% blocktrans with partner_marketing_site_url=partner_marketing_site_url %}
30-
If no action is taken, the course will no longer be available for enrollment or access by learners on {{ partner_marketing_site_url }} after the end date.
38+
{% elif days_to_expire == 'course_ended' %}
39+
40+
{% blocktrans with course_name=course_name course_key=course_key course_end_date=course_end_date %}
41+
Our records show that the course "{{ course_name }}" (Course Key: {{ course_key }}) officially ended on {{ course_end_date }} and has now entered the archived state. Despite our previous reminders, it appears no action has been taken yet.
3142
{% endblocktrans %}
43+
44+
{% trans "Important: If you decide not to extend the course or create a new course run at this time, you must inform your dedicated Project Coordinator with the reasons behind this. This will help ensure our internal teams are fully updated on your plans for the course." %}
45+
46+
{% trans "If you wish to keep this course active, please choose one of the following options:" %}
47+
48+
- {% trans "Create a New Course Run:" %}
49+
{{ publisher_url }}courses/{{ course_uuid }}
50+
51+
- {% trans "Extend the Course End Date:" %}
52+
{{ course_schedule_settings_url }}
53+
3254
{% endif %}
3355

34-
{% trans "Thanks" %}
56+
{% trans "NOTE: This email address isn’t monitored for replies. If you have any questions or need assistance, please reach out to your dedicated Project Coordinator." %}
57+
58+
{% trans "Thank you for your attention to this—looking forward to your updates!" %}
59+
60+
{% trans "Best," %}
61+
{% trans "edX Operational Team" %}

0 commit comments

Comments
 (0)