This article is relevant if you seek to automatically populate NetSuite’s email composer with a list of email addresses.
Background
As we assist our clients in automating their billing, a frequent request is the ability to add more email addresses to the invoice processing distribution list. This is largely focused on enabling hands-free mass processing and distribution of transactions.
However, there are occasions when manual message crafting is necessary. NetSuite provides a native email composer that allows users to create communications manually. The core content of these emails can be efficiently generated using NetSuite’s template system.
Despite this, other time-saving capabilities are needed. Building on my 2020 article, Get Control over NetSuite’s Email Reply-To Address, and my 2016 article, on how to automatically add attachments, we aim to automatically add additional recipients to the email sublist. This automation will save time and reduce the risk of errors.
Add Additional Email Addresses to the Transaction
The key to adding additional email addresses for transaction processing (e.g., Invoices) is determining how you will store them. There are several approaches you can take.
In 2015, I discussed a method to Extend NetSuite’s Transaction Email Address List to handle this. The main idea is to create a custom field at the customer level that holds a semicolon-separated list of email addresses. Then, during invoice processing, populate NetSuite’s native {email} field with these addresses. The great news is that NetSuite will automatically send emails to these addresses if the {tobeemailed} checkbox is selected when the transaction is saved.
Once we identify the source of the email addresses we need, we can enhance NetSuite’s native email composer (communications) feature accordingly.
Click images to see them full-size for clarity.
SuiteScript to Populate Additional Email Recipients
With the source of additional email addresses identified, you can use the following pattern to implement a solution. The NetSuite Message Composer provides access to the source transaction it originates from, allowing you to easily look up the {email} field on that transaction. You can then parse this field into a list to populate NetSuite’s native ‘additional recipients’ sublist.
Note that while the ‘additional recipients’ list (otherrecipientslist) is not documented in NetSuite’s Help, it follows standard approaches for driving data into forms.
/* * Description: add more capability to a message when clicking * the Email button inside the message subtab */ /** * @NApiVersion 2.1 * @NScriptType UserEventScript * @NModuleScope Public */ define(['N/record', 'N/search', 'N/runtime', 'N/error'], function(record, search, runtime, error) { var scriptName = "article_message_ue_21."; /* --------------------------------------------------- */ function beforeLoad(context) { var funcName = scriptName + "beforeLoad " + context.type + " " + context.newRecord.type + " " + context.newRecord.getValue("id") + " via " + runtime.executionContext; try { var REC = context.newRecord; //run only if in create on the user interface if (context.type != context.UserEventType.CREATE) return; if (runtime.executionContext != runtime.ContextType.USER_INTERFACE) return; //get the values on the url parametes to help see the composer source var str =""; var params = context.request.parameters; log.debug(funcName,'params: '+JSON.stringify(params)); var rootRecType = ''; var recid = ''; //use the following source pattern the help drive the value lookups if(!isEmpty(params.transaction)) { recid = params.transaction; rootRecType= 'TRANSACTION'; } else if(!isEmpty(params.record)) { recid = params.record; rootRecType = 'CUSTOMRECORD'; } else { recid = params.entity; rootRecType = 'ENTITY'; } log.debug(funcName,'recid: '+recid); if(isEmpty(recid)){ log.debug(funcName, 'No record or transaction found'); return; } //now do the lookup work which will vary based on your solution var rectype = ''; var email = ''; if(rootRecType == 'TRANSACTION') { lookupResults = search.lookupFields({ type: search.Type.TRANSACTION, id: recid, columns: ['recordtype', 'email'] }) rectype = lookupResults.recordtype email = lookupResults.email } else if(rootRecType == 'CUSTOMRECORD'){ rectype = params.recordtype; } else if(rootRecType == 'ENTITY'){ rectype = params.entitytype; } log.debug(funcName,'rectype: '+ rectype); log.debug(funcName,'email: '+ email); if(isEmpty(rectype)){ log.debug(funcName, 'No record type found'); return; } //in this solution, we know the email list is semicolon separated var emaillist = email.split(';') log.debug(funcName,'emaillist: '+ JSON.stringify(emaillist)); //add to the email sublist the emails that were selected var line = 0 emaillist.forEach((element) => { log.debug(funcName,'emaillist: '+ line + ':' + element); if (element){ REC.insertLine({ sublistId: 'otherrecipientslist', line: line }); REC.setSublistValue({ sublistId: 'otherrecipientslist', fieldId: 'email', line: line, value: element }); // use 'cc' or 'bcc' for other fields REC.setSublistValue({ sublistId: 'otherrecipientslist', fieldId: 'toRecipients', line: line, value: 'T' }); } line++ }); } catch (e) { log.error(funcName, e); } } /* --------------------------------------------------- */ function isEmpty(val) { if(typeof(val) == 'object'){ for(var key in val) { if(val.hasOwnProperty(key)) return false; } return true; } else{ return (val == null || val == '' || val == undefined); } } return { beforeLoad: beforeLoad, } });
If you prefer to download this code, click here.
Drive Enhanced NetSuite Email Processing
This solution aims to inspire NetSuite Administrators with SuiteScript experience. It leverages the capabilities of the NetSuite extensibility platform to create better user experiences. It’s important to remember that NetSuite is designed to be enhanced, meaning we’re never truly stuck. With innovation, we can always find a way to get the job done.
If you found this article relevant, feel free to sign up for notifications to new articles as I post them. If you are the type of professional who would enjoy being part of a team that gets to produce these solutions every day, let’s have a conversation.
Good morning,
First of all, thank you for all the great content, I feel like you have been helping us all out through our NetSuite career.
Second of all, I’m having an issue trying to implement a solution that is similar to this.
I have tried deploying a UserEvent script on the message record. I’m receiving an invalid sublist operation error. I have tried deploying a CS on the message record but to no avail. Tried also to deploy it in an entity userevent, but also did not work. I am sure there must be something I’m missing.
I would be very grateful if you could shed some light into this issue.
Best regards!
Hello Victor. Please send over the code snippet (or screenshot) so that we can have a review.
Marty