The API does not allow you to delete photos, or even filter by device, user, or any metadata. This is very frustrating. There are ways you can do this programatically though.
Using Google Takeout(takeout.google.com), you can export all your photos and save them locally. Each media asset comes with a corresponding .json file. This JSON has property that looks like this:
"googlePhotosOrigin": {"fromPartnerSharing": {}}
when the file is from your partner. This JSON includes the Id
of the asset.
If you don't care about the files in Google Photos and only care about the local files, you could write a script that deletes any asset with a JSON that has the fromPartnerSharing
property.
Otherwise, you could write a small Node.js program or something that gets the Id
from that asset and uses the API to create an new album and assign every media item from your partner to that album. Then in the web interface you could open that album and delete all the files in the album.
To create an album using the API: https://developers.google.com/photos/library/reference/rest/v1/albums/create
POST https://photoslibrary.googleapis.com/v1/albums
{
"album": {
object (Album)
}
}
And then to add an asset to the album: (50 max at a time) https://developers.google.com/photos/library/reference/rest/v1/albums/batchAddMediaItems
POST https://photoslibrary.googleapis.com/v1/albums/{albumId}:batchAddMediaItems
{
"mediaItemIds": [
string
]
}
Here is a good article that shows you how to get the API up and running with Postman. This is a good start to play around with the API before writing your program that will actually create the the new album and copy all of the assets to it, so you can delete them via the web interface.
https://medium.com/@yogeswari.narayasamy/fetching-data-from-google-photos-api-with-postman-2959b0f35844
Here is a simple program that would delete the local files from Google Takeout. You could adapt this to make API calls instead to add the files a new album to group them for deletion through the web or mobile app. (Make sure to set startDirectory
to the path of your files first)
const fs = require('fs');
const path = require('path');
let nonPartnerCount = 0
let partnerCount = 0;
// Function to recursively traverse the file system
function traverseDirectory(directory) {
const files = fs.readdirSync(directory);
files.forEach((file) => {
const filePath = path.join(directory, file);
const stats = fs.statSync(filePath);
if (stats.isDirectory()) {
// If it's a directory, recursively traverse it
console.log('Directory: ', file);
traverseDirectory(filePath);
} else if (path.extname(file) === '.json') {
// If it's a JSON file, read its content
try {
const jsonData = JSON.parse(fs.readFileSync(filePath, 'utf8'));
if (jsonData.googlePhotosOrigin && jsonData.googlePhotosOrigin.fromPartnerSharing) {
partnerCount++;
const title = jsonData['title'];
if (title) {
const fileToDeletePath = path.join(directory, title);
// Check if the file to delete exists and is not a directory
if (fs.existsSync(fileToDeletePath) && !fs.statSync(fileToDeletePath).isDirectory()) {
console.log(`Deleting: ${fileToDeletePath}`);
//fs.unlinkSync(fileToDeletePath);
} else {
console.log(`File not found or is a directory: ${fileToDeletePath}`);
}
}
}
else nonPartnerCount++;
} catch (error) {
console.error(`Error processing JSON file: ${filePath}`);
console.error(error);
}
}
});
console.log('Non Partner Count: ', nonPartnerCount);
console.log('Partner Count', partnerCount);
}
// Specify the starting directory path
const startDirectory = '/path/to/directory/withFiles';
// Call the function to start the traversal
traverseDirectory(startDirectory);