Want to send attchment(excel sheet) through inbound email action and information is populated on incident table

Harsha1
Tera Contributor

Hello,

I want to send a attachment  (through mail) excel sheet Information into the servicenow with the help of inbound email action. and the information is populated on the incident table. please provide step by step process.

 

Thanks & Regards,

Harsha

1 ACCEPTED SOLUTION

Hello Harsha,

Below are the steps I performed on your instance to achieve your requirement.

1. Created Transform Map and Import Set table: 

Transform Map Name :Incident Creation from Inbound

Import set table Name : Incident Template(x_433801_email_incident_template)

Field Mappings : State, Category & Short Description,

Note : In case you need to add more fields in excel then you need to create a field mapping in transform maps as well.

2. Created a Inbound Action :

Name : "Create Incident With Attachment" with below code :

Table : Data Source (sys_data_source)     

Condition : Subject STARTS WITH "Template: Incident Creation"       

Order : 50

Script :

(function runAction( /*GlideRecord*/ current, /*GlideRecord*/ event, /*EmailWrapper*/ email, /*ScopedEmailLogger*/ logger, /*EmailClassifier*/ classifier) {

var importSetTableName = "x_433801_email_incident_template";
var applicatonScope = "Email";
var transformMapIDs = "1d10d3e52fbed010622959a72799b611";


// Create the datasource record
current.name = "File import from: " + email.from; //Feel free to rename this as appropriate
current.import_set_table_name = importSetTableName;
current.file_retrieval_method = "Attachment";
current.type = "File";
current.format = "Excel"; // For Excel Files
//current.format = "CSV"; // For CSV Files
current.header_row = 1;
current.sheet_number = 1;
current.sys_package.setDisplayValue(applicatonScope);
current.sys_scope.setDisplayValue(applicatonScope);
var dataSourceID = current.insert();

new global.EmailFileImportUtils().scheduleImport(dataSourceID, transformMapIDs);

})(current, event, email, logger, classifier);

3. Created a Script Include In Global Application scope: If you are creating with in scoped application then schedule will be created in sys_trigger table and your transform wont run.

Name : EmailFileImportUtils

API Name : global.EmailFileImportUtils

Accessible from : All application Scope

Script :

var EmailFileImportUtils = Class.create();
EmailFileImportUtils.prototype = {
initialize: function() {},

scheduleImport: function(dataSourceID, transformMapIDs) {

var schRec = new GlideRecord("sys_trigger");
schRec.name = "Load Data Source: " + dataSourceID;
schRec.trigger_type = 0; // Run Once
schRec.script = "new global.EmailFileImportUtils().loadImportSet('" + dataSourceID + "', '" + transformMapIDs + "')";

var nextAction = new GlideDateTime();
nextAction.addSeconds(30); // 30 seconds should be enough time however this can be changed.
schRec.next_action = nextAction;
var triggerID = schRec.insert();
gs.info("triggerID:" + triggerID);
},

loadImportSet: function(dataSourceID, transformMapIDs) {

// Get Datasource Record
var dataSource = new GlideRecord("sys_data_source");
dataSource.get(dataSourceID);

// If CSV and header isn't on row 1, recreate attachment with empty rows removed, and delete original
if (dataSource.getValue("format") == "CSV" && dataSource.getValue("header_row") > 1) {
var attachmentRec = new GlideRecord("sys_attachment");
attachmentRec.addQuery("table_sys_id", dataSource.getValue("sys_id"));
attachmentRec.query();
if (attachmentRec.next()) {
var oldAttachmentID = attachmentRec.getValue("sys_id");
var inputStream = new GlideSysAttachment().getContentStream(oldAttachmentID);
var textReader = new GlideTextReader(inputStream);
var ln = " ";
var newLine = "";

var lineCounter = 0;
var headerRow = parseInt(dataSource.getValue("header_row"));
while ((ln = textReader.readLine()) != null) {
lineCounter += 1;
if (lineCounter < headerRow) {
continue;
}

if (ln.length > 1) {
newLine += ln + "\n";
}
}
new GlideSysAttachment().write(dataSource, 'Changed ' + attachmentRec.getValue('file_name'), "text/csv", newLine);
//Delete original email attachment so that the new one is processed. If two remain, API may get confused on which one to process.
attachmentRec.deleteRecord();
}
}

// Process data source file
var loader = new GlideImportSetLoader();
var importSetRec = loader.getImportSetGr(dataSource);
var ranload = loader.loadImportSetTable(importSetRec, dataSource);
importSetRec.state = "loaded";
importSetRec.update();

// Transform import set
var transformWorker = new GlideImportSetTransformerWorker(importSetRec.sys_id, transformMapIDs);
transformWorker.setBackground(true);
transformWorker.start();
},

type: 'EmailFileImportUtils'

};

Please let me you if you are facing issue while testing or any explanation required on codes.

Please mark as Correct Answer and Helpful, if applicable.
Thank You!
Abhishek Gardade
ServiceNow MVP 2020

Thank you,
Abhishek Gardade

View solution in original post

12 REPLIES 12

Willem
Giga Sage
Giga Sage

Step 1. Create the Import Set Table and Transform Map(s)
The easiest way to create the Import Set Table is to manually load a sample file using the Load Data wizard on the left navigation menu in ServiceNow. Then create your Transform Maps and make sure they are linked to this new Import Set Table.

Step 2. Create the Inbound Email Action

Set the following fields on the Inbound Action record:
Target table: Data Source [sys_data_source]
Action type: Record Action
Script:

(function runAction(current, event, email, logger, classifier) {  
                
                // modify the next 2 lines with the names of your Import Set Table.
                var importSetName = "myImportSet";
		   var importSetLabel= "my_import_set_table_name";

   var applicationScope = "Global"; 

                // setup the data source
                current.name = importSetName + " " + gs.nowDateTime();
                current.import_set_table_name = importSetLabel;
                current.import_set_table_label = importSetName;
                current.type = "File";
                current.format = "Excel";
                current.sheet_number = 1;
                current.header_row = 1;
                current.file_retrieval_method = "Attachment";
                current.sys_package.setDisplayValue(applicationScope);
                current.sys_scope.setDisplayValue(applicationScope);
                var myDS = current.insert();

                new global.EmailFileImportUtils().scheduleImport(myDS);  
     
})(current, event, email, logger, classifier);  

Step 3. Create the Script include

Set the following fields:
Name:EmailFileImportUtils
Script:

var EmailFileImportUtils = Class.create();  
EmailFileImportUtils.prototype = {  
    initialize: function() {  
    },  
      
    scheduleImport: function(dataSourceID) {  
        /* 
         * Create scheduled job to process import 
         * 
         * will generate an import data source, however the attachment 
         * isn't copied to the data source until after the record insert.
         * The code below creates a scheduled job to process the file import
         * 30 seconds later so that attachment has time to be copied to the
         * data source from the email. 
         */  
          
        var schRec = new GlideRecord("sys_trigger");  
        schRec.name = "Load Data Source: " + dataSourceID;  
        schRec.trigger_type = 0; // Run Once  
        schRec.script = "new global.EmailFileImportUtils().loadImportSet('" + dataSourceID + "')";  
          
        var nextAction = new GlideDateTime();  
        nextAction.addSeconds(30); // 30 seconds however this can be changed.  
        schRec.next_action = nextAction;  
        schRec.insert();  
    },  
      
    loadImportSet: function(dataSourceID) {  
        // Get Datasource Record  
        var dataSource = new GlideRecord("sys_data_source");  
        dataSource.get(dataSourceID);  
          
        // Process data source file  
        var loader = new GlideImportSetLoader();  
        var importSetRec = loader.getImportSetGr(dataSource);  
        var ranload = loader.loadImportSetTable(importSetRec, dataSource);  
        importSetRec.state = "loaded";  
        importSetRec.update();  
          
        // Transform import set  
        this._doTransform(importSetRec); 
    },  
      
    _doTransform: function(set){
        var importSetRun = new GlideImportSetRun(set.getUniqueValue());
        var importLog = new GlideImportLog(importSetRun, set.data_source.name);
        var ist = new GlideImportSetTransformer();

        ist.setLogger(importLog);
        ist.setImportSetRun(importSetRun);
        ist.transformAllMaps(set);
     },
    type: 'EmailFileImportUtils'  
};





Please refer to:

https://servicenowexpert.wordpress.com/2019/01/28/auto-load-excel-spreadsheet-using-email-inbound-ac...

Subhojit Das
Kilo Guru

Hi Harsha,

 

Please refer the link https://community.servicenow.com/community?id=community_blog&sys_id=908c26e1dbd0dbc01dcaf3231f9619c4

Please mark as Correct and Helpful if the link resolved your issue.

 

Regards,

Subhojit

 

Harsha1
Tera Contributor

Hello,

Thank you for your response.

I do all process above mentioned. But I phase some problem.I am new to learn ServiceNow.

I created inbound email action and script include. But when l send data(excel sheet) into  snow the information not showing on the incident.

Also  New attacthed file(excel) not get into the data source. So please suggest me what I do ?

 

Thanks & Regards,

Harsha

In addition to Willem's response,

You need to copy attachment to Data Source from Incident table to Data Source, so your data source will process your attachment.

#Copying an Attachment from One Table/Record to Anothet Table/Record:

Copying all of the attachments associated with a given record is fairly straightforward. You simply call the copy method of the GlideSysAttachment class, and pass in four parameters:

  • The table you want to copy the attachment from (incident, change_request, etc.).
  • The sys_ID of the record you want to copy the attachment from.
  • The table that you want to copy the attachment to.
  • The sys_ID of the record you want to copy the attachment to.

This might look something like this: 

var donorTable = sc_req_ite’;//

var donorID = '2b6644b15f1021001c9b2572f2b47763';

var recipientTable = sc_task; //

var recipientID = '78e47fe94f31d200bf004a318110c7d4';

GlideSysAttachment.copy(donorTable, donorID, recipientTable, recipientID);

Thank you,

Abhishek Gardade

Thank you,
Abhishek Gardade