summaryrefslogblamecommitdiffstats
path: root/lib/WWW/Pocket.pm
blob: 6567a9450b85599cbcda0c63b4b2cf0d7df17906 (plain) (tree)
1
2
3
4
5
6
7
8
9

                    
                                         

               
                                                              
             
         
 




































                                                                              
                     


                      

  









                                                                             
                     





                                                            

  







                                                                       
                 



                                 

  





                                                                           


                     


                                        






                                                                        










                                   






                                                                              








                                   

  





                                                  






                                       










                                                                              

                          
                            
 
                                      
 
                                   
                                              
         
                                                


                                          



                                                                                                      

 









                                                                            

                           
                    

                                   
                                                
         
                                                



                                  

                                                        

           

 






                                                                          





                                                     






                                                                            





                                                      







                                                                      










                                                     
                                                                     















                                                                    
                                                                               







                                             








































                                                                         
  
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<Pocket|https://getpocket.com/> 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<start_authentication> and
C<finish_authentication> methods). Once logged in, you can interact with the
API via the C<add>, C<modify>, and C<retrieve> methods, which correspond to
the endpoints documented at L<https://getpocket.com/developer/docs/overview>.

This module also ships with a command line scripts called C<pocket>, 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<https://getpocket.com/developer/apps/>. 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<finish_authentication>, 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<finish_authentication>, 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<https://getpocket.com/>.

=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</v3/> to the
C<base_uri>.

=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</auth/>
to the C<base_uri>.

=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<HTTP::Tiny> 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<finish_authentication> 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<start_authentication> after the user has visited the URL which was also
returned by C<start_authentication>. Once this method returns, the
C<access_key> and C<username> 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<add|https://getpocket.com/developer/docs/v3/add> 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<modify|https://getpocket.com/developer/docs/v3/modify> 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<retrieve|https://getpocket.com/developer/docs/v3/retrieve>
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<https://github.com/doy/www-pocket/issues>.

=head1 SEE ALSO

L<Webservice::Pocket> 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<https://metacpan.org/release/WWW-Pocket>

=item * Github

L<https://github.com/doy/www-pocket>

=item * RT: CPAN's request tracker

L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=WWW-Pocket>

=item * CPAN Ratings

L<http://cpanratings.perl.org/d/WWW-Pocket>

=back

=cut

1;