def send_learner_survey(application): """ send email to learner with link to survey, if goal is specified, also ask if they achieved their goal """ learner_goal = application.get_signup_questions().get('goals', None) base_url = f'{settings.PROTOCOL}://{settings.DOMAIN}' path = reverse('studygroups_learner_survey', kwargs={'study_group_uuid': application.study_group.uuid}) querystring = '?learner={}'.format(application.uuid) survey_url = base_url + path + querystring facilitator_email = application.study_group.facilitator.email context = { 'learner_name': application.name, 'learner_goal': learner_goal, 'survey_url': survey_url } subject, txt, html = render_email_templates( 'studygroups/email/learner_survey', context) to = [application.email] notification = EmailMultiAlternatives(subject.strip(), txt, settings.DEFAULT_FROM_EMAIL, to, reply_to=[facilitator_email]) notification.attach_alternative(html, 'text/html') notification.send()
def send_reminder(reminder): # mark it as sent, we don't retry any failures reminder.sent_at = timezone.now() reminder.save() to = [ su.email for su in reminder.study_group.application_set.active().filter( accepted_at__isnull=False).exclude(email='') ] if reminder.study_group_meeting: send_meeting_reminder(reminder) else: context = { "reminder": reminder, "facilitator_message": reminder.email_body, "domain": 'https://{0}'.format(settings.DOMAIN), } subject, text_body, html_body = render_email_templates( 'studygroups/email/facilitator_message', context) to += [reminder.study_group.facilitator.email] sender = '{0} <{1}>'.format( reminder.study_group.facilitator.first_name, settings.DEFAULT_FROM_EMAIL) try: reminder_email = EmailMultiAlternatives( reminder.email_subject.strip('\n'), text_body, sender, [], bcc=to, reply_to=[reminder.study_group.facilitator.email], ) reminder_email.attach_alternative(html_body, 'text/html') reminder_email.send() except Exception as e: logger.exception('Could not send reminder to whole study group', exc_info=e) # send SMS if reminder.sms_body != '': applications = reminder.study_group.application_set.active().filter( accepted_at__isnull=False).exclude(mobile='') applications = applications.filter(mobile_opt_out_at__isnull=True) tos = [su.mobile for su in applications] for to in tos: try: send_message(to, reminder.sms_body) except TwilioRestException as e: logger.exception("Could not send text message to %s", to, exc_info=e)
def send_facilitator_survey(study_group): """ send survey to all facilitators if their last study group meetings was a week ago """ now = timezone.now() today = now.replace(hour=0, minute=0, second=0, microsecond=0) last_week = today - datetime.timedelta(days=7) last_meeting = study_group.meeting_set.active()\ .order_by('-meeting_date', '-meeting_time').first() if last_meeting and last_week <= last_meeting.meeting_datetime( ) and last_meeting.meeting_datetime() < last_week + datetime.timedelta( days=1): facilitator_name = study_group.facilitator.first_name path = reverse('studygroups_facilitator_survey', kwargs={'study_group_id': study_group.id}) domain = 'https://{}'.format(settings.DOMAIN) survey_url = domain + path context = { 'facilitator_name': facilitator_name, 'survey_url': survey_url, 'course_title': study_group.course.title, } timezone.deactivate() subject, txt, html = render_email_templates( 'studygroups/email/facilitator-survey', context) to = [study_group.facilitator.email] cc = [settings.DEFAULT_FROM_EMAIL] notification = EmailMultiAlternatives(subject, txt, settings.DEFAULT_FROM_EMAIL, to, cc=cc) notification.attach_alternative(html, 'text/html') notification.send()
def send_meeting_reminder(reminder): to = [ su.email for su in reminder.study_group.application_set.active().filter( accepted_at__isnull=False).exclude(email='') ] sender = '{0} <{1}>'.format(reminder.study_group.facilitator.first_name, settings.DEFAULT_FROM_EMAIL) for email in to: yes_link = reminder.study_group_meeting.rsvp_yes_link(email) no_link = reminder.study_group_meeting.rsvp_no_link(email) application = reminder.study_group_meeting.study_group.application_set.active( ).filter(email__iexact=email).first() unsubscribe_link = application.unapply_link() context = { "reminder": reminder, "learning_circle": reminder.study_group, "facilitator_message": reminder.email_body, "rsvp_yes_link": yes_link, "rsvp_no_link": no_link, "unsubscribe_link": unsubscribe_link, "domain": 'https://{0}'.format(settings.DOMAIN), "event_meta": True, } subject, text_body, html_body = render_email_templates( 'studygroups/email/learner_meeting_reminder', context) # TODO not using subject try: reminder_email = EmailMultiAlternatives( reminder.email_subject.strip('\n'), text_body, sender, [email], reply_to=[reminder.study_group.facilitator.email]) reminder_email.attach_alternative(html_body, 'text/html') # TODO attach icalendar event if reminder.study_group.attach_ics: ical = make_meeting_ics(reminder.study_group_meeting) part = MIMEText(ical, 'calendar') part.add_header('Filename', 'shifts.ics') part.add_header('Content-Disposition', 'attachment; filename=lc.ics') reminder_email.attach(part) reminder_email.send() except Exception as e: logger.exception('Could not send email to ', email, exc_info=e) # Send to organizer without RSVP & unsubscribe links try: context = { "reminder": reminder, "facilitator_message": reminder.email_body, "domain": 'https://{0}'.format(settings.DOMAIN), } subject, text_body, html_body = render_email_templates( 'studygroups/email/facilitator_meeting_reminder', context) reminder_email = EmailMultiAlternatives( reminder.email_subject.strip('\n'), text_body, sender, [reminder.study_group.facilitator.email]) reminder_email.attach_alternative(html_body, 'text/html') reminder_email.send() except Exception as e: logger.exception('Could not send email to ', reminder.study_group.facilitator.email, exc_info=e)
def send_facilitator_learner_survey_prompt(study_group): # TODO not supported for non-English learning circles if study_group.language != 'en': return now = timezone.now() # a learning circle could have no meetings and be published last_meeting = study_group.meeting_set.active().order_by( '-meeting_date', '-meeting_time').first() if not last_meeting: logger.warning( 'Published learning circle does not have any associated meetings. StudyGroup.id={0}' .format(study_group.id)) return start_of_window = now.replace(minute=0, second=0, microsecond=0) end_of_window = start_of_window + datetime.timedelta(hours=1) time_to_send = last_meeting.meeting_datetime() + datetime.timedelta(days=2) if start_of_window <= time_to_send and time_to_send < end_of_window: timezone.deactivate() facilitator_name = study_group.facilitator.first_name facilitator_survey_path = reverse( 'studygroups_facilitator_survey', kwargs={'study_group_uuid': study_group.uuid}) learner_survey_path = reverse( 'studygroups_learner_survey', kwargs={'study_group_uuid': study_group.uuid}) report_path = reverse('studygroups_final_report', kwargs={'study_group_id': study_group.id}) base_url = f'{settings.PROTOCOL}://{settings.DOMAIN}' facilitator_survey_url = base_url + facilitator_survey_path learner_survey_url = base_url + learner_survey_path report_url = base_url + report_path learners_without_survey_responses = study_group.application_set.active( ).filter(learnersurveyresponse__isnull=True) context = { "facilitator": study_group.facilitator, 'facilitator_name': facilitator_name, 'learner_survey_url': learner_survey_url, 'facilitator_survey_url': facilitator_survey_url, 'course_title': study_group.course.title, 'study_group_name': study_group.name, 'learners_without_survey_responses': learners_without_survey_responses, 'learner_responses_count': study_group.learnersurveyresponse_set.count(), 'report_url': report_url, } if study_group.facilitatorsurveyresponse_set.exists(): context['facilitator_survey_url'] = None if learners_without_survey_responses.count() == 0: context['learners_without_survey_responses'] = None subject, txt, html = render_email_templates( 'studygroups/email/facilitator_learner_survey_prompt', context) to = [study_group.facilitator.email] cc = [settings.DEFAULT_FROM_EMAIL] notification = EmailMultiAlternatives(subject, txt, settings.DEFAULT_FROM_EMAIL, to, cc=cc) notification.attach_alternative(html, 'text/html') notification.send()