This is a pre-production deployment of Warehouse, however changes made here WILL affect the production instance of PyPI.
Latest Version Dependencies status unknown Test status unknown Test coverage unknown
Project Description
django-chimpusers
=================

Integrates users from Django's authentication system `django.contrib.auth` with
a [MailChimp][1] email marketing list. Provides a model to store opt-in data
and a form factory to allow users to edit their [interest groups][3].


Requirements
------------

* [MailSnake][10], a Python wrapper for the [MailChimp v1.3 API][2]. You can
install MailSnake using `easy_install` or `pip`:

pip install mailsnake

* The API key for your MailChimp account. [Where can I find my API key?][4]
* The ID of the list you want to integrate with. [How can I find my List ID?][5]


Installation
------------

For the latest stable version, install using `easy_install` or `pip`:

pip install django-chimpusers

For the latest development version, install from the git repository.

git clone git@github.com:Quixotix/django-chimpusers.git
setup.py install django-chimpusers

Then, add `chimpusers` to your installed apps and sync the database:

./manage.py syncdb


Settings
--------

* `MAILCHIMP_API_KEY` - [required] Your MailChimp API key.
* `MAILCHIMP_LIST_ID` - [required] The list ID of the MailChimp list you want to integrate
with.
* `MAILCHIMP_TEST_IP` - [optional] A __public__ IP address to use with the test cases. This
must be a public IP for the tests to pass.


How it Works
------------

### The UserSubscription Model

A `UserSubscription` model is created each time a `User` is created. This model
simply provides some convenience methods that wrap MailSnake calls to the
MailChimp API. It also stores the user's subscription status, opt-in IP addresss,
and opt-in date.

You would typically use `UserSubscription` when you register or activate new
members or in a specific view for subscribing to your email list. (You make
sure your users are opting in right? They should be physically checking a check
box, clicking a big "subscribe" button, etc. Don't spam folks, they don't like
it)

__UserSubscription.subscribe()__

The `UserSubscription.subscribe()` calls [listSubscribe][6], automatically
adding the list ID, the user's email, the user's first name, and the user's
last name. All other parameters defined for [listSubscribe][6] can be passed
to `UserSubscription.subscribe()` as keyword arguments (again, it just wraps
MailSnake).

from chimpusers.models import UserSubscription

# ...

subscription = UserSubscription.objects.get(user=request.user)
subscription.subscribe() # double_optin is True by default

If the MailChimp API returns an error (say the email is already subscribed), you
can catch the `MailChimpError` eception.

from chimpusers.models import UserSubscription
from chimpusers.exceptions import MailChimpError

# ...

subscription = UserSubscription.objects.get(user=request.user)
try:
subscription.subscribe() # double_optin is True by default
except MailChimpError as e:
# Handle exception. Message will be that returned by MailChimp.
pass

When you subscribe a user you should save the user's IP address and a timestamp
as opt-in "proof".

from datetime import datetime
from chimpusers.models import UserSubscription

# ...

subscription = UserSubscription.objects.get(user=request.user)
optin_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
if 'HTTP_X_FORWARDED_FOR' in request.META: # IP forwarded from proxy
optin_ip = request.META['HTTP_X_FORWARDED_FOR']
else:
optin_ip = request.META['REMOTE_ADDR']
merge_vars = {'OPTIN_IP': optin_ip, 'OPTIN_TIME': optin_time}

subscription.subscribe(merge_vars=merge_vars)

And just to drive home the point that the `UserSubscription.subscribe()` just
wraps a MailSnake call to [listSubscribe][6]...

from chimpusers.models import UserSubscription

# ...

subscription = UserSubscription.objects.get(user=request.user)
subscription.subscribe(email_type="text",
double_optin=False,
update_existing=True,
replace_interests=False,
send_welcome=True)


__UserSubscription.update()__

The `UserSubscription.update()` calls [listMemberUpdate][7], automatically
adding the list ID, the user's email, the user's first name, and the user's
last name. All other parameters defined for [listMemberUpdate][7] can be passed
to `UserSubscription.update()` as keyword arguments.

from chimpusers.models import UserSubscription

# ...

subscription = UserSubscription.objects.get(user=request.user)
merge_vars = {"GROUPINGS": [{"name":"Interest Groups",
"groups":"Monthly Newsletter,New Products"}]}
subscription.update(merge_vars=merge_vars)


__UserSubscription.unsubscribe()__

The `UserSubscription.unsubscribe()` calls [listUnsubscribe][8], automatically
adding the list ID and the user's email. All other parameters defined for
[listUnsubscribe][8] can be passed to `UserSubscription.unsubscribe()` as
keyword arguments.

from chimpusers.models import UserSubscription

# ...

subscription = UserSubscription.objects.get(user=request.user)
subscription.unsubscribe(send_goodbye=False, send_notify=True)


__UserSubscription.sync()__

The `UserSubscription` model provides the `sync` method to synchronize the model
fields with the MailChimp API. Since the user or an administrator can manipulate
subscriptions from the MailChimp website and you _may_ not have any [webhooks][9]
setup yet, syncing the `UserSubscription` can come in handy.

from chimpusers.models import UserSubscription

# ...

subscription = UserSubscription.objects.get(user=request.user)
subscription.sync()
# the following fields are now in sync with MailChimp
# subscription.status
# subscription.optin_ip
# subscription.optin_time


### The groups_form_factory Form Factory

One of the great features of MailChimp is to segregate your list into various
interest [groups][3]. This allows you to maintain one list for your website's
users and allow them to sign up for one or more groups.

For example, an e-commerce website may have a list of all their customers, and
groups to allow their customers to recieve a monthly newsletter, another group
for new product announcements, and another group for holiday promotions.

The `groups_form_factory()` function dynamically generates a form for opting in
and out of your list's groups. This could be used in a view allowing existing
subscribers to modify their group preferences or combined with a registration
form to allow new subscribers to opt-in to specific groups at sign up.

from chimpusers.models import UserSubscription
from chimpusers.forms import groups_form_factory
from datetime import datetime

# ...

subscription = UserSubscription.objects.get(user=request.user)
GroupsForm = groups_form_factory(request.user.email)

if request.method == 'POST':
form = GroupsForm(request.post)
if form.is_valid():
merge_vars = {'GROUPINGS': [form.merge_var]}
if subscription.is_subscribed():
# update user's groups
subscription.update(merge_vars=merge)
else:
# subscribe
optin_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
if 'HTTP_X_FORWARDED_FOR' in request.META:
optin_ip = request.META['HTTP_X_FORWARDED_FOR']
else:
optin_ip = request.META['REMOTE_ADDR']
merge['OPTIN_IP'] = optin_ip
merge['OPTIN_TIME'] = optin_time
subscription.subscribe(merge_vars=merge)
else:
form = GroupsForm()

# ...


[1]: http://mailchimp.com
[2]: http://apidocs.mailchimp.com/api/1.3/
[3]: http://mailchimp.com/features/groups/
[4]: http://kb.mailchimp.com/article/where-can-i-find-my-api-key/
[5]: http://kb.mailchimp.com/article/how-can-i-find-my-list-id/
[6]: http://apidocs.mailchimp.com/api/1.3/listsubscribe.func.php
[7]: http://apidocs.mailchimp.com/api/1.3/listupdatemember.func.php
[8]: http://apidocs.mailchimp.com/api/1.3/listunsubscribe.func.php
[9]: http://apidocs.mailchimp.com/webhooks/
[10]: https://github.com/leftium/mailsnake
Release History

Release History

0.1.8

This version

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.1.6

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.1.5

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.1.4

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.1.0

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

Download Files

Download Files

TODO: Brief introduction on what you do with files - including link to relevant help section.

File Name & Checksum SHA256 Checksum Help Version File Type Upload Date
django-chimpusers-0.1.8.tar.gz (15.2 kB) Copy SHA256 Checksum SHA256 Source Sep 15, 2012

Supported By

WebFaction WebFaction Technical Writing Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS HPE HPE Development Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Rackspace Rackspace Cloud Servers DreamHost DreamHost Log Hosting