Google Play package download and archival tool
Find a file
2025-09-25 01:08:02 +02:00
src Update device list 2025-03-30 23:09:20 +02:00
.gitignore Initial commit 2024-10-29 00:44:26 +01:00
.gitlab-ci.yml Use minimal rustup profile in CI 2025-01-10 17:33:33 +01:00
Cargo.lock Update dependencies 2025-03-28 15:46:13 +01:00
Cargo.toml Initial commit 2024-10-29 00:44:26 +01:00
LICENSE Initial commit 2024-10-29 00:44:26 +01:00
README.md Update README 2025-09-25 01:08:02 +02:00

gplay-dl

Google Play package download and archival tool.

Warning: Usage of this program is against the Google ToS. Your account can be banned. I have been successfully using it without issues, and a similar project that also interfaces with Google Play in ToS breaking ways called Aurora Store has a sizable user base, but there's no guarantees. Avoid using with your primary account if possible, and in case you get banned, don't blame it on me. I warned you.

Keep in mind this project is currently in it's early stages. It can already download packages, but it might break, and it's not easy to use.

Setup

Download the latest master branch artifacts for your OS from the CI system (currently there are Linux and Windows builds available). The binary can be found in the artifacts archive at target/<platform>/release. Put it in a location on your PATH.

The Linux builds require OpenSSL 3 (libssl3 package on Debian).

Basic usage

Configuration file

Create a config.toml file holding the program configuration. An example config.toml can look like this:

check_delay = 10000

[authentication]
email = "example@example.com"
aas_token = ""

[download]
locale = "en"
download_devices = ["fp_3"]
target_directory = "{package}/{version}"
skip_existing = true
lax = false

Configuration overview:

  • check_delay (integer): Time in miliseconds to wait between checks using the check-versions command.

  • authentication.email (string): E-mail address tied to the authenticated Google account.

  • authentication.aas_token (string): Authentication token.

  • download.locale (string): Locale string. See Advanced downloading section.

  • download.download_devices (string array): Device set. See Advanced downloading section.

  • download.target_directory (string): Directory to download package files to.

    {package} is replaced with the package ID, and {version} is replaced with the version code.

  • download.skip_existing (bool): Skip existing files rather than overwriting them.

  • download.lax (bool): Don't error out of a download if one device fails to get version info. This is not recommended, as you might miss downloads if something goes wrong, but you'll still get a warning.

Authentication

Change authentication.email in config.toml to your Google account e-mail address. Go to the embedded Google sign in page, and log in with the same address. When you sign in and the page continues to load infinitely, use your browser's devtools to grab the oauth_token cookie.

Now, generate an aas token by running the following command, where TOKEN is the value of the cookie:

gplay-dl login TOKEN

It should output something like this:

Some("aas_et/...")

Copy everything in between the quotes and paste it into config.toml as authentication.aas_token.

Checking if everything works

Run the following command:

gplay-dl check-versions moe.low.arc 1208210 1208210

If it outputs the following, everything should be set up properly:

Trying 1208210...
1208210

Downloading

Provided you have an appropriate device set, you can download all files associated with a package like this:

gplay-dl download PACKAGE [VERSION]...

Where PACKAGE is the package ID to download, and VERSION is the version code. You can provide more than one version code. Not providing a version code downloads the latest version of the package, but this has caveats.

The device set given in the example configuration should be able to download files required to run the program on an ARM64 device. If this is not enough, read the Advanced downloading section.

Advanced downloading

Google Play is complicated. It's not possible to simply ask for "all files of a package". Instead, the client provides information about itself (Android version, architecture, locale etc.), and the server decides which files to serve (it also decides what is treated as the latest version).

Because of this, gplay-dl uses a device set system - you can provide a set of devices, and it will ask Google Play to provide a download for each one, getting all available files. An appropriate device set needs to be constructed for each package (sometimes even version) - asking for downloads for all existing devices would take too much time, and also abuse the Google Play API, which could lead to ratelimiting or account bans.

Package files

First, we need to talk about what files we might want to download. There's a bunch of them.

As you might know, the file format used for Android packages is APK. An APK can be full or split.

Full APKs are what most people are familiar with, you have one file, which can be installed by opening it with the package installer on your device. Depending on the package, they can come with corresponding OBB files.

Split APKs are the more modern way to distribute packages - they come in groups, and the entire group (or a subset of it) has to be installed at once, which requires more complicated methods. That's because the functionality is split between multiple APK files, allowing you to only download and install the ones your device needs. This is not a bad thing, since the package takes up less space after installation, but downloading split APKs from Google Play is more complex.

They are divided into the following categories:

Name Downloaded Filename Number in package
Base Always base.apk 1
Architecture Depending on supported and primary instruction sets config.architecture.apk 0-4
DPI Depending on display DPI config.prefixdpi.apk 0-7
Locale Depending on current locale config.locale code.apk 0+ (usually 0 or a few dozen)
Asset Most likely always name.apk 0+ (usually 0 or 1)

Full APKs used to be the only way packages are distributed, but nowadays an overwhelming amount of packages on Google Play comes as split APKs.

Versions that had split APKs used to also have a full APK, but this is no longer the case - the full APKs of these versions were for all intents and purposes completely removed from Google Play. A version always has either split APKs or a full APK.

Constructing a device set

First, investigate what files are available for the package and version you are trying to download. To do this, use the check-devices subcommand:

gplay-dl check-devices PACKAGE [VERSION]

Where PACKAGE is the package ID, and VERSION is the version code.

This gives an output like the following.

Each line represents a device, and is split by commas into sections. The device section is the device identifier. If a login error or download error section is present, then this device failed to download the package and can be ignored. For all the other devices, which we'll call supported devices (usually a failed download means the device is unsupported), see if the split apks section is empty or not - if it's empty, this version has a full APK, if it's not - it has split APKs.

If the version has a full APK, you can make a simple set with just one supported device. Note that if the data files section is not empty, an OBB should be downloaded as well.

If the version has a split APK, consider each unique split found in the split apks sections of all supported devices. Since the base split (not shown in split apks) and asset splits are always downloaded, we do not need to worry about them - as long as one supported device is in the set, it will be downloaded. Now, add a device for each unique architecture and DPI split to the set.

Try to make device sets as small as possible, as it reduces the amount of required requests to Google Play.

Locales

Locale splits are not part of the device set construction process, because a single device can easily download all possible locale splits. If a version has one or more locale split in the split apks section, then we can know that at least those splits are available, but it's usually more than that. Sadly, there's no perfect way to guess what locale splits are available. One method includes using the output of aapt dump badging on an older full APK.

Once you have a list of locale splits to download, set the locale string to a comma separated list of locales.

Versions

TBD

Region locking

TBD

Copyright © 2024-2025 Grzesiek11

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.