Server side authorization with Google Play Developer API?

不打扰是莪最后的温柔 提交于 2019-11-30 22:25:18

After lots of headache (like always with Google APIs and services) I figured out how one can access Google Play Developer API information (like billing) by using existing APIs.

1.) Create in Developer API Console a service account (JSON) key:

2.) Download this service-account-private-key.json file (don't mistake it with the OAuth2.0 client secret file!).

3.) In Google Play Developer Console go to Settings -> Users & Permissions -> Invite New User and set as user e-mail of the new user the client_email from the downloaded file. Assign the access rights you want to give to this users via the checkboxes inside this view (for example 'View financial data').

4.) Add the proper dependency to your project (version ...-1.23.0 does not work for me):

<dependency>
    <groupId>com.google.apis</groupId>
    <artifactId>google-api-services-androidpublisher</artifactId>
    <version>v2-rev50-1.22.0</version>
</dependency>

5.) Load the service-account-private-key.json file into your application. In my case it's a webserver:

@Singleton
@Startup
public class WebserverConfiguration
{
    private String serviceAccountPrivateKeyFilePath;

    /** Global instance of the HTTP transport. */
    public static HttpTransport HTTP_TRANSPORT;

    /** Global instance of the JSON factory. */
    public static JsonFactory JSON_FACTORY;

    private GoogleCredential credential;

    @PostConstruct
    public void init()
    {
        assignServiceAccountFileProperty();
        initGoogleCredentials();
    }

    public String getServiceAccountPrivateKeyFilePath()
    {
        return serviceAccountPrivateKeyFilePath;
    }

    public GoogleCredential getCredential()
    {
        return credential;
    }

    private void initGoogleCredentials()
    {
        try
        {
            newTrustedTransport();
            newJsonFactory();

            String serviceAccountContent = new String(Files.readAllBytes(Paths.get(getServiceAccountPrivateKeyFilePath())));
            InputStream inputStream = new ByteArrayInputStream(serviceAccountContent.getBytes());

            credential = GoogleCredential.fromStream(inputStream).createScoped(Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER));

        }
        catch (IOException | GeneralSecurityException e)
        {
            throw new InitializationException(e);
        }
    }

    private void newJsonFactory()
    {
        JSON_FACTORY = JacksonFactory.getDefaultInstance();
    }

    private void assignServiceAccountFileProperty()
    {
        serviceAccountPrivateKeyFilePath = System.getProperty("service.account.file.path");
        if (serviceAccountPrivateKeyFilePath == null)
        {
            throw new IllegalArgumentException("service.account.file.path UNKNOWN - configure it as VM startup parameter in Wildfly");
        }
    }

    private static void newTrustedTransport() throws GeneralSecurityException, IOException
    {
        if (HTTP_TRANSPORT == null)
        {
            HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        }
    }
}

6.) Now I am able the fetch Google Play Developer API information, e.g. reviews:

private void invokeGoogleApi() throws IOException
{       
    AndroidPublisher publisher = new AndroidPublisher.Builder(WebserverConfiguration.HTTP_TRANSPORT, WebserverConfiguration.JSON_FACTORY, configuration.getCredential()).setApplicationName("The name of my app on Google Play").build();
    AndroidPublisher.Reviews reviews = publisher.reviews();
    ReviewsListResponse reviewsListResponse = reviews.list("the.packagename.of.my.app").execute();
    logger.info("review list response = " + reviewsListResponse.toPrettyString());
}

This worked.

I cannot test it yet, but I'm sure that fetching the billing information works as well:

private SubscriptionPurchase getPurchase() throws IOException
{
    AndroidPublisher publisher = new AndroidPublisher.Builder(WebserverConfiguration.HTTP_TRANSPORT, WebserverConfiguration.JSON_FACTORY, configuration.getCredential()).setApplicationName("The name of my app on Google Play").build();
    AndroidPublisher.Purchases purchases = publisher.purchases();

    SubscriptionPurchase purchase = purchases.subscriptions().get("the.packagename.of.my.app", "subscriptionId", "billing token sent by the app").execute();

    //do something or return
    return purchase;
}

There are complete code samples and documentation for doing this in Java here

In the Java source code this authorizes like this

private static Credential authorizeWithServiceAccount(String serviceAccountEmail)
            throws GeneralSecurityException, IOException {
        log.info(String.format("Authorizing using Service Account: %s", serviceAccountEmail));

        // Build service account credential.
        GoogleCredential credential = new GoogleCredential.Builder()
                .setTransport(HTTP_TRANSPORT)
                .setJsonFactory(JSON_FACTORY)
                .setServiceAccountId(serviceAccountEmail)
                .setServiceAccountScopes(
                        Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER))
                .setServiceAccountPrivateKeyFromP12File(new File(SRC_RESOURCES_KEY_P12))
                .build();
        return credential;
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!