๐งฉ Email Automation & Template Management in NetSuite
Introduction
Email is one of the most powerful tools inside NetSuite โ used for everything from invoice delivery to integration alerts.
Yet, many companies still hardcode messages into scripts or rely on static workflow emails.
With the right framework, you can automate data-driven, dynamic emails that adapt to transaction type, subsidiary, language, or user role โ all from a central configuration hub.
๐ก Why Centralize Email Management?
Problem | Without Automation | With Email Framework |
---|---|---|
Static Messages | Hardcoded email content | Configurable templates |
Inconsistent Branding | Different layouts | Standard design |
Hard Maintenance | Edit script to change wording | Update template record |
No Logs | Hard to track sent emails | Centralized logging record |
No Localization | One language only | Multi-language support |
โ Goal: One reusable system for all NetSuite-driven emails.
๐งฑ Step 1: Create a Custom Record for Email Templates
Name: Email Template Library
ID: customrecord_email_template
Field Label | ID | Type | Description |
---|---|---|---|
Template Key | custrecord_email_key | Text | Unique key like โINV_SENDโ |
Subject | custrecord_email_subject | Text | Email subject line |
Body | custrecord_email_body | Long Text | Supports FreeMarker or HTML |
Active | custrecord_email_active | Checkbox | Enables/disables |
Language | custrecord_email_lang | List | Optional localization |
Audience | custrecord_email_audience | List | Customer / Vendor / Internal |
Notes | custrecord_email_notes | Long Text | Internal documentation |
๐ก Each template becomes reusable by any script or workflow.
โ๏ธ Step 2: Build a Utility Script to Fetch & Merge Templates
/**
* @NApiVersion 2.1
* @NModuleScope Public
*/
define(['N/search', 'N/render'], (search, render) => {
const getTemplate = (key, lang='en') => {
const results = search.create({
type: 'customrecord_email_template',
filters: [['custrecord_email_key', 'is', key], 'AND', ['custrecord_email_lang', 'anyof', lang]],
columns: ['custrecord_email_subject', 'custrecord_email_body']
}).run().getRange({ start: 0, end: 1 });
if (!results.length) return null;
return {
subject: results[0].getValue('custrecord_email_subject'),
body: results[0].getValue('custrecord_email_body')
};
};
const mergeTemplate = (body, data) => {
const template = render.create();
template.templateContent = body;
template.addCustomDataSource({
alias: 'data',
format: render.DataSource.OBJECT,
data
});
return template.renderAsString();
};
return { getTemplate, mergeTemplate };
});
โ
This utility fetches template content and merges dynamic data (like {data.customer}
or {data.total}
) into it.
๐ง Step 3: Example Email Script for Transactions
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
*/
define(['N/email', 'N/runtime', 'N/record', './lib/emailUtil', 'N/log'],
(email, runtime, record, emailUtil, log) => {
const afterSubmit = (ctx) => {
if (ctx.type === ctx.UserEventType.DELETE) return;
const rec = ctx.newRecord;
const recType = rec.type;
const recId = rec.id;
const template = emailUtil.getTemplate('INV_SEND');
if (!template) {
log.error('Missing Template', 'Template INV_SEND not found');
return;
}
const customer = record.lookupFields({
type: 'customer',
id: rec.getValue('entity'),
columns: ['email', 'companyname']
});
const mergedBody = emailUtil.mergeTemplate(template.body, {
tranid: rec.getValue('tranid'),
total: rec.getValue('total'),
customer: customer.companyname
});
email.send({
author: runtime.getCurrentUser().id,
recipients: customer.email,
subject: template.subject,
body: mergedBody
});
log.audit('Email Sent', `Invoice #${recId} โ ${customer.email}`);
};
return { afterSubmit };
});
โ Auto-sends personalized invoices using your stored template.
๐งฉ Step 4: Add Dynamic Variables in Templates
Use placeholders in your template body:
<p>Hello ${data.customer},</p>
<p>Your invoice <b>#${data.tranid}</b> totaling <b>${data.total}</b> has been issued.</p>
<p>Thank you for your business!</p>
๐ก You can extend with:
${data.date}
${data.salesrep}
${data.url}
โ Merge any record field or computed value dynamically.
๐งฎ Step 5: Integrate with PDF Attachments
Combine with your PDF Automation System to send both message + attachment:
attachments: [pdfFile]
โ Fully automated, branded invoice delivery.
โก Step 6: Email Logging Framework
Create another custom record: customrecord_email_log
Field | Description |
---|---|
Template Key | INV_SEND / APPROVAL_REMINDER |
Recipient | Email address |
Status | Sent / Failed |
Record ID | Source record |
Timestamp | Date sent |
Message | Error or confirmation text |
โ Allows monitoring of all automated emails for compliance or troubleshooting.
๐งฑ Step 7: Add Language & Subsidiary Logic
Extend your utility to pick templates dynamically:
getTemplate(key, lang = currentUser.language, subsidiaryId)<br>
โ Enables multilingual, multi-subsidiary communication.
๐งฉ Step 8: Trigger Emails via Workflows or Map/Reduce
- Workflow Action Script: send approval reminders.
- Map/Reduce Script: send bulk statements or customer updates.
- Scheduled Script: nightly reports to managers.
โ Scalable for both transactional and operational notifications.
๐ง Step 9: Centralized Email Dashboard
Create a SuiteAnalytics Workbook or portlet:
- Emails Sent This Week
- Top 5 Failed Templates
- Most Used Template Keys
- Delivery Rate by Type
โ Visibility for Admins, Finance, and IT.
โ๏ธ Step 10: Best Practices
Category | Tip |
---|---|
Security | Never hardcode email addresses; fetch dynamically |
Performance | Queue bulk sends using Map/Reduce |
Compliance | Include unsubscribe or footer in marketing emails |
Branding | Use consistent HTML & CSS templates |
Testing | Validate templates with sandbox test data |
๐ Related Tutorials
- ๐ Custom PDF Automation System
- ๐ Dynamic SuiteScript Configuration Framework
- ๐ Security & Governance Framework
โ FAQ
Q1. Can templates include inline CSS?
Yes, inline styles are supported; external CSS is not.
Q2. Can I store templates per subsidiary?
Yes โ add a Subsidiary field to the custom record.
Q3. Can non-technical users edit templates?
Yes, give them access to the Email Template Library record.
Q4. Can I attach multiple files?
Yes โ include multiple file IDs in the attachments array.
๐งญ Summary
The Email Automation & Template Management Framework lets you deliver personalized, branded, and compliant emails automatically.
By combining template storage, data-driven placeholders, and SuiteScript automation, you eliminate manual messaging, standardize communications, and gain complete control over customer-facing communication in NetSuite.
This system can power everything from invoices and order confirmations to integration alerts and approval notifications, turning NetSuite into a smart communication hub.
Leave a Reply