addresses = GMAIL.users().settings().sendAs().list( userId='me' ).execute().get('sendAs')
{ "sendAs": [{ "sendAsEmail": string, "displayName": string, "replyToAddress": string, "signature": string, "isPrimary": boolean, "isDefault": boolean, "treatAsAlias": boolean, "smtpMsa": { "host": string, "port": integer, "username": string, "password": string, "securityMode": string }, "verificationStatus": string }, ...] }
addresses = GMAIL.users().settings().sendAs().list( userId='me', fields='sendAs(sendAsEmail,isPrimary)' ).execute().get('sendAs')
Posted by Wesley Chun (@wescpy), Developer Advocate, G Suite
Email continues to be a dominant form of communication, personally and professionally, and our email signature serves as both a lightweight introduction and a business card. It's also a way to slip-in a sprinkling of your personality. Wouldn't it be interesting if you could automatically change your signature whenever you wanted without using the Gmail settings interface every time? That is exactly what our latest video is all about.
If your app has already created a Gmail API service endpoint, say in a variable named GMAIL, and you have the YOUR_EMAIL email address whose signature should be changed as well as the text of the new signature, updating it via the API is as pretty straightforward, as illustrated by this Python call to the GMAIL.users().settings().sendAs().patch() method:
GMAIL
YOUR_EMAIL
GMAIL.users().settings().sendAs().patch()
signature = {'signature': '"I heart cats." ~anonymous'} GMAIL.users().settings().sendAs().patch(userId='me', sendAsEmail=YOUR_EMAIL, body=signature).execute()
For more details about the code sample used in the requests above as well as in the video, check out the deepdive post. In addition to email signatures, other settings the API can modify include: filters, forwarding (addresses and auto-forwarding), IMAP and POP settings to control external email access, and the vacation responder. Be aware that while API access to most settings are available for any G Suite Gmail account, a few sensitive operations, such as modifying send-as aliases or forwarding, are restricted to users with domain-wide authority.
Developers interested in using the Gmail API to access email threads and messages instead of settings can check out this other video where we show developers how to search for threads with a minimum number of messages, say to look for the most discussed topics from a mailing list. Regardless of your use-case, you can find out more about the Gmail API in the developer documentation. If you're new to the API, we suggest you start with the overview page which can point you in the right direction!
Be sure to subscribe to the Google Developers channel and check out other episodes in the G Suite Dev Show video series.
Posted by Michael Winser, Product Lead, Google Apps and Wesley Chun, Developer Advocate, Google Apps
Last week, we clarified the expectations and responsibilities when accessing Google user data via OAuth 2.0. Today, we’re announcing that in order to better protect users, we are increasing account security for enterprise Gmail users effective October 5, 2016. At this time, a new policy will take effect whereby users in a Google Apps domain, while changing their passwords on or after this date, will result in the revocation of the OAuth 2.0 tokens of apps that access their mailboxes using Gmail-based authorization scopes. Please note that users will not notice any specific changes on this date and their applications will continue to work. It is only when a user changes their password from that point moving forward that their Gmail-related tokens become invalid.
Developers should modify their applications to handle HTTP 400 or 401 error codes resulting from revoked tokens and prompt their users to go through the OAuth flow again to re-authorize those apps, such that they can access the user’s mailbox again (additional details below). Late last year, we announced a similar, planned change to our security policy that impacted a broader set of authorization scopes. We later decided not to move forward with that change for Apps customers and began working on a less impactful update as described above.
What is a revoked token?
A revoked OAuth 2.0 token no longer provides access to a user’s resources. Any attempt to use a revoked token in API calls will result in an error. Any existing token strings will no longer have any value and should be discarded. Applications accessing Google APIs should be modified to handle failed API calls.
Token revocation itself is not a new feature. Users have always been able to revoke access to applications in Security Checkup, and Google Apps admins have the ability to do the same in the Admin console. In addition, tokens that were not used for extended periods of time have always been subject to expiration or revocation. This change in our security policy will likely increase the rate of revoked tokens that applications see, since in some cases the process will now take place automatically.
What APIs and scopes are impacted?
To achieve the security benefits of this policy change with minimal admin confusion and end-user disruption, we’ve decided to limit its application to mail scopes only and to exclude Apps Script tokens. Apps installed via the Google Apps Marketplace are also not subject to the token revocation. Once this change is in effect, third-party mail apps like Apple Mail and Thunderbird―as well as other applications that use multiple scopes that include at least one mail scope―will stop accessing data upon password reset until a new OAuth 2.0 token has been granted. Your application will need to detect this scenario, notify the user that your application has lost access to their account data, and prompt them to go through the OAuth 2.0 flow again.
Mobile mail applications are also included in this policy change. For example, users who use the native mail application on iOS will have to re-authorize with their Google account credentials when their password has been changed. This new behavior for third-party mail apps on mobile aligns with the current behavior of the Gmail apps on iOS and Android, which also require re-authorization upon password reset.
How can I determine if my token was revoked?
Both short-lived access tokens and long-lived refresh tokens will be revoked when a user changes their password. Using a revoked access token to access an API or to generate a new access token will result in either HTTP 400 or 401 errors. If your application uses a library to access the API or handle the OAuth flow, then these errors will likely be thrown as exceptions. Consult the library’s documentation for information on how to catch these exceptions. NOTE: because HTTP 400 errors may be caused by a variety of reasons, expect the payload from a 400 due to a revoked token to be similar to the following:
{ "error_description": "Token has been revoked.", "error": "invalid_grant" }
How should my application handle revoked tokens?
This change emphasizes that token revocation should be considered a normal condition, not an error scenario. Your application should expect and detect the condition, and your UI should be optimized for restoring tokens.
To ensure that your application works correctly, we recommend doing the following:
If your application uses incremental authorization to accrue multiple scopes in the same token, you should track which features and scopes a given user has enabled. The end result is that if your app requested and obtained authorization for multiple scopes, and at least one of them is a mail scope, that token will be revoked, meaning you will need to prompt your user to re-authorize for all scopes originally granted.
Many applications use tokens to perform background or server-to-server API calls. Users expect this background activity to continue reliably. Since this policy change also affects those apps, this makes prompt notification requesting re-authorization even more important.
What is the timeline for this change?
To summarize, properly configured applications should be expected to handle invalid tokens in general, whether they be from expiration, non-existence, and revocation as normal conditions. We encourage developers to make any necessary changes to give their users the best experience possible. The policy change is planned to take effect on October 5, 2016.
Please see this Help Center article and FAQ for more details and the full list of mail scopes. Moving forward, any additional scopes to be added to the policy will be communicated in advance. We will provide those details as they become available.
Posted by Brandon Jewett-Hall, Software Engineer, Gmail and Wesley Chun, Developer Advocate, Google Apps
If you've been pining for a way to update your users' email signatures with a different inspirational quote each day or enable "Out of Office" auto-replies when their calendars are marked as busy, then you're in luck. Today, we're extending the Gmail API with new endpoints for managing settings. These new endpoints cover the following features:
With this update, we're equipping developers with some new tools that have never been available in any previous Google API. These include the ability to:
Over time we'll continue to expand the API with additional settings features such as support for managing mailbox delegates, so stay tuned for more announcements.
Get started now
Most of the settings endpoints are available for any Google Apps or Gmail account, but a few sensitive operations, such as modifying send-as aliases or forwarding, are restricted to service accounts with domain-wide authority. See the reference docs for more details and to get started.
What about the existing Email Settings API in the Admin SDK?
This update to the Gmail API effectively replaces the older Email Settings API, so we're also announcing its deprecation today and will turn it down fully on July 7, 2017. We've put together a migration guide to assist clients in porting their existing integrations over to their newer counterparts in the Gmail API. If you have any issues, check out the gmail-api tag on StackOverflow.
We look forward to seeing what you build with these new features in the Gmail API!
If your app needs to keep up with changes in a Gmail mailbox, whether it's new mail being received or a label being added, you are likely familiar with periodically polling the Gmail API's history feed for updates. If you find this tedious, we have good news for you. Today, at Google I/O 2015, we're launching push notifications for the Gmail API.
Just subscribe to a Gmail mailbox and whenever a change occurs, the Gmail API will instantly notify your server using webhooks or another Cloud Pub/Sub API notification method. No polling required.
Check out the developers’ guide at https://developers.google.com/gmail/api/guides/push to get started. We can’t wait to see what you build.
Posted by Eric DeFriez, Gmail Extensibility Team. As a technical lead for Gmail APIs, Eric works to make it easy for developers to build on top of Gmail.
Posted by Wesley Chun, Developer Advocate, Google Apps
Last summer, we launched the new Gmail API, giving developers more flexible, powerful, and higher-level access to programmatic email management, not to mention improved performance. Since then, it has been expanded to replace the Google Apps Admin SDK's Email Migration API (EMAPI v2). Going forward, we recommend developers integrate with the Gmail API.
EMAPI v2 will be turned down on November 1, 2015, so you should switch to the Gmail API soon. To aid you with this effort, we've put together a developer’s guide to help you migrate from EMAPI v2 to the Gmail API. Before you do that, here’s your final reminder to not forget about these deprecations including EMAPI v1, which are coming even sooner (April 20, 2015).
We launched Actions in the Inbox at Google I/O 2013 as a quick way for users to get things done directly from Gmail. Integrating with this technology only requires adding some markup to an email to define what the message is about and what actions the user can perform.
We support a variety of action types covering common scenarios such as adding a movie to a queue, product reviews, or other even pre-defined requests. Especially popular with senders is the One-Click Action to validate a user’s email address, as shown below:
If you are using Mandrill, the email infrastructure service from MailChimp, writing a Python app to send one of those emails, only takes a few lines of code! Take a look at this example:
import mandrill # Replace with your own values API_KEY = 'YOUR_API_KEY' FROM_ADDRESS = 'YOUR_FROM_ADDRESS' TO_ADDRESS = 'YOUR_TO_ADDRESS' SUBJECT = 'Please validate your email address' HTML_CONTENT = """ <html> <body> <script type='application/ld+json'> { "@context": "http://schema.org", "@type": "EmailMessage", "action": { "@type": "ConfirmAction", "name": "Confirm Registration", "handler": { "@type": "HttpActionHandler", "url": "https://mydomain.com/validate?id=abc123" } } } </script> <p>Please click on this link to validate your email address:</p> <p><a href="https://mydomain.com/validate?id=abc123">https://mydomain.com/validate?id=abc123</a></p> </body> </html> """ # Instantiate the Mandrill client with your API Key mandrill_client = mandrill.Mandrill(API_KEY) message = { 'html': HTML_CONTENT, 'subject': SUBJECT, 'from_email': FROM_ADDRESS, 'to': [{'email': TO_ADDRESS}], } result = mandrill_client.messages.send(message=message)
To run this app, just replace the API key with the credentials from your Mandrill account and configure the sender and recipient addresses. You should also edit the HTML content to provide your action handler URL, and customize the messaging if you want.
You can use Actions in the Inbox to reduce the friction and increase the conversion rate. Please note that you are not limited to validating email addresses: you can also review products and services, reply to event invitations, and much more.
For more information, please visit our documentation at https://developers.google.com/gmail/actions. You can also ask questions on Stack Overflow, with the tag google-schemas.
Search engines have been using structured data for years to understand the information on web pages and provide richer search results. Today, we are introducing schemas in emails to make messages more interactive and allow developers to deliver a slice of their apps to users’ inboxes.
Schemas in emails can be used to represent various types of entities and actions. Email clients that understand schemas, such as Gmail, can render entities and actions defined in the messages with a consistent user interface. In the case of Gmail, this means that the emails can display quick action buttons that let users take actions directly from their inboxes, as in the following screenshot:
Using schemas to add quick action buttons to the emails you send is easy. All it takes is adding some markup to your HTML emails, together with your regular content, in one of the supported formats - Microdata and JSON-LD.
As an example, the following JSON-LD markup can be used to define a movie and the corresponding one-click action to add the movie to your queue:
<script type="application/ld+json"> { "@context": "schema.org", "@type": "Movie", "name": "The Internship", ... information about the movie ... "action": { "@type": "ConfirmAction", "name": "Add to queue", "actionHandler": { "@type": "HttpActionHandler", "url": "https://my-movies.com/add?movieId=123", "method": "POST", } } } </script>
Gmail renders the markup above with a button labelled “Add to queue” next to the email subject line. When the user clicks on the button, Gmail sends a POST request to the url specified in the action handler. Your app has to handle these requests and respond to the email client with an appropriate HTTP response code (200 for successful requests, 400 for invalid requests, etc.).
Schemas in emails currently support four different types of actions - rate/review, RSVP, one-click action and goto link - and we plan to add more types moving forward. We are collaborating with a number of partners who will launch their integrations in the coming weeks, making the messages they send more useful and interactive for Gmail users. For example, Esna is using this to inform users of missed calls and provide them with a one-click button to be called again, while Seamless is implementing the rate/review action to collect feedback about restaurants.
Other partners who are already implementing schemas in email today include both Billguard, Concur Technologies, Docusign, HelloSign, Insight.ly, Mailchimp, myERP, Netflix, OpenTable, Orangescape, Paperless Post, Spotify, SugarCRM, and Tripit.
To learn more about all supported entities and actions and to find out how to get started with schemas in email, visit http://developers.google.com/gmail.
Gmail servers support the standard IMAP and POP protocols for email retrieval but sometimes you only need to know whether there are any new messages in your inbox. Using any of the two protocols mentioned above may seem like an overkill in this scenario and that’s why Gmail also exposes a read only feed called Gmail Inbox Feed which you can subscribe to and get the list of unread messages in your inbox.
The Gmail Inbox Feed is easily accessible by pointing your browser to https://mail.google.com/mail/feed/atom and authenticating with your username and password if you are not already logged in.
Using basic authentication to access the inbox feed doesn’t provide a very good user experience if we want delegated access. In that case, we should instead rely on the OAuth authorization standard, which is fully supported by the Gmail Inbox Feed.
OAuth supports two different flows. With 3-legged OAuth, an user can give access to a resource he owns to a third-party application without sharing his credentials. The 2-legged flow, instead, resembles a client-server scenario where the application is granted domain-wide access to a resource.
Let’s write a .NET application that uses 2-legged OAuth to access the Gmail Inbox Feed for a user in the domain and list unread emails. This authorization mechanism also suits Google Apps Marketplace developers who want to add inbox notifications to their applications.
There is no dedicated client library for this task and the Inbox Feed is not based on the Google Data API protocol but we’ll still use the .NET library for Google Data APIs for its OAuth implementation.
First, create a new C# project and add a reference to the Google.GData.Client.dll released with the client library. Then add the following using directives to your code:
using System; using System.Linq; using System.Net; using System.Net.Mail; using System.Xml; using System.Xml.Linq; using Google.GData.Client;
The next step is to use 2-legged OAuth to send an authorized GET request to the feed URL. In order to do this, we need our domain’s consumer key and secret and the username of the user account we want to access the inbox feed for.
string CONSUMER_KEY = "mydomain.com"; string CONSUMER_SECRET = "my_consumer_secret"; string TARGET_USER = "test_user"; OAuth2LeggedAuthenticator auth = new OAuth2LeggedAuthenticator("GmailFeedReader", CONSUMER_KEY, CONSUMER_SECRET, TARGET_USER, CONSUMER_KEY); HttpWebRequest request = auth.CreateHttpWebRequest("GET", new Uri("https://mail.google.com/mail/feed/atom/")); HttpWebResponse response = request.GetResponse() as HttpWebResponse;
The response is going to be a standard Atom 0.3 feed, i.e. an xml document that we can load into an XDocument using the standard XmlReader class:
XDocument
XmlReader
XmlReader reader = XmlReader.Create(response.GetResponseStream()); XDocument xdoc = XDocument.Load(reader); XNamespace xmlns = "http://purl.org/atom/ns#";
All the parsing can be done with a single LINQ to XML instruction, which iterates the entries and instantiates a new MailMessage object for each email, setting its Subject, Body and From properties with the corresponding values in the feed:
MailMessage
Subject
Body
From
var messages = from entry in xdoc.Descendants(xmlns + "entry") from author in entry.Descendants(xmlns + "author") select new MailMessage() { Subject = entry.Element(xmlns + "title").Value, Body = entry.Element(xmlns + "summary").Value, From = new MailAddress( author.Element(xmlns + "email").Value, author.Element(xmlns + "name").Value) };
At this point, messages will contain a collection of MailMessage instances that we can process or simply dump to the console as in the following snippet:
Console.WriteLine("Number of messages: " + messages.Count()); foreach (MailMessage entry in messages) { Console.WriteLine(); Console.WriteLine("Subject: " + entry.Subject); Console.WriteLine("Summary: " + entry.Body); Console.WriteLine("Author: " + entry.From); }
If you have any questions about how to use the Google Data APIs .NET Client Library to access the Gmail Inbox Feed, please post them in the client library discussion group.
var MARK_UNREAD = false; var ADD_UNSNOOZED_LABEL = false;
setup()
function getLabelName(i) { return "Snooze/Snooze " + i + " days"; } function setup() { // Create the labels we’ll need for snoozing GmailApp.createLabel("Snooze"); for (var i = 1; i <= 7; ++i) { GmailApp.createLabel(getLabelName(i)); } if (ADD_UNSNOOZED_LABEL) { GmailApp.createLabel("Unsnoozed"); } }
function moveSnoozes() { var oldLabel, newLabel, page; for (var i = 1; i <= 7; ++i) { newLabel = oldLabel; oldLabel = GmailApp.getUserLabelByName(getLabelName(i)); page = null; // Get threads in "pages" of 100 at a time while(!page || page.length == 100) { page = oldLabel.getThreads(0, 100); if (page.length > 0) { if (newLabel) { // Move the threads into "today’s" label newLabel.addToThreads(page); } else { // Unless it’s time to unsnooze it GmailApp.moveThreadsToInbox(page); if (MARK_UNREAD) { GmailApp.markThreadsUnread(page); } if (ADD_UNSNOOZED_LABEL) { GmailApp.getUserLabelByName("Unsnoozed") .addToThreads(page); } } // Move the threads out of "yesterday’s" label oldLabel.removeFromThreads(page); } } } }
GmailApp
GmailApp.search()
DocumentApp
DocsList.find()
File.getId()
Document.saveAndClose()
Posted by Corey Goldfeder, Google Apps Script Team
Want to weigh in on this topic? Discuss on Buzz
Dan Holevoet, Google Developer Team
Posted by Ryan Boyd, Google Apps Marketplace Team