Posted by Saurabh Gupta, Product Manager, Google Apps Script
There are two ways to send email in Apps Script: MailApp's sendEmail and GmailApp's sendEmail method. One of the differences between these two methods is that the MailApp’s sendEmail method doesn’t require the developer to be a Gmail user. For example, a Google Apps customer who doesn’t use Gmail, but uses Apps Script instead, can send emails through MailApp but not GmailApp.
Starting on September 13, 2016, users with free public Google Accounts (consumers) and Google Apps for Education and Google Apps Free edition users, will be required to have Gmail access to send messages through Apps Script’s Mail Service. Consumers can enable Gmail on their Google account after signing-in—note your Gmail will then become the primary address of your Google account. Administrators of Google Apps domains (Education and Free edition only) can use the Admin console to turn on Gmail for their domain.
This change does not require any updates to your code. You can continue to use MailApp as before; just make sure that you have signed up for Gmail. We realize that sometimes these changes are disruptive to our developers, but we can assure you that we put lot of care and deliberation into this process.
Posted by Ben Greve, Developer Support Specialist, Google Apps Script
So you’ve started to build an add-on. Congrats! You identified a problem, figured out a solution, and wrote some code to accomplish it like a pro. Now it’s time to focus on design, to make sure your audience understands what your add-on does and how to use it.
In this post, I will outline five simple design tips to help make your add-on a pleasure to use. Don’t worry if you’re not an artist – these are basic concepts that anyone can apply.
Crafting a guided workflow takes the guesswork (and stress) out of using an add-on. Your user should never wonder, ‘What am I supposed to do next?’ Actions, forms, text, and buttons should be designed to create a natural flow guiding the user from one step to the next.
This can be accomplished in a number of ways. Try presenting actions in a natural order: from left to right and from top to bottom (assuming LtR language; adjust as needed). You can indicate which button is the primary action by styling it using the blue .action class. You can guide the user’s behavior by limiting the actions available (sometimes referred to as ‘forcing function’). For example, actions/options with dependencies can be disabled or hidden until they should be used. Another option is to spread a workflow across several pages and require the user to complete a given page before they can proceed to the next.
Complex add-ons require effective communication. Simple add-ons do, too. Effective communication is necessary for your audience to understand what your add-on does and how they should use it.
Use accessible language that anyone can understand. Don’t use complex wording if more easily digestible terminology is available. Unless your target audience has been demanding a feature to “asynchronously call an RPC with dependent proto messages,” you should avoid using unnecessarily technical or jargony language.
Present information when and where it’s needed. Instructions should be displayed in the context which they will be used. Actions should be clearly labeled so that users will know exactly what they do. Provide enough information so the user understands what they are doing, why they are doing it, and where they are going.
Have you ever used an app where you click on a button and nothing happens? You sit there wondering: Did it work? Did it not work? Did anything happen at all? When building your add-on, don’t do this to your users. Make sure that all actions have clear and immediate feedback, so no one is never left wondering, “What just happened?”.
With this in mind, there is still room for graceful design. Feedback can be subtle - it doesn’t need to shout, ‘ACTION 1 COMPLETED’! Leverage nuanced changes, such as displaying a quick message in a toast or moving to the next step in the workflow.
What happens if an action takes a long time to complete? Someone clicks a button and waits… and waits… and waits. A good UI will account for this scenario, too. Try using a loading graphic (i.e. a spinner or a progress bar) and for longer loading times consider including a button to cancel.
People make mistakes. It’s sad but true, and unlikely to change any time soon. Keep your users safe from themselves and design actions to have minimal risk.
The ideal solution is to remove the risk entirely. Inserting a bunch of data into a spreadsheet? Consider creating a new sheet and insert the data there. When appropriate, configure actions to add rather than replace, minimizing potential damage to existing content.
There will be situations where avoiding risk entirely won’t be possible. In these cases, do the best you can to explicitly communicate the action’s effect so your user can make a well-informed decision. A preview or a warning of the impending changes will help ensure that the user is aware of what’s coming. And of course, provide a method to ‘undo’ when possible.
Each UI element in your add-on should serve a purpose; consider removing anything that doesn’t. For the best design, keep it focused on functionality and trim any excess.
Using a large range of styling can actually undermine the power of the design. When a website is covered with different colors, styles, and fonts, it makes it difficult for any styling to communicate a specific meaning. Design patterns that are overly complicated or inconsistent make it difficult for users to learn what’s important and what isn’t.
Instead, consider an app with only three text stylings: one large, one bold, and one plain. The large style is always (and only) used for headers/titles, the bold style is used for labels, and the plain style is normal body text. Any time a user sees one of these, they’ll know exactly what they are looking at. Less is more.
Too many brilliant add-ons and apps have failed due to simple design flaws that made them inaccessible to users. These five tips are intended to help you prevent those common mistakes and provide a foundation for a great user experience.
As you work on your next add-on, remember the five lessons here:
Finally: please make sure to include the necessary onOpen() and onInstall() functions (if you want the add-on to work), follow our UI Style Guide, and use the provided CSS Package.
Have any tips or tricks of your own? Leave a comment below and share your design insights with the rest of the Apps Script community!
Posted by Henry Wang, Associate Product Marketing Manager
Posted by Romain Vialard, a Google Developer Expert and developer of Yet Another Mail Merge, a Google Sheets add-on.
Google Apps Script makes it easy to create and publish add-ons for Google Sheets, Docs, and Forms. There are now hundreds of add-ons available and many are reaching hundreds of thousands of users. Google Analytics is one of the best tools to learn what keeps those users engaged and what should be improved to make an add-on more successful.
Add-ons run inside Google Sheets, Docs, and Forms where they can display content in dialogs or sidebars. These custom interfaces are served by the Apps Script HTML service, which offers client-side HTML, CSS, and JS with a few limitations.
Among those limitations, cookies aren’t persistent. The Google Analytics cookie will be recreated each time a user re-opens your dialog or sidebar, with a new client ID every time. So, Analytics will see each new session as if initiated by a new user, meaning the number of sessions and number of users should be very similar.
Fortunately, it’s possible to use localStorage to store the client ID — a better way to persist user information instead of cookies. After this change, your user metrics should be far more accurate.
Add-ons can also run via triggers, executing code at a recurring interval or when a user performs an action like opening a document or responding to a Google Form. In those cases, there’s no dialog or sidebar, so you should use the Google Analytics Measurement Protocol (see policies on the use of this service) to send user interaction data directly to Google Analytics servers via the UrlFetch service in Google Apps Script.
A Client ID is also required in that case, so I recommend using the Apps Script User properties service. Most examples on the web show how to generate a unique Client ID for every call to Analytics but this won’t give you an accurate user count.
You can also send the client ID generated on client side to the server so as to use the same client ID for both client and server calls to Analytics, but at this stage, it is best to rely on the optional User ID in Google Analytics. While the client ID represents a client / device, the User ID is unique to each user and can easily be used in add-ons as users are authenticated. You can generate a User ID on the server side, store it among the user properties, and reuse it for every call to Analytics (both on the client and the server side).
In add-ons, we usually rely on event tracking and not page views. It is possible to add different parameters on each event thanks to categories, actions, labels and value, but it’s also possible to add much more info by using custom dimensions & metrics.
For example, the Yet Another Mail Merge add-on is mostly used to send emails, and we have added many custom dimensions to better understand how it is used. For each new campaign (batch of emails sent), we record data linked to the user (e.g. free or paying customer, gmail.com or Google for Work / EDU user) and data linked to the campaign (e.g. email size, email tracking activated or not). You can then reuse those custom dimensions inside custom reports & dashboards.
Once you begin to leverage all that, you can get very insightful data. Until October 2015, Yet Another Mail Merge let you send up to 100 emails per day for free. But we’ve discovered with Analytics that most people sending more than 50 emails in one campaign were actually sending 100 emails - all the free quota they could get - but we failed to motivate them to switch to our paid plan.
As a result of this insight, we have reduced this free plan to 50 emails/day and at the same time introduced a referral program, letting users get more quota for free (they still don’t pay but they invite more users so it’s interesting for us). With this change, we have greatly improved our revenue and scaled user growth.
Or course, we also use Google Analytics to track the efficiency of our referral program.
To help you get started in giving you more insight into your add-ons, below are some relevant pages from our documentation on the tools described in this post. We hope this information will help your apps become more successful!:
Romain Vialard profile | website
Romain Vialard is a Google Developer Expert. After some years spent as a Google Apps consultant, he is now focused on products for Google Apps users, including add-ons such as Yet Another Mail Merge and Form Publisher.
Posted by Posted by Wesley Chun (@wescpy), Developer Advocate, Google Apps
Seasons greetings! In case you missed it last week, the Google Drive team announced the release of the next version of their API. Today, we dig deeper into details about the release with developers. In the latest edition of the Launchpad Online developer video series, you'll get everything you need to know about the new release (v3), as well as its relationship with the previous version (v2).
This jam-packed episode features an introduction to the new API, an interview with a Google Drive engineer about the API design and a code walkthrough of real source code you can use today (as with all my Launchpad Online episodes). This time, it's a command-line script that performs Google Drive file uploads and downloads, presented first in v2 followed by a how-to segment on migrating it step-by-step to v3. In addition, the uploading segment includes the option of converting to Google Apps formats while the download portion covers exporting to alternative formats such as PDF®.
To get started using the Drive API, check out the links to the official documentation above (v2 or v3) where you’ll also find quickstart samples in a variety of programming languages to the left. For a deeper dive into both Python code samples covered here, including v3 migration, start with the first of two related posts posted to my blog.
If you’re new to the Launchpad Online, we share technical content aimed at novice Google developers -current tools with a little bit of code to help you launch your next app. Please give us your feedback below and tell us what topics you would like to see in future episodes!
Posted by Matt Hessinger, Project Specialist, Google Apps Script
Welcome to our 100th blog post on Apps Script! It’s amazing how far we’ve come from our first post back in 2010. We started out highlighting some of the simple ways that you could develop with the Apps platform. Today, we’re sharing tips and best practices for developing more complex Apps Script solutions by pointing out some community contributions.
The Apps Script editor does not allow you to use your own source code management tool, making it a challenge to collaborate with other developers. Managing development, test, and production versions of a project becomes very tedious. What if you could have the best of both worlds — the powerful integration with Google’s platform that Apps Script offers, along with the development tooling and best practices that you use every day? Now, you can.
npm install -g node-google-apps-script
This project, “node-google-apps-script”, is a Node.js based command-line interface (CLI) that uses Google Drive API to update Apps Script project from the command line. You can view the node package on the NPM site, and also view the GitHub repo. Both links have usage instructions. This tool was created by Dan Thareja, with additional features added by Matt Condon.
Before using the tool, take a look at the Apps Script Importing and Exporting Projects page. There are a few things that you should be aware of as you plan out your development process. There are also a few best practices that you can employ to take full advantage of developing in this approach.
There is a sample project that demonstrates some of the practices described in this post: click here to view that code on GitHub. To get all of the Apps Script samples, including this import/export development example:
Your standalone Apps Script projects live in Google Drive. If you use a command-line interface (CLI) tool like the one linked above, you can work in your favorite editor, and commit and sync code to your chosen repository. You can add tasks in your task runner to push code up to one or more Apps Script projects, conditionally including or excluding code for different environments, checking coding style, linting, minifying, etc. You can more easily create and push UI-related files to a file host outside of Apps Script, which could be useful if those same files are used in other apps you are building.
In addition to the information on the Importing and Exporting Projects page, here are a few things to consider:
Over and above the editing experience, the biggest improvements you get by working outside the script editor is that you are no longer locked into working in just one Apps Script project. You can much more easily collaborate as a team, with individual developers having their own working Apps Script projects, while also having more controlled test, user acceptance and production versions, each with more process and security. Beyond just the consistency with other normal project practices, there are a few Apps Script specific ways you can leverage this multi-environment approach.
If you are going to use this approach, here are three best practices to consider:
The provided sample shows a simple example of how a base configuration class could allow a developer to inject their local values for their own debugging and testing. In this case, the developer also added the annotation @NotOnlyCurrentDoc, which tells Apps Script that they need the full scope for Drive API access. In this project, the “production” deployment has the annotation @OnlyCurrentDoc, which leads to the OAuth scope that is limited to the document associated with script running as Sheets, Docs, or Forms add-on. If you add a standard file pattern to the source project’s “ignore” file, these developer-specific files will never get into the actual codebase.
Benefits for your project — Production can have more limited OAuth scopes, while a developer can use broader access during development. Developers can also have their own personal configuration settings to support their individual development efforts.
While there is no current way to trigger tests in an automated way, you still may want to author unit tests that validate specific functions within your projects. You’ll also likely have specific configuration values for testing. Once again, none of these files should make it into a production deployment. You can even use the Apps Script Execution API to drive those tests from a test runner!
Benefits for your project — You can author test functions, and keep them separate from the production Apps Script file. This slims down your production Apps Script project, and keeps the correct OAuth scopes that are needed for production users.
If you are developing an add-on for Sheets or Docs, and you expect to have an “active” item on the SpreadsheetApp. However when you are developing or testing, you may be running your Apps Script without an “active” context. If you need to develop in this mode, you can wrap the call to get the current active item in a method that also can determine what mode you are running in. This would allow your development or test instance to inject the ID of an “active” document to use for testing, while delegating to the getActive* result when running in a real context.
Benefits for your project — You can integrate better unit testing methodologies into your projects, even if the end deployment state dependents on resources that aren’t typically available when debugging.
You now have the option to use your own development and source management tools. While you still do need to use the Apps Script editor in your application’s lifecycle — to publish as a web app or add-on, configure advanced services, etc. — taking this step will help you get the most out of the power of the Apps Script platform. Remember to check out Apps Script on the Google Developers site to get more information and samples for your Apps Script development.
If you happen to use python tools on the command line to facilitate your team’s build process, you can check out Joe Stump's python-gas-cli. You can view the package info here or the GitHub repo where you’ll also find usage instructions.
Here are some additional reference links related to this post:
Posted by Andrew Garrett, Software Engineer, Classroom API and Michael Stillwell, Developer Advocate, Google Apps
By popular developer request, the Classroom Share Button now supports JavaScript callbacks and a question post type (in addition to announcements and assignments).
The following callbacks are supported:
The callbacks are supported by both the share tag and the JavaScript API, and they work on all supported browsers except Internet Explorer.
What can you use this for? There's a bunch of different things you can do, but to get you started, here are some suggestions:
Finally, if you want to fully control the appearance and behavior of the share button (and don't need the callbacks), you can customize the Classroom icon (as long as it still meets our branding guidelines) and initiate the share via a URL of the form:
As ever, please continue asking questions (or answering them!) on StackOverflow (use the google-classroom tag) and report bugs and feature requests via the Classroom API bug tracker.