{"id":2389,"date":"2018-03-22T03:46:16","date_gmt":"2018-03-22T03:46:16","guid":{"rendered":"https:\/\/www.gmass.co\/blog\/?p=2389"},"modified":"2018-03-22T18:43:03","modified_gmt":"2018-03-22T18:43:03","slug":"develop-gmail-add-on-without-going-insane","status":"publish","type":"post","link":"https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/","title":{"rendered":"How to develop a &#8220;Gmail Add-on&#8221; without going insane"},"content":{"rendered":"<p>In October 2017, Google released its <a href=\"https:\/\/developers.google.com\/gmail\/add-ons\/\">Gmail &#8220;Add-on&#8221; platform<\/a>, allowing developers to <strong>create add-ons for Gmail<\/strong> that work on both <strong>desktop<\/strong> and <strong>mobile<\/strong> (well <strong>Android<\/strong> right now, iOS coming later). I&#8217;m currently working on a Gmail Add-on for GMass that will let you see the campaign history for a contact when\u00a0you&#8217;re viewing an email from that contact.<\/p>\n<p>You can read the <a href=\"https:\/\/developers.google.com\/gmail\/add-ons\/\">Google documentation on how to write an add-on<\/a>, which I&#8217;ve basically memorized at this point. But if you&#8217;re like me, you&#8217;re going to <strong>run into\u00a0some stumbling blocks<\/strong> while writing your Gmail Add-on, and you won&#8217;t have a place to turn, because this development platform is so new that <strong>these issues aren&#8217;t documented<\/strong>.<\/p>\n<h3><span style=\"color: #993300;\">What exactly is an &#8220;Add-on&#8221; anyway?<\/span><\/h3>\n<p>If you&#8217;re confused, thinking that <strong>Add-ons<\/strong> have been around forever and all this hoopla is nothing new, you are partially right. The term &#8220;add-on&#8221; has been used in other contexts for far longer, like <a href=\"https:\/\/addons.mozilla.org\/en-US\/firefox\/\">Firefox&#8217;s Add-ons<\/a>, which are the Firefox equivalent of Chrome extensions. Many people use the term &#8220;add-on&#8221; to describe what is otherwise just a Chrome extension that extends Gmail. Google choosing the term &#8220;add-on&#8221; probably wasn&#8217;t the best idea, but since they did, let&#8217;s clear up the confusion. <a href=\"https:\/\/chrome.google.com\/webstore\/category\/extensions?hl=en\">Chrome extensions<\/a> are pieces of software that are installed in Chrome and can enhance the functionality of any website, Gmail being one of them. They are listed in the <a href=\"https:\/\/chrome.google.com\/webstore\/category\/extensions?hl=en\">Chrome Web Store<\/a>. Chrome extensions only work on desktop and not on mobile. If you are a Firefox user, the equivalent of Chrome extensions are Firefox add-ons. The new <a href=\"https:\/\/developers.google.com\/gmail\/add-ons\/\">Gmail &#8220;Add-on&#8221;<\/a> is a Gmail specific piece of software that enhances Gmail, and it has the benefit of working on both desktop and mobile, via the native Gmail app on Android (iOS support supposedly coming soon).<em> It is possible to write a Chrome extension that does\u00a0the equivalent of what your Gmail Add-on does, except for\u00a0working\u00a0on mobile.<\/em> <em>It is not possible to write a Gmail Add-on that does everything your Chrome extension does, unless what your Chrome extension does is limited to being present in the Gmail sidebar and only being active when an email is being read.<\/em>\u00a0Chrome extensions only work on the desktop. Gmail Add-ons work on desktop and mobile. Chrome extensions offer greater flexibility than Gmail Add-ons, in terms of look, feel, and the code that can be executed. Gmail Add-ons are more controlled,\u00a0limiting you to certain fonts, layouts, and user interface controls.<\/p>\n<h3><span style=\"color: #993300;\">No need to reload<\/span><\/h3>\n<p>As you&#8217;re writing your Add-on and testing it, you&#8217;ll be making changes to the <strong>HEAD deployment<\/strong> of your <strong>Google Apps Script<\/strong> project. To save your changes, you just hit the <strong>SAVE<\/strong> button in the <strong>Google Script editor<\/strong>, and then in another window, where you have Gmail loaded with your Add-on running, you do <strong>NOT<\/strong> need to <strong>RELOAD<\/strong>. Just open up another email, wait for your Add-on to present itself, and it will reflect your updated code. If you notice that your Add-on appears a bit\u00a0<em>too<\/em> fast, then it <strong>might be cached<\/strong>, in which case you should <strong>reload<\/strong> Gmail.<\/p>\n<h3><span style=\"color: #993300;\">Baffling error messages<\/span><\/h3>\n<p>While debugging, the error messages are just plain wrong occasionally. One of the things you&#8217;ll learn to do is to write <a href=\"https:\/\/developers.google.com\/gmail\/add-ons\/how-tos\/navigation\">navigation flows<\/a>, so your <strong>user can navigate smoothly<\/strong> between cards. If you make a slight mistake in how you do this, you&#8217;ll be told that the <strong>updateCard<\/strong> method doesn&#8217;t exist.<\/p>\n<figure id=\"attachment_2414\" aria-describedby=\"caption-attachment-2414\" style=\"width: 300px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-On-Runtime-Error-4.gif\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-2414 size-medium\" src=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-On-Runtime-Error-4-300x197.gif\" alt=\"\" width=\"300\" height=\"197\" \/><\/a><figcaption id=\"caption-attachment-2414\" class=\"wp-caption-text\">A confusing error message, because the updateCard method definitely exists.<\/figcaption><\/figure>\n<p><em>Of course it exists.<\/em> You just didn&#8217;t build your card quite right. I don&#8217;t know why exactly this doesn&#8217;t work, but note the commented lines. If you uncomment the &#8220;var&#8221; lines, and comment out the line at the top, it does work, without the runtime error.<a href=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-On-Code-Error.gif\" data-rel=\"lightbox-image-1\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-2411\" src=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-On-Code-Error-1024x557.gif\" alt=\"\" width=\"720\" height=\"392\" srcset=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-On-Code-Error-1024x557.gif 1024w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-On-Code-Error-300x163.gif 300w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-On-Code-Error-768x418.gif 768w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><\/p>\n<h3><span style=\"color: #993300;\">The Universal Actions are hiding<\/span><\/h3>\n<p>Where\u00a0in the world are your <a href=\"https:\/\/developers.google.com\/gmail\/add-ons\/how-tos\/universal-actions\">Universal Actions<\/a>? I wanted to add a <strong>Help<\/strong> menu item to my cards, so since its context-independent, I figured I&#8217;d use a <strong>Universal Action<\/strong>. You then go to run your Add-on, but it doesn&#8217;t show. It&#8217;s there; it&#8217;s just not obvious where. Click the <strong>three dots<\/strong> in the upper right.\u00a0Since Google doesn&#8217;t give you a screenshot showing where the <strong>Universal Action<\/strong>s go, I will:<\/p>\n<figure id=\"attachment_2417\" aria-describedby=\"caption-attachment-2417\" style=\"width: 526px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-on-Universal-Action-1.gif\" data-rel=\"lightbox-image-2\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-2417 size-full\" src=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-on-Universal-Action-1.gif\" alt=\"\" width=\"526\" height=\"358\" \/><\/a><figcaption id=\"caption-attachment-2417\" class=\"wp-caption-text\">The three dots in the upper right are where the Universal Actions are hiding.<\/figcaption><\/figure>\n<h3><span style=\"color: #993300;\">Want the user&#8217;s email address?<\/span><\/h3>\n<p>You&#8217;ll probably want the <strong>email address of the logged-in user<\/strong>, because that&#8217;s an essential part of the process of determining who this person is and what account on your web app to log this user into. <em>I spent hours trying to figure this out.<\/em> Google uses a default scope of <strong>https:\/\/www.googleapis.com\/auth\/userinfo.email<\/strong> as part of your project, but the question is &#8212; once you have access to retrieve the email address, <strong>how do you write the Google Apps Script code to retrieve the email address<\/strong>? Googling it will lead you to <a href=\"https:\/\/developers.google.com\/apps-script\/reference\/base\/user\">Session.getActiveUser().getEmail<\/a>. This will work\u00a0fine during testing, because the <strong>Google Apps Script project owner<\/strong> will likely be the <strong>same as the Gmail account from which you&#8217;re testing<\/strong>. Once you test from a <strong><em>different<\/em><\/strong> Gmail account, you&#8217;ll be stumped as to why it&#8217;s returning an empty string. There are <a href=\"https:\/\/stackoverflow.com\/questions\/15651781\/google-script-session-getactiveuser-getemail-not-working\">forum posts about this<\/a>, and the solution appears to be using <strong>getEffectiveUser<\/strong> instead of <strong>getActiveUser<\/strong>. Why that works and the other doesn&#8217;t is <em>beyond<\/em> me, but if anyone else has any insight into this issue, I&#8217;d love to see a comment below.<\/p>\n<h3><span style=\"color: #993300;\">What&#8217;s in a name?\u00a0<\/span><\/h3>\n<p>The\u00a0<a href=\"https:\/\/developers.google.com\/gmail\/add-ons\/guides\/style-guide\">UI style guide<\/a> states this specific rule:<\/p>\n<pre>Don\u2019t include the words \"Google\" or \"Gmail\" in your add-on name.<\/pre>\n<p>However if you look at the G Suite Marketplace <a href=\"https:\/\/gsuite.google.com\/marketplace\/category\/works-with-gmail?extension_type=gmail_addon\">Gmail Add-on Store<\/a>, you&#8217;ll note that <strong>pretty much everyone is breaking this rule<\/strong>.\u00a0You want to <strong>get the name of your Add-on just right<\/strong>. The name that your user will see\u00a0in the header of your Add-on\u00a0the name specified in your <a href=\"https:\/\/developers.google.com\/gmail\/add-ons\/concepts\/manifests\">manifest file<\/a>. This name can be different from the name you use in the Gmail Add-on Store though. However,\u00a0those aren&#8217;t the only names your user will see as they interact with and authorize your Add-on. They will also see the name associated with your OAuth client project for the Add-on authorization. They will also then see the name associated with your OAuth client project for authorization into your web app, assuming your Add-on works in conjunction with a web-app which most do, in order to be useful at all. And then there&#8217;s the name that only you, the developer, will see: the name of your Google Apps Script project.<\/p>\n<h3><span style=\"color: #993300;\">Can&#8217;t install Add-on in test accounts<\/span><\/h3>\n<p>When building your Gmail Add-on, it&#8217;s <strong>easiest if the Google account that\u00a0<em>owns<\/em> the Google Apps Script project is also the Gmail account that you are using for testing<\/strong>. As the documentation says, you can run a development Add-on in another Gmail account by specifying its Deployment ID, but if your project is owned by an @gmail.com account, and you try to load the Add-on into a G Suite account (like @wordzen.com), <strong>the Add-on won&#8217;t load<\/strong>, and you&#8217;ll <strong>be told it&#8217;s an invalid Add-on<\/strong>. Don&#8217;t worry. Your Add-on still exists, but for some reason <strong>Google won&#8217;t let you load developer add-ons owned by a Gmail.com account from a G Suite account<\/strong>.<\/p>\n<figure id=\"attachment_2419\" aria-describedby=\"caption-attachment-2419\" style=\"width: 720px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-on-Invalid.gif\" data-rel=\"lightbox-image-3\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-2419 size-large\" src=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-on-Invalid-1024x480.gif\" alt=\"\" width=\"720\" height=\"338\" srcset=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-on-Invalid-1024x480.gif 1024w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-on-Invalid-300x141.gif 300w, https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-on-Invalid-768x360.gif 768w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><figcaption id=\"caption-attachment-2419\" class=\"wp-caption-text\">You can&#8217;t install an unpublished Add-on owned by a gmail.com account in a G Suite account.<\/figcaption><\/figure>\n<h3><span style=\"color: #993300;\">Publishing problems<\/span><\/h3>\n<p>There are a\u00a0bunch of steps to actually <strong>publish your Gmail Add-on publicly<\/strong> to the G Suite Marketplace. After preparing all the <strong>text and image assets<\/strong> Google asks you for, you might find that the little checkbox at the bottom where you can tell Google that your project is indeed a Gmail Add-on is <strong>disabled<\/strong> and <strong>grayed out<\/strong>.<\/p>\n<figure id=\"attachment_2421\" aria-describedby=\"caption-attachment-2421\" style=\"width: 860px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Publish-Gmail-Add-on-checkbox-disabled.gif\" data-rel=\"lightbox-image-4\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-2421 size-full\" src=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Publish-Gmail-Add-on-checkbox-disabled.gif\" alt=\"\" width=\"860\" height=\"658\" \/><\/a><figcaption id=\"caption-attachment-2421\" class=\"wp-caption-text\">If you attempt to publish your Gmail Add-on using an @gmail.com account, this checkbox will be disabled.<\/figcaption><\/figure>\n<p>Now you could fire up <strong>Chrome&#8217;s Developer Tools<\/strong> and try to re-enable that checkbox yourself (I didn&#8217;t try this), but I suspect Google is smarter than to let that fly. I went to publish and it was grayed out. I was publishing from an @gmail.com account &#8212; the same @gmail.com account that I used to create all my other OAuth client projects for my other live products, and the same @gmail.com account I use to manage my <strong>Chrome Web Store<\/strong> extensions. On a hunch, I logged out, and logged in with my @wordzen.com account, and voila! &#8212;\u00a0the checkbox\u00a0was\u00a0<strong>enabled<\/strong>. <em>I guess Google is only allowing G Suite users to publish Gmail Add-ons publicly.<\/em> Now that doesn&#8217;t mean your G Suite account has to\u00a0<em>own<\/em> the Google Apps Script project. In my case, my @gmail.com account still owns the project, but my G Suite account has EDIT permissions on the project, and according to the <a href=\"https:\/\/developers.google.com\/gmail\/add-ons\/how-tos\/publish\">publishing guidelines<\/a>, that allows my G Suite account to publish the project.<\/p>\n<h3><span style=\"color: #993300;\">More publishing problems<\/span><\/h3>\n<p>After you get that checkbox enabled, you now might find that the <strong>SAVE<\/strong> button is disabled.<\/p>\n<figure id=\"attachment_2422\" aria-describedby=\"caption-attachment-2422\" style=\"width: 966px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Publish-Gmail-Add-on-save-disabled.gif\" data-rel=\"lightbox-image-5\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-2422 size-full\" src=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Publish-Gmail-Add-on-save-disabled.gif\" alt=\"\" width=\"966\" height=\"944\" \/><\/a><figcaption id=\"caption-attachment-2422\" class=\"wp-caption-text\">If Google hasn&#8217;t manually granted you permission to publish an Add-on, the &#8220;Save changes&#8221; button will be disabled.<\/figcaption><\/figure>\n<p>Good lord. Why is it disabled? Because Google <strong>hasn&#8217;t yet granted you permission to publish a public Add-on<\/strong>. For now, Google requires that you fill out <a href=\"https:\/\/docs.google.com\/forms\/d\/e\/1FAIpQLSdQD9F5TXZvlpQcY1I6fvaZqLvULG1THhou3y5IpRRwjgwZYg\/viewform\">this permission-request form<\/a>, be <strong>granted permission<\/strong>, and then you can <strong>submit your Add-on for review<\/strong>. I&#8217;m still waiting for permission to be granted. As soon as it is I&#8217;ll\u00a0write another post about how much time that process took, and what it entailed.<\/p>\n<h3><span style=\"color: #993300;\">Double authorization<\/span><\/h3>\n<p>In most cases, you&#8217;ll want your Add-on to <strong>authorize<\/strong> with your own web app. That means your user will have <strong>two sets of authorizations<\/strong> when first setting up the Add-on. They will go through the authorization process so that your <strong>Add-on gets permission<\/strong> to run the scopes you&#8217;ve selected. That means your Add-on code will be able to <strong>access the user&#8217;s email address<\/strong>, and the <strong>Gmail Message Id<\/strong> that&#8217;s currently opened and all that jazz. Then, your user will go through the process of <strong>logging in or creating an account with your web app<\/strong>, because chances are, <strong>any useful Add-on will need to tie information about the email message they&#8217;re viewing to information from your web app<\/strong>. That <strong>double authorization<\/strong> might be confusing, and might make your user think there&#8217;s a\u00a0bug in your software, so be sure to <a href=\"https:\/\/developers.google.com\/gmail\/add-ons\/how-tos\/non-google-services#creating_a_custom_authorization_prompt\">use a custom authorization prompt<\/a> following this process, rather than the default. If you use the default prompt, your user is sure to think something is wrong, being asked to authenticate twice. Additionally,\u00a0the docs state this:<\/p>\n<pre>The above widget must use the\u00a0<a href=\"https:\/\/developers.google.com\/apps-script\/reference\/card-service\/on-close\"><code>OnClose.RELOAD_ADD_ON<\/code><\/a>\u00a0setting in its\u00a0<code><a href=\"https:\/\/developers.google.com\/apps-script\/reference\/card-service\/open-link\">OpenLink<\/a>\u00a0<\/code>object to ensure the add-on reloads after authorization is received.<\/pre>\n<p>but I found it not necessary. In fact, it&#8217;s <a href=\"https:\/\/developers.google.com\/gmail\/add-ons\/how-tos\/non-google-services#creating_a_custom_authorization_prompt\">not even in the example<\/a>. I found that the Add-on frame reloads automatically after the authorization popup is closed, regardless of whether authorization was successful or not.<\/p>\n<h3>Still confused?<\/h3>\n<p>I hope this article clarified the process of creating and publishing a Gmail Add-on, but you may run into stumbling blocks that I didn&#8217;t. If that&#8217;s the case, head over to the <a href=\"https:\/\/stackoverflow.com\/questions\/tagged\/gmail-addons\">Stack Overflow section of Gmail Add-ons<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In October 2017, Google released its Gmail &#8220;Add-on&#8221; platform, allowing developers to create add-ons for Gmail that work on both desktop and mobile (well Android right now, iOS\u2026<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3462,3461],"tags":[],"class_list":["post-2389","post","type-post","status-publish","format-standard","hentry","category-developers","category-gmail-add-ons"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\r\n<title>How to develop a &quot;Gmail Add-on&quot; without going insane<\/title>\r\n<meta name=\"description\" content=\"If you&#039;re developing a Gmail Add-on, here are some obstacles you&#039;re likely to run into, and how to overcome them. Hope this helps!\" \/>\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\/develop-gmail-add-on-without-going-insane\/\" \/>\r\n<meta property=\"og:locale\" content=\"en_US\" \/>\r\n<meta property=\"og:type\" content=\"article\" \/>\r\n<meta property=\"og:title\" content=\"How to develop a &quot;Gmail Add-on&quot; without going insane\" \/>\r\n<meta property=\"og:description\" content=\"If you&#039;re developing a Gmail Add-on, here are some obstacles you&#039;re likely to run into, and how to overcome them. Hope this helps!\" \/>\r\n<meta property=\"og:url\" content=\"https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/\" \/>\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=\"2018-03-22T03:46:16+00:00\" \/>\r\n<meta property=\"article:modified_time\" content=\"2018-03-22T18:43:03+00:00\" \/>\r\n<meta property=\"og:image\" content=\"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-On-Runtime-Error-4-300x197.gif\" \/>\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=\"9 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\\\/develop-gmail-add-on-without-going-insane\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/develop-gmail-add-on-without-going-insane\\\/\"},\"author\":{\"name\":\"Ajay Goel\",\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/#\\\/schema\\\/person\\\/b5fa74f8765b860701158fd77162fff8\"},\"headline\":\"How to develop a &#8220;Gmail Add-on&#8221; without going insane\",\"datePublished\":\"2018-03-22T03:46:16+00:00\",\"dateModified\":\"2018-03-22T18:43:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/develop-gmail-add-on-without-going-insane\\\/\"},\"wordCount\":1929,\"commentCount\":10,\"image\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/develop-gmail-add-on-without-going-insane\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/03\\\/Gmail-Add-On-Runtime-Error-4-300x197.gif\",\"articleSection\":[\"Developers\",\"Gmail Add-ons\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.gmass.co\\\/blog\\\/develop-gmail-add-on-without-going-insane\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/develop-gmail-add-on-without-going-insane\\\/\",\"url\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/develop-gmail-add-on-without-going-insane\\\/\",\"name\":\"How to develop a \\\"Gmail Add-on\\\" without going insane\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/develop-gmail-add-on-without-going-insane\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/develop-gmail-add-on-without-going-insane\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/03\\\/Gmail-Add-On-Runtime-Error-4-300x197.gif\",\"datePublished\":\"2018-03-22T03:46:16+00:00\",\"dateModified\":\"2018-03-22T18:43:03+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/#\\\/schema\\\/person\\\/b5fa74f8765b860701158fd77162fff8\"},\"description\":\"If you're developing a Gmail Add-on, here are some obstacles you're likely to run into, and how to overcome them. Hope this helps!\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/develop-gmail-add-on-without-going-insane\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.gmass.co\\\/blog\\\/develop-gmail-add-on-without-going-insane\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/develop-gmail-add-on-without-going-insane\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/03\\\/Gmail-Add-On-Runtime-Error-4-300x197.gif\",\"contentUrl\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/03\\\/Gmail-Add-On-Runtime-Error-4-300x197.gif\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/develop-gmail-add-on-without-going-insane\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.gmass.co\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to develop a &#8220;Gmail Add-on&#8221; without going insane\"}]},{\"@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":"How to develop a \"Gmail Add-on\" without going insane","description":"If you're developing a Gmail Add-on, here are some obstacles you're likely to run into, and how to overcome them. Hope this helps!","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\/develop-gmail-add-on-without-going-insane\/","og_locale":"en_US","og_type":"article","og_title":"How to develop a \"Gmail Add-on\" without going insane","og_description":"If you're developing a Gmail Add-on, here are some obstacles you're likely to run into, and how to overcome them. Hope this helps!","og_url":"https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/","og_site_name":"GMass Blog","article_publisher":"https:\/\/www.facebook.com\/GmailMailMerge\/","article_published_time":"2018-03-22T03:46:16+00:00","article_modified_time":"2018-03-22T18:43:03+00:00","og_image":[{"url":"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-On-Runtime-Error-4-300x197.gif","type":"","width":"","height":""}],"author":"Ajay Goel","twitter_card":"summary_large_image","twitter_creator":"@PartTimeSnob","twitter_site":"@GMassForGmail","twitter_misc":{"Written by":"Ajay Goel","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/#article","isPartOf":{"@id":"https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/"},"author":{"name":"Ajay Goel","@id":"https:\/\/www.gmass.co\/blog\/#\/schema\/person\/b5fa74f8765b860701158fd77162fff8"},"headline":"How to develop a &#8220;Gmail Add-on&#8221; without going insane","datePublished":"2018-03-22T03:46:16+00:00","dateModified":"2018-03-22T18:43:03+00:00","mainEntityOfPage":{"@id":"https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/"},"wordCount":1929,"commentCount":10,"image":{"@id":"https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/#primaryimage"},"thumbnailUrl":"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-On-Runtime-Error-4-300x197.gif","articleSection":["Developers","Gmail Add-ons"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/","url":"https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/","name":"How to develop a \"Gmail Add-on\" without going insane","isPartOf":{"@id":"https:\/\/www.gmass.co\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/#primaryimage"},"image":{"@id":"https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/#primaryimage"},"thumbnailUrl":"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-On-Runtime-Error-4-300x197.gif","datePublished":"2018-03-22T03:46:16+00:00","dateModified":"2018-03-22T18:43:03+00:00","author":{"@id":"https:\/\/www.gmass.co\/blog\/#\/schema\/person\/b5fa74f8765b860701158fd77162fff8"},"description":"If you're developing a Gmail Add-on, here are some obstacles you're likely to run into, and how to overcome them. Hope this helps!","breadcrumb":{"@id":"https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/#primaryimage","url":"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-On-Runtime-Error-4-300x197.gif","contentUrl":"https:\/\/www.gmass.co\/blog\/wp-content\/uploads\/2018\/03\/Gmail-Add-On-Runtime-Error-4-300x197.gif"},{"@type":"BreadcrumbList","@id":"https:\/\/www.gmass.co\/blog\/develop-gmail-add-on-without-going-insane\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.gmass.co\/blog\/"},{"@type":"ListItem","position":2,"name":"How to develop a &#8220;Gmail Add-on&#8221; without going insane"}]},{"@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\/2389","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=2389"}],"version-history":[{"count":22,"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/posts\/2389\/revisions"}],"predecessor-version":[{"id":2427,"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/posts\/2389\/revisions\/2427"}],"wp:attachment":[{"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/media?parent=2389"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/categories?post=2389"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gmass.co\/blog\/wp-json\/wp\/v2\/tags?post=2389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}