GmailApp.sendEmail() syntax for multiple options? - google-apps-script

I want to send emails with multiple hyperlinked text, line breaks and bolding. In addition to the .sendEmail() documentation, I found this question and answer, but I'm still confused. Here's what I'm doing:
function emailTest() {
var Link1 = "https://sites.google.com/a/****/item-shop" ;
var Link2 = "https://sites.google.com/a/****/leader-board" ;
var name = "Adam";
var message = "Congratulations " + name.bold() + "!" + '\n' + '\n' + "check out this cool " + Link1 + '\n' + '\n' +
"and this cool " + Link2 + '\n' + '\n' +
"Keep up the good work!" + '\n' + "Mr. S.";
GmailApp.sendEmail ('fakename#gmail.com', "Congratulations!", message,
{htmlBody: message.replace(Link1, 'Item Shop'),
htmlBody: message.replace(Link2, 'LeaderBoard')})
}
Here's the result:
bolding worked, and only 1 of the links, the line breaks did not happen.
any guidance is appreciated!

Have you tried starting with the http:// protocol?
Try this:
var link = "http://www.google.com";
var message = "Congratulations " + name[i] + "!" + '\n' + '\n' +
"check out this cool " + link + + '\n' + '\n' +
"Keep up the good work!" + '\n' + "Mr. S."
GmailApp.sendEmail(fakename#gmail.com, "Congratulations!", message,
{htmlBody: message.replace('link', 'Website')})
EDIT:
Try sepperating the links with the email send function, which also helps making it a little more readable. Try this (btw im not that familliar with google script but i am pretty sure this should work):
function emailTest() {
var Link1 = "https://sites.google.com/a/****/item-shop" ;
var Link2 = "https://sites.google.com/a/****/leader-board" ;
var name = "Adam";
var message = "Congratulations " + name.bold() + "!" + '<br/>' + '<br/>' + "check out this cool " + Link1 + '<br/>' + '<br/>' +
"and this cool " + Link2 + '<br/>' + '<br/>' +
"Keep up the good work!" + '<br/>' + "Mr. S.";
message = message.replace(Link1, 'Item Shop');
message = message.replace(Link2, 'LeaderBoard');
GmailApp.sendEmail ('fakename#gmail.com', "Congratulations!", message, {htmlBody: message});
}

Related

spreadsheets.values.batchUpdate() completes successfully, but the destination sheet is still empty

The script doesn't throw any errors, but rarely completely works - i.e. complete successfully with all of the expected data in the destination tab. The results breakdown is generally:
no results in the destination sheet - this happens ~50-75% of the time
all of the results in the destination sheet, except in cell A1 - ~25% of the time
100% completely works - ~15-25% of the time
code snippet of the batchupdate() call
var data = [
{
range: (ss.getSheetName() + "!A1:AQ" + valueArray.length)
,values: valueArray
}
];
const resource = {
valueInputOption: "RAW"
,data: data
};
Logger.log("request = " + JSON.stringify(resource)
+ "\n" + "valueArray = " + valueArray.length
);
Logger.log(" Sheets.Spreadsheets.Values.batchUpdate(params, batchUpdateValuesRequestBody) ");
var response = Sheets.Spreadsheets.Values.batchUpdate(resource, spreadsheetId);
Logger.log("response = " + response.toString());
and the response
response = {
"totalUpdatedRows": 37776,
"responses": [{
"updatedCells": 1482389,
"updatedRange": "BatchUpdateDestination!A1:AP37776",
"updatedColumns": 42,
"spreadsheetId": "adahsdassadasdsadaasdasdasdasdasdasdasdasdas",
"updatedRows": 37776
}
],
"spreadsheetId": "adahsdassadasdsadaasdasdasdasdasdasdasdasdas",
"totalUpdatedCells": 1482389,
"totalUpdatedSheets": 1,
"totalUpdatedColumns": 42
}
Its obviously a very large dataset, but I've pruned the destination spreadsheet to ensure there is ample room for the data, and from earlier testing, I believe that a specific size error would be returned if that was the blocker.
How can I troubleshoot, or better yet, prevent these incomplete executions? is there any way to inspect the batch jobs that these requests initiate?
Answering my own question...
After toiling with this a little more, I couldn't figure out any way to troublshooting or inspect the odd, seemingly successfully batchUpdate() jobs. Thus, I resorted to batching the batchUpdate() calls into batches of 15000. This seems to work consistently, though maybe a bit slower:
// This is the very large 2D array that is populated elsewhere
var valueArray = [];
var maxRows = valueArray.length;
var maxCols = valueArray[0].length;
var batchSize = 15000;
var lastBatchSize = 1;
for (var currentRowCount = 1; currentRowCount <= maxRows; ++currentRowCount) {
if( currentRowCount % batchSize == 0
|| currentRowCount == maxRows
)
{
Logger.log("get new valuesToSet");
valuesToSet = valueArray.slice(lastBatchSize - 1, currentRowCount -1);
var data = [
{
range: (ss.getSheetName() + "!A" + lastBatchSize + ":AQ" + (lastBatchSize + valuesToSet.length))
,values: valuesToSet
}
];
const resource = {
valueInputOption: "RAW"
,data: data
};
Logger.log("request = " + JSON.stringify(resource).slice(1, 100)
+ "\n" + "valuesToSet.length = " + valuesToSet.length
);
try {
var checkValues = null;
var continueToNextBatch = false;
for (var i = 1; i <= 3; ++i) {
Logger.log("try # = " + i
+ "\n" + " continueToNextBatch = " + continueToNextBatch
+ "\n" + " make the batchUpdate() request, then sleep for 5 seconds, then check if there are values in the target range."
+ "\n" + " if no values, then wait 5 seconds, check again."
+ "\n" + " if still not values after 3 tries, then resubmit the batchUpdate() requestion and recheck values"
+ "\n" + "range to check = " + "A" + lastBatchSize + ":AQ" + lastBatchSize
);
Logger.log(" Sheets.Spreadsheets.Values.batchUpdate(params, batchUpdateValuesRequestBody) ");
var response = Sheets.Spreadsheets.Values.batchUpdate(resource, spreadsheetId);
Logger.log("response = " + response.toString());
/// loop and check for data in newly written range
for (var checks = 1; checks <= 3; ++checks) {
Utilities.sleep(5000);
var checkValues = ss.getRange(("A" + lastBatchSize + ":AQ" + lastBatchSize)).getValues();
Logger.log("new cell populated - checks # = " + checks
+ "\n" + "range to check = " + "A" + lastBatchSize + ":AQ" + lastBatchSize
+ "\n" + "checkValues.length = " + checkValues.length
+ "\n" + "checkValues = " + checkValues
);
if(checkValues.length > 1)
{
Logger.log("checkValues.length > 1, so continue to next batch"
+ "\n" + "range to check = " + "A" + lastBatchSize + ":AQ" + lastBatchSize
+ "\n" + "checkValues.length = " + checkValues.length
+ "\n" + "checkValues = " + checkValues
);
continueToNextBatch = true;
continue;
}
else
{
Logger.log("checkValues.length is still not > 1, so try the request again"
+ "\n" + "range to check = " + "A" + lastBatchSize + ":AQ" + lastBatchSize
);
}
}
if(continueToNextBatch)
{
continue;
}
}
}
catch (e) {
console.error("range.setValues(valuesToSet) - yielded an error: " + e
+ "\n" + "valuesToSet = " + valuesToSet.length
+ "\n" + "maxRows = " + maxRows
+ "\n" + "maxCols = " + maxCols
+ "\n" + "currentRowCount = " + currentRowCount
+ "\n" + "current range row start (lastBatchSize) = " + lastBatchSize
+ "\n" + "current range row end (j - lastBatchSize) = " + (currentRowCount - lastBatchSize)
);
}
lastBatchSize = currentRowCount;
}
}

how to retrieve text data in fabricjs?

I wanted to retrieve text data from the fabric text.
I tried with .get('text') but it's telling undefined.
This is my HTML code :
function save(obj){
canvasfabric.forEachObject(function(obj){
// var textname = canvasfabric.setActiveObject().setText(event.target.value);
// alert(textnew);
//var text = canvasfabric.getActiveObject();
// alert(text.get('type'));
//canvasfabric.setActiveObject(textnew);
//var text = obj.get('type');
// var text1 = obj.get('text');
alert("frame : " + i + "\n"
+ "x : " + obj.left + "\n"
+ "y : " + obj.top + "\n"
+ "width : " + obj.width + "\n"
+ "height : " + obj.height + "\n"
+ "class : " + obj.get('text'));
});
//alert("Data has been saved Successfully");
}
Anybody here can help me to retrieve objects text data.

Grails JSON from controller to GSP formatting html tag

I am trying to send the following JSON from my controller to the GSP:
[
"message": errorList + '<br/>' + '<br/>' +
'Rows loaded: ' + rows + '<br/>' +
'<img src="${resource(dir: ''images'', file: ''twc-logo-002.png'')}" alt="logo" />'
+ 'Errors: ' + errors + '<br/>' +
'Yellow Issues: ' + yellowFlags + '<br/>' +
'Red Issues: ' + redFlags
]
I am having a hard time with compiler errors on the line containing the image tag. I don't think I am escaping the inner quotes correctly. Any advice? Thanks.
[
"message": errorList + '<br/>' + '<br/>' +
'Rows loaded: ' + rows + '<br/> \'<img src=\"${resource(dir: \'images\',file: \'twc-logo-002.png\')}\" alt=\"logo\" />'
+ 'Errors: ' + errors + '<br/>' +
'Yellow Issues: ' + yellowFlags + '<br/>' +
'Red Issues: ' + redFlags
]

How to add spaces HTML output

In the below code I want to create spaces when it is executed that is I want to see spaces
"HSC&nbsp" + txthsc.Text + "&nbspHSC" + txthscclg.Text + "
between HSC and txthsc tag so please help..
string strBody = "" +
"" +
"<div>Your name is: <b>" + txtaddress.Text + "</b></div>" +
"<div> your Gender:<b>"+txtgender.Text+"</b></div>"+
"<div> your skills:<b>" + txtskills.Text + "</b></div>" +
"<div> your experience:<b>" + txtexp.Text+ "</b></div>" +
"<div> your phno:<b>" + txtphno.Text + "</b></div>" +
"<table width=\"100%\" style=\"background-color:#cfcfcf;\"><tr><td>1st Cell body data</td><td>2nd cell body data</td></tr></table>" +
"<table width=\"500%\" style=\"background-color:#cfcfcf;\"><tr><td>BBA<b>&nbsp" + txtbba.Text + "&nbsp</td><td>HSC<b>" + txtbbaclg.Text + "</td></tr></table>" +
**"<table width=\"500%\" style=\"background-color:#cfcfcf;\"><tr><td>HSC<b>&nbsp" + txthsc.Text + "&nbsp</td><td>HSC<b>" + txthscclg.Text + "</td>**</tr></table>" +
"<table width=\"500%\" style=\"background-color:#cfcfcf;\"><tr><td>SSC<b>&nbsp" + txtssc.Text + "&nbsp</td><td>HSC<b>" + txtsscclg.Text + "</td></tr></table>" +
"Resume document generated successfully."+
"</body>" +
"</html>";
i think you are missing ; from &nbsp - Correct entity is

How to read Div inner contents at ajax?

I'm trying to update the sql db by a List of variables sent from the Html page.
Some of the Data are correctly sent, while others are not. I put the list in a div which is divided to two parts : "h1" and another "Div". The data at the header are all sent correctly, but the body itself which is at the second div isn't sent at all.
This is the Div which the data is put at:
$('#Classes').append('<div> <h1 class = "flip" wpID="' + subjects[i].Wkp_ID + '" lessonID="' + subjects[i].Ttb_lessonID + '" Date="' + Datecoming + '">' + subjects[i].sbj_Name + " Class:" + subjects[i].Ttb_Class + '</h1><div id ="NewBody" class="panel" contenteditable>' + subjects[i].Wkp_Body + '</div> </div>');
And that's how I read them at the ajax part:
var WeekPlan = [];
$('#Classes div').each(function (index) {
var header = $(this).children('h1');
var WeekBody = $(this).children('div').val();
var wpID = header.attr('wpID');
var lessonID = header.attr('lessonID');
var Wkp_Date = header.attr('Date');
WeekPlan[index] = { "Wkp_ID": wpID, "Wkp_Date": Wkp_Date, "Wkp_Body": WeekBody, "Wkp_lesson": lessonID };
});
The Wkp_ID, Wkp_Date, Wkp_Lesson are right, but the Wkp_Body just returns an empty string.
So do you know why is this happening and how can I truly read the body ? Most probably the problem is with this line:
var WeekBody = $(this).children('div').val();
But how can I access it correctly ?
Thanks a lot.
Here is what worked for me in case anyone needs it:
Creating the div:
$('#Classes').append('<div class="BigDiv"> <h1 class = "flip" wpID="'+ subjects[i].Wkp_ID + '" lessonID="' + subjects[i].Ttb_lessonID + '" Date="' + Datecoming + '">' + subjects[i].sbj_Name + " class:" + subjects[i].Cls_Name + '</h1><div class="panel" contenteditable>' + subjects[i].Wkp_Body + '</div> </div>');