Developing Gmail contextual gadgets
In my last article, we explored How to develop Gmail sidebar gadgets. In today’s article we’ll take a closer look at what is involved in creating a contextual gadget for Gmail. Gmail contextual gadgets are a good way to add additional functionality to Gmail allowing your user to perform tasks right from inside their Gmail session.
Contextual gadget components
A contextual gadget is essentially made up of the following 3 parts:
The Manifest
The manifest file is used to describe the structure and content of an application. The manifest file is the starting point for any contextual Gmail gadget. Our sample contextual gadget will scan the body text of an e-mail for a number of key words and return a search result from the Add-in Express forums and blog posts. Our manifest file for the sample google gadget will look like the following:
<?xml version="1.0" encoding="UTF-8" ?> <ApplicationManifest xmlns="https://schemas.google.com/ApplicationManifest/2009"> <Name>ADX Answers</Name> <Description> Answers to Add-in Express questions inside your e-mail. </Description> <Extension id="ADXExtractor" type="contextExtractor"> <Name>ADX Stuff</Name> <Url>google.com:EmailBodyExtractor</Url> <Triggers ref="ADXGadget"/> <Scope ref="emailBody"/> <Container name="mail"/> </Extension> <Extension id="ADXGadget" type="gadget"> <Name>Add-in Express Gmail contextual gadget</Name> <Url>https://www.coalitionsoft.net/context-gadget.xml</Url> <Container name="mail"/> </Extension> <Scope id="emailBody"> <Url>tag:google.com,2010:auth/contextual/extractor/BODY</Url> <Reason> This application searches the message body of each email for text related to Add-in Express products. </Reason> </Scope> </ApplicationManifest>
In the manifest file, we specified the name and description of our application. We also created a new extension called ADXExtractor which will extract content from the e-mail message body. This is accomplished by creating a <Extension> element and setting its child <Url> element’s text to google.com:EmailBodyExtractor, the <Scope> element’s ref attribute to emailBody and the <Container> element’s name attribute to mail. Next, we’ll specify another extension, which will be a reference to our gadget spec. All we need to set for the gadget extension is the <Name> element and the <Url>. The gadget should be hosted on a publicly available server. Finally, add a <Scope> element to indicate which part of the e-mail the gadget needs to access. This is also used to show the user information about the gadget when they are installing it, as illustrated below:
Extractors
A contextual gadget is triggered based on text matches found in one of the following e-mail fields:
- From
- To
- Subject
- Email message body
Matching is accomplished using an extractor. You have a choice of building your own extractor or to simply use one of Google’s pre-canned extractors. Google supplies us with 15 extractors out of the box:
ID | Description |
google.com:EmailAddressExtractor | Finds e-mail address in the subject and message body of the e-mail. |
google.com:EmailBodyExtractor | Retrieves the first 1000 characters from the e-mail body. |
google.com:EmailTimeExtractor | Retrieves the sent/receive time of the e-mail. |
google.com:HelloWorld | Finds “Hello World” in the body and subject fields of the e-mail message (Case insensitive) |
google.com:HttpLinkExtractor | Returns links to HTTP and HTTPS address inside the message subject and body. |
google.com:ListExtractor | Finds the list ID and unsubscribe link/e-mail address inside the message. |
google.com:MessageIDExtractor | Returns the Gmail internal message id |
google.com:RawSubjectExtractor | Returns the e-mail’s subject line. It contains all annotations such as FW: and RE: |
google.com:RecipientCCEmailExtractor | Returns all the e-mail address inside the CC fields |
google.com:RecipientEmailExtractor | Returns all e-mail address for the e-mail, including the TO and CC fields. |
google.com:RecipientToEmailExtractor | Only return e-mail addresses inside the TO field of the e-mail. |
google.com:SenderEmailExtractor | Returns the sender’s e-mail address. This value is stored in the FROM field of the e-mail. |
google.com:SubjectExtractor | Returns the subject of the e-mail with all annotations (FW, RE, etc.) removed. |
google.com:USPhoneExtractor | Returns all US based phone numbers inside the e-mail message. The format for the phone numbers are : ((1) 800 ) 555-1234) |
google.com:USStockTicker | Matches US stock symbols in the body and subject fields of the e-mail message. |
Gadget Spec
The gadget spec is the same type of file we used for creating the sidebar gadget and contains the settings and actual JavaScript, CSS and HTML code that makes up the gadget. The spec consists of a <ModulePrefs> element, which is used to specify the gadget’s settings. With contextual gadgets you should always include the <Require> element to specify that the gadget depends on the google.contentmatch feature. The <Content> element contains the actual Html, CSS and JavaScript for your gadget and its type attribute should always be set to html and its view attribute to card.
The code for our gadget spec follows below:
<?xml version="1.0" encoding="UTF-8"?> <Module> <ModulePrefs title="Add-in Express Answers" description="You ask, ADX answers!" height="20" author="Add-in Express" author_email="add-in-express.com" author_location="Poland"> <Require feature="dynamic-height"/> <Require feature="google.contentmatch"> <Param name="extractors"> google.com:EmailBodyExtractor </Param> </Require> </ModulePrefs> <Content type="html" view="card"> <![CDATA[ <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <div id="links" class="list-group"> </div> <script type="text/javascript"> matches = google.contentmatch.getContentMatches(); var bodyText = matches[0]["email_body"]; var result1 = /^.*\b(create|build|program|develop|office|add-in|plug in|addon)\b.*$/.test(bodyText); var result2 = /^.*\b(handle|trap|intercept|get|newmail)\b.*$/.test(bodyText); var result3 = /^.*\b(add|create|build|program|develop|outlook|task pane|region)\b.*$/.test(bodyText); var result4 = /^.*\b(add|create|build|program|develop|excel|function)\b.*$/.test(bodyText); var result5 = /^.*\b(add|create|build|program|develop|word|button|ribbon|tab)\b.*$/.test(bodyText); var params = {}; params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON; if (result1){ var url = "//www.add-in-express.com/search-addin-json.php?q=create%20build%20program%20develop%20Outlook%20add-in%20plug%20in%20addon"; } else if (result2) { var url = "//www.add-in-express.com/search-addin-json.php?q=handle%20trap%20intercept%20get%20newmail"; } else if (result3) { var url = "//www.add-in-express.com/search-addin-json.php?q=add%20create%20build%20program%20develop%20outlook%20task%20pane%20region"; } else if (result4) { var url = "//www.add-in-express.com/search-addin-json.php?q=add%20create%20build%20program%20develop%20excel%20functions"; } else if (result5) { var url = "//www.add-in-express.com/search-addin-json.php?q=add%20create%20build%20program%20develop%20word%20button%20ribbon%20tab"; } gadgets.io.makeRequest(url, loadData, params); gadgets.window.adjustHeight(400); function loadData(obj) { var items = obj.data.result; for (var i = 0; i < items.length; i++) { var item = items[i]; $("#links").append('<a href="' + item.link + '" target="_blank" class="list-group-item"><h4 class="list-group-item-heading">' + item.title + '</h4><p class="list-group-item-text">' + item.body + '</p></a>'); } } </script> ]]> </Content> </Module>
In our gadget code above, we first included references to the Bootstrap library’s CSS style sheet – we’ll use Bootstrap to style our user interface components. We have also included a reference to the jQuery library in order to make it easier to manipulate the DOM. Next, we’ve created an empty <div> element, which will contain the search results. We then called the getContentMatches function, in order to get a reference to the message body, using the following code:
matches = google.contentmatch.getContentMatches();
Using a number of regular expressions, we checked whether the message body contained a number of pre-set search strings and then passed the search query to our search function on the Add-in Express site. To request JSON data from an external server, you’ll need to use the makeRequest method and set its ContentType parameter to JSON. We’ve also specified that the callback method is called loadData and this method will receive the data back from the Add-in Express search service and add the items to the “links” <div> element.
Deploying Google contextual gadget
Before we can test our google gadget, we need to deploy it. First sign into your console at: https://code.google.com/googleapps/console/a/mydomain.com. Substituting the mydomain.com part with your own domain name. After you’re logged in, create a new project by clicking on the “Create project…” button.
When prompted, enter a name for your new project:
Next, upload the manifest file we’ve created earlier. If it is in the correct format, it should display the application name and description as illustrated below:
With the manifest file uploaded, we’re ready to deploy the application. Do this by clicking on the “Deploy Application…” button.
A new window will open, prompting you to grant data access for the application. Click on the “Grant data access” button to proceed. A confirmation message should pop up and indicate that your application was successfully installed on your domain.
Testing your Gmail contextual gadget
After you’ve deployed your application, you can log into your Gmail account and if a message contains the appropriate words, our contextual gadget will display the Add-in Express search results below the message, as illustrated in the following image:
Thank you for reading. Until next time, keep coding!
Available downloads:
Google Gmail Contextual Gadget script
20 Comments
Hi there. I tried using your manifest but ran into a problem with OAuth. It says Application Installation not allowed. OAuth1.0 version no longer available. Instead, try installing the OAuth 2.0 version. Any ideas on how to get around this?
Hi Frederick,
Can you elaborate a bit more please? Where/when exactly do you get the OAuth message?
Hi there,
I have the same problem for the OAuth 1.0. I was used to be able to deploy my gadget without any problem. Recently, after I uploaded the manifest and click “Deploy application” button, I got an error which said that “The OAuth1.0 version is no longer available. Instead, try installing the OAuth2.0 version”.
Is there anything I can do to resolve this issue?
Thank you.
I’m having the same issue. When I upload the manifest and then click the ‘Deploy Application’ button, I get the message “Application installation not allowed.
The OAuth1.0 version is no longer available. Instead, try installing the OAuth2.0 version. ”
Any ideas?
Thanks
Same issue,
The OAuth1.0 version is no longer available. Instead, try installing the OAuth2.0 version.
any suggestion?
Thanks
Roberto
Hi All,
It appears Google has changed a lot with regards to contextual gadget. They’ve also implemented a new developer console.
I’ll investigate and let you know what I come up with.
Thank you!
Hi,
I found the solution creating the project within Google APIs console and the MarketPlace SDK, no more needs to create xml files…
Now I have a new question, using google.contentmatch.getContentMatches I can get the email body, but is there a way to get and set email labels direct from the gadget, without to call Gmail apis?
Thanks
Hi Roberto,
Thanks for letting us know!
I haven’t been able to find a way to set email labels. It appears not to be possible, although I could be wrong :)
Any updates for this? This example doesn’t seem to be functional anymore.
Hi Josh,
Google has changed their API and the process for creating gadgets. Unfortunately we do not have any updates for this article yet.
However, you can read more about using the Google Marketplace SDK on https://developers.google.com/apps-marketplace/preparing
Thanks for the comment.
thats great that you maybe will update the article, great news! I am waiting for it.
Hi Everyone,
I am trying to create a gmail contextual gadget which allows set of users to access the gadget but I am totally confused with new Oauth2.0 . I am unable to find any Information.
Could any one can help me In this..
how to create a manifest file and pointing to the project gadget location
Hi Rajkumar,
Unfortunately, its been a while since I worked with Gmail gadgets and things have changed somewhat.
You can read more about using OAuth to access the Google API’s here.
Hope this helps! Good luck!
Hi,
I found the solution creating the project within Google APIs console and the MarketPlace SDK, no more needs to create xml files…
Now I have a new question, using google.contentmatch.getContentMatches I can get the email body, but is there a way to get and set email labels direct from the gadget, without to call Gmail apis?
Thanks
Hi vishwas,
As far as I could determine, the only way to set email labels is via the api
How can we get CC and BCC email ids from the Gmail contextual gadget?
I am literally struggling with this problem.
Any help greatly appreciated
How can we get CC and BCC email ids from the Gmail contextual gadget?
I am literally struggling with this problem.
Any help greatly appreciated
Hi There,
Have a look at this article. It show how to create an extractor. One of the extractor’s scope is emailCC. I don’t think it is possible to get the BCC field.
Hi Peiter,
I have used this post to develop a contextual gadget before 1 year and it was useful for me that time. But now I want to develop another contextual gadget and I am not getting help to develop it. As google has deprecated the old process to develop the gadget.
Can you please help us to develop a new contextual gadget?
Hello Guarav,
No, we can’t. We just don’t have resources. Sorry to be of no help.