API-Google

 view release on metacpan or  search on metacpan

lib/API/Google.pm  view on Meta::CPAN

  warn "get_refresh_token_from_storage(".$user.")" if $self->{debug};
  return $self->{tokensfile}->get('gapi/tokens/'.$user.'/refresh_token');
};

sub get_access_token_from_storage {
  my ($self, $user) = @_;
  $self->{tokensfile}->get('gapi/tokens/'.$user.'/access_token');
};

sub set_access_token_to_storage {
  my ($self, $user, $token) = @_;
  $self->{tokensfile}->set('gapi/tokens/'.$user.'/access_token', $token);
};



sub build_headers {
  my ($self, $user) = @_;
  my $t = $self->get_access_token_from_storage($user);
  my $headers = {};
  $headers->{'Authorization'} = 'Bearer '.$t;
  return $headers;
}


sub build_http_transaction  {
  my ($self, $params) = @_;

  warn "build_http_transaction() params : ".Dumper $params if $self->{debug};

  my $headers = $self->build_headers($params->{user});
  my $http_method = $params->{method};
  my $tx;

  if ($http_method eq 'get' || $http_method eq 'delete') {
    $tx = $self->{ua}->build_tx(uc $http_method => $params->{route} => $headers);
  } elsif (($http_method eq 'post') && $params->{payload}) {
    $tx = $self->{ua}->build_tx(uc $http_method => $params->{route} => $headers => json => $params->{payload})
  } else {
    die 'wrong http_method on no payload if using POST';
  }
  return $tx;

}




sub api_query {
  my ($self, $params, $payload) = @_;

  warn "api_query() params : ".Dumper $params if $self->{debug};

  $payload = { payload => $payload };
  %$params = (%$params, %$payload);

  my $tx = $self->build_http_transaction($params);
  my $res = $self->{ua}->start($tx)->res->json;
    
  # for future:
  # if ( grep { $_->{message} eq 'Invalid Credentials' && $_->{reason} eq 'authError'} @{$res->{error}{errors}} ) { ... }

  warn "First api_query() result : ".Dumper $res if $self->{debug};

  if (defined $res->{error}) { # token expired error handling

    my $attempt = 1;

    while ($res->{error}{message} eq 'Invalid Credentials')  {
      if ($attempt == $self->{max_refresh_attempts}) {
        last;
      }
      warn "Seems like access_token was expired. Attemptimg update it automatically ..." if $self->{debug};
      $self->refresh_access_token_silent($params->{user});
      $tx = $self->build_http_transaction($params);
      $res = $self->{ua}->start($tx)->res->json;
      $attempt++;
    }

    if ($attempt > 1) {
      warn "access_token was automatically refreshed";
    }

  }

  return $res;
};


1;

__END__

=pod

=encoding UTF-8

=head1 NAME

API::Google - Perl library for easy access to Google services via their API

=head1 VERSION

version 0.12

=head1 SYNOPSIS

    use API::Google;
    my $gapi = API::Google->new({ tokensfile => 'config.json' });
    
    $gapi->refresh_access_token_silent('someuser@gmail.com');
    
    $gapi->api_query({ 
      method => 'post', 
      route => 'https://www.googleapis.com/calendar/v3/calendars/'.$calendar_id.'/events',
      user => 'someuser@gmail.com'
    }, $json_payload_if_post);

=head1 CONFIGURATION

config.json must be structured like:

  { "gapi":
    {
      "client_id": "001122334455-abcdefghijklmnopqrstuvwxyz012345.apps.googleusercontent.com",
      "client_secret": "1ayL76NlEKjj85eZOipFZkyM",
      "tokens": {
          "email_1@gmail.com": {
              "refresh_token": "1/cI5jWSVnsUyCbasCQpDmz8uhQyfnWWphxvb1ST3oTHE",



( run in 1.059 second using v1.01-cache-2.11-cpan-f6376fbd888 )