API-Drip-Request
view release on metacpan or search on metacpan
bin/drip_client.pl view on Meta::CPAN
if ( $OPT{startwork} ) { start_workflow( %OPT ) and exit }
if ( $OPT{event} ) { record_event( %OPT ) and exit }
};
if ( $@ ) {
warn "Request failed:";
p $@;
}
exit;
sub record_event {
my %OPT = @_;
$OPT{email} or $OPT{id} or pod2usage( "Either -email or -id is required for -event" );
$OPT{action} or pod2usage( "-action is required for -event" );
my $content = _build_hash( %OPT, keys => [qw(email id action prospect)] );
my $result = $client->do_request( POST => 'events', { events => [ $content ] } );
p $result;
}
sub get_workflows {
my %OPT = @_;
my $result = $client->do_request( GET => 'workflows' );
p $result;
}
sub start_workflow {
my %OPT = @_;
$OPT{workflow} or pod2usage( "Required parameter -workflow missing for -startwork" );
my $subscriber = _build_hash( %OPT, keys => [qw( email id user_id time_zone prospect )] );
my $endpoint = 'workflows/' . $OPT{workflow} . '/subscribers';
my $result = $client->do_request( POST => $endpoint, { subscribers => [ $subscriber ] } );
p $result;
}
sub delete_subscribers {
my %OPT = @_;
my $id = $OPT{email} || $OPT{id};
die "email or id required in delete subscriber" unless $id;
my $result = $client->do_request( DELETE => "subscribers/$id" );
p $result;
}
sub add_subscribers {
my %OPT = @_;
my $subscriber = _build_hash( %OPT, keys => [qw( email id new_email user_id time_zone lifetime_value ip_address )] );
die "email or id required in add subscriber" unless $subscriber->{email} or $subscriber->{id};
my $result = $client->do_request( POST => 'subscribers', { subscribers => [ $subscriber ]});
p $result;
}
sub _build_hash {
my %OPT = @_;
my $build = {};
foreach my $key ( @{$OPT{keys}} ) {
next unless defined $OPT{$key};
$build->{$key} = $OPT{$key};
}
return $build;
}
sub get_subscribers {
my $result = $client->do_request( GET => 'subscribers' );
p $result;
}
lib/API/Drip/Request.pm view on Meta::CPAN
=cut
my $config_validator = validation_for(
params => {
DRIP_CLIENT_CONF => { type => Str(), optional => 1 },
map { $_ => { type => Str(), optional => 1 } } keys %DEFAULTS,
debugger => { type => CodeRef(), optional => 1 },
}
);
sub new {
my $class = shift;
my %OPT = $config_validator->(@_);
my $self = _load_conf( \%OPT );
# At this point, all configuration values should be set
foreach my $key ( keys %DEFAULTS ) {
confess "Missing configuration $key" unless defined $self->{$key};
}
$self->{debugger} = _mk_debugger( $self, %OPT );
bless $self, $class;
return $self;
}
sub _mk_debugger {
my ($self, %OPT) = @_;
unless ($self->{DRIP_DEBUG}) { return sub {}; }
if ( $OPT{debugger} ) { return $OPT{debugger} }
return sub { warn join "\n", map { ref($_) ? np $_ : $_ } @_ };
}
=head2 do_request
Accepts the following positional parameters:
=over
=item HTTP Method (required)
lib/API/Drip/Request.pm view on Meta::CPAN
=back
On success, returns a Perl data structure corresponding to the data returned
from the server. Some operations (DELETE), do not return any data and may
return undef on success. On error, this method will die() with the
HTTP::Response object.
=cut
my $request_validator = validation_for( params => [ {type => Str()}, {type => Str()}, {type => HashRef(), optional => 1} ] );
sub do_request {
my $self = shift;
my ($method, $endpoint, $content) = $request_validator->(@_);
my $uri = URI->new($self->{DRIP_URI});
$uri->path_segments( $uri->path_segments, $self->{DRIP_ID}, split( '/', $endpoint) );
$self->{debugger}->( 'Requesting: ' . $uri->as_string );
my $request = HTTP::Request->new( $method => $uri->as_string, );
if ( ref($content) ) {
$request->content_type('application/vnd.api+json');
lib/API/Drip/Request.pm view on Meta::CPAN
=item * DRIP_AGENT (optional)
Defaults to "API::Drip". Specifies the HTTP Agent header.
=item * DRIP_DEBUG (optional)
Defaults to 0. Set to a true value to enable debugging.
=cut
sub _load_conf {
my $OPT = shift();
my $conf = {};
KEY:
foreach my $key ( keys %DEFAULTS ) {
next KEY if defined $OPT->{$key};
if ( defined $ENV{$key} ) { $conf->{$key} = $ENV{$key}; next KEY; }
state $YAML_CONF //= _load_yaml_conf( $OPT );
if ( defined $YAML_CONF->{$key} ) { $conf->{$key} = $YAML_CONF->{$key}; next KEY; }
$conf->{$key} = $DEFAULTS{$key};
}
return $conf;
}
sub _load_yaml_conf {
my $OPT = shift();
FILE:
foreach my $location( $OPT->{DRIP_CLIENT_CONF}, $ENV{DRIP_CLIENT_CONF}, File::Spec->catfile( File::HomeDir->my_home, '.drip.conf' )) {
no warnings 'uninitialized';
next FILE unless -f $location && -r _;
return YAML::LoadFile $location;
}
}
xt/boilerplate.t view on Meta::CPAN
#!perl -T
use v5.14;
use strict;
use warnings;
use Test::More;
plan tests => 3;
sub not_in_file_ok {
my ($filename, %regex) = @_;
open( my $fh, '<', $filename )
or die "couldn't open $filename for reading: $!";
my %violated;
while (my $line = <$fh>) {
while (my ($desc, $regex) = each %regex) {
if ($line =~ $regex) {
push @{$violated{$desc}||=[]}, $.;
xt/boilerplate.t view on Meta::CPAN
}
if (%violated) {
fail("$filename contains boilerplate text");
diag "$_ appears on lines @{$violated{$_}}" for keys %violated;
} else {
pass("$filename contains no boilerplate text");
}
}
sub module_boilerplate_ok {
my ($module) = @_;
not_in_file_ok($module =>
'the great new $MODULENAME' => qr/ - The great new /,
'boilerplate description' => qr/Quick summary of what the module/,
'stub function definition' => qr/function[12]/,
);
}
{
not_in_file_ok(README =>
( run in 0.758 second using v1.01-cache-2.11-cpan-a5abf4f5562 )