#
# Copyright (C) 2010 JBA Network (http://www.jbanetwork.com)
# WWW::MyNewsletterBuilder is free software; you can redistribute it
# and/or modify it under the same terms as Perl itself.
#
# WWW::MyNewsletterBuilder is an interface to the mynewsletterbuilder.com
# XML-RPC API.
#
# $Id: MyNewsletterBuilder.pm 59878 2010-05-04 22:15:50Z bo $
#
package WWW::MyNewsletterBuilder;
use strict;
use warnings;
use Frontier::Client;
our $VERSION = '0.021';
sub new {
my $class = shift;
my $args = ($#_ == 0) ? { %{ (shift) } } : { @_ };
if (!$args->{api_key}){
die('you must pass an api_key to WWW::MyNewsletterBuilder->new()');
}
my $self = {
api_key => $args->{api_key},
username => $args->{username},
password => $args->{password},
timeout => $args->{timeout} || 300,
secure => $args->{secure} || 0,
no_validation => $args->{no_validation} || 0,
_api_host => $args->{_api_host} || 'api.mynewsletterbuilder.com',
_api_version => $args->{_api_version} || '1.0',
_debug => $args->{_debug} || 0,
};
bless($self, $class);
# we have to bless before setting up the url and client
my $url = $self->_buildUrl();
if ($self->{_debug}){
print "url: $url\n";
}
$self->{client} = $self->_getClient($url);
return $self;
}
# the only config var that might need to be changed between calls is timeout
sub Timeout{
my $self = shift;
$self->{timeout} = shift;
$self->{client}->{ua}->timeout($self->{timeout});
return 1;
}
sub Campaigns{
my $self = shift;
my $filters = ($#_ == 0) ? { %{ (shift) } } : { @_ };
$filters = $self->_validateHash(
$filters,
{
status => {
value => 'string',
emptyOk => 1,
},
archived => {
value => 'bool',
emptyOk => 1,
},
published => {
value => 'bool',
emptyOk => 1,
},
},
1
);
return $self->_Execute('Campaigns', $filters);
}
sub CampaignDetails{
my $self = shift;
my $id = $self->_intify(shift);
return $self->_Execute('CampaignDetails', $id);
}
sub CampaignCreate{
my $self = shift;
my $name = $self->_stringify(shift);
my $subject = $self->_stringify(shift);
my $from = shift;
my $reply = shift;
my $html = $self->_stringify(shift);
my $text = $self->_stringify(shift || '', 1);
my $link_tracking = $self->_boolify(shift || 1);
my $gat = $self->_boolify(shift || 0);
$from = $self->_validateHash(
$from,
{
name => {
value => 'string',
},
email => {
value => 'string',
},
},
);
$reply = $self->_validateHash(
$reply,
{
name => {
value => 'string',
emptyOk => 1,
},
email => {
value => 'string',
emptyOk => 1,
},
},
1
);
return $self->_Execute(
'CampaignCreate',
$name,
$subject,
$from,
$reply,
$html,
$text,
$link_tracking,
$gat,
);
}
sub CampaignUpdate{
my $self = shift;
my $id = $self->_intify(shift);
my $details = shift;
my $signature = {};
$signature->{name} = {value => 'string'};
$signature->{subject} = {value => 'string'};
$signature->{html} = {value => 'string'};
$signature->{text} = {value => 'string', emptyOk => 1};
$signature->{link_tracking} = {value => 'bool', emptyOk => 1};
$signature->{gat} = {value => 'bool', emptyOk => 1};
$signature->{from} = {
value => {
name => {
value => 'string',
},
email => {
value => 'string',
},
},
};
$signature->{reply} = {
value => {
name => {
value => 'string',
emptyOk => 1,
},
email => {
value => 'string',
emptyOk => 1,
},
},
emptyOk => 1,
};
$details = $self->_validateHash($details, $signature);
return $self->_Execute(
'CampaignUpdate',
$id,
$details,
);
}
sub CampaignCopy{
my $self = shift;
my $id = $self->_intify(shift);
my $name = $self->_stringify(shift || '', 1);
return $self->_Execute('CampaignCopy', $id, $name);
}
sub CampaignDelete{
my $self = shift;
my $id = $self->_intify(shift);
return $self->_Execute('CampaignDelete', $id);
}
sub CampaignSchedule{
my $self = shift;
my $id = $self->_intify(shift);
my $when = $self->_stringify(shift);
my $lists = shift;
my $smart = $self->_boolify(shift || 0);
my $confirmed = $self->_boolify(shift || 0);
$lists = $self->_validateArray($lists, 'int', 1);
return $self->_Execute(
'CampaignSchedule',
$id,
$when,
$lists,
$smart,
$confirmed
);
}
sub CampaignStats{
my $self = shift;
my $id = $self->_intify(shift);
return $self->_Execute('CampaignStats', $id);
}
sub CampaignRecipients{
my $self = shift;
my $id = $self->_intify(shift);
my $page = $self->_intify(shift || 0);
my $limit = $self->_intify(shift || 1000);
return $self->_Execute(
'CampaignRecipients',
$id,
$page,
$limit
);
}
sub CampaignOpens{
my $self = shift;
my $id = $self->_intify(shift);
my $page = $self->_intify(shift || 0);
my $limit = $self->_intify(shift || 1000);
return $self->_Execute(
'CampaignOpens',
$id,
$page,
$limit
);
}
sub CampaignBounces{
my $self = shift;
my $id = $self->_intify(shift);
my $page = $self->_intify(shift || 0);
my $limit = $self->_intify(shift || 1000);
return $self->_Execute(
'CampaignBounces',
$id,
$page,
$limit
);
}
sub CampaignClicks{
my $self = shift;
my $id = $self->_intify(shift);
my $page = $self->_intify(shift || 0);
my $limit = $self->_intify(shift || 1000);
return $self->_Execute(
'CampaignClicks',
$id,
$page,
$limit
);
}
sub CampaignClickDetails{
my $self = shift;
my $id = $self->_intify(shift);
my $url_id = $self->_intify(shift);
my $page = $self->_intify(shift || 0);
my $limit = $self->_intify(shift || 1000);
return $self->_Execute(
'CampaignClickDetails',
$id,
$url_id,
$page,
$limit
);
}
sub CampaignSubscribes{
my $self = shift;
my $id = $self->_intify(shift);
my $page = $self->_intify(shift || 0);
my $limit = $self->_intify(shift || 1000);
return $self->_Execute(
'CampaignSubscribes',
$id,
$page,
$limit
);
}
sub CampaignUnsubscribes{
my $self = shift;
my $id = $self->_intify(shift);
my $page = $self->_intify(shift || 0);
my $limit = $self->_intify(shift || 1000);
return $self->_Execute(
'CampaignUnsubscribes',
$id,
$page,
$limit
);
}
sub CampaignUrls{
my $self = shift;
my $id = $self->_intify(shift);
return $self->_Execute('CampaignUrls', $id);
}
sub Lists{
my $self = shift;
return $self->_Execute('Lists');
}
sub ListDetails{
my $self = shift;
my $id = $self->_intify(shift);
return $self->_Execute('ListDetails', $id);
}
sub ListCreate{
my $self = shift;
my $name = $self->_stringify(shift);
my $description = $self->_stringify(shift || '', 1);
my $visible = $self->_boolify(shift || 0);
my $default = $self->_boolify(shift || 0);
return $self->_Execute(
'ListCreate',
$name,
$description,
$visible,
$default
);
}
sub ListUpdate{
my $self = shift;
my $id = $self->_intify(shift);
my $details = shift;
my $signature = {};
$signature->{name} = {
value => 'string',
emptyOk => 1,
};
$signature->{description} = {
value => 'string',
emptyOk => 1,
};
$signature->{visible} = {
value => 'bool',
emptyOk => 1,
};
$signature->{default} = {
value => 'bool',
emptyOk => 1,
};
$details = $self->_validateHash($details, $signature);
return $self->_Execute('ListUpdate', $id, $details);
}
sub ListDelete{
my $self = shift;
my $id = $self->_intify(shift);
my $delete_subs = $self->_boolify(shift || 0);
return $self->_Execute('ListDelete', $id, $delete_subs);
}
sub Subscribe{
my $self = shift;
my $details = shift;
my $lists = shift;
my $skip_opt_in = $self->_boolify(shift || 0);
my $update_existing = $self->_boolify(shift || 1);
my $signature = {};
$signature->{email} = {value => 'string'};
$signature->{first_name} = {value => 'string', emptyOk => 1};
$signature->{middle_name} = {value => 'string', emptyOk => 1};
$signature->{last_name} = {value => 'string', emptyOk => 1};
$signature->{full_name} = {value => 'string', emptyOk => 1};
$signature->{company_name} = {value => 'string', emptyOk => 1};
$signature->{job_title} = {value => 'string', emptyOk => 1};
$signature->{phone_work} = {value => 'string', emptyOk => 1};
$signature->{phone_home} = {value => 'string', emptyOk => 1};
$signature->{address_1} = {value => 'string', emptyOk => 1};
$signature->{address_2} = {value => 'string', emptyOk => 1};
$signature->{address_3} = {value => 'string', emptyOk => 1};
$signature->{city} = {value => 'string', emptyOk => 1};
$signature->{state} = {value => 'string', emptyOk => 1};
$signature->{zip} = {value => 'string', emptyOk => 1};
$signature->{country} = {value => 'string', emptyOk => 1};
$details = $self->_validateHash($details, $signature);
$lists = $self->_validateArray($lists, 'int', 1);
return $self->_Execute(
'Subscribe',
$details,
$lists,
$skip_opt_in,
$update_existing
);
}
sub SubscribeBatch{
my $self = shift;
my $subscribers = shift;
my $lists = shift;
my $skip_opt_in = $self->_boolify(shift || 0);
my $update_existing = $self->_boolify(shift || 1);
my $signature = {};
$signature->{email} = {value => 'string'};
$signature->{first_name} = {value => 'string', emptyOk => 1};
$signature->{middle_name} = {value => 'string', emptyOk => 1};
$signature->{last_name} = {value => 'string', emptyOk => 1};
$signature->{full_name} = {value => 'string', emptyOk => 1};
$signature->{company_name} = {value => 'string', emptyOk => 1};
$signature->{job_title} = {value => 'string', emptyOk => 1};
$signature->{phone_work} = {value => 'string', emptyOk => 1};
$signature->{phone_home} = {value => 'string', emptyOk => 1};
$signature->{address_1} = {value => 'string', emptyOk => 1};
$signature->{address_2} = {value => 'string', emptyOk => 1};
$signature->{address_3} = {value => 'string', emptyOk => 1};
$signature->{city} = {value => 'string', emptyOk => 1};
$signature->{state} = {value => 'string', emptyOk => 1};
$signature->{zip} = {value => 'string', emptyOk => 1};
$signature->{country} = {value => 'string', emptyOk => 1};
$subscribers = $self->_validateArray($subscribers, $signature);
$lists = $self->_validateArray($lists, 'int', 1);
return $self->_Execute(
'SubscribeBatch',
$subscribers,
$lists,
$skip_opt_in,
$update_existing
);
}
sub Subscribers{
my $self = shift;
my $statuses = shift;
my $lists = shift;
my $page = $self->_intify(shift || 0);
my $limit = $self->_intify(shift || 1000);
return $self->_Execute('Subscribers', $statuses, $lists, $page, $limit);
}
sub SubscriberDetails{
my $self = shift;
my $id_or_email = $self->_stringify(shift);
return $self->_Execute('SubscriberDetails', $id_or_email);
}
sub SubscriberUpdate{
my $self = shift;
my $id_or_email = $self->_stringify(shift);
my $details = shift;
my $lists = shift;
my $signature = {};
$signature->{email} = {value => 'string'};
$signature->{first_name} = {value => 'string', emptyOk => 1};
$signature->{middle_name} = {value => 'string', emptyOk => 1};
$signature->{last_name} = {value => 'string', emptyOk => 1};
$signature->{full_name} = {value => 'string', emptyOk => 1};
$signature->{company_name} = {value => 'string', emptyOk => 1};
$signature->{job_title} = {value => 'string', emptyOk => 1};
$signature->{phone_work} = {value => 'string', emptyOk => 1};
$signature->{phone_home} = {value => 'string', emptyOk => 1};
$signature->{address_1} = {value => 'string', emptyOk => 1};
$signature->{address_2} = {value => 'string', emptyOk => 1};
$signature->{address_3} = {value => 'string', emptyOk => 1};
$signature->{city} = {value => 'string', emptyOk => 1};
$signature->{state} = {value => 'string', emptyOk => 1};
$signature->{zip} = {value => 'string', emptyOk => 1};
$signature->{country} = {value => 'string', emptyOk => 1};
$details = $self->_validateHash($details, $signature);
$lists = $self->_validateArray($lists, 'int', 1);
return $self->_Execute(
'SubscriberUpdate',
$id_or_email,
$details,
$lists,
);
}
sub SubscriberUnsubscribe{
my $self = shift;
my $id_or_email = $self->_stringify(shift);
return $self->_Execute('SubscriberUnsubscribe', $id_or_email);
}
sub SubscriberUnsubscribeBatch{
my $self = shift;
my $ids_or_emails = shift;
$ids_or_emails = $self->_validateArray($ids_or_emails, 'string');
return $self->_Execute('SubscriberUnsubscribeBatch', $ids_or_emails);
}
sub SubscriberDelete{
my $self = shift;
my $id_or_email = $self->_stringify(shift);
return $self->_Execute('SubscriberDelete', $id_or_email);
}
sub SubscriberDeleteBatch{
my $self = shift;
my $ids_or_emails = shift;
$ids_or_emails = $self->_validateArray($ids_or_emails, 'string');
return $self->_Execute('SubscriberDeleteBatch', $ids_or_emails);
}
sub AccountKeys{
my $self = shift;
my $username = $self->_stringify(shift);
my $password = $self->_stringify(shift);
my $disabled = $self->_boolify(shift || 0);
return $self->_Execute(
'AccountKeys',
$username,
$password,
$disabled,
);
}
sub AccountKeyCreate{
my $self = shift;
my $username = $self->_stringify(shift);
my $password = $self->_stringify(shift);
return $self->_Execute('AccountKeyCreate', $username, $password);
}
sub AccountKeyEnable{
my $self = shift;
my $username = $self->_stringify(shift);
my $password = $self->_stringify(shift);
my $id_or_key = $self->_stringify(shift);
return $self->_Execute(
'AccounKeyEnable',
$username,
$password,
$id_or_key
);
}
sub AccountKeyDisable{
my $self = shift;
my $username = $self->_stringify(shift);
my $password = $self->_stringify(shift);
my $id_or_key = $self->_stringify(shift);
return $self->_Execute(
'AccounKeyDisable',
$username,
$password,
$id_or_key
);
}
sub HelloWorld{
my $self = shift;
my $val = $self->_stringify(shift || '', 1);
return $self->_Execute('HelloWorld', $val);
}
sub _Execute{
my $self = shift;
my $method = shift;
$self->{errno} = '';
$self->{errstr} = '';
my $data;
eval{
$data = $self->{client}->call($method, $self->{api_key}, @_);
};
if ($self->{_debug}){
use Data::Dumper;
print "returned data\n";
print Dumper $data;
}
if ($@){
$self->{errno} = 2;
$self->{errstr} = $@;
if ($self->{_debug}){
print 'errors: '. $self->{errno} .'--'. $self->{errstr} ."\n";
}
return 0;
}
elsif (!$data){
$self->{errno} = 2;
$self->{errstr} = 'Empty response from API server';
if ($self->{_debug}){
print 'errors: '. $self->{errno} .'--'. $self->{errstr} ."\n";
}
return 0;
}
if (ref($data) eq 'HASH' && $data->{'errno'}){
$self->{errno} = $data->{'errno'};
$self->{errstr} = $data->{'errstr'};
return 0;
}
return $self->_unBoolify($data);
}
sub _buildUrl{
my $self = shift;
my $url;
if ($self->{secure}){
$url = 'https://';
}
else{
$url = 'http://';
}
return $url . $self->{_api_host} . '/' . $self->{_api_version};
}
sub _getClient{
my $self = shift;
my $url = shift;
my $client = Frontier::Client->new(
url => $url,
debug => 0,
);
# we have to modify Frontier's LWP instance a little bit.
$client->{ua}->agent('MNB_API Perl ' . $self->{_api_version} . '/' . $VERSION . '-' . '$Rev: 59878 $');
$client->{ua}->requests_redirectable(['GET', 'HEAD', 'POST' ]);
$client->{ua}->timeout($self->{timeout});
return $client;
}
sub _error{
my $self = shift;
my $msg = shift;
my $warn = shift || 0;
if ($self->{no_validation} || $warn){
warn($msg);
}
else{
die($msg);
}
}
sub _validateArray{
my $self = shift;
my $array = shift;
my $signature = shift;
my $emptyOk = shift || 0;
my $isHash = 0;
if (ref($signature) eq 'HASH'){
$isHash = 1;
}
if (!$array and !$emptyOk){
$self->_error('invalid param passed to '. (caller(1))[3] .':'. (caller(0))[2] .' from '. (caller(1))[1] .':'. (caller(1))[2] .' expected array got '. $array);
}
foreach (@$array){
if ($isHash){
$_ = validateHash($_, $signature, $emptyOk);
}
else{
my $function = '_' . $signature . 'ify';
$_ = $self->$function($_, $emptyOk);
}
}
return $array;
}
##
#
# takes a hash and a signature for that hash and validates the hash's
# values then makes sure they are the proper xml-rpc types.
#
##
sub _validateHash{
my $self = shift;
my $hash = shift;
my $signature = shift;
my $emptyOk = shift || 0;
if (!$hash and !$emptyOk){
$self->_error('invalid param passed to '. (caller(1))[3] .':'. (caller(0))[2] .' from '. (caller(1))[1] .':'. (caller(1))[2] .' expected hash got '. $hash);
}
##
#
# we loop through the signature keys. if the value is a hash
# we need recursively call this function. if it is a string
# we validate it based on the type.
#
##
foreach (keys(%$signature)){
if (ref($signature->{$_}->{value}) eq 'HASH'){
$hash->{$_} = $self->_validateHash($hash->{$_}, $signature->{$_}->{value}, $signature->{$_}->{emptyOk}) if (defined($hash->{$_}));
}
else{
my $function = '_' . $signature->{$_}->{value} . 'ify';
$hash->{$_} = $self->$function($hash->{$_}, $signature->{$_}->{emptyOk}) if (defined($hash->{$_}));
}
}
return $hash;
}
##
#
# $self->_intify( int $var, bool $require)
# validates value of $var as an int... throws error if it isn't
# converts to Frontier int data type if test passed (or we aren't validating data))
#
##
sub _intify{
my $self = shift;
my $var = shift;
my $emptyOk = shift || 0;
my $check = '\d+';
$check = '\d*' if ($emptyOk);
$self->_error('invalid param passed to '. (caller(1))[3] .':'. (caller(0))[2] .' from '. (caller(1))[1] .':'. (caller(1))[2] .' expected int got '. $var) unless ($var =~ /^($check)$/);
return $self->{client}->int($var);
}
##
#
# $self->_stringify( string $var, bool $require)
# validates value of $var as an string... throws error if it isn't
# converts to Frontier string data type if test passed (or we aren't validating data))
#
##
sub _stringify{
my $self = shift;
my $var = shift;
my $emptyOk = shift || 0;
my $check = '.+';
$check = '.*' if ($emptyOk);
$self->_error('invalid param passed to '. (caller(1))[3] .':'. (caller(0))[2] .' from '. (caller(1))[1] .':'. (caller(1))[2] .' expected string got '. $var) unless ($var =~ /^($check)$/);
return $self->{client}->string($var);
}
##
#
# $self->boolfy( int $var, bool $require)
# validates value of $var as a bool... throws error if it isn't
# converts to Frontier bool data type if test passed (or we aren't validating data))
#
##
sub _boolify{
my $self = shift;
my $var = shift;
$self->_error('invalid param passed to '. (caller(1))[3] .':'. (caller(0))[2] .' from '. (caller(1))[1] .':'. (caller(1))[2] .' expected bool(0 or 1) got '. $var) unless ($var =~ /^(0|1)$/);
return $self->{client}->boolean($var);
}
sub _unBoolify{
my $self = shift;
my $var = shift;
if (ref($var) eq 'ARRAY'){
foreach my $v (@$var){
$v = $self->_unBoolify($v);
}
}
if (ref($var) eq 'HASH'){
foreach (keys(%$var)){
$var->{$_} = $self->_unBoolify($var->{$_});
}
}
if (ref($var) ne 'Frontier::RPC2::Boolean'){
return $var;
}
return $var->value;
}
1;
__END__
=head1 Name
WWW::MyNewsletterBuilder - Perl implementation of the mynewsletterbuilder.com API
=head1 Synopsis
instantiate the module
use WWW::MyNewsletterBuilder;
my $mnb = WWW::MyNewsletterBuilder->new(
api_key => , # your key here
);
quick test of server connection
print $mnb->HelloWorld('Perl Test');
if ($mnb->{errno}){
warn($mnb->{errstr});
#oh no there was an error i should do something about it
}
get a list of campaigns and display their names
my $campaigns = $mnb->Campaigns( status => 'all' );
if ($mnb->{errno}){
warn($mnb->{errstr});
#oh no there was an error i should do something about it
}
foreach my $c (@$campaigns){
print $c->{name} . "\n";
}
create a new campaign
my $cam_id = $mnb->CampaignCreate(
'perl test',
'perl test subject',
{
name => 'perl test from name',
email => 'robert@jbanetwork.com'
},
{
name => 'perl test reply name',
email => 'robert@jbanetwork.com'
},
'<a href="mynewsletterbuilder.com">html content</a>',
'text content',
);
if ($mnb->{errno}){
warn($mnb->{errstr});
#oh no there was an error i should do something about it
}
create a new subscriber list
my $list_id = $mnb->ListCreate(
'perl test',
'perl test list',
);
if ($mnb->{errno}){
warn($mnb->{errstr});
#oh no there was an error i should do something about it
}
add a subscriber
my $sub = $mnb->Subscribe(
{
email => 'robert@jbanetwork.com',
first_name => 'Robert',
last_name => 'Davis',
company_name => 'JBA Network',
phone_work => '8282320016,',
address_1 => '311 Montford Ave',
city => 'Asheville',
state => 'NC',
zip => '28801',
country => 'US',
'blah blah balh' => 'perl goes blah.',
},
[ $list_id ]
);
if ($mnb->{errno}){
warn($mnb->{errstr});
#oh no there was an error i should do something about it
}
schedule a campaign send
$mnb->CampaignSchedule(
$cam_id,
time(), # send it NOW
[ $list_id ],
);
if ($mnb->{errno}){
warn($mnb->{errstr});
#oh no there was an error i should do something about it
}
delete a subscriber
$mnb->SubscriberDelete($sub->{id});
if ($mnb->{errno}){
warn($mnb->{errstr});
#oh no there was an error i should do something about it
}
delete a list
$mnb->ListDelete($list_id);
if ($mnb->{errno}){
warn($mnb->{errstr});
#oh no there was an error i should do something about it
}
delete a campaign
$mnb->CampaignDelete($cam_id);
if ($mnb->{errno}){
warn($mnb->{errstr});
#oh no there was an error i should do something about it
}
=head1 Description
=head2 Methods
=head3 Instantiation And Setup
=over 4
=item $mnb = WWW::MyNewsletterBuilder->new( %options )
This method constructs a new C<WWW::MyNewsletterBuilder> object and returns it.
Key/value pair arguments may be provided to set up the initial state.
The following options correspond to attribute methods described below:
KEY DEFAULT
----------- --------------------
api_key undef (REQUIRED)
username undef
password undef
timeout 300
secure 0 (1 will use ssl)
no_validation 0 (1 will warn instead of die on invalid argument !!WARNING!!)
#############################################
### dev options... use at your own risk...###
#############################################
_api_host 'api.mynewsletterbuilder.com'
_api_version '1.0'
_debug 0 (1 will print all kinds of stuff)
=item $mnb->Timeout( int $timeout )
sets timeout for results
=back
=head3 Campaigns (Emails)
=over 4
=item $mnb->Campaigns( %filters )
returns an arrayref of hashrefs listing campaigns. Optional key/value pair argument allows you to filter results:
KEY OPTIONS
___________ ____________________
status draft, sent, scheduled, all(default)
archived 1, 0
published 1, 0
returns an arrayref of hashrefs in the following format:
KEY DESCRIPTION
___________ ____________________
id numeric id for campaign
name campaign's name
description campaign's description
published 1 if campaign published 0 if not
archived 1 if campaign archied 0 if not
status status will be draft, sent or scheduled
=item $mnb->CampaignDetails( int $id )
requires a campaign id and returns a hashref containing the campaign's details with the following keys:
KEY DESCRIPTION
___________ ____________________
id
name name for reply to
reply_name name for reply to
reply_email email address for reply to
from_name name for from
from_email email address for from
subject email subject
html email html body
text email text body
=item $mnb->CampaignCreate( string $name, string $subject, \%from, \%reply, string $html, string $text, bool $link_tracking, bool $gat )
requires a whole bunch of stuff and returns the id of the newly created campaign. arguments:
string $name -- Internal campaign name
string $subject -- Campaign subject line
hashref $from -- keys are 'name' and 'email'
hashref $reply -- keys are 'name' and 'email' (if empty $from is used)
string $html -- HTML content for the campaign.
string $text -- the text content for the campaign. (defaults to a stripped version of $html)
bool $link_tracking -- 0 turn off link tracking 1(default) turns it on
bool $gat -- 0(default) turns off Google Analytics Tracking 1 turns it on
=item $mnb->CampaignUpdate( int $id, \%details )
requires an int id and hashref details returns 1 if successful and 0 on failure. hashref format:
KEY DESCRIPTION
___________ ____________________
name Internal campaign name
subject Campaign subject line
from hashref with keys 'name' and 'email'
reply hashref with keys are 'name' and 'email' (if empty $from is used)
html HTML content for the campaign.
text the text content for the campaign.
link_tracking 0 turn off link tracking 1(default) turns it on
gat 0(default) turns off Google Analytics Tracking 1 turns it on
=item $mnb->CampaignCopy( int $id, string $name )
takes an id and name copies an existing campaign identified by id and returns the new id. original name will be reused if name is ommitted.
=item $mnb->CampaignDelete( int $id )
takes an id and deletes campaign idenified by that id. returns 1 on success and 0 on failure.
=item $mnb->CampaignSchedule( int $id, string $when, \@lists, bool $smart, bool $confirmed )
schedules a Campaign for sending based on arguments:
int $id -- campaign id to send
datetime $when -- date/time to send this can be in any format readable by PHP's strtotime() function and will be EST.
array @lists -- flat array of list id's the campaign should go out to
bool $smart -- 0(default) disables smart send 1 enables it. see http://help.mynewsletterbuilder.com/Help_Pop-up_for_Newsletter_Scheduler
bool $confirmed -- 0(default) sends to all subscribers 1 sends to only confirmed
returns 0 on failure and 1 on success.
=item $mnb->CampaignStats( int $id )
takes a campaign id and returns stats for that campaign. returned hahsref has the following keys:
KEY DESCRIPTION
___________ ____________________
id numeric id for campaign
clicks number of clicks
clicks_unique number of unique clicks
forwards number of forwards
forwards_unique number of unique forwards
opens number of opens
opens_unique number of unique opens
recipients number of recipients
bounces number of bounces
delivered number delivered
complaints number of complaints
subscribes number of subscribes
unsubscribes number of unsubscribes
sent_on date and time campaign sent ('2010-03-04 01:30:47' EST)
first_open date and time of first open ('2010-03-04 01:30:47' EST)
last_open date and time of last open ('2010-03-04 01:30:47' EST)
archived 1 if archived 0 if not
=item $mnb->CampaignRecipients( int $id, int $page, int $limit)
takes a campaign id, an optional page number and limit (for paging systems on large data sets) and returns an arrayref of hashrefs containing data about subscribers in the format:
KEY DESCRIPTION
___________ ____________________
id numeric id of subscriber
email email address of subscriber
processed when campaign was sent to subscriber ('2010-03-04 01:30:47' EST)
=item $mnb->CampaignOpens( int $id, int $page, int $limit)
takes a campaign id, an optional page number and limit (for paging systems on large data sets) and returns an arrayref of hashrefs containing data about subscribers who have opened the campaign in the format:
KEY DESCRIPTION
___________ ____________________
id numeric id of subscriber
email email address of subscriber
count number of opens
first_open date and time subscriber first opened campaign ('2010-03-04 01:30:47' EST)
last_open date and time subscriber last opened campaign ('2010-03-04 01:30:47' EST)
=item $mnb->CampaignBounces( int $id, int $page, int $limit)
takes a campaign id, an optional page number and limit (for paging systems on large data sets) and returns an arrayref of hashrefs containing data about subscribers who bounced in the format:
KEY DESCRIPTION
___________ ____________________
id numeric id of subscriber
email email address of subscriber
processed when mnb processed bounce from subscriber ('2010-03-04 01:30:47' EST)
=item $mnb->CampaignClicks( int $id, int $page, int $limit)
takes a campaign id, an optional page number and limit (for paging systems on large data sets) and returns an arrayref of hashrefs containing data about subscribers who clicked links in the format:
KEY DESCRIPTION
___________ ____________________
id numeric id of subscriber
email email address of subscriber
=item $mnb->CampaignClickDetails( int $id, int $url_id, int $page, int $limit)
takes a campaign id, url id and optional page number and limit (for paging systems on large data sets) and returns an arrayref of hashrefs containing data about subscribers who clicked links in the format:
KEY DESCRIPTION
___________ ____________________
id numeric id of subscriber
email email address of subscriber
count number of times subscriber clicked link
url_id url id of link clicked
=item $mnb->CampaignSubscribes( int $id, int $page, int $limit)
takes a campaign id, an optional page number and limit (for paging systems on large data sets) and returns an arrayref of hashrefs containing data about subscribers who subscribed based on this campaign in the format:
KEY DESCRIPTION
___________ ____________________
id numeric id of subscriber
email email address of subscriber
processed when subscriber was processed
=item $mnb->CampaignUnsubscribes( int $id, int $page, int $limit)
takes a campaign id, an optional page number and limit (for paging systems on large data sets) and returns an arrayref of hashrefs containing data about subscribers who unsubscribed in the format:
KEY DESCRIPTION
___________ ____________________
id numeric id of subscriber
email email address of subscriber
processed when subscriber was processed
=item $mnb->CampaignUrls( int $id )
takes a campaign id and returns an arrayref of hashrefs with link related data in the format:
KEY DESCRIPTION
___________ ____________________
id numeric id of url
link FQDN for link
unique number of unique clicks
total number of total clicks
title text within link (can include html including img tags)
=back
=head3 Subscriber Lists
=over 4
=item $mnb->Lists()
returns an arrayref of hasrefs of subscriber lists with the following keys:
KEY DESCRIPTION
___________ ____________________
id numeric id for list
name list name
description list description
visible 1 if visible 0 if not
default 1 if default 0 if not
subscribers number of subscribers in list
=item $mnb->ListDetails( int $id )
takes a list id and returns details about that list in a hashref with the following keys:
KEY DESCRIPTION
___________ ____________________
id list id
name list name
description list description
visible 1 if list is visible 0 if not
default 1 if list is a default selection on your subscription form
subscribers total number of subscribers in the list
=item $mnb->ListCreate( string $name, string $description, bool $visible, bool $default )
takes several arguments, creates a new subscriber list and returns it's unique id. arguments:
string $name -- name for new list
string $description -- description for new list
bool $visible -- 1 if list is visible 0(default) if not
bool $default -- 1 if list is default 0(default) if not
=item $mnb->ListUpdate( int $id, \%details )
takes an id and a hashref of details (only id is required though we won't actually do anything without something in the details hashref), updates the subscriber list identified by id and returns 1 on success and 0 on failure.
details hashref format:
KEY DESCRIPTION
___________ ____________________
name new name for list
description new description for list
visible 1 if list is visible 0(default) if not
default 1 if list is default 0(default) if not
=item $mnb->ListDelete( int $id, bool $delete_subs )
deletes the list identified by id. if $delete_subs is 1 all subscribers in list are deleted as well. if delete_subs is 0(default) we don't touch subscribers. returns 1 on success and 0 on failure.
=back
=head3 Subscribers
=over 4
=item $mnb->Subscribe( \%details, \@lists, bool $skip_opt_in, bool $update_existing )
sets up a single subscriber based on %details. if @lists is populated it OVERRIDES a current users current set of lists. if it is empty no changes are made to existing users. skip_opt_in is used to enable confirmation email (default is 0). update_existing is used to specify that you want %details to overrid an existing user's info. it will NOT be applied to lists. if lists is populated an existing user's lists WILL be overridden even with the update_existing flag set. it defaults to true.
%details is a hashref with the following format:
KEY DESCRIPTION
___________ ____________________
email subscriber email address(required)
first_name subscriber first name
middle_name subscriber middle name
last_name subscriber last name
full_name subscriber full name (yes this is a distinct field)
company_name subscriber company name
job_title subscribers job title
phone_work subscriber work phone
phone_home subscriber home phone
address_1 first line of address
address_2 second line of address
address_3 third line of address
city city of address
state state of address
zip postal code
country country part of address
custom field names custom field values
custom fields can be set by using their full name as the key and their value as the value... again this can lead to keys with spaces.
Subscribe() returns a hashref with the following keys:
KEY DESCRIPTION
___________ ____________________
id subscriber's unique id
email subscriber's uniqe email
status status of subscription. possible values are new, updated, error, ignored
status_msg contains text message about update... usually only used for errors
=item $mnb->SubscribeBatch( \@subscribers, \@lists, bool $skip_opt_in, bool $update_existing )
sets up multiple subscriber based on @subscribers which is an array of hashrefs. if @lists is populated it OVERRIDES any current users set of lists. if it is empty no changes are made to existing users. skip_opt_in is used to enable confirmation email (default is 0). update_existing is used to specify that you want %details to overrid an existing user's info. it will NOT be applied to lists. if lists is populated an existing user's lists WILL be overridden even with the update_existing flag set. it defaults to true.
@subscribers is an array of hashrefs with the following format:
KEY DESCRIPTION
___________ ____________________
email subscriber email address
first_name subscriber first name
middle_name subscriber middle name
last_name subscriber last name
company_name subscriber company name
job_title subscribers job title
phone_work subscriber work phone
phone_home subscriber home phone
address_1 first line of address
address_2 second line of address
address_3 third line of address
city city of address
state state of address
zip postal code
country country part of address
custom field names custom field values
custom fields can be set by using their full name as the key and their value as the value... again this can lead to keys with spaces.
SubscribeBatch() returns a hashref with the following keys:
KEY DESCRIPTION
___________ ____________________
meta contains a hashref with overview info described below
subscribers contains an array of hashrefs described below. this will match the order of the @subscribers array you submitted
the meta key of the return from SubscribeBatch() contains a hashref with the following keys:
KEY DESCRIPTION
___________ ____________________
total total count of attempted subscribes
success total count of successful subscribes
errors total count of subscribes with errors
the subscribers key of the return from SubscribeBatch() contains an array of hashrefs with the following keys:
KEY DESCRIPTION
___________ ____________________
id subscriber's unique id
email subscriber's uniqe email
status status of subscription. possible values are new, updated, error, ignored
status_msg contains text message about update... usually only used for errors
=item $mnb->Subscribers( @statuses, @lists, int $page, int $limit )
takes arrays of statuses and list ids to filter by, an optional page number and limit (for paging systems on large data sets). returns an array of subscriber data.
options for statuses are active, unsubscribed, deleted.
return is a keyed array with the following keys:
KEY DESCRIPTION
___________ ____________________
id subscriber's unique id
email subscriber's uniqe email
status status of subscriber. possible values are active, unsubscribed or deleted
=item $mnb->SubscriberDetails( string $id_or_email )
takes an argument that can be either the unique id for the subscriber or an email address and returns a hashref of subscriber data in the following format:
KEY DESCRIPTION
___________ ____________________
id numeric id for subscriber
email subscriber email address
full_name subscriber full name
first_name subscriber first name
middle_name subscriber middle name
last_name subscriber last name
company_name subscriber company name
job_title subscribers job title
phone_work subscriber work phone
phone_home subscriber home phone
address_1 first line of address
address_2 second line of address
address_3 third line of address
city city of address
state state of address
zip postal code
country country part of address (may be improperly formatted)
campaign_id if subscriber subscribed from a campaign it's id is here
lists contains a flat array containing the lists the user is in
last_confirmation_request last time we sent a confirmation to the user
confirmed_date date subscriber confirmed
confirmed_from ip address user confirmed from
add_remove_date date subscriber status changed
status current status possible values: active, unsubscribed, deleted, list_too_small
add_method who last updated the user possible values: U - user added, S - added self, A - Admin added, C - added by complaint system, B - added by bounce management system
confirmed status of confirmation (confirmed, unconfirmed, pending)
custom field names custom field values
custom fields will come back in this hashref with their names as keys and their values as the value. this means there is a possiblity that keys will have spaces in them. sorry.
=item $mnb->SubscriberUpdate( string $id_or_email, \%details, \@lists )
takes an argument that can be either the unique id for the subscriber or an email address and updates a subscribers info and lists based on details hashref and lists arrayref. if @lists is empty NO CHANGES ARE MADE TO A USERS LISTS. use SubscriberDelete or SubscriberUnsubscribe to remove a subscriber from all lists.
%details is a hashref with the following format:
KEY DESCRIPTION
___________ ____________________
id numeric id for subscriber
email subscriber email address
full_name subscriber full name
first_name subscriber first name
middle_name subscriber middle name
last_name subscriber last name
company_name subscriber company name
job_title subscribers job title
phone_work subscriber work phone
phone_home subscriber home phone
address_1 first line of address
address_2 second line of address
address_3 third line of address
city city of address
state state of address
zip postal code
country country part of address
custom field names custom field values
custom fields can be set by using their full name as the key and their value as the value... again this can lead to keys with spaces.
=item $mnb->SubscriberUnsubscribe( string $id_or_email )
takes an argument that can be either the unique id for the subscriber or an email address and permanantly removes that subscriber for the user identified by your api_key. this subscribers will NOT be able to be readded by SubscribeBatch().
returns 1 on success and 0 on failure.
=item $mnb->SubscriberUnsubscribeBatch( \@ids_or_emails )
takes an argument that is an array containing either the unique ids for the subscriber or an email address and permanantly removes those subscribesr for the user identified by your api_key. these subscribers will NOT be able to be readded by SubscribeBatch().
returns 1 on success and 0 on failure.
=item $mnb->SubscriberDelete( string $id_or_email )
takes an argument that can be either the unique id for the subscriber or an email address and removes that subscriber for the user identified by your api_key. this subscriber WILL be readded if their email address is re-submitted to Subscribe() or SubscribeBatch().
returns 1 on success and 0 on failure.
=item $mnb->SubscriberDeleteBatch( \@ids_or_emails )
takes an argument that is an array containing either the unique id for subscribers or an email addresss and removes the subscribers for the user identified by your api_key. these subscribers WILL be readded if their email addresses are re-submitted to Subscribe() or SubscribeBatch().
returns 1 on success and 0 on failure.
=back
=head3 Account Administration
=over 4
=item $mnb->AccountKeys( string $username, string $password, bool $disabled)
takes the user's username and password and returns data on available api keys. if $disabled(default 0) is 1 list will include disabled keys.
return is an array of hashrefs with the following keys:
KEY DESCRIPTION
___________ ____________________
id unique numeric id of key
key unique key string
created date key created
expired date key expired or was disabled (null for valid key)
=item $mnb->AccountKeyCreate( string $username, string $password )
takes the user's username and password creates a key and returns data about created key. return is a hashref with the following keys:
KEY DESCRIPTION
___________ ____________________
id unique numeric id of key
key unique key string
create date key created
expired date key expired or was disabled (null for valid key)
=item $mnb->AccountKeyEnable( string $username, string $password, string $id_or_key )
takes the user's username and password and an id or existing key it enables the referenced key and returns 1 on success and an error on failure.
=item $mnb->AccountKeyDisable( string $username, string $password, string $id_or_key )
takes the user's username and password and an id or existing key it disables the referenced key and returns 1 on success and an error on failure.
=back
=head3 Testing
=over 4
=item $mnb->HelloWorld( string $value )
takes a value and echos it back from the API server.
=back
=head2 Errors
By default we validate your data before sending to the server. If validation fails we issue die() with a relevant error message. You can force us to warn instead of dying by passing no_validation => 1 to new().
Server side errors will cause functions to return 0. They will also populate $mnb->{errno} and $mnb->{errstr}. You should probably check $mnb->{errno} after calling any function. Fatal errors within the underlying Frontier::Client module may be caught by the same mechinism that catches server side exceptions. You REALLY need to check for errors after ever call.
=head2 Requirements
Frontier::Client
Data::Dumper
=head1 See Also
http://api.mynewsletterbuilder.com
=head1 Author
Robert Davis, robert@jbanetwork.com
=head1 Copyright And License
Copyright (C) 2010 by JBA Network (http://www.jbanetwork.com)
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.8 or,
at your option, any later version of Perl 5 you may have available.
=cut