Session.getActiveUser().getEmail() returns an empty string more often than you'd think: in installable triggers, in “execute as me” web apps, and for users outside your domain. Your audit column ends up blank. activeUserEmailOr(fallback) tries the active user first, then the effective user (whoever the script is running as), then an OPERATOR_EMAIL Script Property, then the fallback you pass. You always get something to stamp.
When to use
- “Last edited by” or “Approved by” stamps written from triggers
- Audit logs in web apps deployed to execute as you
- Any place you'd otherwise write a blank cell and wonder who did it
How to use this snippet
/**
* Best available email for audit stamps.
* Order: active user → effective user → OPERATOR_EMAIL Script Property → fallback.
*
* @param {string=} fallback used when everything else is blank (e.g. 'unknown')
* @return {string}
*/
function activeUserEmailOr(fallback) {
var email = '';
try { email = Session.getActiveUser().getEmail(); } catch (e) {}
if (!email) {
try { email = Session.getEffectiveUser().getEmail(); } catch (e) {}
}
if (!email) {
email = PropertiesService.getScriptProperties().getProperty('OPERATOR_EMAIL') || '';
}
return email || fallback || '';
}
Example
function onApprove(e) { // installable onEdit trigger
var sh = e.range.getSheet();
if (sh.getName() !== 'Approvals' || e.range.getColumn() !== 4) return;
sh.getRange(e.range.getRow(), 5).setValues([[activeUserEmailOr('unknown')]]);
sh.getRange(e.range.getRow(), 6).setValue(new Date());
}
Tips:
- Know what you're stamping. The effective user is the person the script runs as (often the trigger owner), not necessarily who clicked. Label the column “Recorded by” if that's what it is.
- If you need the real editor in a web app, deploy it to execute as the user accessing it. In a sheet,
e.useron an edit event has the same domain limits. - Set
OPERATOR_EMAILto a shared ops inbox so stamps point to someone who can answer questions.
Tip: NitroGAS Co-Pilot can replace scattered Session.getActiveUser() calls with activeUserEmailOr across a project. Paste the functions that write audit stamps.
Happy Coding!
