I have a Library of functions that I want to use in a few different Google Forms (it's a simple set of functions that creates a draft to easily reply to the person who submitted the form). I tested my script in a project outside of the Library and all works as expected, so no problems with the script. However, I want to use various HTML templates for my email messages depending on the form -- i.e. a "Contact Us" form template vs. an "Email List" template. My script references an HTML file which I've named Draft.html
for easy reference, and if I have a Draft.html
file saved to my Library project, it works just fine. However, I don't want to actually access the file in the Library... I want to access a file named Draft.html
in each individual container-bound project. I've looked around here but can only seem to find help/info regarding how to reference functions across Libraries/projects, and no info on how to reference a project's local file from within a Library script.
Library function:
function makeDraft(subject, respondent, htmlTemplate) {
var htmlMessage = createEmailTemplate(respondent, htmlTemplate);
Logger.log(htmlMessage);
GmailApp.createDraft(
respondent.email, // Respondent email
subject, // Subject
"", // plaintext body
{
htmlBody: htmlMessage
}
);
}
function createEmailTemplate(respondent, htmlTemplate) {
var template = HtmlService
.createTemplateFromFile(htmlTemplate);
template.respondent = respondent;
var message = template.evaluate().getContent();
return message;
}
Where subject
is a string, respondent
is an object containing the respondent's email, Timestamp, message, etc., and htmlTemplate
is a string which I've set to "Draft" to reference the "Draft.html" file in the container-bound project.
However, like I said, if a file named Draft.html
exists in the Library it accesses it just fine. But, if this file doesn't exist in the Library, it doesn't work, even though I have a file named Draft.html
saved in the container-bound project. I'm sure this is because I'm executing a Library function, and that function is trying to read files in the Library project. Maybe it's obvious, but this is the error I get if I have no Draft.html
in the Library, but I do have a file named Draft.html
in my container-bound script project:
Exception: No HTML file named Draft was found.
So, my main question is, is it even possible to reference a file in a container-bound script project from a Library function? I can't find any info in the documentation about this on Google's side, and my situation seems to be a little unique. Since I'm the creator/owner of the Library, I can update my code easily enough so that part of the original function references the container-bound script it's executing from rather than the Library itself. I just don't know how to do that.
Container-bound script: (adding per request)
const replySubject = "Re: Contact Us"
const draftTemplate = "Draft";
function testFunction() {
emailOnFormSubmit(replySubject,draftTemplate);
}
function emailOnFormSubmit(subject,template) {
return FormAutoEmailLibrary.emailOnFormSubmit(subject,template);
}
Example of respondent
object:
var respondent = {
email : "example@test.com",
firstName : "Susan",
message : "This is an example message."
}
HTML example of Draft.html
file:
<!DOCTYPE html>
<html>
<head>
<!-- style here -->
</head>
<body>
<p>[DRAFT-RESPONSE]</p>
<h2>Original message from: <?= respondent.email ?>!</h2>
<p><strong>Name: </strong> <?= respondent.firstName ?></p>
<p><strong>Message: </strong> <?= respondent.message ?></p>
<p><em>This message was sent through a form submission.</em></p>
</body>
</html>
Although I'm not sure whether I could correctly understand your current situation, how about the following modification?
In the current stage, under the Google Apps Script project (client side) including a library (library side), when the HTML filename is used on the client side by HtmlService.createTemplateFromFile
, it seems that the HTML file in the client side is used. By this, when the HTML filename is used on the library side by HtmlService.createTemplateFromFile
, the HTML filename is searched from the Google Apps Script project in the library. I thought that this might be the reason for your current issue.
In order to avoid this issue, how about giving the object of HtmlService.HtmlTemplate
instead of the filename of the string type? I thought that by this modification, your script might work. When this modification is reflected in your script, how about the following modification?
function makeDraft(subject, respondent, htmlTemplate) {
var htmlMessage = createEmailTemplate(respondent, htmlTemplate);
Logger.log(htmlMessage);
GmailApp.createDraft(
respondent.email, // Respondent email
subject, // Subject
"", // plaintext body
{
htmlBody: htmlMessage
}
);
}
function createEmailTemplate(respondent, template) {
template.respondent = respondent;
var message = template.evaluate().getContent();
return message;
}
Unfortunately, in your question, I cannot see the script of the client side. So, here, I would like to propose a sample script for using this modification.
In this sample, the identification of the installed library is supposed as Library
.
function myFunction() {
const subject = "###"; // Please set your value.
const respondent = {,,,}; // Please set your value.
const htmlTemplate = HtmlService.createTemplateFromFile("Draft");
Library.makeDraft(subject, respondent, htmlTemplate);
}
HtmlService.HtmlTemplate
is given to the library side using HtmlService.createTemplateFromFile("Draft")
at the client side. So, I thought that the script worked.