Spaces in Email - javascript

I am trying to build a GSM Gmail addon that will open a card in the compose window and have several fields and then will generate a template and add it to the email. I have several variables containing HTML content and several containing fields from the card. I have almost gotten that done. The last thing that I need to do is to specify a subject, that will be the same every time, and specify recipients that will be based on a text field in the card.
Here is my code. I have 2 files, one gs code file, and one json manifest file.
Manifest.json:
{
"timeZone": "America/Chicago",
"dependencies": {
},
"exceptionLogging": "STACKDRIVER",
"oauthScopes": ["https://www.googleapis.com/auth/gmail.addons.current.action.compose", "https://www.googleapis.com/auth/gmail.addons.current.message.readonly", "https://www.googleapis.com/auth/gmail.addons.execute", "https://www.googleapis.com/auth/script.locale"],
"runtimeVersion": "V8",
"addOns": {
"common": {
"name": "Review Published Email Template",
"logoUrl": "https://goodbookreviews.page/Logo.png",
"useLocaleFromApp": true,
"universalActions": [{
"label": "Book Review ",
"openLink": "https://www.goodbookreviews.page"
}]
},
"gmail": {
"contextualTriggers": [{
"unconditional": {
},
"onTriggerFunction": "onGmailMessage"
}],
"composeTrigger": {
"selectActions": [{
"text": "Use Template",
"runFunction": "onGmailCompose"
}],
"draftAccess": "NONE"
}
}
}
}
code.js:
function onGmailCompose(e) {
console.log(e);
var header = CardService.newCardHeader()
.setTitle('Use Template')
.setSubtitle('Use the template for sending an email after a review has been published.');
// Create text input for entering the cat's message.
var input = CardService.newTextInput()
.setFieldName('email')
.setTitle('Email')
.setHint('What is the readers email address?');
var input2 = CardService.newTextInput()
.setFieldName('FName')
.setTitle('First Name')
.setHint('What is the readers first name?');
var input3 = CardService.newTextInput()
.setFieldName('BookTitle')
.setTitle('Reviewed Book Title')
.setHint('What is the title of the book reviewed?');
var input4 = CardService.newTextInput()
.setFieldName('BookAuthor')
.setTitle('Reviewed Book Author')
.setHint('Who is the author of the book reviewed?');
// Create a button that inserts the cat image when pressed.
var action = CardService.newAction()
.setFunctionName('useTemplate');
var button = CardService.newTextButton()
.setText('Use Template')
.setOnClickAction(action)
.setTextButtonStyle(CardService.TextButtonStyle.FILLED);
var buttonSet = CardService.newButtonSet()
.addButton(button);
// Assemble the widgets and return the card.
var section = CardService.newCardSection()
.addWidget(input)
.addWidget(input2)
.addWidget(input3)
.addWidget(input4)
.addWidget(buttonSet);
var card = CardService.newCardBuilder()
.setHeader(header)
.addSection(section);
return card.build();
}
function useTemplate(e) {
console.log(e);
var email = e.formInput.email;
var FName = e.formInput.FName;
var Title = e.formInput.BookTitle;
var Author = e.formInput.BookAuthor;
var now = new Date();
var htmlIntro = '<p>Hello, </p>';
var html2 = '<p> Thank you for writing a book review at Good Book Reviews on</p>';
var html3 = '<p>by</p>';
var html4 = '<p>. You Review has been published to our site. Any personal information you included was NOT published, including first name, last name, age, and email address. Only info you wrote about the book was published. You can see it right here! If you need anything else, feel free to contact us at support#goodbookreviews.page or reply to this email to contact us. <br> Happy Reading,<br> The Book Review Team</p>';
var message = htmlIntro + FName + html2 + Title + html3 + Author + html4;
var response = CardService.newUpdateDraftActionResponseBuilder()
.setUpdateDraftBodyAction(CardService.newUpdateDraftBodyAction()
.addUpdateContent(message, CardService.ContentType.MUTABLE_HTML)
.setUpdateType(CardService.UpdateDraftBodyType.IN_PLACE_INSERT))
.build();
return response;
}
function onGmailMessage(e) {
console.log(e);
var header = CardService.newCardHeader()
.setTitle('Unavailable')
.setSubtitle('Open the compose window to use template');
var card = CardService.newCardBuilder()
.setHeader(header);
return card.build();
}
Can someone please tell me how to do this? Thanks!

Your "p" tags create extra newlines. Try something like
var htmlIntro = '<p>Hello, ';
var html2 = 'Thank you for writing a book review at Good Book Reviews on ';
var html3 = ' by ';
var html4 = '. You Review has been published to our site. Any personal information you included was NOT published, including first name, last name, age, and email address. Only info you wrote about the book was published. You can see it right here! If you need anything else, feel free to contact us at support#goodbookreviews.page or reply to this email to contact us. <br> Happy Reading,<br> The Book Review Team</p>';
var message = htmlIntro + FName + html2 + Title + html3 + Author + html4;
Or, if you use V8 engine, even simpler
var message = `<p>Hello, ${FName} Thank you for writing a book review at Good Book Reviews on ${Title} by ${Author}. Your Review has been published to our site. Any personal information you included was NOT published, including first name, last name, age, and email address. Only info you wrote about the book was published. You can see it right here! If you need anything else, feel free to contact us at support#goodbookreviews.page or reply to this email to contact us.</p>
<br>
<p>Happy Reading,</p>
<br>
<p>The Book Review Team</p>
`

Related

Trying to create an Apps Script that pulls data from a few specific cells in Google Sheets and sends it via MailApp to other users

I was hoping I could figure out why the body is not generating in my emails created via Google Apps Script.
My department in our company is responsible for checking over 500 computers in the plant to verify that all software packages are up to date, I have already created a google sheet that has each computer in a "name" field, with a date located in a "last Evaluated" field. The last updated field will highlight red if it has not been updated in 90 days, and there is a COUNTIFs function to find the total of PCs that have not been updated in 90 days, as well as 180 days, 365 days, and last update unknown.
I want to use Google Apps Script to generate an email that sends weekly (or monthly, not sure yet) to other users in the dept where it reads something like this:
Subject: "Weekly PC Update Report
Body: There are {90 days overdue quantity} PCs that are 90 days overdue, {180 days quantity}..., {365 quantity}..., and {unknown quantity}PCs who's last update is unknown.
Searching for solutions, I found an example that pulls data from a stocks spreadsheet, After making the needed changes, I came up with this (I apologize for any readability issues/errors, I am new to Javascript and programming in general):
(days90 is a named range in a google sheet called Update Log)
function sendEmail(){
var overdue90 = get90data();
var body = getEmailText(overdue90);
MailApp.sendEmail({
to: "EMAIL WITHHELD FOR PRIVACY",
subject: "Weekly PC Update Report",
body: body
});
}
function getEmailText(overdue90) {
var text = "";
overdue90.forEach(function(day90) {
text = text + "There are " + days90 + "computers that have not been updated in the last 90 days." + "\n" + "\n";
});
return text;
}
function get90data() {
var values = SpreadsheetApp.getActive().getSheetByName("Update Log").getRange("days90").getValues();
values.shift(); //remove headers
var days90 = [];
values.forEach(function(value) {
var day90 = {};
day90.amount = value[0];
days90.push(day90);
});
//Logger.log(JSON.stringify(days90));
return days90;
}
The email does send to my inbox with the appropriate subject line, but the body is empty, when I tried making small changes I recieved some emails with the text [Ljava.lang.Object;#265ca7f2. (not every one of these emails were identical, but they all had the [Ljava.lang.Object!# portion.
Try to replace return text; in getEmailText function by
return text.toString()
or
return JSON.Stringify(text)

How to delete post in Firebase?

I'm making a food sharing site using firebase I'm trying to add a delete post option so when a food item is taken the user can delete the post so they aren't contacted about something they've already given away. I have managed to get the firebase remove function working but it just deletes all posts not just one. I'm using the push option when sending the data to my database as I need users to be able to make multiple posts but I don't know what the name of the post ids are to select them.
This is the code that sends the donations to the database
function submitDonation() {
var user = firebase.auth().currentUser;
if(user) {
var userid = user.uid;
var email = user.email;
var firebaseRef = firebase.database().ref();
firebaseRef.child("Donations").push({
user: userid,
email: email,
food: document.getElementById("foodType").value,
animal: document.getElementById("animalType").value,
expire: document.getElementById("expirationDate").value,
travel: document.getElementById("travelDistance").value,
location: document.getElementById("what3wordsLocation").value,
contact: document.getElementById("contactPreference").value,
time: document.getElementById("timePreference").value
});
}
}
and this is the code retrieving and drawing the data on the page. I'm using jquery to display my posts so sorry it looks a bit messy but I've basically got a button that calls a function and I need the button's id to match the id of the post but I don't know how to call that. Any help would be much appreciated. I'm still relatively new to firebase so still working on the basics aha.
var rootRef = firebase.database().ref().child("Donations");
rootRef.on("child_added", snap => {
var food = snap.child("food").val();
var animal = snap.child("animal").val();
var expire = snap.child("expire").val();
var travel = snap.child("travel").val();
var location = snap.child("location").val();
var contact = snap.child("contact").val();
var time = snap.child("time").val();
$("#listingDonations").append(
"<div id='donationBox' class='three columns'><div id='donationItem'><button onclick='deletePost()'>Delete</button><p><b>Type of Food:</b> " + food + "</p><p><b>Type of Animal:</b> " + animal + "</p><p><b>Expiration Date:</b> " + expire + "</p><p><b>Travel Distance:</b> " + travel + "</p><p><b>Contact Details:</b> " + contact + "</p><p><b>Preferred Contact Time:</b> " + time + "</p><a href='https://www.what3words.com/"+ location +"'>Location</a></div></div>"
);
})
function deletePost() {
}
Ive deleted the code I'd written in the deletePost function as it didn't work and is probably wrong anyway.

how to use javascript localStorage to save user choices and display in a different html page

I have a school project, the url is http://angelaalarconcreative.com/LB_v3/
I want to be able to save the user's food choices so that when you click on SAVE it automatically directs you to a different HTML page where the food choices and their combined nutrition facts are compiled together. My teacher gave me this code as a "hint" but I feel more lost than ever staring at her code. Could anyone help me please? :)
$(function() {
$("#save-meal").click(function(){
var authenticated = localStorage.getItem("Greetings");
alert(authenticated);
if(authenticated == null) {
//alert saying you need to login to use this feature
alert("You need to login to use this feature!");
}
else {
var openDiv = "<div> Welcome " + document.write(localStorage.getItem("Welcome"));
var calories = " <div> Calories : " + document.write(localStorage.getItem("calories"));
var totalFat = " <div> Total Fat : " + document.write(localStorage.getItem("totalFat"));
var cholesterol = " <div> Cholesterol : " + document.write(localStorage.getItem("cholesterol"));
var sodium = " <div> Sodium : " + document.write(localStorage.getItem("sodium"));
var dietaryFiber = " <div> Dietary Fiber : " + document.write(localStorage.getItem("dietaryFiber"));
var sugar = " <div> Sugar : " + document.write(localStorage.getItem("sugar"));
var protein = " <div> Protein : " + document.write(localStorage.getItem("protein"));
var closeDiv = "</div>"
}
});
});
I want to know how to use localStorage to get the user's random choices and to retrieve it in a different page. What is the proper syntax for that given the interactivity of my project?
UPDATE: I've changed the JS a little bit according to your answer however it still doesnt work! I suspect faulty syntax. Can someone help me? I feel like I'm so close to getting it!!!!
$(document).ready(function() {
$("#save-meal").click(function(){
var calories = $('.nf__table #value--calories').text();
var totalfat = $('.nf__table #value--total-fat').text();
var cholesterol = $('.nf__table #value--cholesterol').text();
var sodium = $('.nf__table #value--sodium').text();
var fiber = $('.nf__table #value--dietary-fiber').text();
var sugar = $('.nf__table #value--sugar').text();
var protein = $('.nf__table #value--protein').text();
localStorage.setItem('value--calories', calories);
localStorage.setItem('value--total-fat', totalfat);
localStorage.setItem('value--cholesterol', cholesterol);
localStorage.setItem('value--sodium', sodium);
localStorage.setItem('value--fiber', fiber);
localStorage.setItem('value--sugar', sugar);
localStorage.setItem('value--protein', protein);
});
$("#gotosave").click(function(){
document.write(localStorage.getItem('value--calories'));
document.write(localStorage.getItem('value--total-fat'));
document.write(localStorage.getItem('value--cholesterol'));
document.write(localStorage.getItem('value--sodium'));
document.write(localStorage.getItem('value--fiber'));
document.write(localStorage.getItem('value--sugar'));
document.write(localStorage.getItem('value--protein'));
});
});
//document.getElementById("#saved-items").innerHTML = calories;
First of all, welcome to StackOverflow.
You can learn more about localStorage (or sessionStorage) from here. Determine which one is most appropriate for your application.
When your user drags a bunch of food to the 'dinner plate', your .nf__table (nutrition facts table) is updated with a bunch of values. At this point, when your user clicks on the save button, you want your Save event handler to basically grab the values in .nf__table and do a localStorage.setItem() to store the values in local storage.
For example, this is how you would store the amount of calories in localStorage:
var calories = $('.nf__table #value--calories').text();
localStorage.setItem('value--calories', calories);
When the user is directed to the next page, your document-ready handler can then retrieve the stored values using getItem() and update the DOM with those values:
localStorage.getItem('value--calories');
So, the idea is that the nutrition fact values are "remembered" on the first page, so that they can be retrieved on the next page.

How do I format my text in Google Script, for it to show when I send an email?

I have been trying to edit a script that I have to bold certain text. This script pulls information from a Google Form Spreadsheet and returns an email that looks like this:
Teacher Engagement:
At initial observation, the teacher is appropriately engaged (Direct Instruction, Modeling, Constructing Knowledge, Guided/Independent Practice, etc.)
Technology Integration:
No evidence of technology use or integration
I would like for the headers "Teacher Engagement:" & "Technology Integration" to be Bold and maybe underlined.How can I implement HTML into my code?
My code is:
function sendEmail() {
var sheet = SpreadsheetApp.getActiveSheet();
var row = sheet.getActiveRange().getRowIndex();
var userEmail = sheet.getRange(row,
getColIndexByName("Username")).getValue();
var body = "Below are the results of a recent Walkthrough: ";
body += "\n\nTeacher Engagement: \n" + sheet.getRange(row,
getColIndexByName("Teacher Engagement")).getValue();
body += "\n\nTechnology Integration: \n" + sheet.getRange(row,
getColIndexByName("Technology Integration")).getValue();
MailApp.sendEmail(userEmail, subject, body, {name:"Classroom Walkthrough"});
}
The only viable solution to format an E-mail with the MailApp is to use the HTMLbody option and to write your texte as HTML.
example :
function sendEmail() {
var sheet = SpreadsheetApp.getActiveSheet();
var row = sheet.getActiveRange().getRowIndex();
var userEmail = sheet.getRange(row,
getColIndexByName("Username")).getValue();
var body = "<HTML><BODY>"
+"Below are the results of a recent Walkthrough: "
+"<P>Teacher Engagement: <BR>"
+sheet.getRange(row,getColIndexByName("Teacher Engagement")).getValue()
+"</P>"
+"<P>Technology Integration: <BR>"
+sheet.getRange(row,getColIndexByName("Technology Integration")).getValue()
+"</P></BODY></HTML>";
MailApp.sendEmail({
to:userEmail,
subject:subject,
htmlBody:body,
name:"Classroom Walkthrough"
});
}
result :
Below are the results of a recent Walkthrough:
Teacher Engagement:
stuff
Technology Integration:
other stuff

Google Docs Mail Merge script not working as of last week

A mail merge script that we use for 5 of our google docs stopped working last week - a similar thing happened a few weeks ago when DocsList became obsolete and I was able to fix it, but now it has stopped working again.
var docTemplate = "15kvC3M8b0Me3Vi3GwErQvG60BlTC0qAHMXrlc3Ocky8";
var docName = "RefundByCheck"
function onFormSubmit(e) {
var first_name = e.values[1];
var last_name = e.values[2];
var customer_email = e.values[3];
var brand = e.values[4];
var amount = e.values[5];
var purchase_date = e.values[6];
var customer_address = e.values[7];
var rep_name = e.values[8];
var order_number = e.values[9];
var copyId = DriveApp.getFileById(docTemplate)
.makeCopy(docName+'_'+order_number)
.getId();
var copyDoc = DocumentApp.openById(copyId);
var copyBody = copyDoc.getActiveSection();
copyBody.replaceText('keyFirst', first_name);
copyBody.replaceText('keyLast', last_name);
copyBody.replaceText('keyBrand', brand);
copyBody.replaceText('keyAmount', amount);
copyBody.replaceText('keyPurchaseDate', purchase_date);
copyBody.replaceText('keyAddress', customer_address);
copyBody.replaceText('keyRep', rep_name);
copyBody.replaceText('keyOrder', order_number);
var todaysDate = Utilities.formatDate(new Date(), "GMT", "MM/dd/yyyy");
copyBody.replaceText('keyTodaysDate', todaysDate);
copyDoc.saveAndClose();
var pdf = DriveApp.getFileById(copyId);
var theblob = pdf.getBlob().getAs('application/pdf');
var folder = DriveApp.getFolderById('0B3nrCN8N5OBcRnlWaUlHZUxZNE0');
var movefile = folder.createFile(theblob);
DriveApp.removeFile(movefile);
var subject = "Text goes here" + order_number
var body = "Hello " + first_name + " " + last_name + "," + "<br /><br />"
+ "Text goes here" + "<br /><br />"
+ "Text goes here"
+ "Text goes here"
+ "Text goes here"
+ "Text goes here"
+ "Text goes here"
+ "Text goes here"
+ "Text goes here"
+ "Text goes here"
var cc = "test#test.com";
MailApp.sendEmail(customer_email, subject, body, {htmlBody: body, attachments: pdf, cc: cc});
DriveApp.getFileById(copyId).setTrashed(true);
}
I have a feeling that Google updated something else and I need to change my code, but I'm not sure - I am pretty sure that it is something broken in this section due to the summary of failures notification I received: 5/25/15 8:59 AM onFormSubmit We're sorry, no servers are currently available. Please wait a bit and try again. (line 41, file "RefundByCheckCode")
var movefile = folder.createFile(theblob);
Any thoughts or suggestions?
This appears to be Issue 3206, "Sending mail with attachment of Drawing (as PDF) consistently fails". Visit that defect and star it for updates. There doesn't appear to be a new scenario in your script, but if you have any additional info that might help the Googler who is responsible for fixing this problem, you could add a comment to the issue tracker.
Since the problem seems to arise some time after a script has been running successfully, and is then persistent, I suggest duplicating your script, and decommissioning the original.
Edit: OP was able to get around the problem by deploying a replacement of their template file.

Categories