Upload APK and set track for publishing
Asked Answered
K

1

9

I am trying to set a new track and upload APK for publishing using nodejs... But no APK is uploaded nor is there a track set.

But the results from the validation and all the other steps are exactly as I expect(according to API). The script succeeds, yet nothing changes in the developer console... So is there a magic guru out there that may see my issue?

NOTE 1: I did publish my app manually because the android-publisher is only for updating apps that have been published before

NOTE 2: This worked before(a long time ago), and has stopped working for a while, I finally got around to updating everything

My code:

var google = require('googleapis').google;
var Promise = require('bluebird');
var _ = require('lodash');
var settings = require('./config/settings.json');

// Enable API access into the Developer Console: https://play.google.com/apps/publish/?account=7639196906174529268#ApiAccessPlace
// Create a service account
// Download the JSON and save it here
// Make sure the email of the JSON is added to the apps for release manager role:
// https://play.google.com/apps/publish/?account=7639196906174529268#AdminPlace
var key = require('./config/google-play-user.json');

// editing "scope" allowed for OAuth2
var scopes = [
    'https://www.googleapis.com/auth/androidpublisher'
];

var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2();
var jwtClient = new google.auth.JWT(key.client_email, null, key.private_key, scopes, null);
var play = google.androidpublisher({
    version: 'v3',
    auth: oauth2Client,
    params: {
        // default options
        // this is the package name for your initial app you've already set up on the Play Store
        packageName: settings.app.id
    }
});

google.options({auth: oauth2Client});

// Start with a new edit.
startEdit().then(function(data) {
    // Load our APK(in this case a Cordova APK).
    var standardAPK = require('fs').readFileSync('./platforms/android/build/outputs/apk/android-release.apk');

    // Stage the upload (doesn't actually upload anything).
    return upload({
        edit: data.edit,
        apk: standardAPK,
        key: 'standardApk'
    });

}).then(function(data) {
    // Set our track.
    return setTrack(data);
}).then(function(data) {
    // Validate our changes.
    return validateToPlayStore(data);
}).then(function(data) {
    console.log('Successful uploaded APK files:', data);
}).catch(function(err) {
    console.log(err);
    process.exit(1);
});

/**
 *  Sets our authorization token and begins an edit transaction.
 */
function startEdit() {
    return new Promise(function(resolve, reject) {
        jwtClient.authorize(function(err, tokens) {
            if (err) {
                console.log(err);
                process.exit(1);
                return;
            }

            // Set the credentials before we doing anything.
            oauth2Client.setCredentials(tokens);

            play.edits.insert({
                packageName: settings.app.id
            }, function(err, edit) {
                if (err || !edit) { reject(err); }

                resolve({
                    edit: edit.data
                });
            });
        });
    });
}

/**
 *  Stages an upload of the APK (but doesn't actually upload anything)
 */
function upload(data) {
    var edit = data.edit;
    var apk = data.apk;
    var key = data.key;

    return new Promise(function(resolve, reject) {
        play.edits.apks.upload({
            editId: edit.id,
            packageName: settings.app.id,
            media: {
                mimeType: 'application/vnd.android.package-archive',
                body: apk
            }
        }, function(err, res) {
            if (err || !res) { reject(err); }

            // Pass any data we care about to the next function call.
            var obj = {};
            obj[key] = res.data;
            resolve(_.omit(_.extend(data, obj), 'apk'));
        });
    });
}

/**
 *  Sets our track (beta, production, etc.)
 */
function setTrack(data) {
    var edit = data.edit;
    var track = 'production';

    return new Promise(function(resolve, reject) {
        play.edits.tracks.update({
            editId: edit.id,
            track: track,
            packageName: settings.app.id
        }, function(err, res) {
            if (err || !res) { reject(err); }

            resolve(_.extend(data, {setTrackResults: res.data}));
        });
    });

}

/**
 *  Validates our edit transaction and makes our changes live.
 */
function validateToPlayStore(data) {
    return new Promise(function(resolve, reject) {
        // play.edits.commit({ // Commit will set the change LIVE
        play.edits.validate({ // Validate will only validate it, not set it LIVE.
            editId: data.edit.id,
            packageName: settings.app.id
        }, function(err, res) {
            if (err || !res) { reject(err); }

            resolve(_.extend(data, {validateToPlayStoreResults: res.data}));
        });
    });
}

Originally from http://frontendcollisionblog.com/javascript/2015/12/26/using-nodejs-to-upload-app-to-google-play.html when it still worked

Kassa answered 3/7, 2018 at 8:15 Comment(1)
you'd need to show us what's happening when you're attempting to update your app in the console.Phosphatize
C
0

You can use apkup to upload APKs to Google Play. apkup is basically a friendly wrapper/CLI for the googleapis package.

CLI example:

npx apkup \
  --key ./config/google-play-user.json \
  --release-notes "en-US=lorem ipsum dolor" \
  --apk ./platforms/android/build/outputs/apk/android-release.apk

Node.js example:

const { Apkup } = require('apkup')
const key = require('./config/google-play-user.json')

const apkup = new Apkup(key)

apkup
  .upload('./platforms/android/build/outputs/apk/android-release.apk', {
    releaseNotes: [
      {
        language: 'en-US',
        text: 'Minor bug fixes...'
      }
    ]
  })
  .then(data => {
    console.log(` > ${data.packageName} version ${data.versionCode} is up!`)
  })
Cartwheel answered 19/6, 2019 at 15:15 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.