I Thought He Came With You is Robert Ellison’s blog about software, marketing, politics, photography and time lapse.

How to backup Google Photos to Google Drive automatically after July 2019 with Apps Script

Updated on Wednesday, September 25, 2019

Google Photos backup to Google Drive shutting down in July 2019

Google has decided that backing up your photos via Google Drive is 'confusing' and so Drive based backup is going away this month. I love Google Photos but I don't trust it - I pull everything into Drive and then I stick a monthly backup from there onto an external drive in a fire safe. There is a way to get Drive backup working again using Google Apps Script and the Google Photos API. There are a few steps to follow but it's pretty straightforward - you should only need to change two lines in the script to get this working for your account.

First two caveats to be aware of. Apps Script has a time limit and so it's possible that it could fail if moving a large number of photos. You should get an email if the script ever fails so watch out for that. Secondly and more seriously you could end up with two copies of your photos. If you use Backup and Sync to add photos from Google Drive then these photos will be downloaded from Google Photos by the script and added to Drive again. You need to either upload directly to Google Photos (i.e. from the mobile app or web site) or handle the duplicates in some way. If you run Windows then I have released a command line tool that sorts photos into year+month taken folders and handles de-duplication.

One more limitation. After a comment by 'Logan' below I realized that Apps Script has a 50MB limitation for adding files to Google Drive. The latest version of the script will detect this and send you an email listing any files that could not be copied automatically.

On to the script. In Google Drive create a new spreadsheet. This is just a host for the script and makes it easy to authorize it to access Google Photos. Select 'Script editor' from the Tools menu to create a new Apps Script project.

In the script editor select 'Libraries...' from the Resources menu. Enter 1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF next to 'Add a library' and click add. This will find the Google OAuth2 library Pick the most recent version and click Save.

Select 'Project properties' from the File menu and copy the Script ID (a long sequence of letters and numbers). You'll need this when configuring the Google Photos API.

In a new window open the Google API Console, part of the Google Cloud Platform. Create a new project, click Enable APIs and Services and find and enable the Google Photos API. Then go to the Keys section and create an OAuth Client ID. You'll need to add a consent screen, the only field you need to fill out is the product name. Choose Web Application as the application type. When prompted for the authorized redirect URL enter https://script.google.com/macros/d/{SCRIPTID}/usercallback and replace {SCRIPTID} with the Script ID you copied above. Copy the Client ID and Client Secret which will be used in the next step.

Go back to the Apps Script project and paste the code below into the Code.gs window:

Enter the Client ID and Client Secret inside the empty quotes at the top of the file. You also need to add an email address to receive alerts for large files. There is a BackupFolder option at the top as well - the default is 'Google Photos' which will mimic the old behavior. You can change this if you like but make sure that the desired folder exists before running the script. Save the script.

Go back to the spreadsheet you created and reload. After a few seconds you will have a Google Photos Backup menu (to the right of the Help menu). Choose 'Authorize' from this menu. You will be prompted to give the script various permissions which you should grant. After this a sidebar should appear on the spreadsheet (if not choose 'Authorize' from the Google Photos Backup menu again). Click the authorize link from the sidebar to grant access to Google Photos. Once this is done you should be in business - choose Backup Now from the Google Photos Backup menu and any new items from yesterday should be copied to the Google Photos folder in Drive (or the folder you configured above if you changed this).

Finally you should set up a trigger to automate running the script every day. Choose 'Script editor' from the Tools menu to re-open the script, and then in the script window choose 'Current project's triggers' from the Edit menu. This will open yet another window. Click 'Add Trigger' which is cunningly hidden at the bottom right of the window. Under 'Choose which function to run' select 'runBackup'. Then under 'Select event source' select 'Time-driven'. Under 'Select type of time based trigger' select 'Day timer'. Under 'Select time of day' select the time window that works best for you. Click Save. The backup should now run every day.

The way the script is written you'll get a backup of anything added the previous day each time it runs. If there are any duplicate filenames in the backup folder the script will save a new copy of the file with (1) appended in front of the filename. Let me know in the comments if you use this script or have any suggestions to improve it.



Hi, great script - works flawlessly! Thanks a lot!

One improvement idea:

Is it possible to sort photos on drive into year and month folders?

With your script the photos are backed up in the targed folder, but no sorting to year and month....

that would be awesome!


Robert Ellison

I have an app that does this which I've used for a while because even the old integration had this problem of sticking everything in one folder. I'll look at tidying this up and releasing it - ideally solving the duplicate problem at the same time. Will probably be a few weeks before I get to this.


Perfect - looking forward to it!


is this only work w/ photos?

I synced video clips and synced files only have 50mb files and cannot play


Any way with a script to reverse this process? (ie. automatically copy all pictures in Drive over to photos)

Fabian Briese

Hi, very nice. Thank you. But I have some trouble: When clicking on "Backup Now" I get this error message: "Error: Access not granted or expired."

Any ideas?

Robert Ellison

Logan - UrlFetchApp has a 50MB limit so larger files that that won't work. I'd expect an exception in this case but unfortunately it just downloads a truncated file which isn't good. I'm testing an update that will skip these files and send an email to let you know they need to be downloaded manually, will update once it looks like it's working. I don't see a great work around for this so far but will keep looking.

Robert Ellison

Cleve - should be possible using the APIs. Would need to enumerate files in drive that look like photos or videos and then upload these to Google Photos. I'm not likely to implement this, it might be that a client app is needed to really solve this problem completely.

Robert Ellison

Fabian - there are three types of authorization needed, as outlined in the steps above. Make sure that the API is enabled in Google Cloud Console, that the script is authorized to run and that Google Photos has granted access to the script.

If that doesn't help there is a 'Reset Settings' option in the Google Photos Backup menu that gets added to the spreadsheet that hosts the script. Run that and then go to myaccount.google.com, click Security and then Manage third-party access. Find the Google Photos Backup item and click Remove Access. Once this is done run through authorizing again and see if that clears the problem.

Robert Ellison

Hurst - I just released the app that sorts pictures and videos into date + month folders. This also handles de-duplication. See Photo Sorter 1.00.

Fabian Briese

Hi Robert, thanks for your help. I forgot a point: click on "Authorize. Close this after you have finished." Now its running. :-)

David Katz

Before Google stopped Google Photos and Google Drive sync, this feature created files in Google Drive regardless of the storage space available in the Google Drive account. How does this script handle storage capacity - must there be available space in the Google Drive account?

Robert Ellison

David - yes, you need space in Google Drive. For any new photos you need quota in both services if you want a copy in both places.

John Gillings


Thanks, this is very useful! For my purposes, I want a reasonably frequent update, skipping duplicates instead of making a copy. I adjusted the endDate to

"day": date.getDate() + 1

to include files from today, and the body of the copy loop to

var response = UrlFetchApp.fetch(downloadList[i].baseUrl, {

headers: {

Authorization: 'Bearer ' + photos.getAccessToken()



var files = folder.getFilesByName(filename);

if (!files.hasNext()) {

var blob = response.getBlob();




so duplicates are ignored. My trigger is hourly, which is often enough for what I need. It's almost back to previous behaviour, just a bit lagged.

(I log photos in entries in a Google Calendar work diary - they need to be in Drive to see them from the "Add Attachment" dialog when editing a calendar entry).

Robert Ellison

Logan - I just updated the script to email you if it encounters files larger than 50MB. Not perfect but at least you'll know that there are files you need to download manually.

Google - UrlFetchApp should really exception in this case.

John Gillings

Not really knowing much about Google script, my adjusted date calculations seemed to work, until we rolled over into the new month. Having read some documentation about how dates work, I've changed the start and end dates to this. Hopefully clearer and will survive month (and year?) rollovers? :

var MILLIS_PER_MINUTE = 60000;



var now = new Date();

var from = new Date(now.getTime() - MILLIS_PER_DAY)

var request = {


"filters": {

"dateFilter": {

"ranges": [


"startDate": {

"year": from.getFullYear(),

"month": from.getMonth() + 1,

"day": from.getDate()


"endDate": {

"year": now.getFullYear(),

"month": now.getMonth() + 1,

"day": now.getDate()






Tim L

Thanks, Robert for this blog posting.

I created the above script with John Gillings' modification but I am still getting duplicates showing up.

Do I need to remove something to stop the duplicates being created?

Robert Ellison

Tim - unfortunately yes. There are a couple of ways of handling this. If your photo sources are mobile and a camera you can just add them differently. Mobile photos are added to Google Photos from your phone, allow the script to copy these over to your backup archive and you shouldn't get duplicates. For the camera upload directly to Google Photos and don't copy to your backup location. The script will move these over to drive and again you shouldn't have duplicates.

The other way - which is what I do - is to detect and remove duplicates locally. I allow all my photos to collect in the Google Photos folder in Google Drive and then periodically copy them to the Windows Photos folder with a tool that sorts them into month + year subfolders and skips any duplicates. I released this tool for Windows recently, it's called Photo Sorter. I don't have anything equivalent for Mac or Linux.

Tim L

Thanks for the reply. All my photos are from my mobile and I have auto-backup to Google Photos switched on.

I cannot make use of Windows as for security reasons, the link between a PC and Google drive is switched off. It's not possible to determine if someone's computer is encrypted like it is with a mobile.

The additional comment said they modified the script to ignore duplicates, which is what I was trying to do. This has to be reasonably straight forward or I'll spend more time deleting photos than the script spends keeping the stuff in sync.

Robert Ellison

Tim - I haven't tried or tested John's modifications. Can you go back to the original script and see if you get any duplicates?

Robert Ellison

Tim - One more thing. I had an email exchange with John and he suggests checking that you modified both the date code an the section that creates the file in drive. I'll add the full snippet below. This prevents duplicate filenames on the upload to drive.

John's full code

Add Comment

All comments are moderated. Your email address is used to display a Gravatar and optionally for notification of new comments and to sign up for the newsletter.