def post(self, request): marketing_prefs = request.POST.get("marketing", "") == "on" request.user.settings["email"] = { "marketing": marketing_prefs, "updated": timezone.now().isoformat(), } request.user.save() try: client = get_mailchimp_client() email = find_best_email_for_user(request.user) client.lists.members.create_or_update( settings.MAILCHIM_LIST_KEY_ID, get_subscriber_hash(email.email), { "email_address": email.email, "status_if_new": get_mailchimp_subscription_status(request.user) }) except Exception as e: log.warning("Failed to contact MailChimp API: %s" % e) influx_metric("mailchimp_request_failures", {"count": 1}) messages.info(request, _("Your email preferences have been saved.")) return redirect(self.success_url)
def _publish_tag_changes(self, user, email_str, tags_to_add, tags_to_remove, verbose=False): list_key_id = settings.MAILCHIMP_LIST_KEY_ID email_hash = get_subscriber_hash(email_str) client = get_mailchimp_client() # We may never have seen this user's email address before or sent it to MailChimp, # so do a defensive subscriber creation. try: client.lists.members.create_or_update( list_key_id, email_hash, { "email_address": email_str, "status_if_new": get_mailchimp_subscription_status(user) }) influx_metric("mailchimp_requests", {"count": 1}, method="create_or_update") self.mailchimp_api_requests += 1 # Tell MailChimp to add any tags that we added locally. if len(tags_to_add) > 0: tag_names = list(map(lambda tag: tag.name, tags_to_add)) if verbose: print( f"Sending request to add tags {tag_names} to {email_str}" ) client.lists.members.tags.add(list_key_id, email_hash, tag_names) influx_metric("mailchimp_requests", {"count": 1}, method="add_tags") self.mailchimp_api_requests += 1 # Tell MailChimp to remove any tags that we removed locally. if len(tags_to_remove) > 0: tag_names = list(map(lambda tag: tag.name, tags_to_remove)) if verbose: print( f"Sending request to remove tags {tag_names} from {email_str}" ) client.lists.members.tags.delete(list_key_id, email_hash, tag_names) influx_metric("mailchimp_requests", {"count": 1}, method="delete_tags") self.mailchimp_api_requests += 1 except Exception as e: print("Failed to contact MailChimp API: %s" % e, flush=True) influx_metric("mailchimp_request_failures", {"count": 1})
def add_address_to_mailchimp(request, user, from_email_address, to_email_address, **_): """Signal handler for the email_changed event to add or update emails in MailChimp""" client = get_mailchimp_client() try: if from_email_address: # If there was a previous email address, we may (or may not) have added it to # our list in MailChimp already, along with zero or more tags. So let's try to # update it via the subscriber hash of the _previous_ address and update the # email address to the _new_ address. client.lists.members.create_or_update( settings.MAILCHIMP_LIST_KEY_ID, get_subscriber_hash(from_email_address.email), { "email_address": to_email_address.email, "status_if_new": get_mailchimp_subscription_status(user) }) influx_metric("mailchimp_requests", {"count": 1}, method="create_or_update") else: # But if there was no previous primary address, just add a new list member. client.lists.members.create( settings.MAILCHIMP_LIST_KEY_ID, { "email_address": to_email_address.email, "status": get_mailchimp_subscription_status(user) }) influx_metric("mailchimp_requests", {"count": 1}, method="create") except Exception as e: log.warning("Failed to contact MailChimp API: %s" % e) influx_metric("mailchimp_request_failures", {"count": 1})
def _update_mailchimp_tags_for_premium_subscriber(user): email = find_best_email_for_user(user) if email: tag = PremiumSubscriberTag() if tag.should_apply_to(user) and tag.add_user_to_tag_group(user): client = get_mailchimp_client() list_key_id = settings.MAILCHIMP_LIST_KEY_ID email_hash = get_subscriber_hash(email.email) # At this point we have no idea whether the user's email address is already # registered with MailChimp, so do a defensive create-or-update to make sure # it's on the list before we give them the premium tag. try: client.lists.members.create_or_update( list_key_id, email_hash, { "email_address": email.email, "status_if_new": get_mailchimp_subscription_status(user), }) influx_metric("mailchimp_requests", {"count": 1}, method="create_or_update") # ...then assign the premium tag. client.lists.members.tags.add(list_key_id, email_hash, tag.name) influx_metric("mailchimp_requests", {"count": 1}, method="add_tags") except Exception as e: log.warning("Failed to contact MailChimp API: %s" % e) influx_metric("mailchimp_request_failures", {"count": 1})
def test_get_mailchimp_subscription_status_missing(user): user.settings = {} assert get_mailchimp_subscription_status(user) == "unsubscribed" user.settings = {"email": {}} assert get_mailchimp_subscription_status(user) == "unsubscribed"
def test_get_mailchimp_subscription_status_false(user): user.settings = {"email": {"marketing": False}} assert get_mailchimp_subscription_status(user) == "unsubscribed"
def test_get_mailchimp_subscription_status_true(user): user.settings = {"email": {"marketing": True}} assert get_mailchimp_subscription_status(user) == "subscribed"
def post(self, request): marketing_prefs = request.POST.get("marketing", "") == "on" client = get_mailchimp_client() try: request.user.settings["email"] = { "marketing": marketing_prefs, "updated": timezone.now().isoformat(), } status = get_mailchimp_subscription_status(request.user) email = find_best_email_for_user(request.user) try: client.lists.members.create_or_update( settings.MAILCHIMP_LIST_KEY_ID, get_subscriber_hash(email.email), { "email_address": email.email, "status_if_new": status, "status": status }) except MailChimpError as e: # The request to Mailchimp may fail if the user unsubscribed via the # Mailchimp interface (through a link in an email footer, e.g.). In this # case, they can only resubscribe through a confirmation email. Setting the # user's status to 'pending' will trigger the confirmation email to be sent. args = e.args[0] if (args.get("status") == 400 and args.get("title") == "Member In Compliance State"): client.lists.members.update( settings.MAILCHIMP_LIST_KEY_ID, get_subscriber_hash(email.email), { "email_address": email.email, "status": "pending" }) influx_metric("mailchimp_requests", {"count": 1}, method="update") return self._redirect_with_message( request, _("Check your inbox! We've sent an email to confirm your subscription preferences." )) else: self._log_mailchimp_error(e) return self._redirect_with_message( request, _("Failed to save your email preferences. Please try again later!" )) except Exception as e: self._log_mailchimp_error(e) return self._redirect_with_message( request, _("Failed to save your email preferences. Please try again later!" )) # Only save the user record if we were actually able to sync the marketing # preferences with Mailchimp. request.user.save() influx_metric("mailchimp_requests", {"count": 1}, method="create_or_update") return self._redirect_with_message( request, _("Your email preferences have been saved."))