0

I am trying to write a GMAIL contextual gadget. I am ready with all the building blocks (services , gadgets, manifest.repositories...) basic hello world is working fine.

To simplify lets say, " I have a Mark as favorite " functionality in my widget

I would be needing to store (in my SQL database) some object against some marked as favorite mails.

And as the mails would open, my widget would load and now i want to make an ajax call to my database and check if "this particular mail" is a favorite mail or not.

ques : I just require a Unique message id in my java-script so that whenever any user marks an email as favorite. I would store that unique message id in the favorite list in my database.

the manifest


<?xml version="1.0" encoding="UTF-8" ?>
<ApplicationManifest xmlns="http://schemas.google.com/ApplicationManifest/2009">

<!-- Support info to show in the marketplace & control panel -->
<Support>
<!-- URL for application setup as an optional redirect during the install -->
<Link rel="setup" href="https://www.google.com" />

<!-- URL for application configuration, accessed from the app settings
 page in the control panel -->
<Link rel="manage" href="https://www.google.com" />

<!-- URL explaining how customers get support. -->
<Link rel="support" href="https://www.google.com" />

<!-- URL that is displayed to admins during the deletion process,
 to specify policies such as data retention, how to claim accounts, etc. -->
<Link rel="deletion-policy" href="https://www.google.com" />
</Support>

<!-- Name and description pulled from message bundles -->
<Name>HelloWorld</Name>
<Description>A simple Hello World application for testing
Gmail contextual gadgets</Description>

<!-- Show this link in Google's universal navigation for all users -->
<Extension id="navLink" type="link">
<Name>HelloWorld</Name>
<Url>http://www.google.com</Url>
</Extension>

<!-- Declare our OpenID realm so our app is white listed -->
<Extension id="realm" type="openIdRealm">
<Url>http://_example.com_</Url>
</Extension>

<!-- EXTRACTOR -->

<Extension id="HelloWorldExtractor" type="contextExtractor">
<Name>Hello World</Name>
<Url>google.com:HelloWorld</Url>
<!-- Uncomment this Param to apply a filter to the extractor's
default output. The example regexp below makes the match case sensitive.
<Param name="hello" value="H[a-z]* W[a-z]*"/> -->
<Triggers ref="HelloWorldGadget"/>
<Scope ref="emailSubject"/>
<Scope ref="emailBody"/>
<Container name="mail"/>
</Extension>

<!-- GADGET -->

<Extension id="HelloWorldGadget" type="gadget">
  <Name>Hello World Gmail contextual gadget</Name>
  <Url>mydomain/widget-module.xml</Url>
  <Container name="mail"/>
  <!-- Uncomment this to enable Caja. -->
  <!-- <Param name="caja" value="enabled"/> -->
</Extension>

<!-- SCOPE -->

<Scope id="emailSubject">
<Url>tag:google.com,2010:auth/contextual/extractor/SUBJECT</Url>


 <Reason>This application searches the Subject: line of each email
  for the text "Hello World."</Reason>
</Scope>

<Scope id="emailBody">
  <Url>tag:google.com,2010:auth/contextual/extractor/BODY</Url>
  <Reason>This application searches the message body of each email
  for the text "Hello World."</Reason>
</Scope>

</ApplicationManifest>

the widget

    <?xml version="1.0" encoding="UTF-8"?>
<Module>

<ModulePrefs title="Hello World"
    description="Matches and echoes 'Hello World' string in emails"
    height="20"
    author="Sarah M and Walter Q"
    author_email="..."
    author_location="Mountain View, CA">

    <!-- Declare feature dependencies. -->

    <!-- This one is not specific to Gmail contextual gadgets. -->
    <Require feature="dynamic-height"/>

    <!-- The next feature, Caja, is optional, and is supported for
     use only within test domains. Uncomment the tag only for
     non-production gadgets. -->
    <!-- <Require feature="caja"/> -->

    <!-- The next feature, google.contentmatch, is required for all
     Gmail contextual gadgets.
     <Param> - specify one or more comma-separated extractor IDs in
     a param named "extractors". This line is overridden by the extractor ID
     in the manifest, but is still expected to be present. -->
    <Require feature="google.contentmatch">
      <Param name="extractors">
        google.com:HelloWorld
      </Param>
    </Require>

  </ModulePrefs>

  <!-- Define the content type and display location. The settings
   "html" and "card" are required for all Gmail contextual gadgets. -->
  <Content type="html" view="card">
    <![CDATA[
      <!-- Start with Single Sign-On -->
      <script type="text/javascript" src="https://example.com/gadgets/sso.js"></script>
      <script type="text/javascript">

        <!-- Fetch the array of content matches. -->
        matches = google.contentmatch.getContentMatches();
        var matchList = document.createElement('UL');
        var listItem;
        var extractedText;

    //**I JUST WANT THE UNIQUE MESSAGE ID OVER HERE**

        <!-- Iterate through the array and display output for each match. -->
        for (var match in matches) {
          for (var key in matches[match]) {
            listItem = document.createElement('LI');
            extractedText = document.createTextNode(key + ": " + matches[match][key]);
            listItem.appendChild(extractedText);
            matchList.appendChild(listItem);
          }
        }
        document.body.appendChild(matchList);
        gadgets.window.adjustHeight(100);
      </script>
    ]]>
  </Content>
</Module>

I just need some unique message if over here:

//I JUST WANT THE UNIQUE MESSAGE ID OVER HERE

EDIT ==============================================================================

As suggested I have made the following changes :

My Manifest :

 <?xml version="1.0" encoding="UTF-8" ?>
<ApplicationManifest xmlns="http://schemas.google.com/ApplicationManifest/2009">

  <!-- Support info to show in the marketplace & control panel -->
  <Support>
    <!-- URL for application setup as an optional redirect during the install -->
    <Link rel="setup" href="https://www.google.com" />
    <!-- URL for application configuration, accessed from the app settings
     page in the control panel -->
    <Link rel="manage" href="https://www.google.com" />
    <!-- URL explaining how customers get support. -->
    <Link rel="support" href="https://www.google.com" />
    <!-- URL that is displayed to admins during the deletion process,
     to specify policies such as data retention, how to claim accounts, etc. -->
    <Link rel="deletion-policy" href="https://www.google.com" />
  </Support>

  <!-- Name and description pulled from message bundles -->
  <Name>HelloWorld</Name>
  <Description>A simple Hello World application for testing
  Gmail contextual gadgets</Description>

  <!-- Show this link in Google's universal navigation for all users -->
  <Extension id="navLink" type="link">
    <Name>HelloWorld</Name>
    <Url>http://www.google.com</Url>
  </Extension>

  <!-- Declare our OpenID realm so our app is white listed -->
  <Extension id="realm" type="openIdRealm">
    <Url>http://_example.com_</Url>
  </Extension>

  <Extension id="uniqueId" type="contextExtractor">
    <Name>Custom_Extractor_7</Name>     
    <Url>sample2ForUniqueReceipients:Custom_Extractor_7</Url>       
    <Triggers ref="HelloWorldGadget" />     
    <Scope ref="senderScope" />     
    <Container name="mail" />       
</Extension> 
<!-- EXTRACTOR 
<Extension id="from" type="contextExtractor">
  <Name>Email Sender</Name>
  <Url>google.com:SenderEmailExtractor</Url>
  <Param name="sender_email" value="amalhotra@ivp.in"/>
  <Triggers ref="HelloWorldGadget"/>
  <Scope ref="senderScope"/>
  <Container name="mail"/>
</Extension>

<Extension id="MessageID" type="contextExtractor">
  <Name>Message ID Extractor</Name>
  <Url>google.com:MessageIDExtractor</Url>
  <Param name="message_id" value=".*"/>
  <Triggers ref="HelloWorldGadget"/>
  <Scope ref="messageID"/>
  <Container name="mail"/>
</Extension>
-->
<!-- GADGET -->

<Extension id="HelloWorldGadget" type="gadget">
  <Name>Hello World Gmail contextual gadget</Name>
  <Url>MY_GADGET_URL</Url>
  <Container name="mail"/>
  <!-- Uncomment this to enable Caja. -->
  <!-- <Param name="caja" value="enabled"/> -->
</Extension>

<!-- SCOPE -->

<Scope id="emailSubject">
  <Url>tag:google.com,2010:auth/contextual/extractor/SUBJECT</Url>
  <Reason>This application searches the Subject: line of each email
  for the text "Hello World."</Reason>
</Scope>

<Scope id="emailBody">
  <Url>tag:google.com,2010:auth/contextual/extractor/BODY</Url>
  <Reason>This application searches the message body of each email
  for the text "Hello World."</Reason>
</Scope>

<Scope id="messageID">
  <Url>tag:google.com,2010:auth/contextual/extractor/MESSAGE_ID</Url>
  <Reason>This application searches the message header of each email
  for the text.</Reason>
</Scope>


<Scope id="emailMessageId">
  <Url>tag:google.com,2010:auth/contextual/extractor/MESSAGE_ID</Url>
  <Reason>This would get the message id and most probalbly trigger the widget</Reason>
</Scope>


<Scope id="senderScope">
  <Url>tag:google.com,2010:auth/contextual/extractor/FROM_ADDRESS</Url>
  <Reason>This application searches the Subject: line of each email
    for the text "Hello World."</Reason>
    </Scope>


    </ApplicationManifest>

custom extractor

 <?xml version="1.0" encoding="UTF-8"?>      
<OpenCOBData id="Custom_Extractor_7">   
    <ExtractorSpec platform="gmail" language="en">
        <Search>        
            <Pattern input_fields="from_email">     
                <![CDATA[(myemailaddress@mydomain.in)]]>       
            </Pattern>      
        </Search>       

        <Response platform="gmail" format="cardgadget">     

            <Output name="id">{@__MESSAGE_ID__}</Output>        
            <Output name="sender">{@__FROM_ADDRESS__}</Output>      
            <Output name="date">{@__DATE_SENT__}</Output>       
            <Output name="to">{@__TO_ADDRESS__}</Output>        

            <!--Output name="email_subject">{@__SUBJECT__}</Output>     
            <Output name="received_date">{@__DATE_RECEIVED__}</Output-->        
        </Response>     
    </ExtractorSpec>        
</OpenCOBData>
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
ankur
  • 557
  • 1
  • 10
  • 37

3 Answers3

1

Use the message id extractor which will give you the frontend unique message id.

Extractor Detail :

ID  = google.com:MessageIDExtractor

Description = Matches the Gmail frontend message id of the message (this is a 64-bit hexadecimal value, different from the RFC 822 Message-ID)

Scope   = tag:google.com,2010:auth/contextual/extractor/MESSAGE_ID

Output Fields   = @message_id - Message ID of the message
Ankit Singla
  • 198
  • 2
  • 15
  • you can find all available extractors here: https://developers.google.com/gmail/contextual_gadgets#supported_extractors – Ankit Singla May 27 '14 at 10:25
  • now the problem is that when I would write an extractor for this. the gadget would be fired in whole domain. so what is want is that i write an extractor for the "from" address and get the message id in my javascript. **why** because widget would load up for **specific** email addresses and in my javascript i would be able to attach the message id with whatever i intend to do. i want to prevent this gadget from appearing in everyone's mail boxes and still want to achieve my functionality – ankur May 30 '14 at 08:24
1

Use this Extractor :

<?xml version="1.0" encoding="UTF-8"?>      
<OpenCOBData id="Custom_Extractor_7">   
    <ExtractorSpec platform="gmail" language="en">
        <Search>        
            <Pattern input_fields="from_email">     
                <![CDATA[(email_1|email_2|email_3)]]>       
            </Pattern>      
        </Search>       

        <Response platform="gmail" format="cardgadget">     

            <Output name="id">{@__MESSAGE_ID__}</Output>        
            <Output name="sender">{@__FROM_ADDRESS__}</Output>      
            <Output name="date">{@__DATE_SENT__}</Output>       
            <Output name="to">{@__TO_ADDRESS__}</Output>        

            <!--Output name="email_subject">{@__SUBJECT__}</Output>     
            <Output name="received_date">{@__DATE_RECEIVED__}</Output-->        
        </Response>     
    </ExtractorSpec>        
</OpenCOBData>

In below line replace email_1, email_2, email_3 with the emails you want to match and add as much you want.

<![CDATA[(email_1|email_2|email_3)]]> 
Ankit Singla
  • 198
  • 2
  • 15
  • okay.... havent tried, but one question... can i write this extractor in the above manifest. or this would go into the **extractor(optional)** part in the googleapps console – ankur May 30 '14 at 18:28
0

you have to add its reference in Mamifiest as given below,

and it will also go into extractor(optional) part in the googleapps console.

Reference in Manifest like this :

<Extension id="uniqueId" type="contextExtractor">

    <Name>Custom_Extractor_7</Name>     

    <Url> ProjectID:ExtractorId</Url>       

    <Triggers ref="GadgetID" />     

    <Scope ref="ScopeId" />     

    <Container name="mail" />       

</Extension>     

Here Project Id is id of your project that you have created on Google apps console.

And Extractor Id is id of your Custom Extractor.

And Gadget Id is id of your gadget part present in your Manifest.

And Scope Id is id of your scope part present in your Manifest you can add multiple scopes these corresponds to output of your extractor.

Ankit Singla
  • 198
  • 2
  • 15
  • just tried it.its not working. just to clarify : (according to your custom extractor) i have replaced in my manifest "ExtractorId" with "Custom_Extractor_7" .... also scope i have used like this **tag:google.com,2010:auth/contextual/extractor/FROM_ADDRESS** . please tell me what am i doing wrong. everything was validated and i got my application redeployed too. – ankur Jun 02 '14 at 14:10
  • also do i need to change my gadget file( by the way its exactly the same as it was earlier-and it was working). i just uploaded the custom extractor(i copied your code) . then i replaced the email addesses as explained by you. third, i removed the old content extractors and replaced it with a new one(as given by you).. then i changed the appropriate values in my content-extractor tag – ankur Jun 02 '14 at 14:14
  • Custom_Extractor_7 is not the extractor id its just a name the actual extractor id is specified in extension tag ``. here the id attribute is the extractor's id. – Ankit Singla Jun 20 '14 at 04:01