Beispiel #1
0
def test_add_address_to_mailchimp_existing(requests_mock, user):
    user.settings = {"email": {"marketing": True}}

    email1 = EmailAddress.objects.add_email(None, user,
                                            "*****@*****.**")

    email2 = EmailAddress.objects.add_email(None, user, "*****@*****.**")
    email2.set_as_primary()

    id = get_subscriber_hash("*****@*****.**")

    adapter = requests_mock.put(MAILCHIMP_TEST_ENDPOINT +
                                "lists/test-list-key-id/members/" + id,
                                json={
                                    "email_address": "*****@*****.**",
                                    "unique_email_id": "12345",
                                    "status": "subscribed",
                                    "list_id": "test-list-key-id"
                                })

    signals.email_changed.send(sender=None,
                               request=None,
                               user=user,
                               from_email_address=email1,
                               to_email_address=email2)

    assert adapter.last_request.json() == {
        "email_address": "*****@*****.**",
        "status_if_new": "subscribed"
    }
Beispiel #2
0
    def update_member(self, user: User) -> None:
        """
        Update a single users data. 
        """
        subscription_status = self.get_status(user=user)
        try:
            response = self.client.lists.members.create_or_update(
                list_id=self.list_id,
                subscriber_hash=get_subscriber_hash(member_email=user.email),
                data={
                    'email_address': user.email,
                    'status': subscription_status,
                    'status_if_new': subscription_status,
                    'merge_fields': {
                        'FNAME': user.first_name,
                        'LNAME': user.last_name,
                    }
                })
            logger.info(response)

        except requests.HTTPError:
            # This usually means that the person has unsubscribed via MailChimp.
            # If this is the case, unsubscribe the user - and don't submit this
            # to the API via signal!
            if not self.is_active_member(user=user):
                from .signals import update_newsletter_subscription
                post_save.disconnect(update_newsletter_subscription,
                                     sender=User)
                user.unsubscribe()
                post_save.connect(update_newsletter_subscription, sender=User)
Beispiel #3
0
def synchronize_mailchimp_email(client,
                                list_id,
                                email,
                                merge_fields,
                                email_type='Email'):
    '''Handles common exceptions thrown by Mailchimp when synchronizing.
    '''
    try:
        # Create or update subscriber
        client.lists.members.create_or_update(
            list_id=list_id,
            subscriber_hash=get_subscriber_hash(email),
            data={
                'email_address': email,
                'status': SUBSCRIBED,
                'status_if_new': SUBSCRIBED,
                'merge_fields': merge_fields
            })
    except HTTPError as ex:
        # Handle Mailchimp complaining about potentially faulty data, don't synchronize
        if ex.response.status_code == 400 and 'fake' in ex.response.content:
            logger.warning(
                'Unable to synchronize `%s %s`, they are suspected to have a fake email'
                % (email_type, email))
        else:
            logger.warning(
                'Unable to synchronize `%s %s`, an unknown error occured' %
                (email_type, email))
    except ValueError:
        # Someone didn't give a valid email
        logger.warning('Unable to synchronize `%s %s`, invalid email' %
                       (email_type, email))
Beispiel #4
0
def test_sync_premium_accounts_for_paypal_subscription_existing(
        requests_mock, user):
    id = get_subscriber_hash("*****@*****.**")
    current_time = datetime.now(tz=timezone.utc)

    agreement = _create_billing_agreement(user, current_time,
                                          current_time + timedelta(days=100))

    EmailAddress.objects.add_email(None, user, "*****@*****.**")
    event = WebhookEvent(resource_type="agreement",
                         resource=agreement.__dict__)

    _stub_stripe_api(requests_mock)

    members_endpoint = _stub_mailchimp_create_or_update(
        requests_mock, "*****@*****.**")
    tag_endpoint = requests_mock.post(MAILCHIMP_TEST_ENDPOINT +
                                      "lists/test-list-key-id/members/" + id +
                                      "/tags",
                                      json={})

    group, created = Group.objects.get_or_create(
        name="mailchimp:premium-subscriber")
    group.user_set.add(user)

    sync_premium_accounts_for_paypal_subscription(None, event)

    assert members_endpoint.last_request is None
    assert tag_endpoint.last_request is None
Beispiel #5
0
def test_add_address_to_mailchimp(requests_mock, user):
    user.settings = {"email": {"marketing": True}}

    email = EmailAddress.objects.add_email(None, user, "*****@*****.**")
    email.set_as_primary()
    email.save()

    adapter = requests_mock.post(
        MAILCHIMP_TEST_ENDPOINT + "lists/test-list-key-id/members",
        json={
            "id": get_subscriber_hash("*****@*****.**"),
            "email_address": "*****@*****.**",
            "unique_email_id": "12345",
            "status": "subscribed",
            "list_id": "test-list-key-id"
        })

    signals.email_changed.send(sender=None,
                               request=None,
                               user=user,
                               from_email_address=None,
                               to_email_address=email)

    assert adapter.last_request.json() == {
        "email_address": "*****@*****.**",
        "status": "subscribed"
    }
Beispiel #6
0
def test_sync_premium_accounts_for_stripe_subscription(requests_mock, user):
    user.settings = {"email": {"marketing": True}}
    user.save()

    id = get_subscriber_hash("*****@*****.**")

    customer = _create_stripe_customer(user)
    EmailAddress.objects.add_email(None, user, "*****@*****.**")
    event = _create_stripe_event(user)

    _stub_stripe_api(requests_mock, stripe_id=customer.stripe_id)

    members_endpoint = _stub_mailchimp_create_or_update(
        requests_mock, "*****@*****.**")
    tag_endpoint = requests_mock.post(MAILCHIMP_TEST_ENDPOINT +
                                      "lists/test-list-key-id/members/" + id +
                                      "/tags",
                                      json={})

    sync_premium_accounts_for_stripe_subscription(event)

    assert members_endpoint.last_request.json() == {
        "email_address": "*****@*****.**",
        "status_if_new": "subscribed"
    }
    assert tag_endpoint.last_request.json() == {
        "tags": [{
            "name": "Premium Subscriber",
            "status": "active"
        }]
    }

    group = Group.objects.get(name="mailchimp:premium-subscriber")
    assert user in group.user_set.all()
Beispiel #7
0
def test_sync_premium_accounts_for_stripe_subscription_existing(
        requests_mock, user):
    user.settings = {"email": {"marketing": True}}

    id = get_subscriber_hash("*****@*****.**")

    customer = _create_stripe_customer(user)
    EmailAddress.objects.add_email(None, user, "*****@*****.**")
    event = _create_stripe_event(user)

    _stub_stripe_api(requests_mock, stripe_id=customer.stripe_id)

    members_endpoint = _stub_mailchimp_create_or_update(
        requests_mock, "*****@*****.**")
    tag_endpoint = requests_mock.post(MAILCHIMP_TEST_ENDPOINT +
                                      "lists/test-list-key-id/members/" + id +
                                      "/tags",
                                      json={})

    group, created = Group.objects.get_or_create(
        name="mailchimp:premium-subscriber")
    group.user_set.add(user)

    sync_premium_accounts_for_stripe_subscription(event)

    assert members_endpoint.last_request is None
    assert tag_endpoint.last_request is None
Beispiel #8
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)
Beispiel #9
0
def update_mailchimp(modeladmin, request, queryset):
    
    valid_contacts = queryset.filter(email__isnull=False)

    client = MailChimp(mc_api=settings.MAILCHIMP_API, mc_user=settings.MAILCHIMP_USER)

    listas = client.lists.all(get_all=True, fields="lists.name,lists.id")
    lista = listas['lists'][0]['id']

    for p in valid_contacts:
        user_hash = get_subscriber_hash(p.email)

        contact = {
            'email_address': p.email,
            'status_if_new': 'subscribed',
            'merge_fields': {
                'FNAME': p.nome,
                'LNAME': p.sobrenome,
                'CITY' : p.cidade,
                'STATE' : p.estado,
                'ORG' : p.entidade.first().nome if p.entidade.first() else '',
                'SENSIBLE' : '',
                'EVENTS' : '',
                'PHONE' : p.telefone,
                'ADDRESS' : p.endereco,
                'GENDER' :  p.sexo.nome if p.sexo else '',
                'AGE' : p.idade()
            },
            'tags' : [],
        }

        contact['merge_fields'] = return_empty(contact['merge_fields'])

        resultado = client.lists.members.create_or_update(lista, user_hash, return_empty(contact))
    modeladmin.message_user(request, '{} contatos atualizados.'.format(valid_contacts.count()))
Beispiel #10
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})
Beispiel #11
0
    def _validate_profile(self, payload):
        """
        Returns an active Profile that matches the claims's user_id.
        """

        user_id = payload.get("sub")
        try:
            auth_user = AuthUser.objects.get(user_id=user_id)
            profile = auth_user.profile
        except AuthUser.DoesNotExist:
            user_info = get_user_info(user_id)
            profile, is_new = get_or_create_safeish(Profile, email=user_info["email"])

            if is_new is True:
                profile.first_name = user_info["first_name"]
                profile.last_name = user_info["last_name"]
                profile.save()

                if (
                    settings.MC_API_KEY is not None
                    and settings.MC_USER is not None
                    and settings.MC_LIST_ID is not None
                ):
                    from mailchimp3 import MailChimp
                    from mailchimp3.helpers import get_subscriber_hash

                    # https://developer.mailchimp.com/documentation/mailchimp/guides/manage-subscribers-with-the
                    # -mailchimp-api/
                    try:
                        client = MailChimp(
                            mc_api=settings.MC_API_KEY, mc_user=settings.MC_USER
                        )

                        client.lists.members.create_or_update(
                            settings.MC_LIST_ID,
                            get_subscriber_hash(profile.email),
                            {
                                "email_address": profile.email,
                                "status_if_new": "pending",
                                "merge_fields": {
                                    "FNAME": profile.first_name,
                                    "LNAME": profile.last_name,
                                    "API": "yes",
                                },
                            },
                        )
                    except:  # Don't ever fail because subscription didn't work
                        logger.error(
                            "Unable to create mailchimp member {} {} <{}>".format(
                                profile.first_name, profile.last_name, profile.email
                            )
                        )

        get_or_create_safeish(AuthUser, profile=profile, user_id=user_id)

        return profile
Beispiel #12
0
def unsubscribe_user(
    email_address,
    list_id=settings.MAILCHIMP_LIST_ID,
):

    client = get_client()
    client.lists.members.delete(
        list_id=list_id, subscriber_hash=get_subscriber_hash(email_address))

    return
Beispiel #13
0
 def is_active_member(self, user: User) -> bool:
     try:
         response = self.client.lists.members.get(
             list_id=self.list_id,
             subscriber_hash=get_subscriber_hash(member_email=user.email))
     except requests.HTTPError:
         # Invalid request -> the user doesn't exist on MailChimp and
         # therefore is not subscribed.
         return False
     return response.get('status', '') == 'subscribed'
Beispiel #14
0
def _stub_mailchimp_create_or_update(requests_mock, email):
    id = get_subscriber_hash(email)
    return requests_mock.put(MAILCHIMP_TEST_ENDPOINT +
                             "lists/test-list-key-id/members/" + id,
                             json={
                                 "id": id,
                                 "email_address": email,
                                 "unique_email_id": "12345",
                                 "status": "subscribed",
                                 "list_id": "test-list-key-id"
                             })
Beispiel #15
0
def main_post():
    # mc_user will be removed in v2.1.0
    mc = MailChimp(mc_secret=app.config['MAILCHIMP_KEY'], mc_user='******')
    try:
        email = request.form.get('email')

        try:
            data = mc.lists.members.create_or_update(
                list_id=app.config['MAILCHIMP_LIST'],
                subscriber_hash=get_subscriber_hash(email),
                data={'email_address': email, 'status': 'subscribed', 'status_if_new': 'pending'}
            )
            status = data.get('status')
            if status == 'pending':
                flash('Thanks for subscribing! You will receive a confirmation email shortly.')
            elif status == 'subscribed':
                flash('You were already subscribed! Thanks for checking back.')
            else:
                raise ValueError('Unexpected status %s' % status)

        except ValueError as e:
            # ugh, this library is awful
            app.logger.info('ValueError from mailchimp3 %s, assuming bad email: %r', e, email)
            flash("Your email address was not accepted - please check and try again.")

        # should also be changed to exceptions in v2.1.0
        except HTTPError as e:
            if e.response.status_code != 400:
                raise

            data = e.response.json()
            title = data.get('title')
            if title == "Member In Compliance State":
                app.logger.info('Member in compliance state: %r', email)
                flash("""You've already been unsubscribed from our list, so we can't add you again.
                         Please contact %s to update your settings.""" % app.config['TICKETS_EMAIL'][1])

            elif title == 'Invalid Resource':
                app.logger.warn('Invalid Resource from MailChimp, assuming bad email: %r', email)
                flash("Your email address was not accepted - please check and try again.")

            else:
                app.logger.warn('MailChimp returned %s: %s', title, data.get('detail'))
                flash('Sorry, an error occurred: %s.' % (title or 'unknown'))

    except Exception as e:
        app.logger.error('Error subscribing: %r', e)
        flash('Sorry, an error occurred.')

    return redirect(url_for('.main'))
Beispiel #16
0
    def save(self, request):
        email = self.cleaned_data['email']

        mailchimp_settings = MailchimpSettings.for_site(request.site)
        client = mailchimp_settings.get_client()
        list_id = mailchimp_settings.newsletter_list
        hash = get_subscriber_hash(email)

        client.lists.members.create_or_update(
            list_id, hash, {
                'email_address': email,
                'status': 'subscribed',
                'status_if_new': 'subscribed',
            })
Beispiel #17
0
def subscribe_user(
    email_address,
    list_id=settings.MAILCHIMP_LIST_ID,
):

    client = get_client()
    client.lists.members.create_or_update(
        list_id=list_id,
        subscriber_hash=get_subscriber_hash(email_address),
        data={
            'email_address': email_address,
            'status_if_new': 'subscribed',
        })

    return
Beispiel #18
0
    def test_post_marketing_true_compliance(self, client, settings, user):
        user.emailaddress_set.add(
            EmailAddress.objects.create(user=user, email="*****@*****.**"))
        client.force_login(user, backend=settings.AUTHENTICATION_BACKENDS[0])

        mock_mailchimp_client = Mock()
        create_or_update = mock_mailchimp_client.lists.members.create_or_update
        create_or_update.side_effect = MailChimpError({
            "status":
            400,
            "title":
            "Member In Compliance State"
        })

        with patch("hsreplaynet.web.views.dashboard.get_mailchimp_client"
                   ) as get_client:
            get_client.return_value = mock_mailchimp_client
            response = client.post("/account/email/preferences/",
                                   {"marketing": "on"})

        assert response.status_code == 302

        create_or_update.assert_called_once_with(
            "test-list-key-id", get_subscriber_hash("*****@*****.**"), {
                "email_address": "*****@*****.**",
                "status_if_new": "subscribed",
                "status": "subscribed"
            })

        update = mock_mailchimp_client.lists.members.update
        update.assert_called_once_with("test-list-key-id",
                                       get_subscriber_hash("*****@*****.**"),
                                       {
                                           "email_address": "*****@*****.**",
                                           "status": "pending"
                                       })
Beispiel #19
0
def subscribe():
    """Subscribe email address to the newsletter"""
    data = request.get_json()
    try:
        client = MailChimp(current_app.config.get("MAILCHIMP_API_KEY"))

        subscribe_data = {
            "email_address": data["email"],
            "status_if_new": "subscribed"
        }

        interest_ids = current_app.config.get("MAILCHIMP_INTEREST_IDS",
                                              []).split(",")

        if interest_ids:
            subscribe_data["interests"] = {
                interest_id: True
                for interest_id in interest_ids
            }

        client.lists.members.create_or_update(
            current_app.config.get("MAILCHIMP_LIST_ID"),
            get_subscriber_hash(data["email"]),
            data=subscribe_data)

        return jsonify({"result": "subscribed"})

    except HTTPError as e:
        if e.response.status_code == 400:
            json = e.response.json()
            resp = json.get("errors") or json.get("detail") or json
            print(json.get("errors") or json.get("detail") or json)
            current_app.logger.error(
                "An HTTPError occurred subscribing email to MailChimp: {}".
                format(json.get("errors") or json.get("detail") or json))

    except Exception as e:
        current_app.logger.error(
            "An {} occurred subscribing email to MailChimp: {}".format(
                e.__class__, e))
        resp = "An error occurred: {} - {}".format(e.__class__, e)

    return jsonify({"result": resp}), 500
Beispiel #20
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})
Beispiel #21
0
def test_sync_premium_accounts_for_paypal_subscription(requests_mock, user):
    user.settings = {"email": {"marketing": True}}
    user.save()

    id = get_subscriber_hash("*****@*****.**")
    current_time = datetime.now(tz=timezone.utc)

    agreement = _create_billing_agreement(user, current_time,
                                          current_time + timedelta(days=100))

    EmailAddress.objects.add_email(None, user, "*****@*****.**")
    event = WebhookEvent(resource_type="agreement",
                         resource=agreement.__dict__)

    _stub_stripe_api(requests_mock)

    members_endpoint = _stub_mailchimp_create_or_update(
        requests_mock, "*****@*****.**")
    tag_endpoint = requests_mock.post(MAILCHIMP_TEST_ENDPOINT +
                                      "lists/test-list-key-id/members/" + id +
                                      "/tags",
                                      json={})

    sync_premium_accounts_for_paypal_subscription(None, event)

    assert members_endpoint.last_request.json() == {
        "email_address": "*****@*****.**",
        "status_if_new": "subscribed"
    }
    assert tag_endpoint.last_request.json() == {
        "tags": [{
            "name": "Premium Subscriber",
            "status": "active"
        }]
    }

    group = Group.objects.get(name="mailchimp:premium-subscriber")
    assert user in group.user_set.all()
Beispiel #22
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})
Beispiel #23
0
def main_post():
    mc = MailChimp(mc_api=app.config["MAILCHIMP_KEY"])
    try:
        email = request.form.get("email")

        try:
            data = mc.lists.members.create_or_update(
                list_id=app.config["MAILCHIMP_LIST"],
                subscriber_hash=get_subscriber_hash(email),
                data={
                    "email_address": email,
                    "status": "subscribed",
                    "status_if_new": "pending",
                },
            )
            status = data.get("status")
            if status == "pending":
                flash(
                    "Thanks for subscribing! You will receive a confirmation email shortly."
                )
            elif status == "subscribed":
                flash("You were already subscribed! Thanks for checking back.")
            else:
                raise ValueError("Unexpected status %s" % status)

        except ValueError as e:
            # ugh, this library is awful
            app.logger.info(
                "ValueError from mailchimp3 %s, assuming bad email: %r", e,
                email)
            flash(
                "Your email address was not accepted - please check and try again."
            )

        # should also be changed to exceptions in v2.1.0
        except HTTPError as e:
            if e.response.status_code != 400:
                raise

            data = e.response.json()
            title = data.get("title")
            if title == "Member In Compliance State":
                app.logger.info("Member in compliance state: %r", email)
                flash(
                    """You've already been unsubscribed from our list, so we can't add you again.
                         Please contact %s to update your settings.""" %
                    app.config["TICKETS_EMAIL"][1])

            elif title == "Invalid Resource":
                app.logger.warn(
                    "Invalid Resource from MailChimp, assuming bad email: %r",
                    email)
                flash(
                    "Your email address was not accepted - please check and try again."
                )

            else:
                app.logger.warn("MailChimp returned %s: %s", title,
                                data.get("detail"))
                flash("Sorry, an error occurred: %s." % (title or "unknown"))

    except Exception as e:
        app.logger.error("Error subscribing: %r", e)
        flash("Sorry, an error occurred.")

    return redirect(url_for(".main"))
Beispiel #24
0
	def _construct_endpoint(self, email):
		return "%slists/123456/members/%s/tags" % (
			self.MAILCHIMP_TEST_ENDPOINT,
			get_subscriber_hash(email)
		)
Beispiel #25
0
def main_post():
    # mc_user will be removed in v2.1.0
    mc = MailChimp(mc_secret=app.config['MAILCHIMP_KEY'],
                   mc_user='******')
    try:
        email = request.form.get('email')

        try:
            data = mc.lists.members.create_or_update(
                list_id=app.config['MAILCHIMP_LIST'],
                subscriber_hash=get_subscriber_hash(email),
                data={
                    'email_address': email,
                    'status': 'subscribed',
                    'status_if_new': 'pending'
                })
            status = data.get('status')
            if status == 'pending':
                flash(
                    'Thanks for subscribing! You will receive a confirmation email shortly.'
                )
            elif status == 'subscribed':
                flash('You were already subscribed! Thanks for checking back.')
            else:
                raise ValueError('Unexpected status %s' % status)

        except ValueError as e:
            # ugh, this library is awful
            app.logger.info(
                'ValueError from mailchimp3 %s, assuming bad email: %r', e,
                email)
            flash(
                "Your email address was not accepted - please check and try again."
            )

        # should also be changed to exceptions in v2.1.0
        except HTTPError as e:
            if e.response.status_code != 400:
                raise

            data = e.response.json()
            title = data.get('title')
            if title == "Member In Compliance State":
                app.logger.info('Member in compliance state: %r', email)
                flash(
                    """You've already been unsubscribed from our list, so we can't add you again.
                         Please contact %s to update your settings.""" %
                    app.config['TICKETS_EMAIL'][1])

            elif title == 'Invalid Resource':
                app.logger.warn(
                    'Invalid Resource from MailChimp, assuming bad email: %r',
                    email)
                flash(
                    "Your email address was not accepted - please check and try again."
                )

            else:
                app.logger.warn('MailChimp returned %s: %s', title,
                                data.get('detail'))
                flash('Sorry, an error occurred: %s.' % (title or 'unknown'))

    except Exception as e:
        app.logger.error('Error subscribing: %r', e)
        flash('Sorry, an error occurred.')

    return redirect(url_for('.main'))
Beispiel #26
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."))