Automatically Print Files Placed in Drive with Google Cloud Print and Apps Script

With Google Cloud Print, you can manage your printers and create print jobs from any computer or mobile device even if they are not connected to the printer or they are on a different network. Cloud Printer also includes a special “Save to Google Docs” virtual printer that lets you save web pages and documents as PDFs in your Google Drive.

In this tutorial, you’ll learn how to use the Google Cloud Print API from Google Apps Scripts. You can use such a system to enable auto-printing, i.e., print a file as soon as it is uploaded in your Google Drive or print an email thread from Gmail. Remote printing is also possible via Dropbox but Cloud Print runs on Google Servers and all you need is a Mac or Windows computer running the Chrome browser (the connector).

To get started, create a new Google Apps Script project and include the OAuth2 library. Next go to the developer console of that project and create a new web application. Set the Redirect URL as below and set the allowed domains as script.google.com (the Project Key is under File – Project Properties).

https://script.google.com/macros/d/{PROJECT KEY}/usercallback

Add this code to the Apps Script project, replace the Client ID and Client Secret with the actual values from Developer Console and save the project. Go to Run – ShowURL and authorize the script. Open the Logger (Cmd + Enter), copy the URL and paste it in a new browser tab to complete the authorization.


function showURL() {
  var cpService = getCloudPrintService();
  if (!cpService.hasAccess()) {
    Logger.log(cpService.getAuthorizationUrl());
  }
}

function getCloudPrintService() {
  return OAuth2.createService('print')
    .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
    .setTokenUrl('https://accounts.google.com/o/oauth2/token')
    .setClientId('CLIENT_ID')
    .setClientSecret('CLIENT_SECRET')
    .setCallbackFunction('authCallback')
    .setPropertyStore(PropertiesService.getUserProperties())
    .setScope('https://www.googleapis.com/auth/cloudprint')
    .setParam('login_hint', Session.getActiveUser().getEmail())
    .setParam('access_type', 'offline')
    .setParam('approval_prompt', 'force');
}

function authCallback(request) {
  var isAuthorized = getCloudPrintService().handleCallback(request);
  if (isAuthorized) {
    return HtmlService.createHtmlOutput('You can now use Google Cloud Print from Apps Script.');
  } else {
    return HtmlService.createHtmlOutput('Cloud Print Error: Access Denied');
  }
}

Now that your Cloud Print API script is authorized, we can send print jobs or run queries. For instance, if you are to retrieve a list of printers connected to Google Cloud Print, the code would be something like this:

function getPrinterList() {

  var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/search', {
    headers: {
      Authorization: 'Bearer ' + getCloudPrintService().getAccessToken()
    },
    muteHttpExceptions: true
  }).getContentText();

  var printers = JSON.parse(response).printers;

  for (var p in printers) {
    Logger.log("%s %s %s", printers[p].id, printers[p].name, printers[p].description);
  }

Similarly, to print a file in your Google Drive, you can write a routine like this. The docID is the ID of your Google Document that resides in Drive.

function printGoogleDocument(docID, printerID, docName) {

  var ticket = {
    version: "1.0",
    print: {
      color: {
        type: "STANDARD_COLOR",
        vendor_id: "Color"
      },
      duplex: {
        type: "NO_DUPLEX"
      }
    }
  };

  var payload = {
    "printerid" : printerID,
    "title"     : docName,
    "content"   : DriveApp.getFileById(docID).getBlob(),
    "contentType": "application/pdf",
    "ticket"    : JSON.stringify(ticket)
  };

  var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/submit', {
    method: "POST",
    payload: payload,
    headers: {
      Authorization: 'Bearer ' + getCloudPrintService().getAccessToken()
    },
    "muteHttpExceptions": true
  });

  response = JSON.parse(response);

  if (response.success) {
    Logger.log("%s", response.message);
  } else {
    Logger.log("Error Code: %s %s", response.errorCode, response.message);
  }
}

These can be extended to print web pages, images or any file that is preset in your Google Drive. You’ll have to modify the “content-Type” based on the mimeType of the file. The valid values are:

"url" (for web pages)
"dataUrl" (for printing base64 encoded images)
"google.drive" (Google Drive files)
"google.kix" (Google Document)
"google.mail" (Gmail thread)
"google.presentation" (Google Presentations)
"google.spreadsheet" (Google Spreadsheets)

If you looking for a automated system to email Google Spreadsheets as PDF, Google Cloud Print maybe too complex a solution, try this alternative.