Email is not sending - javascript

Code Runs No Errors But I Do Not Receive and email when I check my gmail
This line is the issue I believe I am writing this incorrectly so its not sending the email help please
if(values.getDisplayValues() === "On-going" || values.getDisplayValues() === "" && values1.getDisplayValues() >= 80)
Rest of the code:
function sendEmail(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var SpreadsheetID = ss.getSheetId();
var spreadsheetURL = ss.getUrl();
var SpreadsheetID = spreadsheetURL.split("/")[5];
var filterViewName = 'PO_Log Precentage';
var filterViewID = filterId(SpreadsheetID, filterViewName);
var url = createURL(spreadsheetURL, filterViewID);
Logger.log(url);// Testing to see the correct url is created
var po_numID = ss.getSheetByName("Purchase Orders List").getRange("A2").getDisplayValue().substr(0,3);
Logger.log(po_numID);
var email_va = ss.getSheetByName("Purchase Orders List");
var values = email_va.getRange("Q2:Q");
var values1 = email_va.getRange("T2:T");
Logger.log(values)
var emailDataSheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/17G0QohHxjuAcZzwRtQ6AUW3aMTEvLnmTPs_USGcwvDA/edit#gid=1242890521").getSheetByName("TestA");
Logger.log(emailDataSheet.getSheetName());
var emailData = emailDataSheet.getRange("A2:A").getDisplayValues().flat().map(po => po.substr(0,3));
Logger.log(emailData)
var subject = po_numID + " Po Log Daily Notification ";
var options = {}
options.htmlBody = "Hi All, " + "The following" + '<a href=\"' +url+ '" > Purchase Orders </a>' + "are over 80% spent" + "";
// I believe this if statement is the problem I am writing it in correctly
if(values.getDisplayValues() === "On-going" || values.getDisplayValues() === "" && values1.getDisplayValues() >= "80%"){
emailData.every((po, index) => {
if (po == po_numID){
const email = emailDataSheet.getRange(index + 2,7).getValue();
console.log(email);
MailApp.sendEmail(email, subject, '', options);
return false;
} else {
return true;
}
});
}
}
https://docs.google.com/spreadsheets/d/1QW5PIGzy_NSh4MT3j_7PggxXq4XcW4dCKr4wKqIAp0E/edit#gid=611584429
Here is the spread sheet

values.getDisplayValues() gives you an array.
Basically it makes no sense to compare an array and a string with === and >= etc.
You need to decide which element of the array there should be. May be something like values.getDisplayValues()[0][0] (because it's likely an 2D-array). I can't check your code, so just a guess.

Related

How do I make the right conditions for the url based on the value of a variable? (javascript)

My script javascript like this :
<script>
var url = 'http://my-app.test/item';
var sessionBrand = 'honda';
var sessionModel = 'jazz';
var sessionCategory = 'velg';
var sessionKeyword = 'RS 175/60 R 15';
if(sessionBrand)
var brand = '?brand='+sessionBrand;
else
var brand = '';
if(sessionModel)
var model = '&model='+sessionModel;
else
var model = '';
if(sessionCategory)
var category = '&category='+sessionCategory;
else
var category = '';
if(sessionKeyword)
var keyword = '&keyword='+this.sessionKeyword;
else
var keyword = '';
var newUrl = url+brand+model+category+keyword;
console.log(newUrl);
</script>
The result of console.log like this :
http://my-app.test/item?brand=honda&model=jazz&category=velg&keyword=RS 175/60 R 15
var sessionBrand, sessionModel, sessionCategory and sessionKeyword is dynamic. It can change. It can be null or it can have value
I have a problem
For example the case like this :
var sessionBrand = '';
var sessionModel = '';
var sessionCategory = '';
var sessionKeyword = 'RS 175/60 R 15';
The url to be like this :
http://my-app.test/item&keyword=RS 175/60 R 15
Should the url like this :
http://my-app.test/item?keyword=RS 175/60 R 15
I'm still confused to make the condition
How can I solve this problem?
Just use the array for params and then join them with & separator. For example:
var url = 'http://my-app.test/item';
var sessionBrand = 'honda';
var sessionModel = 'jazz';
var sessionCategory = 'velg';
var sessionKeyword = 'RS 175/60 R 15';
var params = [];
if (sessionBrand) {
params.push('brand=' + sessionBrand);
}
if (sessionModel) {
params.push('model=' + sessionModel);
}
if(sessionCategory) {
params.push('category=' + sessionCategory);
}
if(sessionKeyword) {
params.push('category=' + sessionCategory);
}
var newUrl = url + '?' + params.join('&');
console.log(newUrl);
The problem with your code is that it is prefacing all query parameters with a & - except for the sessionBrand. What you need in a URL is for the first parameter to start with a ?, and all others with a &. As you saw, your code doesn't do this when there is no sessionBrand.
There are number of ways to fix this. Probably the neatest I can think of is to assemble the various parts as you are, but without any prefixes - then join them all together at the end. Like this (I just saw Viktor's solution, it's exactly the same idea, but neater because he rewrote more of your earlier code):
if(sessionBrand)
var brand = 'brand='+sessionBrand;
else
var brand = '';
if(sessionModel)
var model = 'model='+sessionModel;
else
var model = '';
if(sessionCategory)
var category = 'category='+sessionCategory;
else
var category = '';
if(sessionKeyword)
var keyword = 'keyword='+this.sessionKeyword;
else
var keyword = '';
var queryString = '?' + [sessionBrand, sessionModel, sessionCategory, sessionKeyword].filter(function(str) {
return str.length > 0;
}).join("&");
var newUrl = url+queryString;

Docusign Signer Name

At my current company we have DocuSign integrated with Salesforce for sending out contracts to our potential clients.
Each contract is required to be signed by our potential client but also from our VP of sales/services.
I created a custom button on the quote object to submit the quote to DocuSign passing the information required (Signer Role, name, email etc) The problem I am having is that for some reason the full name of the second signer (the internal signer) does not get passed on to DocuSign so the sales rep has to manually go and edit the recipients each time and add the name.
Button code:
var quoteApproved = {!Quote.Quote_Approved__c};
//********* Option Declarations (Do not modify )*********//
var RC = '';
var RSL = '';
var RSRO = '';
var RROS = '';
var CCRM = '';
var CCTM = '';
var CCNM = '';
var CRCL = '';
var CRL = '';
var OCO = '';
var DST = '';
var LA = '';
var CEM = '';
var CES = '';
var STB = '';
var SSB = '';
var SES = '';
var SEM = '';
var SRS = '';
var SCS = '';
var RES = '';
//*************************************************//
switch ("{!Quote.Signed_by__c}") {
case "John Cash":
CRL = "Email~john.cash#company.com; FirstName~John; LastName~Cash; Role~Signer 2; RoutingOrder~1";
CCTM = "Signer 2~Signer";
break;
case "Mark Cash":
CRL = "Email~mark.cash#company.com; FirstName~Mark; LastName~Cash; Role~Signer 2; RoutingOrder~1";
CCTM = "Signer 2~Signer";
}
if (quoteApproved) {
{
!REQUIRESCRIPT("/apex/dsfs__DocuSign_JavaScript")
}
var sourceId = DSGetPageIDFromHref();
var RQD = DSGetPageIDFromHref();
window.location.href = "/apex/dsfs__DocuSign_CreateEnvelope?DSEID=0&SourceID=" + sourceId + "&CCTM=" + CCTM + "&CRL=" + CRL + "&RQD=" + RQD;
} else {
alert("Your quote has not been approved yet. \nPlease submit for approval before sending the contract.");
}
I have resolved the issue. The RQD variable was adding a # at the end of the URL preventing the completion of the field mapping.

Javascript Send mail on Gmail with signature and BCC with Google Spreadsheet

Is there a way with Javascript (or other) from Google Spreadsheet to get the Gmail account signature?
Details:
I have a Google spreadsheet with information in it.
When clicking on a button, it identifies who has to receive the information, prepare a mail, and send it to the person.
However, I want to add the sender's signature at the end of the mail (it includes name, phone, logo, etc.).
I'm open if I get the signature from an other place, as long as it can change according to who's sending the mail.
This is for my volunteering association, not a job.
In case my code may help (I look to fill the var Signature):
var Signature;
var Receivers;
var Subject;
var Location ;
var MailtoSend= "Hello, \n\n The next meeting will be at " + Location + ". \n" + Signature;
MailApp.sendEmail(Receivers, Subject, MailtoSend);
SOLUTION:
I've find a way from another site (can't find it):
Create a template in your gmail draft with your signature, and put in the subject "Template" and in the body {Body}.
Then use the following code to create a copy of the mail, and fill it with all the information:
In the function to send the mail add:
sendGmailTemplate(RecipientTo, RecipientCC, RecipientBCC, SujetAEnvoyer, CourrielAEnvoyer);
Referring to the following functions:
function sendGmailTemplate(RecipientTo, RecipientCC, RecipientBCC, subject, body, options) { //mettre à jour la quantité de recipeien cc bcc to
options = options || {}; // default is no options
var drafts = GmailApp.getDraftMessages();
var found = false;
for (var i=0; i<drafts.length && !found; i++) {
if (drafts[i].getSubject() == "Template") {
found = true;
var template = drafts[i];
}
}
if (!found) throw new Error( "Impossible de trouver le brouillon 'Template' sur le gmail" );
// Generate htmlBody from template, with provided text body
var imgUpdates = updateInlineImages(template);
options.htmlBody = imgUpdates.templateBody.replace('{BODY}', body);
options.attachments = imgUpdates.attachments;
options.inlineImages = imgUpdates.inlineImages;
options.cc = RecipientCC;
options.bcc = RecipientBCC;
options.replyTo = "";
return GmailApp.sendEmail(RecipientTo, subject, body, options);
}
function updateInlineImages(template) {
//////////////////////////////////////////////////////////////////////////////
// Get inline images and make sure they stay as inline images
//////////////////////////////////////////////////////////////////////////////
var templateBody = template.getBody();
var rawContent = template.getRawContent();
var attachments = template.getAttachments();
var regMessageId = new RegExp(template.getId(), "g");
if (templateBody.match(regMessageId) != null) {
var inlineImages = {};
var nbrOfImg = templateBody.match(regMessageId).length;
var imgVars = templateBody.match(/<img[^>]+>/g);
var imgToReplace = [];
if(imgVars != null){
for (var i = 0; i < imgVars.length; i++) {
if (imgVars[i].search(regMessageId) != -1) {
var id = imgVars[i].match(/realattid=([^&]+)&/);
if (id != null) {
var temp = rawContent.split(id[1])[1];
temp = temp.substr(temp.lastIndexOf('Content-Type'));
var imgTitle = temp.match(/name="([^"]+)"/);
if (imgTitle != null) imgToReplace.push([imgTitle[1], imgVars[i], id[1]]);
}
}
}
}
for (var i = 0; i < imgToReplace.length; i++) {
for (var j = 0; j < attachments.length; j++) {
if(attachments[j].getName() == imgToReplace[i][0]) {
inlineImages[imgToReplace[i][2]] = attachments[j].copyBlob();
attachments.splice(j, 1);
var newImg = imgToReplace[i][1].replace(/src="[^\"]+\"/, "src=\"cid:" + imgToReplace[i][2] + "\"");
templateBody = templateBody.replace(imgToReplace[i][1], newImg);
}
}
}
}
var updatedTemplate = {
templateBody: templateBody,
attachments: attachments,
inlineImages: inlineImages
}
return updatedTemplate;
}
There is not a method to request a signature that you have already created. It is possible to create one yourself with inlineImages. The documentation for that can be found here: https://developers.google.com/apps-script/reference/gmail/gmail-app#sendemailrecipient-subject-body-options

How to empty an Array in a Script

I have a script that uses AJAX/PHP/SQL to query data and pushes it into an array with a bunch of IF's statements. The changeData function is called every 6 seconds. The first query I return I have 6 arrays. The second time i send a request, my push array(IsVacant1) is double and went to 12. after a while, I have over 500 arrays going into my .each statement.
How do I 'clear' this every time I make a request so that I am not adding arrays? Any help is most appreciated.
function changeData() {
isPaused = true;
var mydata0 = null;
$.post('php/ProductionChange.php', {
'WC': cc
}, function(data) { // This is Where I use an AJAX call into a php file.
mydata0 = data; // This takes the array from the call and puts it into a variable
var pa = JSON.parse(mydata0); // This parses the data into arrays and elements
var temp = {};
var bayData = '';
if (pa != null) {
for (var i = 0; i <= pa.length - 1; i++) {
var job = pa[i][0];
var shipdate = pa[i][1];
var status = pa[i][2];
var name = pa[i][3];
var EnclLoc = pa[i][13];
var Enclsize = pa[i][14];
var backpan = pa[i][15];
var percentCom = pa[i][16];
var IsVisible = pa[i][17];
var png = pa[i][18];
var WorkC = pa[i][20];
baydata = 'bayData' + i + '';
temp = {
job, shipdate, name, EnclLoc, Enclsize, backpan, percentCom, IsVisible, png, WorkC, status
};
isVacant1.push({
baydata: temp
});
}
} else {
ii = 1;
//alert("There are no more job numbers in this bay location. Thank you. ");
}
$.each(isVacant1, function(key, value) {
var job = value.baydata.job;
var ship = value.baydata.shipdate;
var name = value.baydata.name;
var encl = value.baydata.EnclLoc;
var EnclSize = value.baydata.EnclLoc;
var percentCom = value.baydata.percentCom;
var backpan = value.baydata.backpan;
var PngLogo = value.baydata.png;
var IsVisible = value.baydata.IsVisible;
var WorkC = value.baydata.WorkC;
var status = value.baydata.status;
var p = WorkC;
WorkC = (WorkC < 10) ? ("0" + WorkC) : WorkC;
//// remember if the encl location matches the workcell cell then do stuff based on that....... hint encl image not hiding becase of duplicate 17s
if (((encl == p) || (backpan == p)) && job != 123) {
$('#WC' + p).show();
document.getElementById("bayData" + p).innerHTML = name + ' ' + ship; // Work Cell Name and Ship Date
document.getElementById("bayData" + p + "a").innerHTML = job; // Work cell Job Number
document.getElementById("percentCom" + p).innerHTML = percentCom + '%'; // Work Cell Percent Complete
} else {
$('#WC' + p).hide();
From your question it looks like you want to clear the isVacant1 array.
In your ajax callback just put isVacant1 = []; as the first line. Like this
function(data) { // This is Where I use an AJAX call into a php file.
isVacant1 = [];
mydata0 = data; // This takes the array from the call and puts it into a variable
var pa = JSON.parse(mydata0); // This parses the data into arrays and elements
var temp = {};
var bayData = '';
..................
From your code it's not clear how you are declaring/initializing isVacant1 so i have suggested isVacant1 = [] otherwise you can also use isVacant1.length = 0.
You can also take a look here How do I empty an array in JavaScript?

Perform an async task with a web worker JavaScript

I want to show a loading icon while a task is being performed and then hide the icon after it has been performed. I need to use a web worker for the loading icon to show. The admin at This forum post said to use a web worker.
This is the code to execute in the web worker:
function getTheClients(xml) {
console.log(xml);
var client = xml.getElementsByTagName("WebClientList");
if(client.length === 0) {
$("#noClients" + platform).empty();
$("#noClients" + platform).append('<p style="margin-top:40px;margin-bottom:20px;text-align:center;">No clients at ' +
getSelectedDropDownOptionName("allVillagesDropDown") + ', ' +
getSelectedDropDownOptionName("allLocationsDropDown") + '.</p>');
$("#noClients" + platform).attr("style", "display: block");
$("#theClientsList" + platform).attr("style", "display: none");
} else {
$("#noClients" + platform).attr("style", "display: none");
$("#theClientsList" + platform).attr("style", "display: block");
}
for (i=0; i < client.length; i++) {
var firstName = client[i].getElementsByTagName("givenName")[0].childNodes[0];
var lastName = client[i].getElementsByTagName("familyName")[0].childNodes[0];
var oid = client[i].getElementsByTagName("oid")[0].childNodes[0];
var nhi = client[i].getElementsByTagName("nhi")[0].childNodes[0];
var dwelling = client[i].getElementsByTagName("dwelling")[0].childNodes[0];
var photo = client[i].getElementsByTagName("photo")[0].childNodes[0];
if (!photo) {
photo = "";
} else {
photo = photo.nodeValue;
}
firstName = firstName ? firstName.nodeValue : "";
lastName = lastName ? lastName.nodeValue : "";
oid = oid ? oid.nodeValue : "";
nhi = nhi ? nhi.nodeValue : "";
dwelling = dwelling ? dwelling.nodeValue : "";
var letterDwelling = dwelling ? dwelling[0].toUpperCase() : "";
var letterLastName = lastName ? lastName[0].toUpperCase() : "";
console.log(photo);
dataSource.add({photo: photo, firstName: firstName,lastName: lastName,oid: oid,nhi: nhi,dwelling: dwelling, letterDwelling: letterDwelling, letterLastName: letterLastName});
}
if (clientListViewHasNotLoaded) {
searchFilter = "lastName";
listGroup = "letterLastName"
console.log("e");
$("#theClientsList" + platform).append('<ul id="flat-listview' + platform + '" class="listView' + platform + '" style="width: 100%; margin-bottom:10px; margin-top:10px;"></ul>');
initListView({
field: "lastName",
operator: "startswith",
placeholder: "Search by last name"
}
);
$("#flat-listview" + platform).data("kendoMobileListView").setDataSource(dataSource);
clientListViewHasNotLoaded = false;
}
}
here is the code I'm using to create a web worker, before I take the next step and incorporate my above function:
the script (webServiceScript.js):
self.onmessage = function(event) {
var results = event.data;
// do something
// Done:
postMessage(results);
};
The calling code:
var worker = new Worker('scripts/webServiceScript.js');
worker.onmessage = function(event) {
// Do something with event.data, then hide the spinner.
app.showLoading();
};
app.hideLoading();
worker.postMessage({args: ' foo bar '});
I would like to incorporate my function at the top of the question into the script file (to be used in a web worker). When I incorporate my above function into the script, I need to pass my variable called xml.
Any help greatly appreciated, I'm struggling to understand the documentation here.
As we were discussing in comments, all you need to do is give the browser a chance to do a repaint. You can accomplish that with setTimeout() like this:
app.showLoading()
setTimeout(function() {
getTheClients(xml);
app.hideLoading();
}, 1);
You can't do setTimeout(getTheClients(xml), 1); because that calls getClients() right away and then passes the return result from that to setTimeout(). Instead, you have to pass just a function reference to setTimeout() as shown above.

Categories

Resources