RESTful Web Services API
- RESTful Web Services API
- Debugging Problems
RESTful Web Services API
Experimental
Dada Mail's RESTful API is currently in the Experimental stage and may change in the future. We would love to hear your feedback on how we can make things work better for you:
https://dadamailproject.com/contact
The best way to do that, is to try it out!
Introduction
Dada Mail's web services reveal some of the administrative features you'll find in Dada Mail's List Control Panel. Currently, there are services to allow you to create a new list, verify subscriptions, subscribe addresses, as well as send mass mailings.
These services are authenticated using an HMAC-with-Public/Private Hashes scheme. Data sent is not encrypted, so we suggest always to connect to the web service with an SSL connection.
Example clients are currently available in Perl and php and allow you to access the services available remotely.
Public and Private Keys
Both the public and private keys for your mailing list can be accessed in the mailing list's control panel under,
Mailing List - Web Services API
You may also reset your keys. Doing so will invalidate any other key pairs for the mailing list you're currently working with.
Global Public and Private Keys
Global key pairs can also be found under, Mailing List - Web Services API. These key pairs can be enabled and the keys can be reset using the Dada Mail Installer. More information:
Global keys can be used for anything you would use mailing list-specific keys, as well when creating a new mailing list.
Perl Client
The Perl Client is called, DadaMailWebService
and is located at dada/extras/scripts/webservices/DadaMailWebService.pm.
You'll want to copy this module to the client side server you want to utilize the below API with.
Synopsis
#!/usr/bin/perl
# Change this to path of the following module:
use lib qw(./);
use DadaMailWebService;
use CGI qw(:standard);
print header();
print '<pre>';
use Data::Dumper;
my $server = 'https://example.com/cgi-bin/dada/mail.cgi';
my $list = 'example';
my $public_key = 'QvDYfEfsyV2IsxITFFFQ2';
my $private_key = 'oED89yPgN6DCAYPt6vAZ7YB5OKymHEANIjeE6fF6n';
my $ws = DadaMailWebService->new(
$server,
$public_key,
$private_key,
);
my $params = {
addresses => [
{
email => 'test9@example.com',
fields => {
favorite_color => "red",
},
profile => {
password => 'secret'
}
},
]
};
# Validate Addresses for Subscription
$results = $ws->request(
$list,
'validate_subscription',
$params,
);
print Dumper($results);
# Subscribe Addresses:
$results = $ws->request(
$list,
'subscription',
$params,
);
print Dumper($results);
# UNSubscribe Addresses:
$results = $ws->request(
$list,
'unsubscription',
$params,
);
print Dumper($results);
$params = {
subject => "My Subject!",
format => "Text",
message => "Here's my message!",
test => 0
};
# Send a Mass Mailing:
$results = $ws->request(
$list,
'mass_email',
$params,
);
print Dumper($results);
# Get the List Settings:
$results = $ws->request(
$list,
'settings'
); # No params.
print Dumper($results);
my $params = {
settings => {
'list_name' => 'New List Name',
'info' => 'New List Description!'
}
};
# Set List Settings:
$results = $ws->request(
$list,
'update_settings',
$params
);
print Dumper($results);
# Update Profile Fields
my $params = {
email => 'test9@example.com',
profile_fields => {
favorite_color => 'blue',
},
};
$results = $ws->request(
$list,
'update_profile_fields',
$params
);
print Dumper($results);
new
Initialize a new DadaMailWebService object with the new
method, which takes three arguments:
The URL of your Dada Mail install
public key
private key
request($list, $service, $params)
The request
method will make the request for the service you want, see the Synopsis above and web services description below on how to create the correct $params
. Available services, for the second paramater are:
create_new_list
(using Global API Keypairs only)
validate_subscription
subscription
mass_email
settings
update_settings
update_profile_fields
request
returns the results of the request.
php Client
The php Client is called, DadaMailWebService.php
and is located at dada/extras/scripts/webservices/DadaMailWebService.php.
You'll want to copy this file to the client side server you want to utilize the below API with.
Synopsis:
<?php
require_once('DadaMailWebService.php');
$server = 'https://example.com/cgi-bin/dada/mail.cgi';
$list = 'example';
$public_key = 'QvDYfEfsyV2IsxITFFFQ2';
$private_key = 'oED89yPgN6DCAYPt6vAZ7YB5OKymHEANIjeE6fF6n';
echo '<pre>';
$ws = new DadaMailWebService(
$server,
$public_key,
$private_key
);
$params = [
'addresses' => array(
[
'email' => 'test4@example.com',
'fields' => [
'favorite_color' => 'red',
]
]
)
];
// Validate Addresses for Subscription
$results = $ws->request(
$list,
'validate_subscription',
$params
);
print_r($results) . "\n\n\n";
// Subscribe Addresses:
$results = $ws->request(
$list,
'subscription',
$params
);
print_r($results) . "\n\n\n";
// UNSubscribe Addresses:
$results = $ws->request(
$list,
'unsubscription',
$params
);
print_r($results) . "\n\n\n";
$params = [
'subject' => "My Subject!",
'format' => "Text",
'message' => "Here's my message!",
'test' => 0
];
// Send a Mass Mailing:
$results = $ws->request(
$list,
'mass_email',
$params
);
print_r($results) . "\n\n\n";
// Get the List Settings:
$results = $ws->request(
$list,
'settings'
); # No params.
print_r($results) . "\n\n\n";
$params = [
'settings' => array(
'list_name' => 'New List Name',
'info' => 'New List Description!'
)
];
// Set List Settings:
$results = $ws->request(
$list,
'update_settings',
$params
);
print_r($results) . "\n\n\n";
?>
new
Initialize a new DadaMailWebService object with the new
method, which takes three arguments:
The URL of your Dada Mail install
public key
private key
request($list, $service, $params)
The request
method will make the request for the service you want, see the Synopsis above and web services description below on how to create the correct $params
. Available services, for the second paramater are:
create_new_list
(using Global API Keypairs only)
validate_subscription
subscription
mass_email
settings
update_settings
update_profile_fields
request
returns the results of the request.
Services
Below is a description and explaination of the current web service, to allow you to implement your own client.
Accessing
Dada Mail's RESTful services can be accessed using the URL to the mail.cgi
script, with the following PATH INFO
:
https://example.com/cgi-bin/dada/mail.cgi/api/service_name/list/service/public_key/digest
https://example.com/cgi-bin/dada/mail.cgi
URL to your Dada Mail - notice we're accessing the
mail.cgi
script over SSL.
The PATH INFO broken down:
api
Tells Dada Mail you're using one of the support web services.
list
list
should be set to the list shortname of the list you would like to work withservice
Name of the service you would like to work with
public_key
the public key for the mailing list you're working with. Both the public, and private key for your mailing list can be accessed in the mailing list's control panel under,
Mailing List - Web Services API
digest
Digest contains the HMAC SHA256 signature base64-encoded digest of your POST payload.The POST payload needs to be ordered alphabetically.
Examples of how to create this in various languages can be found here:
The public key and digest sure do make the URL unweildy (and cause problems with
mod_security
), so Dada Mail's web services also support putting these in the,Authorization
header:Authorization: hmac public_key:digest
The
public key
anddigest
are separated by a colon. This is the setup we do suggest, and is what our example clients use as well. Other than making the URL looking tidier, it does stop perhaps sensitive information from being saved in the web server logs. Your public key is public - it's not supposed to be a sercret. The digest will change for each request made.
Payload
Depending on the web service called, the payload is just HTTP POST variables.
All web services, except, settings
for Dada Mail only support using the POST method. The paramaters in the Payload must be in alphabetical order, so that the digest created on both the client and server match.
settings
has no paramaters to pass, so is send using GET. The nonce
(explained below), still needes to be passed, but is don so, in a http header named, X-DADA-NONCE
header.
Services
create_new_list
create_new_list
creates a new list.
The following paramaters are required to be passed:
settings
Holds the settings that will make up the new mailing list. Example:
"settings" : { "list" : "list", "list_name" : "List Name" "list_owner_email" : "user@example.com", "password" : "Password" "info" : "List Description", "privacy_policy" : "Privacy Policy" "physical_address" : "Physical Address", "consent" : "Consent for Mailing List" },
options
Holds any options you would like for your mailing list. The following options are supported:
send_new_list_welcome_email
Boolean, default: 0. If 1 is passed, an email will be sent to the list owner with information about the new mailing list
send_new_list_welcome_email_with_list_pass
Boolean, default: 0. If 1 is passed (and send_new_list_welcome_email is passed and set to 1), an email will be sent to the list owner with information about the new mailing list, including the mailing list password.
clone_settings_from_list
String, default: undef. If a valid list short name is password, list settings will be cloned from the host list, towards this new list.
Note: Pass a blank/undefined value for the, "list" in the request
method for both the Perl and PHP clients! The list
you want the new list to have will be passed in the settings
paramaters.
Here's an example of using the php client to create a new list:
# List is undefined
# public and private key are GLOBAL
$ws = new DadaMailWebService(
$server,
$public_key,
$private_key
);
$params = [
'settings' => [
'list' => 'newlistname',
'privacy_policy' => "privacy_policy",
'list_name' => "New List Name",
'list_owner_email' => 'listowner@example.com',
'password' => "password" ,
'info' => "this is my list info",
'physical_address' => "This is the physical address",
],
'options' => [
'send_new_list_welcome_email' => 1,
'send_new_list_welcome_email_with_list_pass' => 1,
'clone_settings_from_list' => 'existinglist',
]
];
$results = $ws->request(
$list,
'create_new_list',
$params
);
validate_subscription
validate_subscription
takes a list of addresses (and associated metadata) and validates the subscription, but does not subscribe any of the addresses.
The following paramaters are required to be passed:
addresses
addresses
hold the addresses you would like to work with. This data is passed as a JSON encoded string, as the data that can be passed can be complex. Example:[ { "profile" : { "password" : "secret" }, "email" : "test@example.com", "fields" : { "last_name" : "Smith", "first_name" : "John" } } ]
email holds the address you would like to subscribe.
fields holds any Profile Fields you would also like to save (
first_name
,last_name
, etc).profile currently only holds another paramater,
password
, which holds the password you would like the profile for your address to be set to.This JSON encoded string can be created in Perl like this:
#!/usr/bin/perl use strict; use JSON; my $json = JSON->new->allow_nonref; my $addresses = [ { email => 'test@example.com', fields => { first_name => "John", last_name => "Smith", }, profile => { password => 'secret' } }, ]; print $json->pretty->encode($addresses);
and in php, like this:
<?php $addresses = array( [ 'email' => 'test@example.com', 'fields' => [ 'first_name' => "John", 'last_name' => "Smith", ], 'profile' => [ 'password' => 'secret' ] ], ); print json_encode($addresses); ?>
Dada Mail's web services don't care the exact format of your JSON (would that be possible even, across different tools, written in different languages?), just that it's 100% valid JSON. `
nonce
nonce
is created using Unix time and a random string of characters (8), separated by a colon. The nonce is checked to make sure a request is not too old (older than 5 minutes, currently) and in the future, the random characters will be checked to see if they have been passed before, within the time limit.
Returned will be a JSON document, returning your addresses, with a status, and a list of any errors found (if any). The above json, would return,
{
"status" : 1,
"results" : [
{
"profile" : {
"password" : "secret"
},
"email" : "test@example.com",
"errors" : {},
"fields" : {
"first_name" : "John",
"last_name" : "Smith"
},
"status" : 1
}
]
}
status, when set to 1
tells you that the actual request is successful, and nothing incorrect was found (wrong public key, outdated request, incorrect hmac digest).
results holds the results of your validation. In this case, the address passed verification, and would be safe to subscribe. Let's say there's another profile field, favorite_color
and that profile field was required.
When you call this service you would receive the following JSON doc back,
{
"status" : 1,
"results" : [
{
"profile" : {
"password" : "secret"
},
"email" : "test@example.com",
"errors" : {
"invalid_profile_fields" : {
"favorite_color" : {
"required" : 1
}
}
},
"fields" : {
"first_name" : "John",
"last_name" : "Smith"
},
"status" : 0
}
]
}
Errors returned back are the same for the following method:
https://dadamailproject.com/d/MailingList_Subscribers.pm.html#subscription_check
subscription
subscription
takes a list of addresses (and associated metadata) and subscribes the addresses passed. Validation is done beforehand, and only addresses that passed validation will be subscribed.
The following paramaters are required to be passed:
addresses - same as validate_subscription
nonce - same as validate_subscription
Returned will be a JSON doc,
{
"status" : 1,
"results" : {
"skipped_addresses" : n,
"subscribed_addresses" : nn
}
}
status again will be set to, 1
if the request itself was successful (0
, otherwise). results will hold two paramaters:
subscribed_addresses will return the number of addresses subscribed.
skipped_addresses will return the number of addresses that were not subscribed.
This service does not tell you why an address was not subscribed, so it's highly suggested you validate the subscription, beforehand.
unsubscription
unsubscription
takes a list of addresses (no metadata need be added) and removes the addresses passed. Validation is done beforehand, and only addresses that passed validation will be unsubscribed.
The following paramaters are required to be passed:
addresses - same as validate_subscription
, except only the, email
paramater is required, like this:
[
{
"email" : "test@example.com",
},
{
"email" : "test2@example.com",
}
{
"email" : "test3@example.com",
}
]
nonce - same as validate_subscription
Returned will be a JSON doc,
{
"status" : 1,
"results" : {
"skipped_addresses" : n,
"unsubscribed_addresses" : nn
}
}
status again will be set to, 1
if the request itself was successful (0
, otherwise). results will hold two paramaters:
unsubscribed_addresses will return the number of addresses removed.
skipped_addresses will return the number of addresses that were not subscribed.
This service does not tell you why an address was not unsubscribed.
settings
settings
returns the mailing list settings (list, list_name, info, etc). No paramaters need to be passed, and unlike the other services presented here, you'll need to make the request via GET
and put the nonce
in the, X-DADA-NONCE
header.
Returned will be a JSON doc,
{
"status" : 1,
"results" : {
"settings" : {
"list" :'listshortname',
"list_name" : 'My list's name'
etc, etc,
}
}
}
status again will be set to, 1
if the request itself was successful (0
, otherwise).
settings - a key/value list of all settings for this mailing list.
update_settings
update_settings allows you to update your mailing list settings. The following paramaters are required to be passed:
settings - a key/value hash of the settings you would like to change. This data is passed as a JSON encoded string:
{
"list_name" : "my list name ",
"list" : "list"
}
Returned will be a JSON doc,
{
"status" : 1,
"results" : {
"saved" : 1
}
}
}
nonce - same as validate_subscription
update_profile_fields
update_profile_fields allows you to update an address's profile fields The following paramaters are required to be passed:
email holds the address you would like to update the profile fields for
profile_Fields The fields you would like to update.
{
"email" : "test@example.com",
"profile_fields" : {
"first_name" : "Joanne"
}
}
Returned will be a JSON doc,
{
"saved" : 1,
"email" : "test@example.com",
"profile_fields" : {
"first_name" : "Joanne"
},
"previous_profile_fields" : {
"first_name" : "John"
},
}
nonce - same as validate_subscription
mass_email
This service is a proof of concept, and only provides a very simple mass mailing service
mass_email sends out a mass email to your Subscription List.
The following paramaters are required to be passed:
subject - The subject of your message
format - The format of your message; either text or HTML
message - Your message.
test - can be set to either 1
or, 0
. If set to 1
, the message you send out will only be set to the List Owner, rather than the entire mailing list.
Returned will be a JSON doc:
{
"status" : 1,
"results" : {
"message_id" : n,
}
}
status
again will be set to, 1
if the request itself was successful (0
, otherwise). results will hold just one paramater:
message_id
is the message id associated with this particular mass mailing.
Debugging Problems
The actual underlying module for Dada Mail's web services, DADA::App::WebServices
, may have debugging turned on. This also will return additional debugging information to the client itslf, including sensitive information (like the private key!).
This debugging may be turned on from within the installer. See: https://dadamailproject.com/d/install_dada_mail-advanced_configuration.pod.html#Configure-Debugging
You'll want to check the option for, DADA::App::WebServices
.
Make the Authorization header available
For POST requests, the client will send the required digest in the, Authorizaton
header. If this header is not available (and you're running Apache), try adding the following line to your .htaccess
file,
SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0
This line already exists in the .htaccess
file location in the dada
directory, although it's commented out. Just remove the first, #
character to uncomment it.