Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save imthenachoman/6cff4a1170390f01c15d4da87110124a to your computer and use it in GitHub Desktop.
Save imthenachoman/6cff4a1170390f01c15d4da87110124a to your computer and use it in GitHub Desktop.
Developing a GAS Powered Google Workspace Add-on And Launching It To The Marketplace

Developing a GAS Powered Google Workspace Add-on And Launching It To The Marketplace

This guide will walk you through creating a public Google Workspace Add-on, and launching it in the Google Workspace Marketplace for as free as possible.

This guide was written as I developed and launched my first add-on: Nacho Auto Vacation for Gmail™.

Table of Contents

About

I use Out of Office events in Google Calendar and Gmail's vacation responder to stay organized. But you have to make updates in two places: set an OOO event in the calender and then enable Gmail's vacation responder. Not this guy.

I realized I could automate this with Google Apps Script (GAS): every time there is an OOO event in my calendar, automatically enable/disable Gmail's vacation responder. WIN! (I've said it before and I'll say it again, GAS is the best productivity enhancement tool that exists, bar none. It has some issues/gaps that can be annoying. If Google addresses those, GAS could take over the world. But I digress. :P)

As I was developing the automation, I realized I could packge this up as an add-on and publish it to the marketplace. I figure if I want to enable my Gmail vacation responder when I have a Google Calendar OOO event then others must want theirs to do this too. So it made sense to launch this as an add-on.

I'd never developed or published an add-on before. As I was looking into it, I realized that, while it is not super complicated, it is not readily obvious -- especially for anyone just getting into add-on development. Google does have a guide on developing and publishing an add-on but it leaves a lot of unanswered questions.

So I thought I would put together what I learned in this guide -- a playbook for anyone else who wants to develop their own add-on.

The flow of this guide does not align with the flow/process I took because somethings I learned in the end that I wish I had known at the start.

Before You Start

While Google's documentation does leave a lot of unanswered questions, it is a great place to start. I do highly recommend going through the various pages (on the left side navigation) on https://developers.google.com/apps-script/add-ons/overview.

Below are some key items/topics I think are worth highlighting.

Google Account Types

Google has two product offerings. Which kind you are use or need to use will depend on your situation/use-case/needs.

They have:

The best I can tell, you do not need a Google Workspace account to develop and launch a Google Workspace Add-on. But if your add-on is for interacting with capabilities/features that are only available in Google Workspace then you'll need a paid Google Workspace account.

For example, my add-on relies on creating Out of Office events in Google Calendar and that is only available with the paid Google Workspace account. Otherwise, how will you test your add-on?

Internal vs. External Google Workspace Add-Ons

I recommend reading through How can I mark my app as internal-only so it doesn't require verification?. Essentially:

  • internal - only for your use by users in your Google Workspace organization
  • external - for use by anyone in the public domain/realm

Note: This document/guide is geared towards external. You'll need/want to check with your organization's Google Workspace admins for their process on launching an internal add-on for your organization.

Why Google Apps Script Over Other Runtimes

You you can build an add-on in any runtime on your own backend as long as it returns properly formatted JSON. If you have a complex add-on then you might need your own infrastructure (server) and back-end. But, if you don't, then you can build your add-on in Google Apps Script. I've said it before and I'll say it again, GAS is the best productivity enhancement tool that exists, bar none.

If you're just starting out in your add-on journey, start with building your add-on in GAS and if you hit a wall, you can move to your on backend.

Remember The Quotas

The major downside to using Google Apps Script as the runtime for your add-on is you're at the mercy of Google Apps Script quotas. So keep those in mind. But, again, start with building your add-on in GAS and if you hit a wall, you can move to your on backend.

Pre-Requisites

Before you develop and launch an add-on, there are a few things you're going to need. Some of these I knew before I started, some I didn't realize till I got to the end -- and had to start all over. Save yourself the headache I had by making sure you are prepared.

What Required Details
Development experience preferred There are some critical SDLC paradigms this guide does not cover like plan and design. You don't need to know or do these things but you'll save yourself a lot of headache if you do.
GAS yes This guide assumes you know the basics/fundamentals. If you don't, I highly recommend going through Google's tutorials and example scripts on https://www.google.com/script/start/.
Google Account yes Needless to say, you'll need a Google account to do anything. See Google Account Types
Add-on name yes See Naming Your Add-On
Website and Domain Name yes See Website and Domain Name
Read Google's add-on documentation preferred My guide covers everything in Google's guide, but in more detail but I still recommend going through Google's at https://developers.google.com/apps-script/add-ons/how-tos/building-workspace-addons.
Graphic assets yes See https://developers.google.com/workspace/marketplace/create-listing#graphic_assets for details on what you'll need.

The Main Event

Now that we've gotten the boring stuff out of the way, let's dive in.

Developing The Add-on

You're not developing and launching the same add-on I did, so I'm not going to get into the specifics of my add-on. All of my add-on's code is available at https://github.com/imthenachoman/Nacho-Auto-Vacation-for-Gmail if you want to see it.

Google's guide is at https://developers.google.com/apps-script/add-ons/how-tos/building-workspace-addons. I will highlight the things I think are important based on my experience in developing my add-on.

Scopes

Unlike a normal GAS project, you need to explicitly list the scopes your code needs/uses in your project's manifest file in the oauthScopes array property. See https://developers.google.com/apps-script/add-ons/concepts/workspace-manifests for more details.

IMPORTANT: Certain scopes are restricted scopes. If your add-on uses restricted scopes, your add-on will have additional review and requirements. You'll know if your add-on uses restricted scopes when you configure your add-on's OAuth consent screen. If it does, you'll have to go through an additional review.

There are two ways to determine which scopes your project uses:

  1. View scopes from the GAS editor
  2. Check Google's reference documentation for what scopes are necessary for different functions/methods/calls

For example, my add-on makes a call to the Gmail API users.settings.updateVacation which requires the scope https://www.googleapis.com/auth/gmail.settings.basic.

Here is an excerpt of the scopes I use in my add-on from my manifest file:

    ...
    "oauthScopes": [
        "https://www.googleapis.com/auth/gmail.addons.execute",
        "https://www.googleapis.com/auth/gmail.settings.basic",
        "https://www.googleapis.com/auth/calendar.addons.execute",
        "https://www.googleapis.com/auth/calendar.events.readonly",
        "https://www.googleapis.com/auth/script.scriptapp",
        "https://www.googleapis.com/auth/userinfo.email"
    ],
    ...
Scope Type So thiss project can....
https://www.googleapis.com/auth/gmail.addons.execute ... run as a Gmail add-on
https://www.googleapis.com/auth/gmail.settings.basic restricted ... enable or disable the user's vacation responder setting in Gmail
https://www.googleapis.com/auth/calendar.addons.execute ... run as a Calendar add-on
https://www.googleapis.com/auth/calendar.events.readonly sensitive ... list events from your calendar
https://www.googleapis.com/auth/script.scriptapp sensitive ... create triggers
https://www.googleapis.com/auth/userinfo.email ... see your primary Google Account email address so the project can create triggers on your calendar

Remember, these are the scopes I use in my add-on. Yours will be different.

WYSIWYG Card Builder

Writing the code to create cards for the add-on is painful, and if I am being honest, confusing. So I was very happy to discover https://gw-card-builder.web.app/. It is an online WYSIWYG card builder. You can visually create your cards and then copy/paste the code into your project.

I used it to create all of the card code for my add-on. I did refactor the code the builder provided but that was for personal reasons -- you don't need to.

Add-on Manifest File

Every add-on needs specific elements in your project's manifest file. What goes in your add-on's manifest file will depend a lot on your add-on. My advice is to carefully read through https://developers.google.com/apps-script/add-ons/concepts/workspace-manifests to see what you need.

Here is an explanation of what is in my add-on's manifest file:

    ...
    "addOns": {
        "common": {
            "name": "Nacho Auto Vacation for Gmail",
            "logoUrl": "https://lh3.googleusercontent.com/pw/AM-JKLWnXrKoV9rliAUmvgumEE_fTK3IAX5rUAjo95LXXe6Xoai7Mo9XQ3OaNKksMJKNnfleCTQ6vTyit87FYzxdvdAe7W-FqgoP4udjgNpfY3Td77JUaS3RPO04LYBs9LlVnTAVqmjsf9kKztWZZojJDw_FQQ=s480-no?authuser=0",
            "homepageTrigger": {
                "enabled": true,
                "runFunction": "card_onHomepage"
            },
            "universalActions": [
                {
                    "label": "Homepage",
                    "openLink": "https://github.com/imthenachoman/Nacho-Auto-Vacation-for-Gmail"
                },
                {
                    "label": "Privacy Policy",
                    "openLink": "https://github.com/imthenachoman/Nacho-Auto-Vacation-for-Gmail#privacy-policy"
                }
            ]
        },
        "gmail": {},
        "calendar": {}
    },
    "urlFetchWhitelist": [
        "https://github.com/imthenachoman/"
    ]
    ...
Property Reason Reference
addOns Root element for all add-on configuration https://developers.google.com/apps-script/manifest/addons#addons
addOns.common Common properties https://developers.google.com/apps-script/manifest/addons#common
addOns.common.name Name of the add-on https://developers.google.com/apps-script/manifest/addons#Common.FIELDS.name
addOns.common.logoUrl Add-on logo urlFetchWhitelist https://developers.google.com/apps-script/manifest/addons#Common.FIELDS.logoUrl
addOns.common.homepageTrigger Homepage properties https://developers.google.com/apps-script/manifest/addons#Common.FIELDS.homepageTrigger
addOns.common.homepageTrigger.enabled Enable the homepage trigger https://developers.google.com/apps-script/manifest/homepage-trigger#HomepageTrigger.FIELDS.enabled
addOns.common.homepageTrigger.runFunction Call the function card_onHomepage when when this add-on loads the homepage https://developers.google.com/apps-script/manifest/homepage-trigger#HomepageTrigger.FIELDS.runFunction
addOns.common.universalActions Show some universal links in th add-On https://developers.google.com/apps-script/manifest/addons#Common.FIELDS.universalActions
addOns.gmail Show this add-on in Gmail; my add-on does not need to do/show anything special in Gmail https://developers.google.com/apps-script/manifest/addons#AddOns.FIELDS.gmail
addOns.calendar Show this add-on in Google Calendar; my add-on does not need to do/show anything special in Google Calendar https://developers.google.com/apps-script/manifest/addons#AddOns.FIELDS.calendar
urlFetchWhitelist All of the URLs my add-on references so links to them are allowed https://developers.google.com/apps-script/manifest#Manifest.FIELDS.urlFetchWhitelist

Testing Your Add-On

Google makes it stupid easy to test your add-on. Just follow the instructions at https://developers.google.com/apps-script/add-ons/how-tos/testing-workspace-addons#install_an_unpublished_add-on.

You may have to execute your GAS project before you can do a test deployment.

Publishing The Add-on

This is why you're really here, right?

Google's guide is at https://developers.google.com/apps-script/add-ons/how-tos/publish-add-on-overview but I'll dig into the steps I took. Plus, there are some things you want to have ready before you start, and the order of steps Google has isn't right. For example, you'll need to create a GCP project before you can create a version even though Google's guide has it the other way around.

Before you start, make sure you've finished developing and testing your add-on.

Prepare

Homepage, Privacy Policy, and Terms of Service

Your add-on's marketplace listing will need to link to a homepage, privacy policy, and terms of service. If you're reading this guide you're probably asking yourself what those things are and/or what they should say. I'll level with you -- I have no clue. This was kind of a trial and error process for me.

I have no legal experience, nor do I want to point anyone in the wrong direction, so I won't dig into this topic. All I will say is I did a lot of Googling and spoke to a few lawyer friends.

As you go through the OAuth consent screen approval process they will review your privacy policy and provide feedback. This is the various feedback I got when I was going through my approval process:

Limited Use Requirements

If your app uses restricted scopes, we'll thoroughly review your Privacy Policy to check that it follows our Limited Use requirements.

If your Privacy Policy follows the Limited Use requirements, we need to know how your app treats user data. You can tell us this, and show how your app follows Google policies, through a public online disclosure. For example, this could be an in-product disclosure on the application homepage, or a public FAQ. You can read more about this requirement in the FAQ.

We suggest adding a disclosure to your app that meets these requirements:

  • The disclosure must be under 500 characters.
  • The disclosure must clearly call out that the app complies with the Google API Services User Data Policy, including the Limited Use requirements.
  • The disclosure must contain a link to the Google API Services User Data Policy so that it's easily accessible to all users.
  • The disclosure must be accessible on the project’s homepage URL or one click away from the homepage URL.
  • The disclosure must be easily visible to all users.

Example disclosure: "(App’s) use and transfer to any other app of information received from Google APIs will adhere to Google API Services User Data Policy, including the Limited Use requirements."

And:

Privacy Policy Requirements

  • The URL in your project points to a privacy policy on a publicly accessible domain.
  • The privacy policy is hosted and accessible in the domain of your website.
  • The privacy policy is accessible from the app’s home page.
  • Users can view the privacy policy.
  • The privacy policy clearly describes the way your application accesses, uses, stores, or shares Google user data.
  • The privacy policy is linked to the OAuth Consent Screen on the Google API Console.
  • You only use Google user data in the ways described in your published privacy policy.

Limited Use Requirements

If your app uses restricted scopes, we'll check that your privacy policy follows our Limited Use requirements.

NOTE: For your scenario, you will need to update your home page to include your privacy policy URL link with the Limited Use Disclosure.

Demo Video (Maybe)

As mentioned above, if your add-on uses restricted scopes, your add-on will have additional review and requirements. One of these requirements is:

Provide a YouTube video demonstrating how you'll use the data from these scopes in your app. Your video must include all OAuth clients that you assigned to this project.

image

I uploaded an unlisted video to YouTube.

Create A Google Cloud Platform Project

To quote Google:

When you build your add-on in Apps Script, a default Google Cloud Platform (GCP) project is automatically created for it. However, you can’t use the default GCP project to publish your app. Instead, use the steps below to create a standard GCP project:

So the first thing we need to do is create a GCP project:

  1. Open https://console.cloud.google.com/project
    • Make sure you're logged in using the Google account you intend to use to publish the add-on
    • In most cases this will be the same account you developed and tested your add-on with
  2. Click CREATE PROJECT in the top next to Manage Resources image
  3. Fill out the New Project from
    • Your view may look different than mine
    • I am creating this GCP project under my Google Workspace account
    • Project name is the just the name of your GCP project and not necessarily the name of your add-on. They don't have to match. image
  4. Once it finishes creating the project, click SELECT PROJECT in the Notifications window image
  5. Make note of your Project number under Project info -- you will need this later image

(More information on Google Apps Script and Google Cloud Platform Projects can be found at https://developers.google.com/apps-script/guides/cloud-platform-projects.)

Configure Your Add-on's OAuth Consent Screen

When a user goes to install your add-on, they will see an OAuth consent screen asking them to allow the add-on to have access to their Google account/data. You need to configure what this OAuth consenst screen will say.

  1. If you're continuing from Create A Google Cloud Platform Project then you're already at your GCP project's dashboard. Otherwise, go to https://console.cloud.google.com/ and select this add-on's GCP project from the top selector.
    • Make sure you're logged in using the Google account you intend to use to publish the add-on
    • In most cases this will be the same account you developed and tested your add-on with image
  2. Open the left side-bar and navigate to APIs & Services > OAuth consent screen image
  3. This guide assumes you're publishing your add-on to the public space/domain so select External for User Type and then click Create image
  4. Fill in the fields as they apply to your add-on image
  5. Add all of your scopes
    • This is where you'll if you have restricted scopes image
  6. Add your test users image
  7. Go back to the dashboard image
  8. Click on PUBLISH APP under Publishing status image
  9. Confirm for Push to production? image

OAuth Consent Screen Additional Verfification (Maybe)

As mentioned above, if your add-on uses restricted scopes, your add-on will have additional review and requirements. You'll know yours needs this if you see this screen after configuring your OAuth consent screen.

image

  1. Click PREPARE FOR VERIFICATION
  2. Review the app information and click SAVE AND CONTINUE
  3. Answer all of the questions image
  4. Answer some more optional information image
  5. Check the My usage of OAuth Scopes complies with the Google API Services: User Data Policy. box and click SUBMIT FR VERIFICATION image
  6. Sit back and wait

You will get en email from Google as they review your project. You might have to answer more questions, make updates, provide more evidence, etc. Just go through the motions with them.

Be patient as it can take a while. I mean no insult but the review team does not seem to be super technical nor do they seem to know/understand all of Google's products/capabilities. I had to explain basic things like how the only way to enable/disable the vacation responder in Gmail was use a restricted scope. They kept asking me if I could remove the restricted scope as though they didn't understand the technical limtiation from Google's side. By the time everything was said and done, I had exchanged 200+ emails with Google.

Associate Your GAS Project To Your GCP Project

As mentioned above, your GAS project will need to use a standard GCP project instead of the default one.

  1. Go to your GAS project and click on the gear icon image
  2. Scroll to the bottom and click the Change project button image
  3. Enter your GCP project number that you got from step #5 of Create A Google Cloud Platform Project and click Set project

Create A Deployment/Version Of Your GAS Project

  1. Go to your GAS project and click on the gear icon
  2. Go into the code editor
  3. Click on the dropdown arrow next to Deploy
  4. Enter a description and click Deploy
  5. Make note of the Deployment ID -- you will need this later

More information can be found at https://developers.google.com/apps-script/add-ons/how-tos/publish-add-on-overview#create_a_version_of_your_add-on.

Final Steps

From here on, Google's documentation on publishing an add-on is pretty straight forward. Just follow the guide at https://developers.google.com/workspace/marketplace/how-to-publish from step #4.

Appendix

Naming Your Add-on

Google has strict rules on what you can name your add-on. You want to make sure to pick a name they will approve before you start otherwise you'll have to make a lot of changes like redoing all of your logos.

So before you go too far down the rabit hole, read through https://about.google/brand-resource-center/guidance/apis/ to make sure your add-on meets all of their branding requirements.

I originally named my add-on Gmail Auto Vacation for Gmail but they didn't like that because it had Gmail in it. They approved Nacho Auto Vacation for Gmail™. Notice the in the title becuase Gmail is trademarked by Google.

Website and Domain Name

In order for you to publish your add-on to the marketplace, your add-on and marketplace listing will need to link to official documents, like a privacy policy, on a website that Google Search Console shows you as an owner of.

Requirement Details
Website hosting If you have have one, great. If not, I am using Google Sites because it is free and easy.
Domain name Google requires that you can show you own your website through Google Search Console.

I tried to use free solutions like GitHub for hosting my privacy policy but they wouldn't approve it since you can't claim ownership of a website under a domain name you don't own. I've seen quite a few add-ons in the marketplace using GitHub for their privacy policy and I have no clue how they did it because Google wouldn't let me do it. If anyone knows how they do it, please let me know in the comments below.

I got my domain https://www.nachoapps.dev from Google Domains for $12 USD a year -- not too bad. You can get a domain name from wherever you want but going through Google Domains did make my life easier because then it automatically showed me as an owner on Google Search Console.

Verifying Your Domain In Google Search Console

Google requires that the account you use to publish your add-on is listed as an owner of your domain. I did not have to do anything special for this because I bought my domain from Google Domains.

image

If you didn't use Google Domains, you can manually verify your domain:

  1. Go to https://search.google.com/search-console
  2. Click on the drop-down in the top-left image
  3. Click Add property image
  4. Go through the wizard image

When everything is done, you should be able to go to Settings and see you are a verified owner.

Publishing Your Google Site To Your Domain

I used Google Sites because it is free and easy. Your domain name will need to point to your Google Site. To do this:

  1. Go to https://sites.google.com/
  2. Select your site
  3. Click on the gears in the top right corner image
  4. Click Custom domains on the left and Add on the right image
  5. Go through the screens to add your domain
  6. Remember to republish your site to push the updates

References

@peralta
Copy link

peralta commented Oct 2, 2023

Great write-up! It really saves a lot of time to follow your guide. FYI, there is somewhat a similar add-on to yours: AutoOOO

@imthenachoman
Copy link
Author

@peralta You're welcome. And thanks for sharing that -- I didn't know it was there. I had searched before and never found anything. Odd.

@lydiastepanek
Copy link

Thanks for the amazing writeup! I found this super useful as a reference while I was developing a phishing addon for Gmail called TooPhishy.

@imthenachoman
Copy link
Author

@lydiastepanek Glad it helped. Just saw your app -- very, very nice. You do good design work. And I see you're charging for it -- good luck! Super exciting. I need to work on some more add-on ideas I have that I might be able to make money from. I just struggle with the design stuff. Fingers crossed.

@imthenachoman
Copy link
Author

@peralta I now realize AutoOOO is yours. I don't know why I did not see it when I searched before I started writing mine. Had I seen yours, I would have reached out to you first. Would you mind emailing me? I want to ask you something. My email is listed at https://gist.github.com/imthenachoman.

@locatejp
Copy link

Great writeup Anchal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment