As of March 31, 2025, Google has deprecated the following Google Photos API scopes:
photoslibrary.readonlyphotoslibraryphotoslibrary.sharing
These scopes are no longer functional, even if previously authorized.
This means gphoto2immich can no longer access existing photos in Google Photos via the API.
As a result of the API scope deprecations, this project is currently in a frozen state. Development is paused while we evaluate whether it makes sense to continue or pivot the tool in a different direction.
Possible future directions include:
- Parsing Google Takeout exports
- Using Immich's built-in upload capabilities
- Limited support via Picker API for manually selected items
In the meantime, the current implementation is preserved for reference. If you'd like to propose an alternative direction or contribute ideas (e.g., Takeout integration), feel free to open a discussion or issue.
Synchronize photo descriptions from Google Photos to Immich.
- Pull metadata (filename, description, creation time) from Google Photos API
- Find matching assets in Immich by filename
- Update asset descriptions in Immich if found
- Dry-run mode for safe testing
- Docker + Compose setup
- Pre-commit checks (mypy, ruff, pytest)
- Logging with level control (DEBUG, INFO, WARNING, ERROR)
- Synchronization strategy control (overwrite / skip_if_present)
git clone https://github.com/pokornyIt/gphoto2immich.git
cd gphoto2immich
cp .env.example .env
# Fill in .env with your Google credentials and Immich infoOr use Docker:
docker compose run --rm sync- Go to Google Cloud Console
- Create a new project (or reuse existing)
- Enable the Google Photos Library API
- Go to "APIs & Services > Credentials"
- Click Create Credentials > OAuth client ID
- Choose Desktop app as application type
- Download the resulting
client_secret_XXXX.json - Save it as
google-credentials.json(or update path in.env)
On first run, a browser window will open to authenticate your Google account and generate a
token.jsonfile.
Edit .env file:
GOOGLE_CREDENTIALS_PATH=./google-credentials.json
IMMICH_BASE_URL=https://immich.example.com/api
IMMICH_API_KEY=your_api_key
DAYS_BACK=14
DRY_RUN=true
LOG_LEVEL=INFO
SYNC_STRATEGY=overwrite # or skip_if_presentpython main.pypytestUse SYNC_STRATEGY to control how the tool behaves when Immich already has a description:
overwrite– always overwrite existing Immich descriptionsskip_if_present– skip updating if Immich already has a description
When DRY_RUN=true, updates to Immich are skipped but logged, so you can verify the behavior safely.
Set LOG_LEVEL=DEBUG (or INFO/WARNING/ERROR) to control verbosity. Each module uses structured logging.
- Export summary of changes
- Asynchronous sync engine
- Album sync support
- CLI interface
- Docker image publishing
See issues.md for detailed ideas.
Project licensed under MIT.