Apple-AppStoreConnect

 view release on metacpan or  search on metacpan

lib/Apple/AppStoreConnect.pm  view on Meta::CPAN

package Apple::AppStoreConnect;

use 5.008;
use strict;
use warnings;

use Carp;
use Crypt::JWT qw(encode_jwt);
use JSON;

=head1 NAME

Apple::AppStoreConnect - Apple App Store Connect API client

=head1 VERSION

Version 0.12

=cut

our $VERSION = '0.12';

=head1 SYNOPSIS

    use Apple::AppStoreConnect;

    my $asc = Apple::AppStoreConnect->new(
        issuer => $API_key_issuer,  # API key issuer ID
        key_id => $key_id,          # App Store Connect API key ID
        key    => $private_key      # Encrypted private key (PEM)
    );
    
    # Custom API request
    my $res = $asc->get(url => $url);

    # List apps / details convenience function
    $res = $asc->get_apps();                                          # List of apps
    $res = $asc->get_apps(id => $app_id);                             # App details
    $res = $asc->get_apps(id => $app_id, path => 'customerReviews');  # App reviews


=head1 DESCRIPTION

Apple::AppStoreConnect provides basic access to the Apple App Store Connect API.

Please see the L<official API documentation|https://developer.apple.com/documentation/appstoreconnectapi>
for usage and all possible requests.

You can also use it with the L<Apple Store Server API>.

=head1 CONSTRUCTOR

=head2 C<new>

    my $asc = Apple::AppStoreConnect->new(
        key_id      => $key_id,
        key         => $private_key?,
        key_file    => $private_key_pem?,
        issuer      => "57246542-96fe-1a63-e053-0824d011072a",
        scope       => \@scope?,
        timeout     => $timeout_sec?,
        expiration  => $expire_secs?,
        ua          => $lwp_ua?,
        curl        => $use_curl?,
        jwt_payload => {%extra_payload}
    );
  
Required parameters:

=over 4

=item * C<key_file> : The encrypted App Store Connect API private key file that you
create under B<Users and Access> -> B<Keys> on the App Store Connect portal. On the portal
you download a PKCS8 format file (.p8), which you first need to convert to the PEM format.
On a Mac you can convert it simply:

   openssl pkcs8 -nocrypt -in AuthKey_<key_id>.p8 -out AuthKey_<key_id>.pem

=item * C<key> : Instead of the C<.pem> file, you can pass its contents directly
as a string.

=item * C<key_id> : The ID of the App Store Connect API key created on the App Store
Connect portal  (B<Users and Access> section).

=item * C<issuer> : Your API Key B<issuer ID>. Can be found at the top of the API keys
on the App Store Connect Portal (B<Users and Access> section).

=back

Optional parameters:

=over 4

=item * C<scope> : An arrayref that defines the token scope. Example entry:
C<["GET /v1/apps?filter[platform]=IOS"]>.

=item * C<timeout> : Timeout for requests in secs. Default: C<30>.

=item * C<ua> : Pass your own L<LWP::UserAgent> to customise the agent string etc.

=item * C<curl> : If true, fall back to using the C<curl> command line program.
This is useful if you have issues adding https support to L<LWP::UserAgent>, which
is the default method for the API requests.

=item * C<expiration> : Token expiration time in seconds. Tokens are cached until
there are less than 10 minutes left to expiration. Default: C<900> - the API will
not accept more than 20 minutes expiration time for most requests.

=item * C<jwt_payload> : Extra items to append to the JWT payload. Allows extending
the module to support more/newer versions of Apple APIs. For example, for the Apple
Store Server API you'd need to add:

 jwt_payload => {bid => $bundle_id}

=back

=head1 METHODS

lib/Apple/AppStoreConnect.pm  view on Meta::CPAN

        alg           => 'ES256',
        key           => $self->{key},
        extra_headers => {
            kid => $self->{key_id},
            typ => "JWT"
        }
    );

    return $self->{jwt};
}

sub _fetch {
    my ($ua, $url, $jwt) = @_;

    return _curl($url, $jwt) unless $ua;

    return $ua->get($url, Authorization => "Bearer $jwt");
}

sub _curl {
    return `curl "$_[0]" -A "Curl Apple::AppStoreConnect/$VERSION" -s -H 'Authorization: Bearer $_[1]'`;
}

sub _build_url {
    my %args = @_;
    my $url  = $args{url};
    return $url unless ref($args{params});

    my $params = join("&", map {"$_=$args{params}->{$_}"} keys %{$args{params}});

    $url .= "?$params" if $params;

    return $url;
}

sub _process_data {
    my $hash = shift;
    if (ref($hash) && ref($hash->{data}) && ref($hash->{data}) eq 'ARRAY') {
        my $res;
        foreach my $item (@{$hash->{data}}) {
            if ($item->{id} && $item->{attributes}) {
                $res->{$item->{id}} = {%{$item->{attributes}}};
                $res->{$item->{id}}->{type} = $item->{type} if $item->{type};
            }
        }
        return $res if $res;
    }
    return $hash;
}

=head1 NOTES

=head2 Apple Store Server API

You can use this module with the L<Apple Store Server API|https://developer.apple.com/documentation/appstoreserverapi>
by passing your app's bundle ID to the JWT payload. So there is just one addition to the constructor call:

    my $assa = Apple::AppStoreConnect->new(
        issuer      => $API_key_issuer,
        key_id      => $key_id,
        key         => $private_key,
        jwt_payload => {bid => $bundle_id}
    );

You can then pass custon Store Server API requests:

    my $res = $assa->get(url => "https://api.storekit.itunes.apple.com/inApps/v2/history/$transactionId");

=head2 POST/PATCH/DELETE requests

Note that currently only GET requests are implemented, as that is what I needed.
However, POST/PATCH/DELETE can be added upon request.

=head2 403 Unauthorized etc errors

If you suddenly start getting unauthorized errors with a token that should be valid,
log onto App Store Connect and see if you have any documents pending approval (e.g
tax documents, new terms etc).

=head1 AUTHOR

Dimitrios Kechagias, C<< <dkechag at cpan.org> >>

=head1 BUGS

Please report any bugs or feature requests either on L<GitHub|https://github.com/dkechag/Apple-AppStoreConnect> (preferred), or on RT (via the email
C<bug-Apple-AppStoreConnect at rt.cpan.org> or L<web interface|https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Apple-AppStoreConnect>).

I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

=head1 GIT

L<https://github.com/dkechag/Apple-AppStoreConnect>

=head1 LICENSE AND COPYRIGHT

This software is copyright (c) 2023 by Dimitrios Kechagias.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut

1;



( run in 0.277 second using v1.01-cache-2.11-cpan-0d8aa00de5b )