-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add nudge braze email using commands #388
Merged
Merged
Changes from 1 commit
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
c735a39
feat: add nudge braze email using commands
brobro10000 03ff109
chore: PR feedback
brobro10000 60b62a1
Merge branch 'main' of github.com:openedx/enterprise-access into hu/e…
brobro10000 e1d2c2d
feat: Nudge API
brobro10000 197af37
chore: PR feedback 2
brobro10000 937d012
chore: Additional logging and exception handling
brobro10000 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
135 changes: 135 additions & 0 deletions
135
...se_access/apps/content_assignments/management/commands/automatically_nudge_assignments.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
""" | ||
Management command to automatically nudge learners enrolled in a course in advance | ||
""" | ||
|
||
import datetime | ||
import logging | ||
|
||
from django.core.management.base import BaseCommand | ||
from django.core.paginator import Paginator | ||
from django.utils import timezone | ||
|
||
from enterprise_access.apps.content_assignments.api import send_reminder_email_for_pending_assignment | ||
from enterprise_access.apps.content_assignments.constants import LearnerContentAssignmentStateChoices | ||
from enterprise_access.apps.content_assignments.content_metadata_api import get_content_metadata_for_assignments | ||
from enterprise_access.apps.content_assignments.models import AssignmentConfiguration | ||
from enterprise_access.apps.content_assignments.utils import are_dates_matching_with_day_offset | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class Command(BaseCommand): | ||
""" | ||
Automatically nudge learners who are 'days_before_course_start_date' days away from the course start_date | ||
The default notification lead time without a provided `days_before_course_start_date` argument is 30 days | ||
""" | ||
help = ( | ||
'Spin off celery tasks to automatically send a braze email to ' | ||
'remind learners about an upcoming accepted assignment a certain number ' | ||
'of days in advanced determined by the "days_before_course_start_date" argument' | ||
) | ||
|
||
def add_arguments(self, parser): | ||
""" | ||
Entry point to add arguments. | ||
""" | ||
parser.add_argument( | ||
'--dry-run', | ||
action='store_true', | ||
dest='dry_run', | ||
default=False, | ||
help='Dry Run, print log messages without spawning the celery tasks.', | ||
) | ||
parser.add_argument( | ||
'--days_before_course_start_date', | ||
action='store_true', | ||
dest='days_before_course_start_date', | ||
default=30, | ||
help='The amount of days before the course start date to send a nudge email through braze', | ||
) | ||
|
||
@staticmethod | ||
def to_datetime(value): | ||
""" | ||
Return a datetime object of `value` if it is a str. | ||
""" | ||
if isinstance(value, str): | ||
return datetime.datetime.strptime( | ||
value, | ||
"%Y-%m-%dT%H:%M:%SZ" | ||
).replace( | ||
tzinfo=datetime.timezone.utc | ||
) | ||
|
||
return value | ||
|
||
def handle(self, *args, **options): | ||
dry_run = options['dry_run'] | ||
days_before_course_start_date = options['days_before_course_start_date'] | ||
|
||
for assignment_configuration in AssignmentConfiguration.objects.filter(active=True): | ||
subsidy_access_policy = assignment_configuration.subsidy_access_policy | ||
enterprise_catalog_uuid = subsidy_access_policy.catalog_uuid | ||
|
||
message = ( | ||
'[AUTOMATICALLY_REMIND_ACCEPTED_ASSIGNMENTS_1] Assignment Configuration. UUID: [%s], ' | ||
'Policy: [%s], Catalog: [%s], Enterprise: [%s], dry_run [%s]', | ||
) | ||
logger.info( | ||
message, | ||
assignment_configuration.uuid, | ||
subsidy_access_policy.uuid, | ||
enterprise_catalog_uuid, | ||
assignment_configuration.enterprise_customer_uuid, | ||
dry_run, | ||
) | ||
|
||
accepted_assignments = assignment_configuration.assignments.filter( | ||
state=LearnerContentAssignmentStateChoices.ACCEPTED | ||
brobro10000 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
|
||
paginator = Paginator(accepted_assignments, 100) | ||
for page_number in paginator.page_range: | ||
assignments = paginator.page(page_number) | ||
|
||
content_metadata_for_assignments = get_content_metadata_for_assignments( | ||
enterprise_catalog_uuid, | ||
assignments | ||
) | ||
|
||
for assignment in assignments: | ||
content_metadata = content_metadata_for_assignments.get(assignment.content_key, {}) | ||
start_date = content_metadata.get('normalized_metadata', {}).get('start_date') | ||
course_type = content_metadata.get('course_type') | ||
|
||
is_executive_education_course_type = course_type in ( | ||
'executive-education-2u', 'executive-education') | ||
brobro10000 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Determine if the date from today + days_before_course_state_date is | ||
# equal to the date of the start date | ||
# If they are equal, then send the nudge email, otherwise continue | ||
datetime_start_date = self.to_datetime(start_date) | ||
brobro10000 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
can_send_nudge_notification_in_advance = are_dates_matching_with_day_offset( | ||
days_offset=days_before_course_start_date, | ||
target_date=datetime_start_date, | ||
date_to_offset=timezone.now(), | ||
) | ||
|
||
if is_executive_education_course_type and can_send_nudge_notification_in_advance: | ||
message = ( | ||
'[AUTOMATICALLY_REMIND_ACCEPTED_ASSIGNMENTS_2] assignment_configuration_uuid: [%s], ' | ||
'start_date: [%s], datetime_start_date: [%s], ' | ||
'days_before_course_start_date: [%s], can_send_nudge_notification_in_advance: [%s], ' | ||
'course_type: [%s], dry_run [%s]' | ||
) | ||
logger.info(message, | ||
assignment_configuration.uuid, | ||
start_date, | ||
datetime_start_date, | ||
days_before_course_start_date, | ||
can_send_nudge_notification_in_advance, | ||
course_type, | ||
dry_run, | ||
) | ||
brobro10000 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if not dry_run: | ||
send_reminder_email_for_pending_assignment.delay(assignment.uuid) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noticed a typo in this constant, refactored all cases where its used with the correct spelling for the value and variable