This is a newsletter addon for Websauna framework. It is intended for automatic newsletter generation from the site content.
- Automatic newsletter generation from site content
- Admin interface for newsletter preview and send
- Import all site users as newsletter subscribers
- Outbound email through Mailgun
- Unsubscribe management through Mailgun
- Redis based newsletter state management (when the last letter went out, etc.)
- Websauna's Celery based task subsystem is used to run long running operations asynchronously
To run this package you need Python 3.4+, PostgresSQL and Redis.
You need to provide your own site-specific INewsletter implementation that populates the news letter content.
Install this package using pip
.
You need to register a site specific newsletter that is responsible for rendering your newsletter HTML payload. Do this in your Initializer.configure_views
. Example:
# Configure newsletter renderer
from mysite.views.newsletter import NewsletterRenderer
from websauna.newsletter.interfaces import INewsletterGenerator
registry = self.config.registry
registry.registerAdapter(factory=NewsletterRenderer, required=(IRequest,), provided=INewsletterGenerator)
For more information see demo.py
.
In your renderer HTML code you can use Mailgun unsubscription management:
<p class="details">
{# For Mailgun #}
<a href="%mailing_list_unsubscribe_url%">Unsubscribe from TokenMarket newsletter.</a>
</p>
Add Mailgun API keys and such in myapp/conf/development-secrets.ini
.
Example:
[mailgun]
# Get from Mailgun
api_key = x
# What is the mailing list we use in the test suite
mailing_list = [email protected]
# Outbound domain used for the newslettering
domain = mailgun.websauna.org
# From: email we use to send the newsletter
from = MyApp Newsletter <[email protected]>
Easiest to do this through ws-shell
using production configuraition:
ws-shell tokenmarket/conf/production.ini
Then using %cpaste
notebook shell command:
from websauna.system.core.utils import get_secrets from websauna.newsletter.mailgun import Mailgun secrets = get_secrets(request.registry) list_address = secrets["mailgun.mailing_list"] mailgun = Mailgun(request.registry) mailgun.create_list(list_address, "MyApp newsletter")
You get a reply:
{'list': {'access_level': 'readonly', 'address': '[email protected]', 'created_at': 'Wed, 25 Jan 2017 17:08:56 -0000', 'description': 'TokenMarket newsletter', 'members_count': 0, 'name': ''}, 'message': 'Mailing list has been created'}
A boostrap based mini subscription form is provided with the packag. It is ideal e.g. to place in the site footer.
Simply in your template do:
<h3>Follow</h3> {% include "newsletter/subscription_form.html" %}
For more information run the demo and view demotemplates/site/footer.html
.
Visit Newsletter tab in the admin interface to preview and send out newsletters.
You can manually set the newsletter state, when the last newsletter was sent, from shell:
import datetime
from websauna.newsletter.state import NewsletterState
state = NewsletterState(request)
state.set_last_send_timestamp(datetime.datetime(2016, 12, 24).replace(tzinfo=datetime.timezone.utc))
State is managed in Redis.
In console:
from websauna.system.core.utils import get_secrets
from websauna.newsletter.mailgun import Mailgun
secrets = get_secrets(request.registry)
list_address = secrets["mailgun.mailing_list"]
mailgun = Mailgun(request.registry)
print(mailgun.list_members(list_address)) # TODO: pagination
Note that importing website users is supported in the admin interface.
Example:
subscribers = """
[email protected]
[email protected]
"""
from websauna.system.core.utils import get_secrets
from websauna.newsletter.mailgun import Mailgun
from websauna.newsletter.views import subscribe_email
secrets = get_secrets(request.registry)
list_address = secrets["mailgun.mailing_list"]
mailgun = Mailgun(request.registry)
for s in subscribers.split():
s = s.strip()
if s:
subscribe_email(request, s)
You can development this addon locally.
Activate the virtual environment of your Websauna application.
Then:
cd newsletter # This is the folder with setup.py file
pip install -e .
psql create newsletter_dev
ws-sync-db ws://websauna/newsletter/conf/development.ini
pserve ws://websauna/newsletter/conf/development.ini --reload
First create test database:
# Create database used for unit testing psql create newsletter_test
Install test and dev dependencies (run in the folder with setup.py
):
pip install -e ".[dev,test]"
Run test suite using py.test running:
py.test
Make sure Celery is not eager in development.ini
:
websauna.celery_config = { "broker_url": "redis://localhost:6379/15", "task_always_eager": False, }
Start demo (Terminal 1):
pserve ws://websauna/newsletter/conf/development.ini
Start Celery (Terminal 2):
ws-celery ws://websauna/newsletter/conf/development.ini -- worker
- Double confirmation to the mailing list subscription
Please see https://websauna.org/