Exemple #1
0
    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)
Exemple #2
0
    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})
Exemple #3
0
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})
Exemple #4
0
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})
Exemple #5
0
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"
Exemple #6
0
def test_get_mailchimp_subscription_status_false(user):
	user.settings = {"email": {"marketing": False}}
	assert get_mailchimp_subscription_status(user) == "unsubscribed"
Exemple #7
0
def test_get_mailchimp_subscription_status_true(user):
	user.settings = {"email": {"marketing": True}}
	assert get_mailchimp_subscription_status(user) == "subscribed"
Exemple #8
0
    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."))