Time: 30 minutes | Level: Some SuiteScript helps
You will learn: How to build, deploy and test a script that posts to Slack when a big order is saved.
You will need: A NetSuite sandbox, the webhook URL from Step 1, and permission to deploy scripts.
This is the fun one. By the end of this page a real NetSuite sales order will trigger a real message in Slack.
What we are building: an alert for big orders. Whenever a new sales order over a set amount is created, NetSuite posts a short message to a Slack channel. The message shows the customer and the total, with a link straight to the order.
How it works, in plain English
- Someone saves a new sales order.
- NetSuite runs a User Event script in the
afterSubmitstep, which means after the record has safely saved. - The script checks the total. If it is below your threshold, it does nothing.
- If it is above, the script sends a small package of JSON to the Slack webhook.
- Slack shows the message in your channel.
We use afterSubmit on purpose. That way, if anything goes wrong with Slack, the sales order is already saved and the user is not affected.
What you need
- The webhook URL from Step 1.
- A NetSuite sandbox.
- A way to upload files: Documents > Files > SuiteScripts in the File Cabinet.
Part A: The script
Create a file called ns_slack_big_order_ue.js and paste in the following.
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
* @NModuleScope SameAccount
*
* Posts a Slack message when a large sales order is created.
*/
define(['N/https', 'N/runtime', 'N/url', 'N/log'],
(https, runtime, url, log) => {
const afterSubmit = (context) => {
// Never let a Slack problem break saving an order.
try {
// Only care about brand new orders.
if (context.type !== context.UserEventType.CREATE) return;
const script = runtime.getCurrentScript();
const webhookUrl = script.getParameter({ name: 'custscript_slack_webhook_url' });
const threshold = Number(script.getParameter({ name: 'custscript_slack_big_order_min' })) || 10000;
if (!webhookUrl) {
log.error('Slack alert skipped', 'The webhook URL parameter is empty.');
return;
}
const order = context.newRecord;
const total = Number(order.getValue({ fieldId: 'total' })) || 0;
if (total < threshold) return;
const tranId = order.getValue({ fieldId: 'tranid' });
const customer = order.getText({ fieldId: 'entity' });
const shipDate = order.getText({ fieldId: 'shipdate' }) || 'not set';
// Build a link that opens the order in NetSuite.
const domain = url.resolveDomain({ hostType: url.HostType.APPLICATION });
const path = url.resolveRecord({ recordType: 'salesorder', recordId: order.id });
const link = 'https://' + domain + path;
const message = {
text: ':moneybag: *Big order received*\n' +
'*Order:* <' + link + '|' + tranId + '>\n' +
'*Customer:* ' + customer + '\n' +
'*Total:* $' + total.toFixed(2) + '\n' +
'*Ship date:* ' + shipDate
};
const response = https.post({
url: webhookUrl,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(message)
});
if (response.code !== 200) {
log.error('Slack returned an error', response.code + ' ' + response.body);
}
} catch (e) {
// Log it and move on. The order is already saved.
log.error('Slack alert failed', e.name + ': ' + e.message);
}
};
return { afterSubmit };
});
What each part does
- The header comment (
@NApiVersion,@NScriptType) is required. It tells NetSuite this is a 2.1 User Event script. define([...])loads the NetSuite modules we use:N/httpsto call Slack,N/runtimeto read settings,N/urlto build the order link andN/logto write to the Execution Log.context.type !== CREATEmeans “only run for new records”, so editing an order later does not spam the channel.getParameterreads settings from the script deployment, so nothing secret or changeable is hard-coded in the file.tryandcatchmake sure a Slack outage can never stop someone from saving an order.https.postsends the message. Slack replies with HTTP 200 and the textokwhen it works.
Part B: Upload the script
- Go to Documents > Files > SuiteScripts.
- Click Add File and upload
ns_slack_big_order_ue.js. A folder such asSuiteScripts/SlackIntegrationkeeps things tidy.
Part C: Create the script record
- Go to Customization > Scripting > Scripts > New.
- Choose your uploaded file and click Create Script Record.
- Give it a name like
Slack - Big Order Alert. - Set the ID to something like
_slack_big_order_ue.
Add two script parameters
While still on the script record, open the Parameters subtab and add:
| Label | ID | Type |
|---|---|---|
| Slack Webhook URL | custscript_slack_webhook_url |
Free-Form Text |
| Big Order Minimum | custscript_slack_big_order_min |
Currency or Decimal Number |
NetSuite adds the custscript prefix automatically, so check that the final IDs match what the script reads. Save the script.
A quick note on secrets: a script parameter is fine for testing. Before you go live, read Step 3 about keeping the webhook URL safer.
Part D: Deploy it
- On the script record, open the Deployments subtab and click Add, or go to Customization > Scripting > Script Deployments > New.
- Set Applies To to Sales Order.
- Set Status to Testing while you experiment (it only runs for the deploying user), and Released when you are happy.
- Fill in the parameters: paste your webhook URL and set a low minimum (for example 100) so you can test easily.
- Under Audience, choose who the script should run for. Roles and Employees can both be set.
- Save.
Part E: Test it
- Create a new sales order in your sandbox with a total above your minimum.
- Save it.
- Look at your Slack test channel. Your message should appear within a few seconds.
Not there? Go to Customization > Scripting > Script Deployments, open your deployment, click the Execution Log subtab, and look for errors. Common causes are listed on the troubleshooting page.
Ways to adapt it
- Different record? Change
applies toand the record type inurl.resolveRecord. For an invoice, use'invoice'. For a purchase order,'purchaseorder'. - Different trigger? Alert on edits by removing the CREATE check, or check whether a field changed by comparing
context.oldRecordandcontext.newRecord. - Different channel? Create another webhook for another channel and use another deployment with its own parameter value.
- Only certain customers or subsidiaries? Add another
ifthat checks the field and returns early.
A note on limits
Each https.post call uses governance units (Oracle documents this per method), and a User Event script has a per-execution allowance. One Slack call per order is well within limits. If you ever need to send dozens of messages from one save, hand that work to a Map/Reduce or Scheduled script instead. See Best Practices.
What is next
Your alert works, but the webhook URL is sitting in a plain parameter. Step 3 shows how to handle secrets responsibly.