I am trying to build a REST API in Google Apps Script, that a contacts page shall connect to, that sends emails to me or another point of contact. The Google Script is under my Google Suite account, and thus far, looks like this:
/**
* Sends contact email, on behalf of the client, to an email of Open Source Roads.
* @param data - string : a stringified object with the following fields:
* - sender
* - subject
* - message
* - recipient
**/
function sendContactEmail(data) {
var emailData = JSON.parse(data) || {};
Logger.log(Object.keys(emailData).length !== 0)
// if there's no sender, reject it right away
if ((!emailData.sender) || (typeof(emailData.sender) !== 'string') && (!emailData.sender.email)) throw forbidden('Sender missing');
// if there's no recipient, reject it right away
if ((!emailData.recipient) || ((typeof(emailData.recipient) !== 'string') && (!emailData.recipient.email))) throw forbidden('Recipient missing');
// if there's no subject or message, it's a bad request
if (!emailData.subject) throw invalidData('Subject missing');
if (!emailData.message) throw invalidData('Message missing');
// validate sender,recipient (these will be emails!)
var sender = retrievePropFrom(emailData, 'sender'),
recipient= retrievePropFrom(emailData, 'recipient');
if (!isValidEmail(sender)) throw invalidData("sender must contain a valid email")
if (!isValidEmail(recipient)) throw invalidData("recipient must contain a valid email")
// TODO: additional sanitation on emailData.subject,emailData.body?
// send that email message!
MailApp.sendEmail(recipient,
sender,
emailData.subject,
emailData.message
)
}
function makeError(message, code) {
var error = new Error(message);
error.code = code;
return error;
}
makeError.FORBIDDEN = 403;
makeError.UNAUTHORIZED = 401;
makeError.BAD_REQUEST = 400;
function forbidden(message) {
return makeError(message, makeError.FORBIDDEN);
}
function invalidData(message) {
return makeError(message, BAD_REQUEST);
}
function isValidEmail(email) {
return /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/.test(email)
}
/**
* retrieves the specified property from `obj`. If prop is for either sender or recipient, things get a
* little more interesting:
* - if the value at the requested `prop` is a string, we return it, like any other `prop`
* - else if the value at that `prop` contains `email`, we return that
*
**/
function retrievePropFrom(obj, prop) {
if (((prop !== "sender") && (prop !== "recipient")) || (obj[prop] === obj[prop].toString()))
return obj[prop];
if (obj[prop].email) return obj[prop].email;
return undefined;
}
If I sendContactEmail
with myself as the sender
and my personal account (different from the owner of the Script) as the recipient
, MailApp
sends the email message, and I can verify it within seconds. However, when I go to try my actual use case, having the script owning email as recipient
and the other email as sender
, I get nothing.
I read the documentation, and there's no note that this is a thing. How do I get around this?!
MailApp
always sends email from the Gmail account under whose authority the script is executing - you cannot change or set the sender, only thereply-to
. So if they do not authorize your script to run as them (i.e. you publish as a webapp and executing as the user accessing), then you cannot send email from their address. PS: consider editing your question to clearly state your issue – tehhowch