def test_set_and_get_user_email_preferences(self): user_id = 'someUser' username = '******' user_email = '*****@*****.**' user_services.get_or_create_user(user_id, user_email) user_services.set_username(user_id, username) # When UserEmailPreferencesModel is yet to be created, # the value returned by get_email_preferences() should be True. email_preferences = user_services.get_email_preferences(user_id) self.assertEquals( email_preferences['can_receive_editor_role_email'], feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) # The user retrieves their email preferences. This initializes # a UserEmailPreferencesModel instance with the default values. user_services.update_email_preferences( user_id, feconf.DEFAULT_EMAIL_UPDATES_PREFERENCE, feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) email_preferences = user_services.get_email_preferences(user_id) self.assertEquals( email_preferences['can_receive_editor_role_email'], feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) # The user sets their membership email preference to False. user_services.update_email_preferences( user_id, feconf.DEFAULT_EMAIL_UPDATES_PREFERENCE, False) email_preferences = user_services.get_email_preferences(user_id) self.assertEquals( email_preferences['can_receive_editor_role_email'], False)
def test_user_disallowing_emails_on_signup(self): self.login(self.EDITOR_EMAIL) csrf_token = self.get_new_csrf_token() self.post_json(feconf.SIGNUP_DATA_URL, { 'username': '******', 'agreed_to_terms': True, 'can_receive_email_updates': False }, csrf_token=csrf_token) # The email update preference should be False in all cases. editor_id = self.get_user_id_from_email(self.EDITOR_EMAIL) with self.swap(feconf, 'DEFAULT_EMAIL_UPDATES_PREFERENCE', True): email_preferences = user_services.get_email_preferences(editor_id) self.assertEqual(email_preferences.can_receive_email_updates, False) self.assertEqual(email_preferences.can_receive_editor_role_email, feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) self.assertEqual( email_preferences.can_receive_feedback_message_email, feconf.DEFAULT_FEEDBACK_MESSAGE_EMAIL_PREFERENCE) self.assertEqual(email_preferences.can_receive_subscription_email, feconf.DEFAULT_SUBSCRIPTION_EMAIL_PREFERENCE) with self.swap(feconf, 'DEFAULT_EMAIL_UPDATES_PREFERENCE', False): email_preferences = user_services.get_email_preferences(editor_id) self.assertEqual(email_preferences.can_receive_email_updates, False) self.assertEqual(email_preferences.can_receive_editor_role_email, feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) self.assertEqual( email_preferences.can_receive_feedback_message_email, feconf.DEFAULT_FEEDBACK_MESSAGE_EMAIL_PREFERENCE) self.assertEqual(email_preferences.can_receive_subscription_email, feconf.DEFAULT_SUBSCRIPTION_EMAIL_PREFERENCE)
def test_user_disallowing_emails_on_signup(self): self.login(self.EDITOR_EMAIL) response = self.testapp.get(feconf.SIGNUP_URL) csrf_token = self.get_csrf_token_from_response(response) self.post_json( feconf.SIGNUP_DATA_URL, {'username': '******', 'agreed_to_terms': True, 'can_receive_email_updates': False}, csrf_token=csrf_token) # The email update preference should be False in all cases. editor_id = self.get_user_id_from_email(self.EDITOR_EMAIL) with self.swap(feconf, 'DEFAULT_EMAIL_UPDATES_PREFERENCE', True): self.assertEqual( user_services.get_email_preferences(editor_id), { 'can_receive_email_updates': False, 'can_receive_editor_role_email': ( feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) }) with self.swap(feconf, 'DEFAULT_EMAIL_UPDATES_PREFERENCE', False): self.assertEqual( user_services.get_email_preferences(editor_id), { 'can_receive_email_updates': False, 'can_receive_editor_role_email': ( feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) })
def test_user_not_setting_email_prefs_on_signup(self): self.login(self.EDITOR_EMAIL) self.get_html_response(feconf.SIGNUP_URL + '?return_url=/') csrf_token = self.get_new_csrf_token() self.post_json(feconf.SIGNUP_DATA_URL, { 'username': self.EDITOR_USERNAME, 'agreed_to_terms': True }, csrf_token=csrf_token) # The email update preference should be whatever the setting in feconf # is. editor_id = self.get_user_id_from_email(self.EDITOR_EMAIL) with self.swap(feconf, 'DEFAULT_EMAIL_UPDATES_PREFERENCE', True): email_preferences = user_services.get_email_preferences(editor_id) self.assertEqual(email_preferences.can_receive_email_updates, True) self.assertEqual(email_preferences.can_receive_editor_role_email, feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) self.assertEqual( email_preferences.can_receive_feedback_message_email, feconf.DEFAULT_FEEDBACK_MESSAGE_EMAIL_PREFERENCE) self.assertEqual(email_preferences.can_receive_subscription_email, feconf.DEFAULT_SUBSCRIPTION_EMAIL_PREFERENCE) with self.swap(feconf, 'DEFAULT_EMAIL_UPDATES_PREFERENCE', False): email_preferences = user_services.get_email_preferences(editor_id) self.assertEqual(email_preferences.can_receive_email_updates, False) self.assertEqual(email_preferences.can_receive_editor_role_email, feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) self.assertEqual( email_preferences.can_receive_feedback_message_email, feconf.DEFAULT_FEEDBACK_MESSAGE_EMAIL_PREFERENCE) self.assertEqual(email_preferences.can_receive_subscription_email, feconf.DEFAULT_SUBSCRIPTION_EMAIL_PREFERENCE)
def test_post(self): with self.swap_secret, self.swap_audience_id: email_preferences = user_services.get_email_preferences( self.editor_id) self.assertEqual(email_preferences.can_receive_email_updates, False) # User subscribed externally. json_response = self.post_json( '%s/secret' % feconf.BULK_EMAIL_WEBHOOK_ENDPOINT, { 'data[list_id]': 'audience_id', 'data[email]': self.EDITOR_EMAIL, 'type': 'subscribe' }, use_payload=False) self.assertEqual(json_response, {}) email_preferences = user_services.get_email_preferences( self.editor_id) self.assertEqual(email_preferences.can_receive_email_updates, True) # User unsubscribed externally. json_response = self.post_json( '%s/secret' % feconf.BULK_EMAIL_WEBHOOK_ENDPOINT, { 'data[list_id]': 'audience_id', 'data[email]': self.EDITOR_EMAIL, 'type': 'unsubscribe' }, use_payload=False) self.assertEqual(json_response, {}) email_preferences = user_services.get_email_preferences( self.editor_id) self.assertEqual(email_preferences.can_receive_email_updates, False)
def test_set_and_get_user_email_preferences(self): user_id = 'someUser' username = '******' user_email = '*****@*****.**' user_services.get_or_create_user(user_id, user_email) user_services.set_username(user_id, username) # When UserEmailPreferencesModel is yet to be created, # the value returned by get_email_preferences() should be True. email_preferences = user_services.get_email_preferences(user_id) self.assertEquals(email_preferences['can_receive_editor_role_email'], feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) # The user retrieves their email preferences. This initializes # a UserEmailPreferencesModel instance with the default values. user_services.update_email_preferences( user_id, feconf.DEFAULT_EMAIL_UPDATES_PREFERENCE, feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) email_preferences = user_services.get_email_preferences(user_id) self.assertEquals(email_preferences['can_receive_editor_role_email'], feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) # The user sets their membership email preference to False. user_services.update_email_preferences( user_id, feconf.DEFAULT_EMAIL_UPDATES_PREFERENCE, False) email_preferences = user_services.get_email_preferences(user_id) self.assertEquals(email_preferences['can_receive_editor_role_email'], False)
def test_email_preferences_updates(self): """Test that Preferences Handler correctly updates the email preferences of the user. """ self.signup(self.EDITOR_EMAIL, username=self.EDITOR_USERNAME) editor_id = self.get_user_id_from_email(self.EDITOR_EMAIL) self.login(self.EDITOR_EMAIL) response = self.testapp.get('/preferences') csrf_token = self.get_csrf_token_from_response(response) payload = { 'update_type': 'email_preferences', 'data': { 'can_receive_email_updates': True, 'can_receive_editor_role_email': True, 'can_receive_feedback_message_email': True, 'can_receive_subscription_email': True } } # Allow all emails. self.put_json('/preferenceshandler/data', payload, csrf_token=csrf_token) email_preferences = user_services.get_email_preferences(editor_id) self.assertTrue(email_preferences.can_receive_email_updates) self.assertTrue(email_preferences.can_receive_editor_role_email) self.assertTrue(email_preferences.can_receive_feedback_message_email) self.assertTrue(email_preferences.can_receive_subscription_email) payload = { 'update_type': 'email_preferences', 'data': { 'can_receive_email_updates': False, 'can_receive_editor_role_email': False, 'can_receive_feedback_message_email': False, 'can_receive_subscription_email': False } } # Disallow all emails. self.put_json('/preferenceshandler/data', payload, csrf_token=csrf_token) email_preferences = user_services.get_email_preferences(editor_id) self.assertFalse(email_preferences.can_receive_email_updates) self.assertFalse(email_preferences.can_receive_editor_role_email) self.assertFalse(email_preferences.can_receive_feedback_message_email) self.assertFalse(email_preferences.can_receive_subscription_email)
def send_instant_feedback_message_email(recipient_id, sender_id, message, email_subject, exploration_title, exploration_id, thread_title): email_body_template = ( 'Hi %s,<br><br>' 'New update to thread "%s" on ' '<a href="https://www.oppia.org/create/%s#/feedback">%s</a>:<br>' '<ul><li>%s: %s<br></li></ul>' '(You received this message because you are a ' 'participant in this thread.)<br><br>' 'Best wishes,<br>' 'The Oppia team<br>' '<br>%s') if not feconf.CAN_SEND_EMAILS: log_new_error('This app cannot send emails to users.') return if not feconf.CAN_SEND_FEEDBACK_MESSAGE_EMAILS: log_new_error('This app cannot send feedback message emails to users.') return sender_settings = user_services.get_user_settings(sender_id) recipient_settings = user_services.get_user_settings(recipient_id) recipient_preferences = user_services.get_email_preferences(recipient_id) if recipient_preferences['can_receive_feedback_message_email']: email_body = email_body_template % ( recipient_settings.username, thread_title, exploration_id, exploration_title, sender_settings.username, message, EMAIL_FOOTER.value) _send_email(recipient_id, feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_FEEDBACK_MESSAGE_NOTIFICATION, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS)
def map(user_settings_model): user_id = user_settings_model.id email_preferences = user_services.get_email_preferences(user_id) if not email_preferences.can_receive_email_updates: return query_id = ( jobs.BaseMapReduceOneOffJobManager.get_mapper_param('query_id')) query_model = user_models.UserQueryModel.get(query_id) job_class = UserQueryOneOffJob if (user_id == query_model.submitter_id or user_services.is_at_least_moderator(user_id)): return query_criteria_satisfied = True predicates = constants.EMAIL_DASHBOARD_PREDICATE_DEFINITION for predicate in predicates: value = getattr(query_model, predicate['backend_attr']) if value != predicate['default_value']: query_criteria_satisfied = getattr( job_class, '_is_%s_query_satisfied' % predicate['backend_id'])(user_settings_model, query_model) if not query_criteria_satisfied: return yield (query_id, user_id)
def get(self): """Handles GET requests.""" user_settings = user_services.get_user_settings(self.user_id) user_email_preferences = user_services.get_email_preferences( self.user_id) self.values.update({ 'preferred_language_codes': user_settings.preferred_language_codes, 'preferred_site_language_code': (user_settings.preferred_site_language_code), 'profile_picture_data_url': user_settings.profile_picture_data_url, 'user_bio': user_settings.user_bio, 'subject_interests': user_settings.subject_interests, 'can_receive_email_updates': (user_email_preferences.can_receive_email_updates), 'can_receive_editor_role_email': (user_email_preferences.can_receive_editor_role_email), 'can_receive_feedback_message_email': (user_email_preferences.can_receive_feedback_message_email), 'can_receive_subscription_email': (user_email_preferences.can_receive_subscription_email) }) self.render_json(self.values)
def post(self, _): """Handles POST requests.""" if self.request.get('data[list_id]') != feconf.MAILCHIMP_AUDIENCE_ID: self.render_json({}) return email = self.request.get('data[email]') user_settings = user_services.get_user_settings_from_email(email) # Ignore the request if the user does not exist in Oppia. if user_settings is None: self.render_json({}) return user_id = user_settings.user_id user_email_preferences = user_services.get_email_preferences(user_id) if self.request.get('type') == 'subscribe': user_services.update_email_preferences( user_id, True, user_email_preferences.can_receive_editor_role_email, user_email_preferences.can_receive_feedback_message_email, user_email_preferences.can_receive_subscription_email, bulk_email_db_already_updated=True) elif self.request.get('type') == 'unsubscribe': user_services.update_email_preferences( user_id, False, user_email_preferences.can_receive_editor_role_email, user_email_preferences.can_receive_feedback_message_email, user_email_preferences.can_receive_subscription_email, bulk_email_db_already_updated=True) self.render_json({})
def send_suggestion_email(exploration_title, exploration_id, author_id, recipient_list): """Send emails to notify the given recipients about new suggestion. Each recipient will only be emailed if their email preferences allow for incoming feedback message emails. Args: exploration_title: str. Title of the exploration with the new suggestion. exploration_id: str. The ID of the exploration with the new suggestion. author_id: str. The user ID of the author of the suggestion. recipient_list: list(str). The user IDs of the email recipients. """ email_subject = 'New suggestion for "%s"' % exploration_title email_body_template = ( "Hi %s,<br>" "%s has submitted a new suggestion for your Oppia exploration, " '<a href="https://www.oppia.org/create/%s">"%s"</a>.<br>' "You can accept or reject this suggestion by visiting the " '<a href="https://www.oppia.org/create/%s#/feedback">feedback page</a> ' "for your exploration.<br>" "<br>" "Thanks!<br>" "- The Oppia Team<br>" "<br>%s" ) if not feconf.CAN_SEND_EMAILS: log_new_error("This app cannot send emails to users.") return if not feconf.CAN_SEND_FEEDBACK_MESSAGE_EMAILS: log_new_error("This app cannot send feedback message emails to users.") return author_settings = user_services.get_user_settings(author_id) for recipient_id in recipient_list: recipient_user_settings = user_services.get_user_settings(recipient_id) recipient_preferences = user_services.get_email_preferences(recipient_id) if recipient_preferences["can_receive_feedback_message_email"]: # Send email only if recipient wants to receive. email_body = email_body_template % ( recipient_user_settings.username, author_settings.username, exploration_id, exploration_title, exploration_id, EMAIL_FOOTER.value, ) _send_email( recipient_id, feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_SUGGESTION_NOTIFICATION, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS, )
def send_instant_feedback_message_email( recipient_id, sender_id, message, email_subject, exploration_title, exploration_id, thread_title ): """Send an email when a new message is posted to a feedback thread, or when the thread's status is changed. Args: recipient_id: str. The user ID of the recipient. sender_id: str. The user ID of the sender. message: str. The message text or status change text from the sender. email_subject: str. The subject line to be sent in the email. exploration_title: str. The title of the exploration. exploration_id: str. ID of the exploration the feedback thread is about. thread_title: str. The title of the feedback thread. """ email_body_template = ( "Hi %s,<br><br>" 'New update to thread "%s" on ' '<a href="https://www.oppia.org/create/%s#/feedback">%s</a>:<br>' "<ul><li>%s: %s<br></li></ul>" "(You received this message because you are a " "participant in this thread.)<br><br>" "Best wishes,<br>" "The Oppia team<br>" "<br>%s" ) if not feconf.CAN_SEND_EMAILS: log_new_error("This app cannot send emails to users.") return if not feconf.CAN_SEND_FEEDBACK_MESSAGE_EMAILS: log_new_error("This app cannot send feedback message emails to users.") return sender_settings = user_services.get_user_settings(sender_id) recipient_settings = user_services.get_user_settings(recipient_id) recipient_preferences = user_services.get_email_preferences(recipient_id) if recipient_preferences["can_receive_feedback_message_email"]: email_body = email_body_template % ( recipient_settings.username, thread_title, exploration_id, exploration_title, sender_settings.username, message, EMAIL_FOOTER.value, ) _send_email( recipient_id, feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_FEEDBACK_MESSAGE_NOTIFICATION, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS, )
def send_instant_feedback_message_email(recipient_id, sender_id, message, email_subject, exploration_title, exploration_id, thread_title, reply_to_id=None): """Send an email when a new message is posted to a feedback thread, or when the thread's status is changed. Args: recipient_id: str. The user ID of the recipient. sender_id: str. The user ID of the sender. message: str. The message text or status change text from the sender. email_subject: str. The subject line to be sent in the email. exploration_title: str. The title of the exploration. exploration_id: str. ID of the exploration the feedback thread is about. thread_title: str. The title of the feedback thread. reply_to_id: str or None. The unique reply-to id used in reply-to email sent to recipient. """ email_body_template = ( 'Hi %s,<br><br>' 'New update to thread "%s" on ' '<a href="https://www.oppia.org/create/%s#/feedback">%s</a>:<br>' '<ul><li>%s: %s<br></li></ul>' '(You received this message because you are a ' 'participant in this thread.)<br><br>' 'Best wishes,<br>' 'The Oppia team<br>' '<br>%s') if not feconf.CAN_SEND_EMAILS: log_new_error('This app cannot send emails to users.') return if not feconf.CAN_SEND_FEEDBACK_MESSAGE_EMAILS: log_new_error('This app cannot send feedback message emails to users.') return sender_settings = user_services.get_user_settings(sender_id) recipient_settings = user_services.get_user_settings(recipient_id) recipient_preferences = user_services.get_email_preferences(recipient_id) if recipient_preferences.can_receive_feedback_message_email: email_body = email_body_template % ( recipient_settings.username, thread_title, exploration_id, exploration_title, sender_settings.username, message, EMAIL_FOOTER.value) _send_email(recipient_id, feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_FEEDBACK_MESSAGE_NOTIFICATION, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS, reply_to_id=reply_to_id)
def _send_batch_emails(recipient_list, feedback_message_reference): """send feedback message email in batch.""" for recipient_id in recipient_list: recipient_preferences = ( user_services.get_email_preferences(recipient_id)) if recipient_preferences['can_receive_feedback_message_email']: transaction_services.run_in_transaction( _add_feedback_message_reference, recipient_id, feedback_message_reference)
def _send_instant_emails(recipient_list, feedback_message_reference): """send feedback message email instantly.""" for recipient_id in recipient_list: recipient_preferences = ( user_services.get_email_preferences(recipient_id)) if recipient_preferences['can_receive_feedback_message_email']: transaction_services.run_in_transaction( enqueue_feedback_message_instant_email_task, recipient_id, feedback_message_reference)
def test_pre_delete_user_email_subscriptions(self): email_preferences = user_services.get_email_preferences(self.user_1_id) self.assertEqual(email_preferences.can_receive_email_updates, feconf.DEFAULT_EMAIL_UPDATES_PREFERENCE) self.assertEqual(email_preferences.can_receive_editor_role_email, feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) self.assertEqual(email_preferences.can_receive_feedback_message_email, feconf.DEFAULT_FEEDBACK_MESSAGE_EMAIL_PREFERENCE) self.assertEqual(email_preferences.can_receive_subscription_email, feconf.DEFAULT_SUBSCRIPTION_EMAIL_PREFERENCE) wipeout_service.pre_delete_user(self.user_1_id) email_preferences = user_services.get_email_preferences(self.user_1_id) self.assertFalse(email_preferences.can_receive_email_updates) self.assertFalse(email_preferences.can_receive_editor_role_email) self.assertFalse(email_preferences.can_receive_feedback_message_email) self.assertFalse(email_preferences.can_receive_subscription_email)
def test_set_and_get_user_email_preferences(self): user_id = 'someUser' username = '******' user_email = '*****@*****.**' user_services.create_new_user(user_id, user_email) user_services.set_username(user_id, username) # When UserEmailPreferencesModel is yet to be created, # the value returned by get_email_preferences() should be True. email_preferences = user_services.get_email_preferences(user_id) self.assertEqual(email_preferences.can_receive_editor_role_email, feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) email_preferences = user_services.get_email_preferences(user_id) self.assertEqual(email_preferences.can_receive_feedback_message_email, feconf.DEFAULT_FEEDBACK_MESSAGE_EMAIL_PREFERENCE) # The user retrieves their email preferences. This initializes # a UserEmailPreferencesModel instance with the default values. user_services.update_email_preferences( user_id, feconf.DEFAULT_EMAIL_UPDATES_PREFERENCE, feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE, feconf.DEFAULT_FEEDBACK_MESSAGE_EMAIL_PREFERENCE, feconf.DEFAULT_SUBSCRIPTION_EMAIL_PREFERENCE) email_preferences = user_services.get_email_preferences(user_id) self.assertEqual(email_preferences.can_receive_editor_role_email, feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE) self.assertEqual(email_preferences.can_receive_feedback_message_email, feconf.DEFAULT_FEEDBACK_MESSAGE_EMAIL_PREFERENCE) # The user sets their membership email preference to False. user_services.update_email_preferences( user_id, feconf.DEFAULT_EMAIL_UPDATES_PREFERENCE, False, False, False) email_preferences = user_services.get_email_preferences(user_id) self.assertFalse(email_preferences.can_receive_editor_role_email) self.assertFalse(email_preferences.can_receive_feedback_message_email) self.assertFalse(email_preferences.can_receive_subscription_email)
def test_user_not_setting_email_prefs_on_signup(self): self.login(self.EDITOR_EMAIL) response = self.testapp.get(feconf.SIGNUP_URL) csrf_token = self.get_csrf_token_from_response(response) self.post_json( feconf.SIGNUP_DATA_URL, {'username': '******', 'agreed_to_terms': True}, csrf_token=csrf_token) # The email update preference should be whatever the setting in feconf # is. self.EDITOR_ID = self.get_user_id_from_email(self.EDITOR_EMAIL) with self.swap(feconf, 'DEFAULT_EMAIL_UPDATES_PREFERENCE', True): self.assertEqual( user_services.get_email_preferences(self.EDITOR_ID), {'can_receive_email_updates': True}) with self.swap(feconf, 'DEFAULT_EMAIL_UPDATES_PREFERENCE', False): self.assertEqual( user_services.get_email_preferences(self.EDITOR_ID), {'can_receive_email_updates': False})
def get(self): """Handles GET requests.""" user_settings = user_services.get_user_settings(self.user_id) self.values.update({ 'preferred_language_codes': user_settings.preferred_language_codes, 'profile_picture_data_url': user_settings.profile_picture_data_url, 'user_bio': user_settings.user_bio, 'can_receive_email_updates': user_services.get_email_preferences( self.user_id)['can_receive_email_updates'], }) self.render_json(self.values)
def _send_feedback_thread_status_change_emails(recipient_list, feedback_message_reference, old_status, new_status): """send email feedback thread status change.""" for recipient_id in recipient_list: recipient_preferences = ( user_services.get_email_preferences(recipient_id)) if recipient_preferences['can_receive_feedback_message_email']: transaction_services.run_in_transaction( _enqueue_feedback_thread_status_change_email_task, recipient_id, feedback_message_reference, old_status, new_status)
def send_suggestion_email(exploration_title, exploration_id, author_id, recipient_list): """Send emails to notify the given recipients about new suggestion. Each recipient will only be emailed if their email preferences allow for incoming feedback message emails. Args: exploration_title: str. Title of the exploration with the new suggestion. exploration_id: str. The ID of the exploration with the new suggestion. author_id: str. The user ID of the author of the suggestion. recipient_list: list(str). The user IDs of the email recipients. """ email_subject = 'New suggestion for "%s"' % exploration_title email_body_template = ( 'Hi %s,<br>' '%s has submitted a new suggestion for your Oppia exploration, ' '<a href="https://www.oppia.org/create/%s">"%s"</a>.<br>' 'You can accept or reject this suggestion by visiting the ' '<a href="https://www.oppia.org/create/%s#/feedback">feedback page</a> ' 'for your exploration.<br>' '<br>' 'Thanks!<br>' '- The Oppia Team<br>' '<br>%s') if not feconf.CAN_SEND_EMAILS: log_new_error('This app cannot send emails to users.') return if not feconf.CAN_SEND_FEEDBACK_MESSAGE_EMAILS: log_new_error('This app cannot send feedback message emails to users.') return author_settings = user_services.get_user_settings(author_id) for recipient_id in recipient_list: recipient_user_settings = user_services.get_user_settings(recipient_id) recipient_preferences = ( user_services.get_email_preferences(recipient_id)) if recipient_preferences['can_receive_feedback_message_email']: # Send email only if recipient wants to receive. email_body = email_body_template % ( recipient_user_settings.username, author_settings.username, exploration_id, exploration_title, exploration_id, EMAIL_FOOTER.value) _send_email(recipient_id, feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_SUGGESTION_NOTIFICATION, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS)
def add_message_to_email_buffer(author_id, exploration_id, thread_id, message_id): exploration_rights = rights_manager.get_exploration_rights(exploration_id) feedback_message_reference = feedback_domain.FeedbackMessageReference( exploration_id, thread_id, message_id) for owner_id in exploration_rights.owner_ids: owner_preferences = user_services.get_email_preferences(owner_id) if (owner_id != author_id and owner_preferences['can_receive_feedback_message_email']): transaction_services.run_in_transaction( _add_feedback_message_reference, owner_id, feedback_message_reference)
def get(self): """Handles GET requests.""" user_settings = user_services.get_user_settings(self.user_id) user_email_preferences = user_services.get_email_preferences( self.user_id) creators_subscribed_to = subscription_services.get_all_creators_subscribed_to( # pylint: disable=line-too-long self.user_id) creators_settings = user_services.get_users_settings( creators_subscribed_to) subscription_list = [] for index, creator_settings in enumerate(creators_settings): subscription_summary = { 'creator_picture_data_url': (creator_settings.profile_picture_data_url), 'creator_username': creator_settings.username, 'creator_impact': (user_services.get_user_impact_score( creators_subscribed_to[index])) } subscription_list.append(subscription_summary) self.values.update({ 'preferred_language_codes': user_settings.preferred_language_codes, 'preferred_site_language_code': (user_settings.preferred_site_language_code), 'preferred_audio_language_code': (user_settings.preferred_audio_language_code), 'profile_picture_data_url': user_settings.profile_picture_data_url, 'default_dashboard': user_settings.default_dashboard, 'user_bio': user_settings.user_bio, 'subject_interests': user_settings.subject_interests, 'can_receive_email_updates': (user_email_preferences.can_receive_email_updates), 'can_receive_editor_role_email': (user_email_preferences.can_receive_editor_role_email), 'can_receive_feedback_message_email': (user_email_preferences.can_receive_feedback_message_email), 'can_receive_subscription_email': (user_email_preferences.can_receive_subscription_email), 'subscription_list': subscription_list }) self.render_json(self.values)
def test_user_not_setting_email_prefs_on_signup(self): self.login(self.EDITOR_EMAIL) response = self.testapp.get(feconf.SIGNUP_URL) csrf_token = self.get_csrf_token_from_response(response) self.post_json(feconf.SIGNUP_DATA_URL, { 'username': '******', 'agreed_to_terms': True }, csrf_token=csrf_token) # The email update preference should be whatever the setting in feconf # is. editor_id = self.get_user_id_from_email(self.EDITOR_EMAIL) with self.swap(feconf, 'DEFAULT_EMAIL_UPDATES_PREFERENCE', True): self.assertEqual( user_services.get_email_preferences(editor_id), { 'can_receive_email_updates': True, 'can_receive_editor_role_email': (feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE), 'can_receive_feedback_message_email': (feconf.DEFAULT_FEEDBACK_MESSAGE_EMAIL_PREFERENCE), 'can_receive_subscription_email': (feconf.DEFAULT_SUBSCRIPTION_EMAIL_PREFERENCE) }) with self.swap(feconf, 'DEFAULT_EMAIL_UPDATES_PREFERENCE', False): self.assertEqual( user_services.get_email_preferences(editor_id), { 'can_receive_email_updates': False, 'can_receive_editor_role_email': (feconf.DEFAULT_EDITOR_ROLE_EMAIL_PREFERENCE), 'can_receive_feedback_message_email': (feconf.DEFAULT_FEEDBACK_MESSAGE_EMAIL_PREFERENCE), 'can_receive_subscription_email': (feconf.DEFAULT_SUBSCRIPTION_EMAIL_PREFERENCE) })
def send_rejected_voiceover_application_email(user_id, lesson_title, language_code, rejection_message): """Sends an email to users to give update on the rejected voiceover application. Args: user_id: str. The id of the user whose voiceover application got accepted. lesson_title: str. The title of the lessons for which the voiceover application got accepted. language_code: str. The language code in which for which the voiceover application got accepted. rejection_message: str. The message left by the reviewer while rejecting the voiceover application. """ email_subject = 'Updates on submitted voiceover application' email_body_template = ( 'Hi %s,<br><br>' 'Your voiceover application for "%s" lesson in language %s got rejected' ' and the reviewer has left a message.' '<br><br>Review message: %s<br><br>' 'You can create a new voiceover application through the' '<a href="https://oppia.org/community_dashboard">' 'community dashboard</a> page.<br><br>' '- The Oppia Team<br>' '<br>%s') if not feconf.CAN_SEND_EMAILS: log_new_error('This app cannot send emails to users.') return recipient_user_settings = user_services.get_user_settings(user_id) can_user_receive_email = user_services.get_email_preferences( user_id).can_receive_email_updates # Send email only if recipient wants to receive. if can_user_receive_email: language = utils.get_supported_audio_language_description( language_code) email_body = email_body_template % ( recipient_user_settings.username, lesson_title, language, rejection_message, EMAIL_FOOTER.value) _send_email(user_id, feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_VOICEOVER_APPLICATION_UPDATES, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS)
def send_mail_to_onboard_new_reviewers(user_id, category): """Sends an email to users who have crossed the threshold score. Args: user_id: str. The ID of the user who is being offered to become a reviewer. category: str. The category that the user is being offered to review. """ email_subject = 'Invitation to review suggestions' email_body_template = ( 'Hi %s,<br><br>' 'Thank you for actively contributing high-quality suggestions for ' 'Oppia\'s lessons in %s, and for helping to make these lessons better ' 'for students around the world!<br><br>' 'In recognition of your contributions, we would like to invite you to ' 'become one of Oppia\'s reviewers. As a reviewer, you will be able to ' 'review suggestions in %s, and contribute to helping ensure that any ' 'edits made to lessons preserve the lessons\' quality and are ' 'beneficial for students.<br><br>' 'If you\'d like to help out as a reviewer, please visit your ' '<a href="https://www.oppia.org/creator_dashboard/">dashboard</a>. ' 'and set your review preferences accordingly. Note that, if you accept,' 'you will receive occasional emails inviting you to review incoming ' 'suggestions by others.<br><br>' 'Again, thank you for your contributions to the Oppia community!<br>' '- The Oppia Team<br>' '<br>%s') if not feconf.CAN_SEND_EMAILS: log_new_error('This app cannot send emails to users.') return recipient_user_settings = user_services.get_user_settings(user_id) can_user_receive_email = user_services.get_email_preferences( user_id).can_receive_email_updates if can_user_receive_email: # Send email only if recipient wants to receive. email_body = email_body_template % ( recipient_user_settings.username, category, category, EMAIL_FOOTER.value) _send_email( user_id, feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_ONBOARD_REVIEWER, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS)
def _send_instant_emails(recipient_list, feedback_message_reference): """Adds the given FeedbackMessageReference to each of the recipient's email buffers. The collected messages will be sent out immediately. Args: recipient_list: list of str. A list of user_ids of all recipients of the email. feedback_message_reference: FeedbackMessageReference. """ for recipient_id in recipient_list: recipient_preferences = ( user_services.get_email_preferences(recipient_id)) if recipient_preferences['can_receive_feedback_message_email']: transaction_services.run_in_transaction( enqueue_feedback_message_instant_email_task, recipient_id, feedback_message_reference)
def send_accepted_voiceover_application_email(user_id, lesson_title, language_code): """Sends an email to users to an give update on the accepted voiceover application. Args: user_id: str. The id of the user whose voiceover application got accepted. lesson_title: str. The title of the lessons for which the voiceover application got accepted. language_code: str. The language code for which the voiceover application got accepted. """ email_subject = '[Accepted] Updates on submitted voiceover application' email_body_template = ( 'Hi %s,<br><br>' 'Congratulations! Your voiceover application for "%s" lesson got ' 'accepted and you have been assigned with a voice artist role in the ' 'lesson. Now you will be able to add voiceovers to the lesson in %s ' 'language.' '<br><br>You can check the wiki page to learn' '<a href="https://github.com/oppia/oppia/wiki/' 'Instructions-for-voice-artists">how to voiceover a lesson</a><br><br>' 'Thank you for helping improve Oppia\'s lessons!' '- The Oppia Team<br>' '<br>%s') if not feconf.CAN_SEND_EMAILS: log_new_error('This app cannot send emails to users.') return recipient_user_settings = user_services.get_user_settings(user_id) can_user_receive_email = user_services.get_email_preferences( user_id).can_receive_email_updates # Send email only if recipient wants to receive. if can_user_receive_email: language = utils.get_supported_audio_language_description( language_code) email_body = email_body_template % (recipient_user_settings.username, lesson_title, language, EMAIL_FOOTER.value) _send_email(user_id, feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_VOICEOVER_APPLICATION_UPDATES, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS)
def _send_batch_emails(recipient_list, feedback_message_reference): """Adds the given FeedbackMessageReference to each of the recipient's email buffers. The collected messages will be sent out as a batch after a short delay. Args: recipient_list: list of str. A list of user_ids of all recipients of the email. feedback_message_reference: FeedbackMessageReference. The reference to add to each email buffer. """ for recipient_id in recipient_list: recipient_preferences = ( user_services.get_email_preferences(recipient_id)) if recipient_preferences['can_receive_feedback_message_email']: transaction_services.run_in_transaction( _add_feedback_message_reference, recipient_id, feedback_message_reference)
def _send_feedback_thread_status_change_emails( recipient_list, feedback_message_reference, old_status, new_status): """Notifies the given recipients about the status change. Args: recipient_list: list of str. A list of recipient ids. feedback_message_reference: FeedbackMessageReference old_status: str, one of STATUS_CHOICES new_status: str, one of STATUS_CHOICES """ for recipient_id in recipient_list: recipient_preferences = ( user_services.get_email_preferences(recipient_id)) if recipient_preferences['can_receive_feedback_message_email']: transaction_services.run_in_transaction( _enqueue_feedback_thread_status_change_email_task, recipient_id, feedback_message_reference, old_status, new_status)
def get(self): """Handles GET requests.""" user_settings = user_services.get_user_settings(self.user_id) user_email_preferences = user_services.get_email_preferences( self.user_id) self.values.update({ 'preferred_language_codes': user_settings.preferred_language_codes, 'preferred_site_language_code': ( user_settings.preferred_site_language_code), 'profile_picture_data_url': user_settings.profile_picture_data_url, 'user_bio': user_settings.user_bio, 'subject_interests': user_settings.subject_interests, 'can_receive_email_updates': ( user_email_preferences['can_receive_email_updates']), 'can_receive_editor_role_email': ( user_email_preferences['can_receive_editor_role_email']) }) self.render_json(self.values)
def _send_feedback_thread_status_change_emails(recipient_list, feedback_message_reference, old_status, new_status): """Notifies the given recipients about the status change. Args: recipient_list: list of str. A list of recipient ids. feedback_message_reference: FeedbackMessageReference old_status: str, one of STATUS_CHOICES new_status: str, one of STATUS_CHOICES """ for recipient_id in recipient_list: recipient_preferences = ( user_services.get_email_preferences(recipient_id)) if recipient_preferences['can_receive_feedback_message_email']: transaction_services.run_in_transaction( _enqueue_feedback_thread_status_change_email_task, recipient_id, feedback_message_reference, old_status, new_status)
def get(self): """Handles GET requests.""" user_settings = user_services.get_user_settings(self.user_id) user_email_preferences = user_services.get_email_preferences( self.user_id) creators_subscribed_to = subscription_services.get_all_creators_subscribed_to( # pylint: disable=line-too-long self.user_id) creators_settings = user_services.get_users_settings( creators_subscribed_to) subscription_list = [] for index, creator_settings in enumerate(creators_settings): subscription_summary = { 'creator_picture_data_url': ( creator_settings.profile_picture_data_url), 'creator_username': creator_settings.username, 'creator_impact': ( user_services.get_user_impact_score( creators_subscribed_to[index])) } subscription_list.append(subscription_summary) self.values.update({ 'preferred_language_codes': user_settings.preferred_language_codes, 'preferred_site_language_code': ( user_settings.preferred_site_language_code), 'profile_picture_data_url': user_settings.profile_picture_data_url, 'user_bio': user_settings.user_bio, 'subject_interests': user_settings.subject_interests, 'can_receive_email_updates': ( user_email_preferences.can_receive_email_updates), 'can_receive_editor_role_email': ( user_email_preferences.can_receive_editor_role_email), 'can_receive_feedback_message_email': ( user_email_preferences.can_receive_feedback_message_email), 'can_receive_subscription_email': ( user_email_preferences.can_receive_subscription_email), 'subscription_list': subscription_list }) self.render_json(self.values)
def send_mail_to_notify_users_to_review(user_id, category): """Sends an email to users to review suggestions in categories they have agreed to review for. Args: user_id: str. The id of the user who is being pinged to review suggestions. category: str. The category of the suggestions to review. """ email_subject = 'Notification to review suggestions' email_body_template = ( 'Hi %s,<br><br>' 'Just a heads-up that there are new suggestions to ' 'review in %s, which you are registered as a reviewer for.' '<br><br>Please take a look at and accept/reject these suggestions at' ' your earliest convenience. You can visit your ' '<a href="https://www.oppia.org/creator_dashboard/">dashboard</a> ' 'to view the list of suggestions that need a review.<br><br>' 'Thank you for helping improve Oppia\'s lessons!' '- The Oppia Team<br>' '<br>%s') if not feconf.CAN_SEND_EMAILS: log_new_error('This app cannot send emails to users.') return recipient_user_settings = user_services.get_user_settings(user_id) can_user_receive_email = user_services.get_email_preferences( user_id).can_receive_email_updates if can_user_receive_email: # Send email only if recipient wants to receive. email_body = email_body_template % ( recipient_user_settings.username, category, EMAIL_FOOTER.value) _send_email( user_id, feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_REVIEW_SUGGESTIONS, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS)
def send_suggestion_email( exploration_title, exploration_id, author_id, recipient_list): email_subject = 'New suggestion for "%s"' % exploration_title email_body_template = ( 'Hi %s,<br>' '%s has submitted a new suggestion for your Oppia exploration, ' '<a href="https://www.oppia.org/create/%s">"%s"</a>.<br>' 'You can accept or reject this suggestion by visiting the ' '<a href="https://www.oppia.org/create/%s#/feedback">feedback page</a> ' 'for your exploration.<br>' '<br>' 'Thanks!<br>' '- The Oppia Team<br>' '<br>%s') if not feconf.CAN_SEND_EMAILS_TO_USERS: log_new_error('This app cannot send emails to users.') return if not feconf.CAN_SEND_FEEDBACK_MESSAGE_EMAILS: log_new_error('This app cannot send feedback message emails to users.') return author_settings = user_services.get_user_settings(author_id) for recipient_id in recipient_list: recipient_user_settings = user_services.get_user_settings(recipient_id) recipient_preferences = ( user_services.get_email_preferences(recipient_id)) if recipient_preferences['can_receive_feedback_message_email']: # Send email only if recipient wants to receive. email_body = email_body_template % ( recipient_user_settings.username, author_settings.username, exploration_id, exploration_title, exploration_id, EMAIL_FOOTER.value) _send_email( recipient_id, feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_SUGGESTION_NOTIFICATION, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS)
def send_instant_feedback_message_email( recipient_id, sender_id, message, email_subject, exploration_title, exploration_id, thread_title): email_body_template = ( 'Hi %s,<br><br>' 'New update to thread "%s" on ' '<a href="https://www.oppia.org/create/%s#/feedback">%s</a>:<br>' '<ul><li>%s: %s<br></li></ul>' '(You received this message because you are a ' 'participant in this thread.)<br><br>' 'Best wishes,<br>' 'The Oppia team<br>' '<br>%s') if not feconf.CAN_SEND_EMAILS: log_new_error('This app cannot send emails to users.') return if not feconf.CAN_SEND_FEEDBACK_MESSAGE_EMAILS: log_new_error('This app cannot send feedback message emails to users.') return sender_settings = user_services.get_user_settings(sender_id) recipient_settings = user_services.get_user_settings(recipient_id) recipient_preferences = user_services.get_email_preferences(recipient_id) if recipient_preferences['can_receive_feedback_message_email']: email_body = email_body_template % ( recipient_settings.username, thread_title, exploration_id, exploration_title, sender_settings.username, message, EMAIL_FOOTER.value) _send_email( recipient_id, feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_FEEDBACK_MESSAGE_NOTIFICATION, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS)
def send_role_notification_email(inviter_id, recipient_id, recipient_role, exploration_id, exploration_title): """Sends a email when a new user is given activity rights (Manager, Editor, Viewer) to an exploration by creator of exploration. Email will only be sent if recipient wants to receive these emails (i.e. 'can_receive_editor_role_email' is set True in recipent's preferences). """ # Editor role email body and email subject templates. email_subject_template = ('%s - invitation to collaborate') email_body_template = ( 'Hi %s,<br>' '<br>' '<b>%s</b> has granted you %s to their exploration, ' '"<a href="http://www.oppia.org/create/%s">%s</a>", on Oppia.org.<br>' '<br>' 'This allows you to:<br>' '<ul>%s</ul>' 'You can find the exploration ' '<a href="http://www.oppia.org/create/%s">here</a>.<br>' '<br>' 'Thanks, and happy collaborating!<br>' '<br>' 'Best wishes,<br>' 'The Oppia Team<br>' '<br>%s') # Return from here if sending email is turned off. if not feconf.CAN_SEND_EMAILS: log_new_error('This app cannot send emails to users.') return # Return from here is sending editor role email is disabled. if not feconf.CAN_SEND_EDITOR_ROLE_EMAILS: log_new_error('This app cannot send editor role emails to users.') return recipient_user_settings = user_services.get_user_settings(recipient_id) inviter_user_settings = user_services.get_user_settings(inviter_id) recipient_preferences = user_services.get_email_preferences(recipient_id) if not recipient_preferences['can_receive_editor_role_email']: # Do not send email if recipient has declined. return if recipient_role not in EDITOR_ROLE_EMAIL_HTML_ROLES: raise Exception('Invalid role: %s' % recipient_role) role_descriptipn = EDITOR_ROLE_EMAIL_HTML_ROLES[recipient_role] rights_html = EDITOR_ROLE_EMAIL_RIGHTS_FOR_ROLE[role_descriptipn] email_subject = email_subject_template % exploration_title email_body = email_body_template % ( recipient_user_settings.username, inviter_user_settings.username, role_descriptipn, exploration_id, exploration_title, rights_html, exploration_id, EMAIL_FOOTER.value) _send_email(recipient_id, feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_EDITOR_ROLE_NOTIFICATION, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS, sender_name=inviter_user_settings.username)
def send_role_notification_email( inviter_id, recipient_id, recipient_role, exploration_id, exploration_title): """Sends a email when a new user is given activity rights (Manager, Editor, Viewer) to an exploration by creator of exploration. Email will only be sent if recipient wants to receive these emails (i.e. 'can_receive_editor_role_email' is set True in recipent's preferences). Args: inviter_id: str. ID of the user who invited the recipient to the new role. recipient_id: str. User ID of the recipient. recipient_role: str. Role given to the recipient. Must be defined in EDITOR_ROLE_EMAIL_HTML_ROLES. exploration_id: str. ID of the exploration for which the recipient has been given the new role. exploration_title: str. Title of the exploration for which the recipient has been given the new role. Raises: Exception: The role is invalid (i.e. not defined in EDITOR_ROLE_EMAIL_HTML_ROLES). """ # Editor role email body and email subject templates. email_subject_template = ( '%s - invitation to collaborate') email_body_template = ( 'Hi %s,<br>' '<br>' '<b>%s</b> has granted you %s to their exploration, ' '"<a href="http://www.oppia.org/create/%s">%s</a>", on Oppia.org.<br>' '<br>' 'This allows you to:<br>' '<ul>%s</ul>' 'You can find the exploration ' '<a href="http://www.oppia.org/create/%s">here</a>.<br>' '<br>' 'Thanks, and happy collaborating!<br>' '<br>' 'Best wishes,<br>' 'The Oppia Team<br>' '<br>%s') # Return from here if sending email is turned off. if not feconf.CAN_SEND_EMAILS: log_new_error('This app cannot send emails to users.') return # Return from here is sending editor role email is disabled. if not feconf.CAN_SEND_EDITOR_ROLE_EMAILS: log_new_error('This app cannot send editor role emails to users.') return recipient_user_settings = user_services.get_user_settings(recipient_id) inviter_user_settings = user_services.get_user_settings(inviter_id) recipient_preferences = user_services.get_email_preferences(recipient_id) if not recipient_preferences.can_receive_editor_role_email: # Do not send email if recipient has declined. return if recipient_role not in EDITOR_ROLE_EMAIL_HTML_ROLES: raise Exception( 'Invalid role: %s' % recipient_role) role_description = EDITOR_ROLE_EMAIL_HTML_ROLES[recipient_role] rights_html = EDITOR_ROLE_EMAIL_RIGHTS_FOR_ROLE[role_description] email_subject = email_subject_template % exploration_title email_body = email_body_template % ( recipient_user_settings.username, inviter_user_settings.username, role_description, exploration_id, exploration_title, rights_html, exploration_id, EMAIL_FOOTER.value) _send_email( recipient_id, feconf.SYSTEM_COMMITTER_ID, feconf.EMAIL_INTENT_EDITOR_ROLE_NOTIFICATION, email_subject, email_body, feconf.NOREPLY_EMAIL_ADDRESS, sender_name=inviter_user_settings.username)