package WWW::Pocket;
use Moose;
# ABSTRACT: Wrapper for the Pocket v3 API
use HTTP::Tiny;
use IO::Socket::SSL; # Necessary for https URLs on HTTP::Tiny.
use JSON::PP;
use Carp;
=head1 SYNOPSIS
use WWW::Pocket;
my $pocket = WWW::Pocket->new(
# get a consumer key at https://getpocket.com/developer/
consumer_key => '...',
);
my ($url, $code) = $pocket->start_authentication('https://example.com/');
# visit $url, log in
$pocket->finish_authentication($code);
say for map { $_->{resolved_url} } values %{ $pocket->retrieve->{list} };
=head1 DESCRIPTION
This module wraps the L v3 API. To use, you
must first authenticate via OAuth by providing a valid consumer key, and then
visiting the OAuth endpoint (handled by the C and
C methods). Once logged in, you can interact with the
API via the C, C, and C methods, which correspond to
the endpoints documented at L.
This module also ships with a command line scripts called C, for
interacting with the API from the command line. See the documentation for that
script for more details.
=cut
=attr consumer_key
The consumer key for your application. You can generate a consumer key at
L. Required.
=cut
has consumer_key => (
is => 'ro',
isa => 'Str',
required => 1,
);
=attr access_token
The token returned when you successfully authenticate. This can be used to
reauthenticate with the server without having to log in every time. It is set
automatically by C, but can also be provided directly
to avoid having to reauthenticate. It is required to be set before any API
methods are called.
=cut
has access_token => (
is => 'ro',
isa => 'Str',
lazy => 1,
default => sub { die "You must authenticate first." },
predicate => 'has_access_token',
writer => '_set_access_token',
);
=attr username
The username that you have authenticated as. It is set automatically by
C, and can also be provided directly. It is
informational only.
=cut
has username => (
is => 'ro',
isa => 'Str',
predicate => 'has_username',
writer => '_set_username',
);
=attr base_uri
The base URI for the Pocket service. Defaults to C.
=cut
has base_uri => (
is => 'ro',
isa => 'Str',
default => 'https://getpocket.com/',
);
=attr api_base_uri
The base URI for the API endpoints. Defaults to appending C to the
C.
=cut
has api_base_uri => (
is => 'ro',
isa => 'Str',
lazy => 1,
default => sub {
my $base = $_[0]->base_uri;
$base =~ s{/$}{};
return "$base/v3/"
},
);
=attr auth_base_uri
The base URI for the authentication endpoints. Defaults to appending C
to the C.
=cut
has auth_base_uri => (
is => 'ro',
isa => 'Str',
lazy => 1,
default => sub {
my $base = $_[0]->base_uri;
$base =~ s{/$}{};
return "$base/auth/"
},
);
=attr ua
The L instance used to access the api.
=cut
has ua => (
is => 'ro',
isa => 'HTTP::Tiny',
lazy => 1,
default => sub { HTTP::Tiny->new },
);
=method start_authentication($redirect_uri)
Call this method to begin the authentication process. You must provide the
C<$redirect_uri>, which is where the user will be redirected to after
authenticating. This method returns a URL and an authentication code. The user
must visit the URL to log into Pocket and approve the application, and then
you should call C with the authentication code after
that is done.
=cut
sub start_authentication {
my $self = shift;
my ($redirect_uri) = @_;
return if $self->has_access_token;
my $response = $self->_request(
$self->api_base_uri . 'oauth/request',
{
consumer_key => $self->consumer_key,
redirect_uri => $redirect_uri,
},
);
return (
$self->auth_base_uri . "authorize?request_token=$response->{code}&redirect_uri=$redirect_uri",
$response->{code},
);
}
=method finish_authentication($code)
Finishes the authentication process. Call this method with the code returned
by C after the user has visited the URL which was also
returned by C. Once this method returns, the
C and C attributes will be set, and other API methods
can be successfully called.
=cut
sub finish_authentication {
my $self = shift;
my ($code) = @_;
my $response = $self->_request(
$self->api_base_uri . 'oauth/authorize',
{
consumer_key => $self->consumer_key,
code => $code,
},
);
$self->_set_access_token($response->{access_token});
$self->_set_username($response->{username});
return;
}
=method add(%params)
Wraps the L endpoint.
C<%params> can include any parameters documented in the API documentation.
=cut
sub add {
my $self = shift;
my (%params) = @_;
return $self->_endpoint_request('add', \%params);
}
=method modify
Wraps the L endpoint.
C<%params> can include any parameters documented in the API documentation.
=cut
sub modify {
my $self = shift;
my (%params) = @_;
return $self->_endpoint_request('send', \%params);
}
=method retrieve
Wraps the L
endpoint. C<%params> can include any parameters documented in the API
documentation.
=cut
sub retrieve {
my $self = shift;
my (%params) = @_;
return $self->_endpoint_request('get', \%params);
}
sub _endpoint_request {
my $self = shift;
my ($endpoint, $params) = @_;
$params->{consumer_key} = $self->consumer_key;
$params->{access_token} = $self->access_token;
return $self->_request($self->api_base_uri . $endpoint, $params);
}
sub _request {
my $self = shift;
my ($uri, $params) = @_;
my $response = $self->ua->post(
$uri,
{
content => encode_json($params),
headers => {
'Content-Type' => 'application/json; charset=UTF-8',
'X-Accept' => 'application/json',
},
},
);
croak "Request for $uri failed ($response->{status}): $response->{content}"
unless $response->{success};
return decode_json($response->{content});
}
__PACKAGE__->meta->make_immutable;
no Moose;
=head1 BUGS
No known bugs.
Please report any bugs to GitHub Issues at
L.
=head1 SEE ALSO
L for the v2 API
=head1 SUPPORT
You can find this documentation for this module with the perldoc command.
perldoc WWW::Pocket
You can also look for information at:
=over 4
=item * MetaCPAN
L
=item * Github
L
=item * RT: CPAN's request tracker
L
=item * CPAN Ratings
L
=back
=cut
1;