Jaime Requena
–
April 6, 2023
NetSuite’s sFTP module lets you send and receive files from an sFTP server. In this article I will detail a customization to send and receive files using the sFTP module. The customization will use a custom record to save the connection details. We will be using a key file to login to the sFTP server. This customization will not detail using a password to login.
The custom record will allow you to connect to multiple sFTP servers. The scheduled script that sends/receives files (detailed later) will have a reference to the specific sFTP configuration.
In your sFTP server you should have the option to create an sFTP key. Save the key to a file. Now upload the key to NetSuite:
Click Save. You now see the key. Make a note of the ID as it will be used when creating the sFTP configuration record
Go to a command prompt in Windows and type:
ssh-keyscan -t rsa -p <port> rsa <URL of sFTP server> (Example: ssh-keyscan -t rsa -p 22 rsa sftp.yourdomain.com). It will print out something like this:
Copy this text and put it in a file to reference when creating the sFTP configuration record.
Add and deploy the script (code shown below). Reference my article “Quick Guide to Adding and Deploying a Script in NetSuite” if needed. You will need to create a script parameter “sFTP Configuration Internal ID” of type Integer. When deploying the script you will need to set this to the ID of the record you created which should be.
The script below does the following:
/**
* @NApiVersion 2.1
* @NScriptType ScheduledScript
*/
define(['N/runtime', 'N/search', 'N/file', 'N/sftp'],
(runtime, search, file, sftp) => {
const execute = (scriptContext) => {
log.debug('==START==');
try {
// get the sFTP config
const sftpConfig = getsFTPConfig();
const files = getFilesToSend(sftpConfig);
// send files to sftp site
sendTosFTPServer(files, sftpConfig);
// download files from sftp site
downloadFromsFTPServer(sftpConfig);
}
catch(e) {
log.error('Error', JSON.stringify(e));
}
log.debug('==END==');
}
const getFilesToSend = (sftpConfig) => {
let files = [];
let folderSearchObj = search.create({
type: "folder",
filters: [
["internalidnumber","equalto", sftpConfig.toprocessDirectory]
],
columns:
[
search.createColumn({
name: "internalid",
join: "file",
label: "Internal ID"
})
]
});
folderSearchObj.run().each(function(result){
let fileId = result.getValue({
name: "internalid",
join: "file",
label: "Internal ID"
});
files.push(fileId);
return true;
});
log.debug('Files to send',JSON.stringify(files));
return files;
}
const sendTosFTPServer = (files, sftpConfig) => {
const connection = sftp.createConnection({
username: sftpConfig.username,
keyId: sftpConfig.myKey,
url: sftpConfig.url,
directory: sftpConfig.directory,
hostKey: sftpConfig.myHostKey,
port: sftpConfig.port
});
log.debug('connection', "connected");
let fileName = '';
for (let i = 0; i < files.length; i++) {
let fileId = files[i];
errorMessage = '';
let myFileToUpload = file.load({
id: fileId
});
fileName = myFileToUpload.name;
connection.upload({
filename: fileName,
file: myFileToUpload,
replaceExisting: true
});
log.debug('uploaded file', fileName);
if (sftpConfig.completeDirectory) {
// move to complete folder
myFileToUpload.folder = sftpConfig.completeDirectory;
let fileId = myFileToUpload.save();
log.debug('moved file to complete folder');
}
}
}
const downloadFromsFTPServer = (sftpConfig) => {
const connection = sftp.createConnection({
username: sftpConfig.username,
keyId: sftpConfig.myKey,
url: sftpConfig.url,
directory: sftpConfig.directory,
hostKey: sftpConfig.myHostKey,
port: sftpConfig.port
});
log.debug('connection', "connected");
// get the list of files in the directory
const files = connection.list({
path: ''
});
// download each file
for (let i = 0; i < files.length; i++) {
const downloadedFile = connection.download({
directory: '',
filename: files[i].name
});
downloadedFile.folder = sftpConfig.completeDirectory;
downloadedFile.save();
log.debug('saved file to complete folder', files[i].name);
}
}
const getsFTPConfig = () => {
// use a parameter to get the internal ID of the sFTP configuration record to use
const scriptObj = runtime.getCurrentScript();
const serverConfigId = scriptObj.getParameter({
name: 'custscript_config_id'
});
log.debug('serverConfigId=', serverConfigId);
const conn = search.lookupFields({
type: 'customrecord_sftp_configuration',
id: serverConfigId,
columns: [
'custrecord_sftp_config_user',
'custrecord_sftp_config_key',
'custrecord_sftp_config_url',
'custrecord_sftp_config_port',
'custrecord_sftp_config_host_key',
'custrecord_sftp_config_directory',
'custrecord_sftp_config_to_process',
'custrecord_sftp_config_complete'
]
});
let sftpConfig = {};
sftpConfig.myKey = conn.custrecord_sftp_config_key;
sftpConfig.myHostKey = conn.custrecord_sftp_config_host_key;
sftpConfig.username = conn.custrecord_sftp_config_user;
sftpConfig.port = conn.custrecord_sftp_port;
sftpConfig.url = conn.custrecord_sftp_config_url;
sftpConfig.directory = conn.custrecord_sftp_config_directory;
sftpConfig.toprocessDirectory = conn.custrecord_sftp_config_to_process;
sftpConfig.completeDirectory = conn.custrecord_sftp_config_complete;
log.debug('username=', sftpConfig.username);
log.debug('port=', sftpConfig.port);
log.debug('url=', sftpConfig.url);
log.debug('myKey=', sftpConfig.myKey);
log.debug('myHostKey=', sftpConfig.myHostKey);
log.debug('directory=', sftpConfig.directory);
log.debug('toprocessDirectory=', sftpConfig.toprocessDirectory);
log.debug('completeDirectory=', sftpConfig.completeDirectory);
return sftpConfig;
}
return {execute}
});
The sFTP module is a powerful module that allows files to be transferred into and out of NetSuite. This customization allows you to have multiple sFTP configurations without having to hardcode values into a script. If you need help scripting or customizing NetSuite please contact Suite Tooth consulting here to set up a free consultation.
If you liked this article, please sign up for my newsletter to get these delivered to your inbox here.
Do not hesitate to contact us. We’re a team of experts ready to talk to you.