{"id":958,"date":"2021-01-27T09:40:21","date_gmt":"2021-01-27T14:40:21","guid":{"rendered":"http:\/\/techministry.blog\/?p=958"},"modified":"2021-01-27T09:40:21","modified_gmt":"2021-01-27T14:40:21","slug":"automated-printing-of-google-documents-using-google-apps-script-the-dropbox-api-and-automator-folder-actions","status":"publish","type":"post","link":"https:\/\/techministry.blog\/?p=958","title":{"rendered":"Automated Printing of Google Documents using Google Apps Script, the DropBox API, and Automator Folder Actions"},"content":{"rendered":"\n<p>A couple of years ago, I <a href=\"https:\/\/techministry.blog\/2019\/01\/13\/using-google-apps-script-with-user-input-to-automate-repetitive-tasks-in-google-docs\/\">shared a workflow<\/a> that we still use to auto generate documents that we use each week. A few months ago, I <a href=\"https:\/\/techministry.blog\/2020\/09\/16\/using-cronicle-the-planning-center-online-api-and-automator-on-a-mac-to-automate-printing-weekly-paperwork\/\">shared another workflow<\/a> that showed how I automated printing our weekly Planning Center Online paperwork.<\/p>\n\n\n\n<p>I decided recently that I was tired of still having to manually print these weekly &#8220;talking points&#8221; documents, while having my Planning Center paperwork fully automated. So, I took a few minutes and wrote a new Google Apps Script to help with this.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/techministry.blog\/wp-content\/uploads\/2021\/01\/screen-shot-2021-01-18-at-2.06.57-pm.png?w=694\" alt=\"\" class=\"wp-image-976\" width=\"288\" height=\"394\" \/><figcaption>We print these every week. I was doing it manually, but not anymore!<\/figcaption><\/figure><\/div>\n\n\n\n<p>Here is what the script does: <\/p>\n\n\n\n<ul class=\"wp-block-list\" id=\"block-a7ca13ee-db7c-4932-8dc0-232c71536dbf\"><li>Searches a specific Google Drive folder for all subfolders with files that match today&#8217;s date (the script will run on a weekly trigger)<\/li><li>If the file is a match, it opens the file as a PDF and stores the binary contents in a variable<\/li><li>An upload request is made to the Dropbox API with that binary data and a file name<\/li><li>Dropbox saves the file into the &#8220;Automated Printing&#8221; folder<\/li><li>Dropbox then syncs the file to the local computer (Mac)<\/li><li>The local Mac is configured with a Folder Action that automatically prints any files placed in this folder<\/li><li>After the Automator Folder Action prints the file, it removes the file<\/li><\/ul>\n\n\n\n<p>Here&#8217;s how you set it up:<\/p>\n\n\n\n<p>First, you want to create a new Dropbox &#8220;App&#8221;. Go to dropbox.com\/developers and click &#8220;Create apps&#8221;.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/techministry.blog\/wp-content\/uploads\/2021\/01\/screen-shot-2021-01-17-at-12.11.26-pm.png?w=1024\" alt=\"\" class=\"wp-image-962\" \/><\/figure>\n\n\n\n<p>Then, you need to fill out these fields:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/techministry.blog\/wp-content\/uploads\/2021\/01\/screen-shot-2021-01-17-at-12.12.09-pm.png?w=1024\" alt=\"\" class=\"wp-image-965\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\"><li>&#8220;Choose an API&#8221;: Scoped Access. It&#8217;s your only choice.<\/li><li>&#8220;Choose the type of access you need&#8221;: I chose &#8220;Full Dropbox&#8221; because I already had a specific folder set up in the root of my Dropbox. If you&#8217;re setting up the Automator Folder action for the first time, you could probably keep the scope within &#8220;App folder&#8221;.<\/li><li>&#8220;Name Your App&#8221;: Give it a meaningful name. It does have to be unique across all of Dropbox, for some reason, so if you get an error here, just add something unique to you.<\/li><li>&#8220;Choose the Dropbox account that will own your app&#8221;: If you have personal\/business accounts linked, you&#8217;ll need to choose the account that owns the app. I&#8217;m using a business account for this, so I chose that one.<\/li><\/ol>\n\n\n\n<p>On the next page, choose the &#8220;Permissions&#8221; tab.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/techministry.blog\/wp-content\/uploads\/2021\/01\/screen-shot-2021-01-17-at-12.20.04-pm.png?w=1024\" alt=\"\" class=\"wp-image-966\" \/><\/figure>\n\n\n\n<p>Then give your app &#8220;files.content.write&#8221; access.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/techministry.blog\/wp-content\/uploads\/2021\/01\/screen-shot-2021-01-17-at-12.20.20-pm.png?w=1024\" alt=\"\" class=\"wp-image-968\" \/><\/figure>\n\n\n\n<p>Now back on the Settings tab, generate a new Token and set the Expiration to &#8220;No expiration&#8221;.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/techministry.blog\/wp-content\/uploads\/2021\/01\/screen-shot-2021-01-17-at-12.20.35-pm.png?w=1024\" alt=\"\" class=\"wp-image-970\" \/><\/figure>\n\n\n\n<p>This will generate a Token key which you will use within the Google Apps Script in the next steps.<\/p>\n\n\n\n<p>Now in Google Drive, click &#8220;New&#8221;, go down to &#8220;More&#8221;, and choose &#8220;Google Apps Script&#8221;. Google Apps Script is essentially Javascript, so it&#8217;s super easy to use.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/techministry.blog\/wp-content\/uploads\/2021\/01\/screen-shot-2021-01-18-at-2.00.20-pm.png?w=644\" alt=\"\" class=\"wp-image-978\" width=\"350\" height=\"292\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/techministry.blog\/wp-content\/uploads\/2021\/01\/screen-shot-2021-01-18-at-2.01.28-pm.png?w=1024\" alt=\"\" class=\"wp-image-979\" width=\"490\" height=\"210\" \/><figcaption>You&#8217;ll want to give the project a helpful name, as it will be stored in your Google Drive this way.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Give your project a helpful name.<\/p>\n\n\n\n<p>In the code section, paste in my script below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/*\nEDIT THESE VARIABLES FOR YOUR SETUP\n*\/\nvar accessToken = \"token\"; \/\/Dropbox App Access Token\nvar rootFolder = \"folderID\"; \/\/ Google Drive Root Folder where these files live\nvar dropboxPath = \"\/Automated Printing\/\"; \/\/Dropbox Folder Path to place file in\nvar numberOfCopies = 2; \/\/the number of copies you want per file\n\n\/\/Nothing to edit below\n\nfunction myFunction() {\n  var dtDate = new Date();\n  const monthNames = &#091;\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\n  var strDate = monthNames&#091;dtDate.getMonth()] + \" \" + dtDate.getDate() + \", \" + dtDate.getFullYear();\n  var mainFolder = DriveApp.getFolderById(rootFolder);\n  var subFolders = mainFolder.getFolders();\n  while(subFolders.hasNext()) {\n    var subFolder = subFolders.next();\n    var files = subFolder.getFiles();\n    while(files.hasNext()) {\n      var file = files.next();\n      var fileName = file.getName();\n      if ((fileName.indexOf(strDate) &gt; -1) &amp;&amp; (fileName.indexOf(\".pdf\") == -1)) {\n        \/\/this is a file we want to print\n        Logger.log(\"Generating PDF: \" + file.getName());\n        for (let i = 0; i &lt; numberOfCopies; i++) {\n          sendToDropbox(file.getName() + \".pdf\", file.getAs('application\/pdf'));\n          Utilities.sleep(15000); \/\/ wait 15 seconds before doing the next file, so that Dropbox has time to sync the file, the Automator can print the file, remove it, and close out\n        }\n      }\n    }\n  }\n}\n\nfunction sendToDropbox(fileName, fileBlob) {\n  var parameters = {\n    \"path\": dropboxPath + fileName,\n    \"mode\": \"add\",\n    \"autorename\": true,\n    \"mute\": false,\n    \"strict_conflict\": false\n  };\n\n  var headers = {\n    'Authorization': 'Bearer ' + accessToken,\n    'Content-Type': 'application\/octet-stream',\n    'Dropbox-API-Arg': JSON.stringify(parameters)\n  };\n\n  var options = {\n    \"method\": \"POST\",\n    \"headers\": headers,\n    \"payload\": fileBlob\n  };\n\n  var apiUrl = \"https:\/\/content.dropboxapi.com\/2\/files\/upload\";\n  var response = JSON.parse(UrlFetchApp.fetch(apiUrl, options).getContentText());\n}<\/code><\/pre>\n\n\n\n<p>Now modify the top section to include your Dropbox access token (the one you generated earlier), the Google Drive folder ID (the folder ID is in the URL of the page when you open that folder in Google Drive), the Dropbox path to save to, and the number of copies you need for each matching document. In our case, I need 2 copies of each document.<\/p>\n\n\n\n<p>I learned in testing that if Dropbox syncs the files too fast while my Automator folder action is still running, the new files that were added don&#8217;t get included in the folder action, and the folder action doesn&#8217;t re-run those new files. So, what this script does is it uploads a new PDF for every copy needed, but it waits 15 seconds in-between. This gives Google time to upload to Dropbox, Dropbox time to sync to my local Mac with the Automator action, and Automator time to run its script and print the file and delete it. It&#8217;s not very efficient, but the files are not that large.<\/p>\n\n\n\n<p>Now that your script is in place, you need to assign a trigger to it. Click &#8220;Triggers&#8221; on the left-hand side of the screen:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/techministry.blog\/wp-content\/uploads\/2021\/01\/screen-shot-2021-01-18-at-2.11.50-pm.png?w=390\" alt=\"\" class=\"wp-image-982\" width=\"239\" height=\"344\" \/><\/figure><\/div>\n\n\n\n<p>Add a new trigger. I used the following settings to have it run weekly on Sundays between 6 and 7am. Be sure to target the &#8220;myFunction&#8221; function as that&#8217;s the main one we are using.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/techministry.blog\/wp-content\/uploads\/2021\/01\/screen-shot-2021-01-18-at-2.12.17-pm.png?w=818\" alt=\"\" class=\"wp-image-984\" width=\"433\" height=\"541\" \/><\/figure><\/div>\n\n\n\n<p>You&#8217;ll need to create the folder action in Automator. Follow my <a href=\"https:\/\/techministry.blog\/2020\/09\/16\/using-cronicle-the-planning-center-online-api-and-automator-on-a-mac-to-automate-printing-weekly-paperwork\/\">previous post<\/a> on how to do this, as the steps are the same. I didn&#8217;t have to change that at all!<\/p>\n\n\n\n<p>Here&#8217;s a tutorial video if you learn better that way:<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-rich is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<div class=\"embed-youtube\"><iframe loading=\"lazy\" title=\"Automating Printing of Google Docs with Google Apps Script, the Dropbox API, and MacOS Automator\" width=\"840\" height=\"473\" src=\"https:\/\/www.youtube.com\/embed\/6Fqk78bdHrE?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<\/div><\/figure>\n\n\n\n<p>I hope this helps you think of ways to automate what you&#8217;re doing in Google Drive so you can spend more time on ministry and less on manual tasks!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A couple of years ago, I shared a workflow that we still use to auto generate documents that we use each week. A few months ago, I shared another workflow that showed how I automated printing our weekly Planning Center Online paperwork. I decided recently that I was tired of still having to manually print &hellip; <a href=\"https:\/\/techministry.blog\/?p=958\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Automated Printing of Google Documents using Google Apps Script, the DropBox API, and Automator Folder Actions&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[11,12,23,27,38,50,51,62],"class_list":["post-958","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-automation","tag-automator","tag-dropbox","tag-google-docs","tag-ministry","tag-production","tag-programming","tag-scripting"],"_links":{"self":[{"href":"https:\/\/techministry.blog\/index.php?rest_route=\/wp\/v2\/posts\/958","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/techministry.blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/techministry.blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/techministry.blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/techministry.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=958"}],"version-history":[{"count":0,"href":"https:\/\/techministry.blog\/index.php?rest_route=\/wp\/v2\/posts\/958\/revisions"}],"wp:attachment":[{"href":"https:\/\/techministry.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=958"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/techministry.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=958"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/techministry.blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=958"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}