Skip to content

mlauenborg/gopro-to-google-migration

Repository files navigation

GoPro Premium → Google Photos Migration

Migrate all your media (photos and videos) from GoPro Premium to Google Photos so you can cancel your GoPro Premium / Plus subscription without losing your files.

The script works in a stream-based, disk-efficient way: one file is downloaded, uploaded, and then deleted from disk before the next file is processed. Only one file occupies your local disk at any time.


Table of Contents

  1. What this project does
  2. Prerequisites
  3. Finding your GoPro auth token and user ID
  4. Setting up Google Cloud OAuth credentials
  5. Installation and usage
  6. Configuration options
  7. Troubleshooting / FAQ

1. What this project does

Feature Details
Minimal disk usage Downloads one file at a time, uploads it, then deletes the local copy
Resume support Stores progress in migration_state.json; restart safely after interruptions
Retry / backoff Automatically retries on network errors and API rate limits
Resumable uploads Uses Google's resumable upload protocol for large video files
EXIF timestamps Preserves the original capture date on JPEG photos so Google Photos sorts them correctly
Smart ordering Processes smallest files first so you get fast initial progress
Progress bar Live terminal progress via tqdm
Logging Human-readable log written to migration.log

2. Prerequisites

  • Python 3.10 or newer
  • An active GoPro Premium / Plus subscription with media stored in GoPro Premium cloud
  • A Google account with enough free storage for your media (Google Photos counts towards your 15 GB free Google storage quota)

3. Finding your GoPro auth token and user ID

GoPro does not offer a public OAuth flow for third-party scripts, so you need to copy the authentication cookies that your browser already has after you log in to GoPro Premium cloud.

Step-by-step (Chrome / Edge)

  1. Open https://gopro.com in your browser and log in.
  2. Press F12 (or Cmd+Opt+I on macOS) to open DevTools.
  3. Click the Application tab (you may need to click » to find it).
  4. In the left sidebar, expand Cookies → click https://gopro.com.
  5. Find the cookie named gp_access_token – copy its Value.
  6. Find the cookie named gp_user_id – copy its Value.

Note: These tokens expire after some time. If the script starts returning 401 errors, repeat the steps above to get fresh tokens.

Step-by-step (Firefox)

  1. Log in to https://gopro.com.
  2. Press F12Storage tab → expand Cookies → click https://gopro.com.
  3. Copy the values of gp_access_token and gp_user_id.

4. Setting up Google Cloud OAuth credentials

4.1 Create a Google Cloud project

  1. Go to https://console.cloud.google.com/.
  2. Click Select a projectNew Project.
  3. Give it a name (e.g. gopro-migration) and click Create.

4.2 Enable the Photos Library API

  1. In the left menu go to APIs & ServicesLibrary.
  2. Search for Photos Library API and click Enable.

4.3 Configure the OAuth consent screen

Note: Google has redesigned this UI. If you don't see "OAuth consent screen" under "APIs & Services", look for Google Auth PlatformBranding in the left menu instead.

  1. Go to APIs & ServicesOAuth consent screen (or Google Auth PlatformBranding).
  2. Select External and click Create.
  3. Fill in the required fields (App name, user support email, developer email).
  4. Click Save and Continue through the remaining steps.
  5. On the Test users (or Audience) screen, add your own Google account as a test user.

4.4 Create OAuth 2.0 credentials

  1. Go to APIs & ServicesCredentials (or Google Auth PlatformClients).
  2. Click Create CredentialsOAuth client ID (or Create Client).
  3. Choose Desktop app as the application type.
  4. Give it a name and click Create.
  5. Click Download JSON and save the file as client_secrets.json in the project directory.

5. Installation and usage

# 1. Clone or download this project
git clone https://github.com/mlauenborg/gopro-to-google-migration.git
cd gopro-to-google-migration

# 2. (Recommended) Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate

# 3. Install dependencies
pip install -r requirements.txt

# 4. Configure credentials
cp .env.example .env
# Edit .env and fill in GOPRO_ACCESS_TOKEN, GOPRO_USER_ID,
# and adjust GOOGLE_CLIENT_SECRETS_FILE if needed.

# 5. Place client_secrets.json in the project directory
#    (downloaded from Google Cloud Console – see step 4.4 above)

# 6. Run the migration
python migrate.py

On the first run a browser window will open asking you to authorise the script to upload to your Google Photos library. After you approve it, the token is saved to google_token.json so subsequent runs are non-interactive.


6. Configuration options

All options can be set in the .env file (copy from .env.example):

Variable Default Description
GOPRO_ACCESS_TOKEN (required) JWT from browser cookie gp_access_token
GOPRO_USER_ID (required) From browser cookie gp_user_id
GOOGLE_CLIENT_SECRETS_FILE client_secrets.json Path to Google OAuth credentials
GOOGLE_TOKEN_FILE google_token.json Where the OAuth token cache is stored
TEMP_DOWNLOAD_DIR /tmp/gopro_migration Temporary directory for downloads
MIGRATION_STATE_FILE migration_state.json Progress tracker (auto-created)
CHUNK_SIZE 1048576 (1 MB) Download/upload chunk size in bytes
MAX_RETRIES 5 Maximum retry attempts on transient errors
RETRY_BACKOFF_BASE 1.0 Initial backoff delay in seconds (doubles each retry)
GOPRO_PAGE_SIZE 100 Number of items fetched per GoPro API page

7. Troubleshooting / FAQ

The script exits with "Missing required environment variables"

Make sure you have copied .env.example to .env and filled in both GOPRO_ACCESS_TOKEN and GOPRO_USER_ID.

The GoPro API returns 401 Unauthorized

Your gp_access_token has expired. Log in to gopro.com again, copy the fresh cookie value, and update your .env file.

The script keeps failing on large video files

Increase MAX_RETRIES in .env and make sure you have a stable internet connection. The resumable upload will resume where it left off.

I want to re-run the script but some files are already migrated

The script automatically skips files listed in migration_state.json. You can safely re-run it at any time; only files that haven't been migrated yet (or that previously failed) will be processed.

How do I re-try only the failed files?

Open migration_state.json and remove the entries under "failed" that you want to retry, then run the script again.

The Google Photos browser asks me to verify the app

Because this is a personal project using the "External" OAuth consent type, Google shows a warning screen. Click AdvancedGo to <app name> (unsafe) to proceed. This is expected for personal scripts.

Google Photos API quota exceeded

The free tier allows 10 000 requests per day. Each file requires 2 API calls (upload + create), so you can migrate ~5 000 files per day. If you hit the limit, wait 24 hours and re-run the script (it will resume from where it stopped).

Where are the migrated files logged?

Check migration.log in the project directory for a detailed log of every file, including errors and retry attempts.

The file count in Google Photos is lower than the number of migrated files

Google Photos de-duplicates by content. If your GoPro Premium library contains files that are byte-identical (e.g. the same clip saved twice), Google Photos will only store one copy. The migration still counts each upload as successful — this is normal.

How do I clean up after the migration?

After verifying your files are in Google Photos:

  1. Revoke Google API access — go to myaccount.google.com/permissions and remove the app.
  2. Delete local credentials — remove client_secrets.json, google_token.json, and .env from the project directory.
  3. Optionally delete the Google Cloud project at console.cloud.google.com.

Project structure

gopro-to-google-migration/
├── migrate.py              # Entry point – run this
├── gopro_client.py         # GoPro Premium API client
├── google_photos_client.py # Google Photos API client
├── migration_engine.py     # Core loop: download → upload → delete → log
├── config.py               # Configuration loader
├── requirements.txt        # Python dependencies
├── .env.example            # Template for .env credentials file
├── .gitignore
└── README.md

License

This project is released under the MIT License.

About

Migrate all your media from GoPro Premium to Google Photos

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages