Can't fetch mail body using gmail contextual gadget - google-apps

Here is my manifest.xml file
<?xml version="1.0" encoding="UTF-8" ?>
<ApplicationManifest xmlns="http://schemas.google.com/ApplicationManifest/2009">
 
  <Name>My test gadget</Name>
  <Description>Test Gmail contextual gadgets for mail body</Description>
 
 
<Extension id="MailBodyReaderGadget" type="contextExtractor">
  <Name>Mail Body Reader Gadget</Name>
  <Url>google.com:EmailBodyExtractor</Url>
<Param name="body" value=".*" /> 
  <Triggers ref="mailBodyTextWidget" /> 
  <Scope ref="emailBody" />
  <Container name="mail" />
</Extension>
 
<!-- our GADGET -->
<Extension id="mailBodyTextWidget" type="gadget">
  <Name>Get mail body</Name>
  <Url>http://test.com/spec.xml</Url>
  <Container name="mail" />
</Extension>
 
<!-- gadget Scope -->
<Scope id="emailBody">
  <Url>tag:google.com,2010:auth/contextual/extractor/BODY</Url>
  <Reason>This app will show the mail body text when you click the button "Show Mail Body"</Reason>
</Scope>
</ApplicationManifest>
and spec.xml file
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs
height="200"
author=""
author_email=""
author_location="US">
        <Require feature="dynamic-height"/>
        <Require feature="google.contentmatch">
            <Param name="extractors">
                google.com:EmailBodyExtractor
            </Param>
        </Require>
    </ModulePrefs>
    <Content type="html" view="card">
<![CDATA[      
<script type="text/javascript">
document.write([
"\<script src='",
("https:" == document.location.protocol) ? "https://" : "http://",
"ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js' type='text/javascript'>\<\/script>"
].join(''));
</script>
<button id="btn">Show Mail Body</button>
<div id="widget" style="heigth:300px;width:500px;">
</div>
    <script>
        matches = google.contentmatch.getContentMatches();
        for (var match in matches) {
          for (var key in matches[match]) {                     
            $("#widget").html(matches[match][key]);           
          }
        }       
    </script>    
    ]]>
  </Content>
</Module>
This is my code, i have been tried to fetch mail subject and from and to email addresses it has been worked. But the main issue is i can't fetch mail body. Is there any solution to fix this?

The answer is to delete the node <Param name="body" value=".*" />
This one had me stuck, as I thought that the <param> node was required to define the name of the output parameter to use in our gadget.
But in fact the MailBodyReaderGadget outputs the parameter of "body" automatically.
So the <Param> node is only used if you wish to filter the output.
As you always want to output the body, you can delete this node entirely.
The reason it is not working at the moment is because the .* filter doesn't match return characters (which will be in the body)

Related

AEM/CQ6.2: How to integrate Google reCaptcha or built-in captcha on an Adaptive Form?

Someone created a form that uses Adaptive Form.
I want to include some sort of captcha function on the form.
I tried using the built-in captcha (Form => Captcha). I made sure the captcha field is ticked as required but I have no problems submitting the form even if the captcha field is blank.
I was looking at incorporating Google's reCaptcha and the best guide I've seen is this: PracticalAEM article. But it doesn't really tell me how to include this new component into my existing setup.
Thanks very much for the help!
Captcha should be implemented on both sides of your application client and server.
Lets describe how reCaptcha work:
1) Browser render page with reCaptcha script with site ID(that is what you did based on article)
2) User answer reCaptcha and google return back some long string with captcha code(on that moment technically captcha still not validated)
3) Your frontend has to decide what to do with response(usually you placing it in mandatory field)
4) Submit reCaptcha captcha code to backEnd.(captcha still not validated)
This part is not described in the article that you read because it is basic for all captchas:
5) Backend should read captcha code and request google for verification of captcha code for current site ID
ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
reCaptcha.setPrivateKey("your_private_key");
String challenge = request.getParameter("recaptcha_challenge_field");
String uresponse = request.getParameter("recaptcha_response_field");
ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(remoteAddr, challenge, uresponse);
if (reCaptchaResponse.isValid()) {
....
} else {
//send response to browser with message "Captcha is invalid"
}
As you can see only response from google to backend is reCaptcha validation.
And for any captcha implementation there is two parts:
1) frontend where you can fulfil captcha check
2) backend where you can verify that check was done properly.
See if this helps. I have done this on a simple html form (not adaptive).
Folder structure..
recaptcha (main component folder name)
> _cq_editConfig.xml
> .content.xml
> dialog.xml
> recaptch.html
cq_editConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
cq:disableTargeting="true"
jcr:primaryType="cq:EditConfig"/>
.content.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
allowedParents="[*/parsys]"
componentGroup="ABC Commons"
jcr:description="ABC reCaptcha"/>
dialog.xml
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="cq:Dialog"
title="ABC reCaptcha Component"
xtype="dialog">
<items jcr:primaryType="cq:WidgetCollection"></items>
</jcr:root>
recaptcha.html
<div class="col-md-12">
<div id="response-div" style="color:red; font-weight: bold;"></div>
<script src='https://www.google.com/recaptcha/api.js?onload=reCaptchaCallback&render=explicit' async defer></script>
<div id="rcaptcha" class="g-recaptcha" data-sitekey="SITE-KEY"></div>
<input type="hidden" value="true" id="recaptchaRequired" name="recaptchaRequired" />
<button id="addButton" class="btn plus btn-success">Submit</button>
</div>
</div>
<script>
var RC2KEY = 'SITE-KEY';
var doSubmit = false;
function reCaptchaVerify(response) {
if (response === document.querySelector('.g-recaptcha-response').value) {
doSubmit = true;
}
}
function reCaptchaExpired () {
/* do something when it expires */
}
function reCaptchaCallback () {
grecaptcha.render('rcaptcha', {
'sitekey': RC2KEY,
'callback': reCaptchaVerify,
'expired-callback': reCaptchaExpired
});
}
$("#addButton").click(function (e) {
e.preventDefault();
if (doSubmit) {
//alert('submit pressed');
$( "form:first" ).submit();
} else {
//alert('recaptcha not selected');
document.getElementById("response-div").innerHTML = "Recaptcha is required!";
}
});
</script>
Note: Replace the SITE-KEY

TVML: adding new lines to a description text

Experimenting with Apple TV's TVML: I'm using a Product Template, and in the description field I'd like to add carriage returns, to make it look somewhat like a list.
Here is a simple example:
var Template = function() { return `<?xml version="1.0" encoding="UTF-8" ?>
<document>
<productTemplate>
<banner>
<infoList>
</infoList>
<stack>
<title>Big Title</title>
<description>
Line one
Line two
</description>
</stack>
</banner>
</productTemplate>
</document>`
}
I've tried \n, &#xD, &#xA between the lines, and even something like this:
<![CDATA[
Line 1 <br />
Line 2 <br />
]]>
But none of these work. Is there a way to incorporate line breaks in TVML descriptions?
Having this code in a template.xml.js and loading it via the Presenter.js in the TVMLCatalog example from apple:
<stack>
<description>Insert your \n username (tipically your ID)</description>
</stack>
It renders
This also works:
var Template = function() {
const description = `
Line 1
Line 2
`.trim();
return `<?xml version="1.0" encoding="UTF-8" ?>
<document>
<productTemplate>
<banner>
<infoList>
</infoList>
<stack>
<title>Big Title</title>
<description>
${description}
</description>
</stack>
</banner>
</productTemplate>
</document>`
}

How do I pass an object to, or set a variable in a TVML template file I am using?

I'm working with the TVMLCatalog sample files from Apple, and am stuck trying to pass an object to a template file I am loading in the presenter (javascript file). This seems like it should be a totally rudimentary thing to accomplish, but it has me beat.
I have the following, which loads a template with the resource loader, and pushes it to the view.
resourceLoader.loadResource('http://localhost/mytemplate.xml.js',
function(resource) {
if (resource) {
var doc = self.makeDocument(resource);
doc.addEventListener("select", self.load.bind(self));
navigationDocument.pushDocument(doc);
}
}
);
Where do I define an object or set a variable that will be in the document when the template file is loaded in the view?
Yes! You can inject variables into your TVML templates.
First, you have to create a string that contain the same TVML template, and use ${variable} to inject values.
Then, use DOMParser object to convert this string into XML DOM element.
Finally, present the document with help of presentModal method (main object navigationDocument)
Your function will look like this:
function catalogTemplate(title, firstMovie, secMovie) {
var xmlStr = `<?xml version="1.0" encoding="UTF-8" ?>
<document>
<catalogTemplate>
<banner>
<title>${title}</title>
</banner>
<list>
<section>
<listItemLockup>
<title>All Movies</title>
<decorationLabel>2</decorationLabel>
<relatedContent>
<grid>
<section>
<lockup>
<img src="http://a.dilcdn.com/bl/wp-content/uploads/sites/2/2014/03/Maleficent-Poster.jpg" width="250" height="376" />
<title>${firstMovie}</title>
</lockup>
<lockup>
<img src="http://www.freedesign4.me/wp-content/gallery/posters/free-movie-film-poster-the_dark_knight_movie_poster.jpg" width="250" height="376" />
<title>${secMovie}</title>
</lockup>
</section>
</grid>
</relatedContent>
</listItemLockup>
</section>
</list>
</catalogTemplate>
</document>`
var parser = new DOMParser();
var catalogDOMElem = parser.parseFromString(xmlStr, "application/xml");
navigationDocument.presentModal(catalogDOMElem );
}
PS: I used Catalog template as an example. You can use any template
In the onLaunch function, you can call the catalogTemplate function by passing any variable.
App.onLaunch = function(options) {
catalogTemplate("title", "Maleficent.", "The Dark knight");
}
You can add a listener and pass an function to move to another page or trigger an action using addEventListener
function catalogTemplate(title, firstMovie, secMovie, cb) {
var xmlStr = `<?xml version="1.0" encoding="UTF-8" ?>
<document>
<catalogTemplate>
<banner>
<title>${title}</title>
</banner>
<list>
<section>
<listItemLockup>
<title>All Movies</title>
<decorationLabel>2</decorationLabel>
<relatedContent>
<grid>
<section>
<lockup>
<img src="http://a.dilcdn.com/bl/wp-content/uploads/sites/2/2014/03/Maleficent-Poster.jpg" width="250" height="376" />
<title>${firstMovie}</title>
</lockup>
<lockup>
<img src="http://www.freedesign4.me/wp-content/gallery/posters/free-movie-film-poster-the_dark_knight_movie_poster.jpg" width="250" height="376" />
<title>${secMovie}</title>
</lockup>
</section>
</grid>
</relatedContent>
</listItemLockup>
</section>
</list>
</catalogTemplate>
</document>
`
var parser = new DOMParser();
var catalogDOMElem = parser.parseFromString(xmlStr, "application/xml”);
catalogDOMElem.addEventListener("select", cb, false);
navigationDocument.presentModal(catalogDOMElem );
}
Let's create another template just to showcase how we jump to another page by selecting a specific item.
function ratingTemplate(title) {
var xmlStr = `<?xml version="1.0" encoding="UTF-8" ?>
<document>
<ratingTemplate>
<title>${title}</title>
<ratingBadge value="0.8"></ratingBadge>
</ratingTemplate>
</document>`
var parser = new DOMParser();
var ratingDOMElem = parser.parseFromString(xmlStr,"application/xml");
navigationDocument.presentModal(ratingDOMElement);
}
In our onLaunch function.
App.onLaunch = function(options) {
catalogTemplate("title", "Maleficent.", "The Dark knight", function() {
navigationDocument.dismissModal();
ratingTemplate(“rating template title")
});
}
Check this list for more tutorials.

how to populate a drop down(<s:select) in struts2 from json response

i am unable to populate my Struts2 select drop down in my jsp page.
Note: My jsp page loads through json response.
I have a select box inside a form. But i don't t know how to populate it when my jsp page loads.
And in the same page i have a select dropdown in my Struts2 jquery grid,which i am able to populage but i don't know how to populate a drop down for my form which are out side of the grid.
Please help me regarding this issue.
my jsp page
<s:url id="selecturl" action="selectaction"/>
<s:url id="bookediturl" action="bookeditt"/>
<s:url id="bookremoteurl" action="booksetups"/>
<sjg:grid
id="bookgrid"
formIds="form2"
reloadTopics="reloadMyGrid"
caption="List of Cover Details"
dataType="json"
href="%{bookremoteurl}"
pager="true"
gridModel="gridModel"
rowList="50,100,5000"
rowNum="20"
filter="true"
filterOptions="{stringResult :false,searchOnEnter : false,enableClear : true,gridModel : true}"
rownumbers="true"
editurl="%{bookediturl}"
navigator="true"
editinline="true"
navigatorSearch="false"
autowidth="false"
width= "1550"
viewrecords="true"
navigatorRefresh="true"
navigatorDelete="true">
<sjg:gridColumn name="id" index="locationId" title="ID" formatter="integer" sortable="false" key="true"
search="false" editable="true" hidden="true" />
<sjg:gridColumn name="authLastname" index="authLastname" title="AuthorLastname" sortable="true" search="true" editrules="{required: true}"
editable="true" edittype="text" />
<sjg:gridColumn name="subjectId" title="Subject Name" editable="true" sortable="false" align="center" search="false" searchtype="select"
searchoptions="{dataUrl:'%{selecturl}'}" edittype="select" editoptions="{dataUrl:'%{selecturl}'}" />
</sjg:grid>
<div id="myDivBox" style="display:none; width :300px;position: relative;top: -30px;left: 299px;button:0px;">
<s:form action="searchkeywordss" id="form2" theme="simple" cssClass="yform">
<sj:textfield placeholder="Enter keyword to search" cssClass="txtbox" size="42" maxLength="255" name="keywordsearch"/>
<sj:select href="%{selecturl}" name="countryselect" list="%{lstsub}" listKey="id" listValue="subjectName" theme="jquery" cssStyle="margin-top:4px;"/>
<sj:a button="true" id="btnid" cssStyle="position: relative;top: 0px;left: 09px;" onClickTopics="reloadMyGrid">Find</sj:a>
</s:form>
</div>
struts.xml
<action name="booksetups" class="v.esoft.actions.bookdetails.BookdetailsAction" >
<result name="success" type="json"/>
<result name="login" type="redirect"> /index.jsp </result>
</action>
<action name="selectaction" class="v.esoft.actions.bookdetails.SelectAction">
<result name="success">/select.jsp</result>
</action>
You should only use the sj:select like below
<sj:select href="%{selecturl}" name="countryselect" list="subjectList" listKey="id" listValue="subjectName" theme="jquery" cssStyle="margin-top:4px;"/>
where selecturl returns a json response, subjectList is name of list in the json reponse which contains the options
Your selectaction should have a json response, but what you have now is an action returning a jsp so it would not work. If you cannot change it, you should create another action which returns json.

How to extend Zend_Form prefix path while configuring form through XML (Zend_Config) to load custom form elements?

I'm loading my Zend_Form from an XML file :
<form>
<elements>
<role>
<type>MyProject_Form_Element_Select_Roles</type>
<options>
<label>Role:</label>
<value></value>
</options>
</role>
<valid>
<type>submit</type>
<options>
<label>Valid</label>
</options>
</valid>
</elements>
</form>
Of course the XML below doesn't work since Zend doesn't know how to load my custom field (which is just an extension of Zend_Form_Element_Select), but the line below doesn't work, if anyone can help :
<form>
<elementPrefixPath>
<prefix>MyProject_Form_Element_Select</prefix>
<path>MyProject/Form/Element/Select</path>
<type>element</type>
</elementPrefixPath>
...
I found these config features really cool but finding info or tutorial on them is really tough (I know there's some mapping rule between the Zend_Form objects structure and the expected config file, but I do never found a complete description of it if someone has a link)
Here's the correct form XML description :
<form>
<prefixPath>
<element>
<prefix>MyProject_Form_Element_Select</prefix>
<path>MyProject/Form/Element/Select</path>
</element>
</prefixPath>
<prefixPath>
<element>
<prefix>MyLib_Form_Element_Select</prefix>
<path>MyLib/Form/Element/Select</path>
</element>
</prefixPath>
<elements>
<role>
<type>Roles</type>
<options>
<label>Role:</label>
<value></value>
</options>
</role>
<valid>
<type>submit</type>
<options>
<mycustomoption></mycustomoption>
<label>Valid</label>
</options>
</valid>
</elements>
</form>
The custom options will be send inside the $options argument of the constructor of your Element
class MyProject_Form_Element_Select_Roles extends Zend_Form_Element_Select
{
public function __construct($spec, $options = null) {
//don't forget to call parent !
//$options is a Zend_Config that should have as a member mycustomptions
}
}