Drip campaigns are pre-written sets of emails sent to customers or prospects over time. Django Drips lets you use the admin to manage drip campaign emails using querysets on Django's User model.
This project is a fork of the one written by Zapier.
pip install django-drip-campaigns
'drip'
to your INSTALLED_APPS
list on your settings.```python INSTALLED_APPS = [ 'django.contrib.contenttypes', 'django.contrib.comments', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin',
# ...
'drip',
] ```
(Optional) Set DRIP_FROM_EMAIL = '<your_app_from_email>'
in your settings, where <your_app_from_email>
is the email account that is going to be shown in the sent emails. Otherwise EMAIL_HOST_USER
value will be used.
Finally, run python manage.py migrate drip
to set up the necessary database tables.
If you haven't, create a superuser with the Django createsuperuser command. Login with the admin user, and select Drips
to manage them. You will be able to:
Now you can also manage campaigns, select Campaigns
to manage them. You will be able to:
- View created campaigns.
- Create a new campaign.
- Select and delete campaign.
In the Django admin, after select Campaigns
, you can click on ADD CAMPAIGN +
button to create a new one. You will see the add campaign
page:
When you create a campaign, you need to decide if the related drips will be deleted along with the campaign, using the Delete drips
field.
Here you will find an inline creation or edition for Drips
this will not include the QUERY SET RULES
section. It will only allow you to change the mail content in the Drip.
Campaigns will allow you to manage many Drips that need to be related between them.
In the Django admin, after select Drips
, you can click on ADD DRIP +
button to create a new one. You will see the add drip
page:
Here you can relate the Drip to the corresponding Campaign
. Grouping several drips under a campaign.
On the FIELD NAME OF USER
input, when you click on it, you will be able to view:
Please take a look a this example:
With this, you can select one or more fields to create useful drips.
Additionally if you select a field name of user that has a date type, you can enter in the FIELD VALUE
input, a date value written in natural language that combines operations on the current datetime.
For example, if you have selected the field last_login
that has a date type, and you want to create a drip to send emails to the users who logged in exactly one week ago; you can enter:
now-1 week
or
now- 1 w
Possible operations and values:
+
) or subtract (-
) dates.now
.seconds
or s
.minutes
or m
.hours
or h
.days
or d
.weeks
or w
.1
, you can write second
, minute
, etc.now
and the operation symbol. Optionally you can add (or not) a space around the number value.Let's see some examples of the date values that you can enter:
now-1 day
now+ 8days
now+ 1 h
now-4hours
now- 3 weeks
now-1 weeks
In the Django admin, you can select a drip and then click on the VIEW TIMELINE
button to view the mails expected to be sent with the corresponding receivers:
To send the created and enabled drips, run the command:
python manage.py send_drips
You can use cron to schedule the drips.
You may want to have an easy way to send drips periodically. It's possible to set a couple of parameters in your settings to do that. First activate the scheduler by adding the DRIP_SCHEDULE_SETTINGS
dictionary:
```python
DRIP_SCHEDULE_SETTINGS = { 'DRIP_SCHEDULE': True, }
```
After that, choose:
0-6
, or a string: 'mon'
, 'tue'
, 'wed'
, 'thu'
, 'fri'
, 'sat'
, 'sun'
. The name in the settings is DRIP_SCHEDULE_DAY_OF_WEEK
(default is set to 0
).0-23
. The name in the settings is DRIP_SCHEDULE_HOUR
(default is set to 0
).0-59
. The name in the settings is DRIP_SCHEDULE_MINUTE
(default is set to 0
).With those values, a cron scheduler will execute the send_drips
command every week in the specified day/hour/minute. The scheduler will use the timezone of your TIME_ZONE
parameter in your settings (default is set to 'UTC'
). For example, if you have:
python
DRIP_SCHEDULE_SETTINGS = {
'DRIP_SCHEDULE': True,
'DRIP_SCHEDULE_DAY_OF_WEEK': 'mon',
'DRIP_SCHEDULE_HOUR': 13,
'DRIP_SCHEDULE_MINUTE': 57,
}
Then every Monday at 13:57 the send_drips
command will be executed.
Last but not least, add this line at the end of your main urls.py
file to start the scheduler:
```python
... from drip.scheduler.cron_scheduler import cron_send_drips
... cron_send_drips() ```
We recommend you to do it there because we know for sure that it's a file that is executed once at the beginning.
Some tips:
'*'
.DRIP_SCHEDULE_DAY_OF_WEEK
to more than one value. For example, if you set that to 'mon-fri'
the command will be executed from Monday to Friday.IMPORTANT: We use Celery 5.2.2 that supports Django 1.11 LTS or newer versions.
If you need to use celery it can be configured in the same way you just need to add the following key SCHEDULER
setted as "CELERY"
:
python
DRIP_SCHEDULE_SETTINGS = {
'DRIP_SCHEDULE': True,
'DRIP_SCHEDULE_DAY_OF_WEEK': 'mon',
'DRIP_SCHEDULE_HOUR': 13,
'DRIP_SCHEDULE_MINUTE': 57,
'SCHEDULER': "CELERY",
}
The default value of this key is "CRON"
, if you enable DRIP_SCHEDULE
it will work with a Cron by default.
In order to make this happen, the project's celery.py
setup shall invoke the
autodiscoverttasks
function. This task is scheduled with a simple
Celery beat configuration.
Bumps django from 3.2.15 to 3.2.18.
722e9f8
[3.2.x] Bumped version for 3.2.18 release.a665ed5
[3.2.x] Fixed CVE-2023-24580 -- Prevented DoS with too many uploaded files.932b5bd
[3.2.x] Added stub release notes for 3.2.18.c35a578
[3.2.x] Added CVE-2023-23969 to security archive.9bd8db3
[3.2.x] Post-release version bump.aed1bb5
[3.2.x] Bumped version for 3.2.17 release.c7e0151
[3.2.x] Fixed CVE-2023-23969 -- Prevented DoS with pathological values for Ac...9da4634
[3.2.x] Fixed inspectdb.tests.InspectDBTestCase.test_custom_fields() on SQLit...4c2b261
[3.2.x] Removed 'tests' path prefix in a couple tests.d215431
[3.2.x] Adjusted release notes for 3.2.17.Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase
.
Bumps ipython from 8.4.0 to 8.10.0.
15ea1ed
release 8.10.0560ad10
DOC: Update what's new for 8.10 (#13939)7557ade
DOC: Update what's new for 8.10385d693
Merge pull request from GHSA-29gw-9793-fvw7e548ee2
Swallow potential exceptions from showtraceback() (#13934)0694b08
MAINT: mock slowest test. (#13885)8655912
MAINT: mock slowest test.a011765
Isolate the attack tests with setUp and tearDown methodsc7a9470
Add some regression tests for this changefd34cf5
Swallow potential exceptions from showtraceback()Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase
.
Bumps setuptools from 64.0.2 to 65.5.1.
Sourced from setuptools's changelog.
v65.5.1
Misc ^^^^
- #3638: Drop a test dependency on the
mock
package, always use :external+python:py:mod:unittest.mock
-- by :user:hroncok
- #3659: Fixed REDoS vector in package_index.
v65.5.0
Changes ^^^^^^^
- #3624: Fixed editable install for multi-module/no-package
src
-layout projects.- #3626: Minor refactorings to support distutils using stdlib logging module.
Documentation changes ^^^^^^^^^^^^^^^^^^^^^
- #3419: Updated the example version numbers to be compliant with PEP-440 on the "Specifying Your Projectβs Version" page of the user guide.
Misc ^^^^
- #3569: Improved information about conflicting entries in the current working directory and editable install (in documentation and as an informational warning).
- #3576: Updated version of
validate_pyproject
.v65.4.1
Misc ^^^^
- #3613: Fixed encoding errors in
expand.StaticModule
when system default encoding doesn't match expectations for source files.- #3617: Merge with pypa/[email protected] including fix for pypa/distutils#181.
v65.4.0
Changes ^^^^^^^
- #3609: Merge with pypa/[email protected] including support for DIST_EXTRA_CONFIG in pypa/distutils#177.
v65.3.0
... (truncated)
a462cb5
Bump version: 65.5.0 β 65.5.1de35d8b
Merge pull request #3656 from bmorris3/typos58e23de
Update changelog. Ref #3659.43a9c9b
Limit the amount of whitespace to search/backtrack. Fixes #3659.5791343
Add test capturing failed expectation. Ref #3659.1f97905
β« Fade to black.6254567
Remove workaround for emacs.729b180
β« Fade to black.c068081
Typo correctionsf777a40
Suppress deprecation warning in --rsyncdir. Workaround for #3655.Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase
.
Bumps certifi from 2020.12.5 to 2022.12.7.
9e9e840
2022.12.07b81bdb2
2022.09.24939a28f
2022.09.14aca828a
2022.06.15.2de0eae1
Only use importlib.resources's new files() / Traversable API on Python β₯3.11 ...b8eb5e9
2022.06.15.147fb7ab
Fix deprecation warning on Python 3.11 (#199)b0b48e0
fixes #198 -- update link in license9d514b4
2022.06.154151e88
Add py.typed to MANIFEST.in to package in sdist (#196)Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase
.
Hello, Firstly, thanks for maintaining this package, it is very useful.
Secondly, is it possible to send HTML emails? Also, how about a WYSIWYG editor like CKEditor for composing a well formatted email.
Any ideas on how to achieve this?
Allows django drips to write simpler Human readable queries to be applied to Drips
Input:
(enable is False) and (sent_drips null True) and (name is "Nacho's Drip")
Output:{'enabled': False, 'sent_drips__isnull': True, 'name': "Nacho's Drip"}
python
input_expression = "(enabled is False) and (sent_drips null False)"
filter = translate_query(input_expression, grammar)
assert Drip.objects.filter(**filter).count() == 0
There is needed some work to include OR
branching and stuff.
hacktoberfest