package WWW::Pocket; use Moose; # ABSTRACT: Wrapper for the Pocket v3 API use HTTP::Tiny; use JSON::PP; =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', }, }, ); die "Request for $uri failed ($response->{status}): $response->{reason}" 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;