Why would I use node.js to upload an Android app?
Perhaps you’re developing a Cordova (hybrid mobile) app :)
The only library I found available to upload to the Play Store is google-api-nodejs-client
(written by Google).
Since I couldn’t find much documentation, I had to comb a bit through the source code of the library to figure out what was going on. This post will go over some of the initial set-up of the library (there are a few holes, which are left to be figured out).
This tutorial starts at the point after you’ve already set up your app in the Google Play store (but have not yet uploaded a new APK).
Important: according to Play Store docs, you must first MANUALLY upload your APK the first time (by going into your developer console and clicking the “Upload” button). Any time after that, however, you can use a library such as the one in this tutorial.
Also, I’m assuming you’ve already found out a way to build your APK. If you’re using Ionic/Cordiva, follow their official tutorial to figure out how to generate an APK.
Useful documents before we start
- My full example code used in this tutorial (on Github. Save it as something like
upload.js
, and remember tochmod a+x upload.js
to be able to run it on the command line.) This may be incomplete or not fully functional in some places (it was originally tailored for one of our organization’s apps), but the basic “skeleton” is there. You can also download the ZIP (this is linked from Github). googleapis
README on Githubgoogleapis
npm pageandroidpublisher
v2 source code, which is what I used as my documentation (it’s pleasantly well-commented)- Google documentation on developers.google.com for generic usage of the
android-publisher
module
Download the library
This is the abovementioned library, which, according to Github is:
Google’s officially supported node.js client library for using Google APIs
Supposedly it supports all of Google’s APIs, including the androidpublisher
(which is what we’ll be using).
Uploading isn’t quite what it seems
With this API, we don’t simply upload an APK.
Instead, we:
- Open an “edit” (
play.edits.insert
) - Upload the APK in sort of a limbo state (
play.edits.apks.upload
) - Do whatever else in this step (say, set a track, etc.)
- “Commit” the edit (
play.edits.commit
)
Basically what we’re doing is opening some sort of “container” in cyberspace where we have a white room to upload our app, set whatever properties, etc., and then finally we either discard or commit all those edits.
Primer on “tracks”
Read the official Google docs about tracks.
“Tracks” are just channels (alpha
, beta
, and production
). In the Play Store, you can put your app in any of these tracks. Why have alpha
and beta
? Well, in each one of those tracks, you can designate specific testers.
For example, your alpha
track can be closed testing for your developers only, and your beta
track can be for, say, QA engineers, or a small subset of other people.
These “limited” tracks (alpha
and beta
) are also fantastic if your app is some sort of “admin” app that will only ever be available to specific users in your organization. But be careful: the moment you send your app to production, it is there to stay (and it’s live to everyone in the Play Store) (see Unable to deactivate APK accidentally uploaded to Prod on StackOverflow).
Just as an aside, if you want each APK in each track to hit a different server (for example, if you want your beta
to hit “staging.example.com/api/1.0” and your production
track to hit “production.example.com/api/1.0”), you’re out of luck (as far as I know). The APK you upload and promote through the various tracks can’t be reconfigured each time you move it to a different track (by the way, to move your beta
to production
, you can just hit the “Promote to…” button and click the new channel. I haven’t yet tried to use the API to do this, as opening a new zshell window is as easy as just logging into the Play Store console in Chrome and pressing the button. Some hardcore shell users may disagree with me.)
Initial set up
There’s a lot going on here. Here are the initial module declarations.
Finding your secret.json
You can make one! Go to https://console.developers.google.com.
Click on "permissions" in the side menu
You can generate your key here. Don't worry, as of the date of writing this post, you can generate as many keys as you'd like without the fear of revoking other active keys! :)
secret.json
should look something like this:
I found the initial options and how to initialize androidpublisher
through a bit of trial and error. You can use the general googleapis
README (which is not specific to androidpublisher
) if you want to see example of connecting to other APIs, using OAuth2, etc. Again, you won’t find much useful information for this specific case.
Let’s actually do some stuff
In the code above, all we’re doing is calling these steps in order:
- Open our edit (
startEdit
) - Stage our APK for upload (
upload
) - Set our track (
setTrack
) - Committing our changes (
commitToPlayStore
)
Throughout all these steps, all we’re doing is manipulating our data after each function call and piping it into the next function (nothing special about that part).
If all went well, you should see something like this printed in your consol:
Forgetting to bump your version
If you see this:
This means you need to bump your package.json
version.
Final thoughts
The node.js client used in this tutorial is still very much in its early stages, as noted by Google in their official README:
This library is in Alpha. We will make an effort to support the library, but we reserve the right to make incompatible changes when necessary.
Another gaping hole missing in this tutorial is promotion through tracks. If anyone knows more about that, please comment below! Thanks for reading, and I hope you’ve found some useful information in this post!