{"id":12304,"date":"2020-05-13T10:47:57","date_gmt":"2020-05-13T10:47:57","guid":{"rendered":"https:\/\/www.gmass.co\/blog\/?p=12304"},"modified":"2020-05-16T14:56:27","modified_gmt":"2020-05-16T14:56:27","slug":"google-picker-api","status":"publish","type":"post","link":"https:\/\/www.gmass.co\/blog\/google-picker-api\/","title":{"rendered":"Advanced Techniques with the Google Picker API"},"content":{"rendered":"<p>If your app needs to let a user pick a file from his Google Drive, you might consider using the Google Picker API.<\/p>\n<p>I recently implemented the Picker for my users because I need to let users choose a Google Sheet from their account, and in some rare cases, Google Drive access is blocked the G Suite Admin, rendering my code that lists Sheets from Google Drive useless. The Picker is an alternative that doesn&#8217;t require Drive access, and so it allows my users to pick a spreadsheet from their account, even though Google Drive access may be denied by their G Suite admin.<\/p>\n<p>In implementing the Picker API, I encountered several challenges and subsequently came up with several advanced techniques that you also might find useful.<\/p>\n<p>The main documentation for the Picker API is <a href=\"https:\/\/developers.google.com\/picker\">here<\/a>. After you get the <a href=\"https:\/\/developers.google.com\/picker\/docs#example\">example<\/a> provided by Google working, here are a few advanced techniques you might find useful.<\/p>\n<h2>Open the Picker in a popup, and return the file\u2019s ID to the main window<\/h2>\n<p>In your web app, you might link to the Picker and then open it in a popup. Normally it&#8217;s just a matter of simple JavaScript to return a value from the popup to the main window, and many have written about <a href=\"https:\/\/stackoverflow.com\/questions\/9276086\/popup-window-to-return-data-to-parent-on-close\">how to do that<\/a>. What if, however, you&#8217;re launching the Picker from a Chrome extension, and the Chrome extension is running on a site for which you don&#8217;t have any control, like Gmail. If you use the normal technique to retrieve the value from the popup, you&#8217;ll get this error in the Console:<\/p>\n<pre class=\"lang-none prettyprint prettyprinted\"><code><span class=\"pln\">SecurityError: Blocked a frame with origin \"http:\/\/www.&lt;domain&gt;.com\" from accessing a cross-origin frame.<\/span><\/code><\/pre>\n<p>The only known way around this is to use the window.postMessage function to pass a message from the popup to the main window, as <a href=\"https:\/\/stackoverflow.com\/questions\/25098021\/securityerror-blocked-a-frame-with-origin-from-accessing-a-cross-origin-frame\">explained here<\/a>. In this case, the message is the ID of the file the user has chosen from his Google Drive, prepended by the string &#8220;spreadsheetid&#8212;&#8221; so that I know the message is from my popup.<\/p>\n<p>Here&#8217;s the code from my Picker HTML:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nfunction pickerCallback(data) {\r\n   if (data.action == google.picker.Action.PICKED) {\r\n   var fileId = data.docs[0].id;\r\n   window.opener.postMessage('spreadsheetid---' + fileId, '*');\r\n   window.close();\r\n  }\r\n}\r\n<\/pre>\n<p>And here&#8217;s the code in the parent window.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n  window.addEventListener('message', function(event) {\r\n  if (event.data.toString().includes('spreadsheetid---')) {\r\n  SpreadsheetId = event.data.toString();\r\n  }\r\n});\r\n<\/pre>\n<h2>Retrieve the file ID without access to any scopes<\/h2>\n<p>If you read the Google documentation for the Picker API, you might assume that to use it, you must request access to the &#8220;drives&#8221; scope.<\/p>\n<p>Google&#8217;s <a href=\"https:\/\/developers.google.com\/picker\/docs\">documentation<\/a> even states:<\/p>\n<blockquote><p><strong>Note:<\/strong>\u00a0For a list of valid views, refer to\u00a0<a href=\"https:\/\/developers.google.com\/picker\/docs\/reference#ViewId\">ViewId<\/a>\u00a0in the Google Picker reference. To obtain the token for any of these views, use the\u00a0<code dir=\"ltr\" translate=\"no\">https:\/\/www.googleapis.com\/auth\/drive.file<\/code>\u00a0scope.<\/p><\/blockquote>\n<p>And in the sample code, we find this:<\/p>\n<p><a href=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-code-130kb.png\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-12330\" src=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-code-130kb.png\" alt=\"Google Picker code\" width=\"729\" height=\"298\" srcset=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-code-130kb.png 1224w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-code-130kb-300x123.png 300w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-code-130kb-768x314.png 768w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-code-130kb-1024x418.png 1024w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-code-130kb-24x10.png 24w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-code-130kb-36x15.png 36w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-code-130kb-48x20.png 48w\" sizes=\"auto, (max-width: 729px) 100vw, 729px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>After all, in order to actually do anything with the file, you need to be able to at least read the file, and the various <a href=\"https:\/\/developers.google.com\/drive\/api\/v2\/about-auth\">Google Drive scopes<\/a> is what makes that possible. In some cases, however, you might only care about retrieving the file ID, and in that case, you don&#8217;t need access to any scopes. This is the case for my use case, where I&#8217;m using the Picker to let a user choose a Google Sheet. Once I have the ID of the Google Sheet, then I use a scope that I&#8217;ve requested access to separately as part of the user login process, the spreadsheets.readonly scope as part of the V4 Sheets API, to read the spreadsheet data.<\/p>\n<h2>Use an existing OAuth token rather than requiring the user to log in every time<\/h2>\n<p>If you follow the Google example for getting the Picker going, you&#8217;ll notice that every time you load the picker, an OAuth login is presented to the user. And if you step through the sample code, you&#8217;ll see that this code is what triggers the login process:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    var oauthToken;\r\n\r\n    \/\/ Use the Google API Loader script to load the google.picker script.\r\n    function loadPicker() {\r\n      gapi.load('auth', {'callback': onAuthApiLoad});\r\n      gapi.load('picker', {'callback': onPickerApiLoad});\r\n    }\r\n\r\n    function onAuthApiLoad() {\r\n      window.gapi.auth.authorize(\r\n          {\r\n            'client_id': clientId,\r\n            'scope': scope,\r\n            'immediate': false\r\n          },\r\n          handleAuthResult);\r\n    }\r\n\r\n    function handleAuthResult(authResult) {\r\n      if (authResult &amp;amp;amp;&amp;amp;amp; !authResult.error) {\r\n        oauthToken = authResult.access_token;\r\n        createPicker();\r\n      }\r\n    }\r\n<\/pre>\n<p>If a user is going to be &#8220;picking&#8221; a file over and over, though, you don&#8217;t want your user to have to log in every time. In this case, you have a couple of options:<\/p>\n<ol>\n<li>You can store the token value somewhere and then use it the next time. Notice that the only important value from the Google sample above is authResult.access_token. If you store that and then set that the next time you need to load the Picker for a user, you can comment out the code in the &#8220;onAuthApiLoad&#8221; function.<\/li>\n<li>If you&#8217;re already generating a token value from the initial Google OAuth login to your app, then you can use that token value and never make the user log in before picking a file. Again, comment out the code in the &#8220;onAuthApiLoad&#8221; function and replace it with your own code that retrieves the token value and manually all handleAuthResult yourself, passing in the token value that you retrieved from your database or perhaps, localStorage. I&#8217;m not going to comment on the security of where you store your token values, because that&#8217;s beyond the &#8220;scope&#8221; of this article, but I&#8217;m just presenting a couple of options here for the purpose of demonstration.<\/li>\n<\/ol>\n<h2>List just a particular file type in the Picker<\/h2>\n<p>This is fairly well presented in the Google documentation, but it&#8217;s worth going over anyway. In my case, I only want spreadsheets to be displayed in the picker. So in the picker builder, I need this line of code:<\/p>\n<p>var view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);<\/p>\n<p>Here&#8217;s the createPicker function with that filter included.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n    function createPicker() {\r\n      if (pickerApiLoaded &amp;amp;amp;&amp;amp;amp; oauthToken) {\r\n        var view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\r\n        var picker = new google.picker.PickerBuilder()\r\n            .enableFeature(google.picker.Feature.NAV_HIDDEN)\r\n            .setAppId(appId)\r\n            .setOAuthToken(oauthToken)\r\n            .addView(view)\r\n            .addView(new google.picker.DocsUploadView())\r\n            .setDeveloperKey(developerKey)\r\n            .setCallback(pickerCallback)\r\n            .build();\r\n         picker.setVisible(true);\r\n      }\r\n    }\r\n<\/pre>\n<p>Here&#8217;s a list of other types from the <a href=\"https:\/\/developers.google.com\/picker\/docs\/reference\">documentation<\/a> you can include to display different file types.<\/p>\n<p><a href=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-file-types-120kb.png\" data-rel=\"lightbox-image-1\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-12329\" src=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-file-types-120kb.png\" alt=\"Google Picker file types\" width=\"730\" height=\"974\" srcset=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-file-types-120kb.png 920w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-file-types-120kb-225x300.png 225w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-file-types-120kb-768x1025.png 768w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-file-types-120kb-767x1024.png 767w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-file-types-120kb-18x24.png 18w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-file-types-120kb-27x36.png 27w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Google-Picker-file-types-120kb-36x48.png 36w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/a><\/p>\n<h2>Conclusion<\/h2>\n<p>I hope this helps you use the Google Picker API more effectively. Also see my other <a href=\"https:\/\/www.gmass.co\/blog\/category\/google-oauth\/\">insights into Google OAuth<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If your app needs to let a user pick a file from his Google Drive, you might consider using the Google Picker API. I recently implemented the Picker\u2026<\/p>\n","protected":false},"author":2,"featured_media":12332,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3462],"tags":[],"class_list":["post-12304","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\r\n<title>Advanced Techniques with the Google Picker API<\/title>\r\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\r\n<link rel=\"canonical\" href=\"https:\/\/www.gmass.co\/blog\/google-picker-api\/\" \/>\r\n<meta property=\"og:locale\" content=\"en_US\" \/>\r\n<meta property=\"og:type\" content=\"article\" \/>\r\n<meta property=\"og:title\" content=\"Advanced Techniques with the Google Picker API\" \/>\r\n<meta property=\"og:description\" content=\"If your app needs to let a user pick a file from his Google Drive, you might consider using the Google Picker API. I recently implemented the Picker\u2026\" \/>\r\n<meta property=\"og:url\" content=\"https:\/\/www.gmass.co\/blog\/google-picker-api\/\" \/>\r\n<meta property=\"og:site_name\" content=\"GMass Blog\" \/>\r\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/GmailMailMerge\/\" \/>\r\n<meta property=\"article:published_time\" content=\"2020-05-13T10:47:57+00:00\" \/>\r\n<meta property=\"article:modified_time\" content=\"2020-05-16T14:56:27+00:00\" \/>\r\n<meta property=\"og:image\" content=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Featured-image-google-picker-code-91kb.png\" \/>\r\n\t<meta property=\"og:image:width\" content=\"1001\" \/>\r\n\t<meta property=\"og:image:height\" content=\"467\" \/>\r\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\r\n<meta name=\"author\" content=\"Ajay Goel\" \/>\r\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\r\n<meta name=\"twitter:creator\" content=\"@PartTimeSnob\" \/>\r\n<meta name=\"twitter:site\" content=\"@GMassForGmail\" \/>\r\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Ajay Goel\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\r\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/google-picker-api\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/google-picker-api\\\/\"},\"author\":{\"name\":\"Ajay Goel\",\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/#\\\/schema\\\/person\\\/b5fa74f8765b860701158fd77162fff8\"},\"headline\":\"Advanced Techniques with the Google Picker API\",\"datePublished\":\"2020-05-13T10:47:57+00:00\",\"dateModified\":\"2020-05-16T14:56:27+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/google-picker-api\\\/\"},\"wordCount\":1096,\"commentCount\":4,\"image\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/google-picker-api\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/05\\\/Featured-image-google-picker-code-91kb.png\",\"articleSection\":[\"Developers\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.gmass.co\\\/blog\\\/google-picker-api\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/google-picker-api\\\/\",\"url\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/google-picker-api\\\/\",\"name\":\"Advanced Techniques with the Google Picker API\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/google-picker-api\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/google-picker-api\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/05\\\/Featured-image-google-picker-code-91kb.png\",\"datePublished\":\"2020-05-13T10:47:57+00:00\",\"dateModified\":\"2020-05-16T14:56:27+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/#\\\/schema\\\/person\\\/b5fa74f8765b860701158fd77162fff8\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/google-picker-api\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.gmass.co\\\/blog\\\/google-picker-api\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/google-picker-api\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/05\\\/Featured-image-google-picker-code-91kb.png\",\"contentUrl\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/05\\\/Featured-image-google-picker-code-91kb.png\",\"width\":1001,\"height\":467,\"caption\":\"google picker\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/google-picker-api\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Advanced Techniques with the Google Picker API\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/\",\"name\":\"GMass Blog\",\"description\":\"Tips and tricks for sending mail merge and mass email campaigns directly from Gmail\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/#\\\/schema\\\/person\\\/b5fa74f8765b860701158fd77162fff8\",\"name\":\"Ajay Goel\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f3a70af05bbabe47925150d5a1320540e801b78055a74da20658fc97cd0706a2?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f3a70af05bbabe47925150d5a1320540e801b78055a74da20658fc97cd0706a2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f3a70af05bbabe47925150d5a1320540e801b78055a74da20658fc97cd0706a2?s=96&d=mm&r=g\",\"caption\":\"Ajay Goel\"},\"description\":\"Ajay is the founder of GMass and has been developing email sending software for 20 years.\",\"sameAs\":[\"https:\\\/\\\/twitter.com\\\/PartTimeSnob\",\"https:\\\/\\\/x.com\\\/PartTimeSnob\"],\"url\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/author\\\/ajay-goel\\\/\"}]}<\/script>\r\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Advanced Techniques with the Google Picker API","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.gmass.co\/blog\/google-picker-api\/","og_locale":"en_US","og_type":"article","og_title":"Advanced Techniques with the Google Picker API","og_description":"If your app needs to let a user pick a file from his Google Drive, you might consider using the Google Picker API. I recently implemented the Picker\u2026","og_url":"https:\/\/www.gmass.co\/blog\/google-picker-api\/","og_site_name":"GMass Blog","article_publisher":"https:\/\/www.facebook.com\/GmailMailMerge\/","article_published_time":"2020-05-13T10:47:57+00:00","article_modified_time":"2020-05-16T14:56:27+00:00","og_image":[{"width":1001,"height":467,"url":"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Featured-image-google-picker-code-91kb.png","type":"image\/png"}],"author":"Ajay Goel","twitter_card":"summary_large_image","twitter_creator":"@PartTimeSnob","twitter_site":"@GMassForGmail","twitter_misc":{"Written by":"Ajay Goel","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.gmass.co\/blog\/google-picker-api\/#article","isPartOf":{"@id":"https:\/\/www.gmass.co\/blog\/google-picker-api\/"},"author":{"name":"Ajay Goel","@id":"https:\/\/www.gmass.co\/blog\/#\/schema\/person\/b5fa74f8765b860701158fd77162fff8"},"headline":"Advanced Techniques with the Google Picker API","datePublished":"2020-05-13T10:47:57+00:00","dateModified":"2020-05-16T14:56:27+00:00","mainEntityOfPage":{"@id":"https:\/\/www.gmass.co\/blog\/google-picker-api\/"},"wordCount":1096,"commentCount":4,"image":{"@id":"https:\/\/www.gmass.co\/blog\/google-picker-api\/#primaryimage"},"thumbnailUrl":"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Featured-image-google-picker-code-91kb.png","articleSection":["Developers"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.gmass.co\/blog\/google-picker-api\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.gmass.co\/blog\/google-picker-api\/","url":"https:\/\/www.gmass.co\/blog\/google-picker-api\/","name":"Advanced Techniques with the Google Picker API","isPartOf":{"@id":"https:\/\/www.gmass.co\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.gmass.co\/blog\/google-picker-api\/#primaryimage"},"image":{"@id":"https:\/\/www.gmass.co\/blog\/google-picker-api\/#primaryimage"},"thumbnailUrl":"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Featured-image-google-picker-code-91kb.png","datePublished":"2020-05-13T10:47:57+00:00","dateModified":"2020-05-16T14:56:27+00:00","author":{"@id":"https:\/\/www.gmass.co\/blog\/#\/schema\/person\/b5fa74f8765b860701158fd77162fff8"},"breadcrumb":{"@id":"https:\/\/www.gmass.co\/blog\/google-picker-api\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.gmass.co\/blog\/google-picker-api\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.gmass.co\/blog\/google-picker-api\/#primaryimage","url":"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Featured-image-google-picker-code-91kb.png","contentUrl":"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2020\/05\/Featured-image-google-picker-code-91kb.png","width":1001,"height":467,"caption":"google picker"},{"@type":"BreadcrumbList","@id":"https:\/\/www.gmass.co\/blog\/google-picker-api\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.gmass.co\/blog\/"},{"@type":"ListItem","position":2,"name":"Advanced Techniques with the Google Picker API"}]},{"@type":"WebSite","@id":"https:\/\/www.gmass.co\/blog\/#website","url":"https:\/\/www.gmass.co\/blog\/","name":"GMass Blog","description":"Tips and tricks for sending mail merge and mass email campaigns directly from Gmail","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.gmass.co\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.gmass.co\/blog\/#\/schema\/person\/b5fa74f8765b860701158fd77162fff8","name":"Ajay Goel","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f3a70af05bbabe47925150d5a1320540e801b78055a74da20658fc97cd0706a2?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f3a70af05bbabe47925150d5a1320540e801b78055a74da20658fc97cd0706a2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f3a70af05bbabe47925150d5a1320540e801b78055a74da20658fc97cd0706a2?s=96&d=mm&r=g","caption":"Ajay Goel"},"description":"Ajay is the founder of GMass and has been developing email sending software for 20 years.","sameAs":["https:\/\/twitter.com\/PartTimeSnob","https:\/\/x.com\/PartTimeSnob"],"url":"https:\/\/www.gmass.co\/blog\/author\/ajay-goel\/"}]}},"_links":{"self":[{"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/posts\/12304","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/comments?post=12304"}],"version-history":[{"count":16,"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/posts\/12304\/revisions"}],"predecessor-version":[{"id":12331,"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/posts\/12304\/revisions\/12331"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/media\/12332"}],"wp:attachment":[{"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/media?parent=12304"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/categories?post=12304"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/tags?post=12304"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}