The Google drive api has an endpoint which we can use to create and upload files directly to google drive. The Google Drive API endpoint I am referring to is called Files Create, it takes the file metadata, and a file stream and returns to you a file resource object containing the file id the file newly created up on Google drive. Uploading binary files like images is the easiest type of file to upload because it does not require any conversion on the part of the Google drive api.
In this sample we will be using the Google Drive api with a service account to upload a file to my personal google drive account. Service accounts allow us to access Google drive without needing a user’s interaction because we will be pre authorizing the service account to access a folder on my personal google drive account.
Create service account
In order to access Google APIs we need to identify our application, as well as in the case of accessing private user data we need to be authorized to access that private data. We identify our application by creating a project on Google Cloud console, we set up authorization by creating service account credentials and downloading the Json Key file. So the very the first thing we will need to do is to go to Google Cloud console and create service account credentials. Remember to go to library and enabled the Google drive api after that dont forget to download a json key file.
Install package
Google has been kind enough to create client libraries which we can use to access their apis. The Google apis Node js client library is one of these libraries. In order to access the google drive api with node js we will need to install the googleapis package. The googleapis package will install all the methods we will need to authorize our service account as well as access the Google drive api from Node js.
npm install googleapis
Constants
I will be setting up a couple of constants in my script. The first will be the location of the Json service account key file, which we downloaded earlier form Google Cloud console. The second will define the scope that our application will need in order to upload files. Scopes are used to define the amount of access the authenticated user is granted when access the api. In our case the user is the service account, the amount of access it needs is quite high because it needs to be able to write to Google drive. So I will be questing the full drive scope.
// service account key file from Google Cloud console.
const KEYFILEPATH = 'C:\\Youtube\\dev\\ServiceAccountCred.json';
// Request full drive access.
const SCOPES = ['https://www.googleapis.com/auth/drive'];
Scopes is a comma separated array you can add more than one.
// Request full drive scope and profile scope, giving full access to google drive as well as the users basic profile information.
const SCOPES = ['https://www.googleapis.com/auth/drive', 'profile'];
Initialize service account
In order to use the service account in our code we will need to initialize. We do this by calling GoogleAuth and passing it the keyfile and the scopes we will be using.
// Create a service account initialize with the service account key file and scope needed
const auth = new google.auth.GoogleAuth({
keyFile: KEYFILEPATH,
scopes: SCOPES
});
Drive service
The way the client library works is that all calls to the api go through a service. A service grants you access to a single api, so for each api that you need to use you would create a service for that API. A service must also be configured with the authorization method you intend to use. This authorization is single user, so a service gives you access to a single api and a single users data. When the service is used it will handle all of the authorization for us. Everytime the service is used to call an api endpoint it will add the authorization header to the request automatically and we will not need to concern ourselves with it.
So we create a drive service by calling google.drive and passing the API version and the auth we created earlier.
const driveService = google.drive({version: 'v3', auth});
Create new file
Creating new files on google drive is done in two parts The first part of creating a new file is the metadata, name, description, type of the file, and the directory where you would like it created. If you don’t supply a directory the file will be created in the root google drive folder of the currently authenticated user. In our case the file would be created on the service accounts google drive account. I am using a service account in this example so I would like to upload the file to a directory on my own personal drive account.
I shared the directory with the service account using the service accounts email address, this preauthorizes the service account to access that directory. In the file metadata i am specifying that the parent directory of the new folder I am creating is the file id of the directory on my google drive account.
let fileMetadata = {
'name': 'icon.png',
'parents': [ '10krlloIS2i_2u_ewkdv3_1NqcpmWSL1w' ]
};
The second part of crating a new file up on google drive is to upload the actual file stream.
let media = {
mimeType: 'image/jpeg',
body: fs.createReadStream('icon.png')
};
Google Drive api Create File.
Once we have everything set up we can then call file.create method though the drive service to google. Notice how I don’t need to add anything regarding the authorization the drive service object is going to handle all that for me.
let response = await driveService.files.create({
resource: fileMetadata,
media: media,
fields: 'id'
});
Handle the response
There are two things that could happen with the response, either it worked or there was an error. Notice how the response in the case of a good result contains the file id of the file that was just uploaded.
switch(response.status){
case 200:
let file = response.result;
console.log('Created File Id: ', response.data.id);
break;
default:
console.error('Error creating the file, ' + response.errors);
break;
}
Conclusion
Creating a new file and uploading it to Google drive with the Google drive api v3 and node js can be quite useful. If you want to upload nightly log files for example. Remember that this is a two part process if you forget to add the metadata your file will be uploaded with a name of unnamed.
It’s a wonderful tuto Linda!
You salved my life hehe. Thanks a lot!
Keep it up, regards!
Great video Linda. So clear and useful
Thanks for the great resources! I work with a school and we are trying to create an iPhone app that will allow end users to choose photos from their Photos app, click the Share icon, then they choose our app name, then the app sends the chosen photos to a pre-chosen Google Drive folder, using a service account’s permissions, as you described. The app will only send/write files. No reading the shared folder. Can we somehow embed this code/functionality into an iPhone app as I have described? Any insight you can provide would be helpful!
Sorry I am not going to be any help with mobile development. Try stackoverflow.com
Thank you for taking the time to write this detailed tutorial Linda!
Can a service account be used to view/open files?
I currently can create, delete, edit but cannot view the file by using the webViewLink…
it can open some types of files if its a google doc file it could open them in the google docs api or a google sheet could be opened though the google sheets api.
Service accounts have no UI option to them so you cant just open it in the google drive web application like you would for a normal user.