jason_petty
Tera Expert

The method below was originally published on Oct 25, 2012, is an outdated process

Please see the following post for help! >   Loading data from an email attachment


I had a number of people respond to this post with the same problem and together with my colleague I re-wrote the instructions to make it work.

I had a customer that wanted to have IBM Maximo product send an email to ServiceNow and have a CSV/XLS file attached to the email automatically create a new Data Source, load the data, then transform it all automatically just from receiving the email. Here is what I did to get that to work:


1. Create a Data Source Manually first so you can set up the Import Set Table and the Transform Map that you will use later. This is necessary since you need a Transform Map defined before you send the email inbound to ServiceNow. This Data Source can be deleted after creating the Import Set Table and Transform Map.
2. Get a sample CSV/XLS file and attach it to the Data Source and load the data at least once.
3. Define your Transform Map and set it up so the data is getting transformed into the right table in the format that you need.
4. Create a user that you will use for basic authentication with no roles and has a password.
5. Create a REST Message that points to your own instance for the REST endpoint: https://instancename/sys_import.do as the url named "Inbound Import Set Poster"
6. Check the box for "Use basic auth" and set the username and password from step #4
7. Edit the "get" function and add the following function parameters:

8. Create an Inbound Email Action with the following settings:

HERE IS THE CODE TO COPY:



if (current.getTableName() == "sys_data_source") {

      current.name = email.subject.substring(3);
      current.import_set_table_label = email.body.import_set_table_label;
      current.import_set_table_name = email.body.import_set_table_name;
      current.file_retrieval_method = email.body.file_retrieval_method;
      current.format = email.body.format;

      current.update();

var r = new RESTMessage('Inbound Import Set Poster', 'get');
r.setStringParameter('tableLabel', encodeURIComponent(current.name));
r.setStringParameter('customDataSource', current.sys_id);
              r.setStringParameter('tableName', current.import_set_table_name);
r.execute();
}


9. The Condition can be anything you want but the Target table needs to be sys_data_source.
10. Enable the inbound email settings in your instance to receive email and process them. See WIKI http://wiki.servicenow.com/index.php?title=Configuring_Email for this.
11. Now send an email like this to the email instancename@unix.service-now.com (The "unix" part of this avoids any email formatting issues with email clients):

  1. To: instancename@unix.service-now.com
  2. Subject: DS:Test Data Source 1
  3. Body:


              import_set_table_label:Test Import Set Table
              import_set_table_name:u_test_import_set_table
              file_retrieval_method:Attachment
              format:CSV

NOTE: CSV would be Excel if you are using an XLS file

12. Wait until the email is processed and it should have created your Data Source with whatever is after the "DS:" in the subject
13. Make sure the import_set_table_name is set to whatever you named your import set table when you created your Data Source in step 1 (This is very important since the Transform Map is linked to this table)
14. The format is set to either Excel or CSV.
15. You need to attach the file you want to attach to the Data Source.

>


The method above was originally published on Oct 25, 2012, is an outdated process

Please see the following post for help! >   Loading data from an email attachment


Comments
ServiceNow Employee
ServiceNow Employee

Great post Jason.

Love it.


Kilo Contributor

Problems with XML

Good afternoon,

I appreciate this post. However, I am being provided data in the XML format. I modified your script for my purposes so that the format is XML and the xpath_root_node is set appropriately. Now, the data source does get created automatically with the attachment. However, the automation of loading the data and having the transform map run automatically is not working. What might I be missing?


Tera Expert

Thanks. The part of the Inbound Email Action after the "current.update();" is what does the load and so when that URL is formulated with those parameters, it should do that automatically. The only thing I can think of that would cause it not to work is the import set table that you specify doesn't have a transform map linked to it. When you look at your Data Source that was created, is there a Transform Map that shows linked to it?


Kilo Contributor

Screenshot

Yes, there is. Please see the attached screenshoot.
Capture.PNG


Giga Contributor

Not Transforming

Hi

tried the above script, it is Loading the data but not transforming, any suggestion will be appreciated.


Tera Expert

What happens if you load data right there on that data source then run transform, does it work? If not, what does the log show, that might show errors.


Tera Expert

Try manually running the transform and see if it works. There must be an error occurring.


Giga Contributor

Thanks for the Response

If I Try manually it is working fine. Only the problem with the automated script. It is not generating any error in the Log


Tera Expert

Try this. Put a gs.log() statement right before the setRedirect() call at the bottom of the script to see what the url ends up being. Copy that url and paste it in a browser and see what it does. Does that work?

You could also set up your email action in a demo instance and I can look at it or I could take a quick peek in your instance.


Kilo Contributor

The URL works but ....

If I run the load manually it works fine even with the newly created data source. I was looking at the latest part of this thread and I used a gs.log() statement to write the redirect URL to the log. I took that string and prepended it with our service-now specific instance and it worked fine.

I'm still down to the automation not doing the loading of the data and transforming the data from the inbound email action.


Tera Expert

I have duplicated your issue on the Aspen Release. I will see if I can figure it out. This works on Berlin.


Tera Expert

I duplicated your issue on Aspen. This works in Berlin.


Tera Expert

Ok, after troubleshooting this I think what is happening is the setRedirect() call is not running at all. This is only happening in Aspen and Berlin works. You might want to upgrade. I can keep trying to make it work somehow and will update when I figure it out but Berlin is a good way to go.


Giga Contributor

Thanks for the Update

Anyway we are using the Berlin release only.
The aim is getting a xls fine as attachment and with reference to the data in the xls file we need to create the Incident.
Thanks for the valuable support. and appologise as i was on vaccation.
Autopopulate the Attachment.JPG


Kilo Contributor

Is there a solution for Aspen?

We are going live on Aspen and looking to update to Berlin shortly after.


Tera Expert

Make sure you have the inbound emails script the same as mine.

You should only have one current.update() before the whole URL forming.

Also, make sure you have the last parameter I have in the URL:



redirectStr += "&sysparm_transform_after_load=true";


Also, make sure you have only one setRedirect() call to the redirectStr after it is formulated.


Kilo Contributor

Using another solution

After seeing in the thread that this work in Berlin and not necessarily in Aspen, and as we are currently deploying Aspen, I have developed a work-around when I update the data source of scheduled import to what is coming in and allowing the scheduled import to handle the data load and transform.

When we update to Berlin, I will use this script as is.

One more thing though: this solution creates a number of data sources that clutter up the interface. So, I'll be adding one more schedule job that deletes "old" (greater than three days old) data source. My current need is to have data uploaded on a daily basis.


Giga Contributor

Copied the same script and tried to execute, the issue remains same, I can able to see the new entry in the Data Source with the Subject of the Mail, If I open I can able to see the attachment and below option as Load all records link and Test Load 20 Records option.

I is not Loading and Transforming the Data.

If I manually Load the Data and Transform it is working fine.

I am not knowing what is the mistake I am doing.
Attachment.PNG


Tera Expert

I have tried to set this up in demo11 instance for you to look at but I think they have inbound email capabilities disabled. I cannot get it to receive email. You could email me and I could look at your instance for a few min to see if I can see what it is. I am curious why there are multiple customers out there having the problem.


Tera Expert

I updated this post with new instructions.


Tera Expert

I updated this post with new instructions.


Kilo Contributor

Issues with Excel

Firstly I'd like to thank Jason for the original post.

Unfortunately, I'm having issues with an Excel spreadsheet that specifies the field headings on row four. I have tried modifying the REST Message Parameters to include 'sheet' and 'header_row' values, but this doesn't seem to be working.

Any advice will be greatly appreciated.

Thanks
Kathy


Tera Expert

Kathy,

I don't know of any way to do this and add parameters on the url for those options. The only way I have found how to do this is with the Load Data module where you can specify these options. I will keep looking into this and let you know if I find anything. (See attachment of screenshot)
LoadData.png


Tera Contributor

Calgary Fix?

I followed your steps in the post but do not see any results past the data source step. It was my impression that this would follow through to the completion of the transform. Does Calgary require different steps? My logs show the import set was created and then cleaned but I don't see an actual transform being run. My transform map has worked manually in the past.

EDIT: The issue is solved. Not sure what the issue was, my guess is that something behind the scenes was done out of order in the creation & population & cleaning of various import sets. Either way, it worked the second time.


Giga Contributor

Great solution

Hi Jason,
This is a great add on process for many and I know I am coming late to the game, but can you please repost your final code including the above redirect code addition.
We are implementing SNOW into prod and the CI team would really like to use this automatic method of updating the CI tables.
Thanks
Kirk


Tera Expert

I am working on a similar solution with XML data. How did you modify the script to set the format to XML and the xpath_root_node?


Kilo Contributor

by using this can we update the records


Giga Sage

Can anyone speak to the unix email address you're referring to.   I've never heard of that and would like to know what it really does but I couldn't find any documentation on it.


Kilo Expert

Post was originally written in 2012, so not sure if the unix.service-now address is still valid with some of the security enhancements made with Eureka and Fuji. I just ran through this setup and wasn't able to receive any emails when using that address, I had to use the default of instance_name@service-now.com. It worked without any issues.


Giga Sage

That's good to know


Tera Contributor

Hi Jason,



I know this is an old thread, but still very valuable, can you post the updated script and where it goes with the inclusion of the redirect?   What we see stops after the RestMessage r.execute();     Would love to see how this finishes off as it appears to be the last piece I need.   Manual import works from this, but automated transform from email does not.



Kirk, did Jason happen to send this to you that you can share?



Thanks everyone!


Kilo Contributor

Hello



its create the data source with the transform map but it not makes the transformation. maybe needs to execute the transform button?


Tera Contributor

Hey everyone, I got this working successfully recently, without using a mid-server.   Maybe this will work for you.



Make sure you have a dedicated report from your system, in my instance its Dell KACE.   You can capture whatever fields you want, but you need to pick a primary key in SN and coalesce on that field.   I picked the bios serial number, and created a new field for that data on the cmdb_ci_computer table.   Other fields I grabbed - Ram, mac address, user name, warranty end date, system name, chassis type, name, model, and manufacturer.



From KACE, you should have it email your report in a CSV format to your SN instance.  



You will need to import the data once manually so you can create the transform map.


Source table: imp_computer


Target: cmdb_ci_computer


Run business rules: no



Next, create a scheduled data import, and use the manual data source that you imported manually for the first run.   Set the timer to run sometime in the future (this won't matter because the inbound action script will kick off the run immediately)



Then you need an inbound action script.   This fortunately does all of the work for you, no extra scripts needed.   This should capture the attachment, create a new data source of the attached file, update the scheduled import set based on this, then kick off a process to import the data, and run the scheduled import.


Keep in mind I have sourced the inbound action from several different posts to make this work.   Not my code, I don't claim it as mine   (also, couldn't find the code tag, sorry!)




Inbound action:


Target table: sys_data_source


Action: record action


script:


[CODE]


// set up the data source. The system will automatically add the attachment for us.


gs.log ('TDI001 - Setting up data source');


current.name = "SNKaceImport" + gs.nowDateTime(); //append date time to name of data source for audit


current.import_set_table_label = "Computer";


current.import_set_table_name = "imp_computer";


current.type= "File";


current.format = "CSV";


current.file_retrieval_method = "Attachment";



var myNewDataSource = current.insert();



gs.lg ('TDI002 - Data source inserted with sys_id - ' + myNewDataSource);



//point the scheduled import record to the new data source


var gr2 = new GlideRecord ('scheduled_import_set');


gr2.addQuery('sys_id', '693eeccc135d62000d087981xxxxxxx'); //sys id of the Scheduled Data


gr2.query();


if (gr2.next()) {


gs.log ('TDI003 - Found Scheduled Import definition');


gr2.data_source = myNewDataSource;


gr2.update();


gs.log ('TDI004 - Scheduled Import definition updated to point to data source just added');


//Packages.com.snc.automation.TriggerSynchronizer.executeNow(gr2);   <----- old line!


SncTriggerSynchronizer.executeNow(gr2);     //<------ this works!


} else {


// add error conditions to email somebody that this has occurred


gs.log('TDI005 - ERROR - Unable to locate scheduled import definition. Please contact your system administrator');


}


gs.log ('TDI007 - Inbound email processing complete');


[/CODE]




Let me know if this doesn't work, I might be able to help with your problems.


Giga Guru

We kept the same data source, wrote it to remove the existing attachment and add the new one, then trigger the synchronizer:



//   First section deletes files attached to data source.


//   Otherwise, the second part won't overwrite, but will add on more attachments every day.


//


var gr = new GlideRecord('sys_attachment');


gr.addQuery('table_name', 'sys_data_source');


gr.addQuery('table_sys_id','913d34a4f9fedd047a219da3b79c7778');


gr.query()


while (gr.next()) {


  gr.deleteRecord();


  }


//


//   Note that the data source sys_id below is the one to which the email attachment will be affixed.


//


var emailSysId=sys_email.sys_id;


GlideSysAttachment.copy('sys_email', emailSysId, 'sys_data_source', '913d34a4f9fedd047a219da3b79c7778');


//


//   Trigger start of scheduled import


var rec = new GlideRecord('scheduled_import_set');


rec.get('name', 'PeopleSoft Import');


SncTriggerSynchronizer.executeNow(rec);


Tera Contributor

The only thing I need to do and am struggling with is: When we import computers from our KACE environment, we would like to mark them as 'installed' for the status.   Then, if the item did not get imported (because it was deleted from KACE), then it would mark that item as 'retired'.   Any thoughts on how to do this?   It's a weird thought process because we are trying to retire things that don't get updated.   Possibly could be done with another business rule, but would rather have this run after transform, so it doesn't run every day without importing data.



Any help would be appreciated, thanks!


Kilo Contributor

Thanks Matthew,



now it does execute the transform but it stack on 'Loading' state.


the email log shows that the excel spreadsheet uploaded but it desappear from the form and not forwarding to the Data Source record that created by the inbound action.


Tera Contributor

What step are you in?   I would need a little more information based on your system setup and your import data.


Kilo Contributor

user sent an email with excel file (contains uniqe name).


there is an inbound action contains the script above.


the script creating record on sys_data_source table and set all the values from the script well.


the excel file from the email is not attached to the record from some reason.


then this line 'SncTriggerSynchronizer.executeNow(gr2);'   creates import set but the import set stack on 'Loading' state and not complete the transform.


i think its happend because the excel file is not attaching to the data source.


Kilo Contributor

here is my script





if (current.getTableName() == "sys_data_source") {



  current.name = email.subject.substring(0) + ' ' + gs.nowDateTime();


  current.import_set_table_label = 'TEST';


  current.import_set_table_name = 'u_test';


  current.file_retrieval_method = 'Attachment';


  current.type = 'File';


  current.format = 'Excel';


  current.sheet_number = '1';


  current.header_row = '1';




  var myNewDataSource = current.insert();


  gs.log ('TD002 - Data source inserted with sys_id - ' + myNewDataSource);


  var gr2 = new GlideRecord ('scheduled_import_set');


  // gr2.addQuery('sys_id', '693eeccc135d62000d087981xxxxxxx'); //sys id of the Scheduled Data


  gr2.query();


  if (gr2.next()) {


  gs.log ('TDI003 - Found Scheduled Import definition');


  gr2.data_source = myNewDataSource;


  gr2.update();


  gs.log ('TDI004 - Scheduled Import definition updated to point to data source just added');


  SncTriggerSynchronizer.executeNow(gr2);


  } else {


  gs.log('TDI005 - ERROR - Unable to locate scheduled import definition. Please contact your system administrator');


  }


  gs.log ('TDI007 - Inbound email processing complete');


find_real_file.png


Giga Guru

Since the import and transform method finds correlation ids, I struggle with how you might use that to retire items that are not in the list.   I'm tossing around an idea of a business rule on the transform history table that looks for new entries for that particular import set.   When it sees a new one that meets criteria, it could do a GlideRecord search for active configuration items that were not updated "today" and set those to 'inactive' or whatever.


Tera Contributor

Yeah, same here.   My first thought process was; use a onBefore transform script that would mark them as Installed, and then do target.update();


Then I would have an onComplete script that would search for any items that weren't updated [today()] or now(), to get the today's date.   And IF it wasn't updated today, then change the status to "retired".



For the life of me, I can't get the statement right, I think the logic is there, but also having trouble because it will mark them as installed, but then the onComplete script overwrites and marks everything as "retired"   so it works, then it reverts midway.   Blah!


Tera Contributor

Is it a CSV or excel?   I had trouble with excel files.   Have you done the other steps?   I found doing a manual import and walk through helped because it ensured all other steps worked properly.   The inbound action just automated that for me.   SO if the manual steps aren't working, then I would start there and figure out what broke, and then go back to your inbound action.


Giga Guru

If you always import on "Fridays" or some such, you could set a scheduled job to do it that night perhaps.   I don't care for that approach since if your import fails for some reason, everything would get marked as retired.   I'd rather tie it to the fact that the import happened.


Giga Guru

You've probably already done a lot of troubleshooting like this, but if you haven't tried it, run a "fix script" with your query after your import is complete, just to see what you're returning on that GlideRecord query about items not updated "today".   If you can get the fix script to spit out the right answers, then try the script after completion, either by a BR or OnComplete.


Tera Contributor

This sounds like a great idea - I'm not familiar with the 'fix script' do you have a sample I can follow?


Giga Guru

Fix scripts are like background scripts, except that they are stored and you can see more diagnostic information.   Also very similar to a scheduled job, except that you can use gs.print to show variable contents and messages.   It's a great place to test your scripts and keep them for later.   If you look for Steve Bell's work, sabell2012 , he's got some really good stuff on GlideRecord queries and promotes use of Fix Scripts for development and testing.   If you get to visit a Knowledge event, I'd encourage you to sign up for one of his labs.  



Anyway, type 'fix script' in the navigator and it should take you there.   Click 'New', put in some code, click the 'run fix script' link below the 'script' box, and see what it does.   It's live, so be sure to verify before doing something that will write a bunch of data back.   It does seem to have a timer on it (5 minutes?   might be adjustable), so if you have a script that will take a long time to complete, you might test it here with a subset of data, and then move it to a scheduled job for the big run.



find_real_file.png


Tera Contributor

Super helpful, I appreciate the feedback there.   I like background scripts, but hate that you can't save them!       Thanks for the heads up about Steve.   I went to K15 and 16, not sure if we are going this year or not, but will keep my ear to the ground on that.   I'll let you know if I come up with anything nifty for my project too.


Mega Sage
Mega Sage

Thomas, thanks for the mention!



Matthew:   The article on Fix Scripts you will probably be interested in reading is here:ServiceNow Scripting 101: Two Methods for Code Development



After you have read that; this is a useful upgrade: Mini-Lab: Fix Script Application Enhancement



Steven.


Community Code Snippets: Articles List to Date


Tera Contributor

Hi Everyone, so I believe I figured this out.   I just moved it into our Prod instance and it seems to be working well.  



To solve this, I added two scripts to the Transform Map.



onBefore:


//This script marks everything that comes in as installed, and then updates the record.   Important for the next step.


var name = source.u_system_name.toString();


if(name.length == 0 ){


  ignore = true;


} else {


  target.install_status = 1;


      target.update();


}


The bold part above is what is important, I had an issue where this was causing the action to create null records and doubling my number of computers, quite annoying.   I fix this in the onComplete script.



onComplete:


//This finds all records that weren't updated 'recently' - could be anything after 10 minutes or later if you want, then marks them as 'retired', and updates those.


var gr = new GlideRecord("cmdb_ci_computer");


gr.addQuery("install_status", "1");


gr.addQuery('sys_class_name','cmdb_ci_computer');


gr.addQuery('sys_updated_on','<=','javascript:gs.hoursAgo(2)');


gr.query();


while (gr.next()) {


      gr.install_status = 7;


  gr.update();


}



//This does my clean up and finds my null values and deletes.   Not terribly clean, but gets the job done.


var gr = new GlideRecord("cmdb_ci_computer");


gr.addQuery('sys_class_name','cmdb_ci_computer');


gr.addQuery("name", "");


gr.query();


while (gr.next()) {


    gr.deleteRecord();


}





All of this runs at 1am EST, and is done within about 10 minutes, so not a lot of stress on the system or any down time.   The coolest part is, if a computer shows up on the first run, then it marks it as installed.   If the same computer is missing from the report on the next day, it retires it.   If the computer checks back into KACE and is active again, and therefore would show up on the report the 3rd day, it marks it as installed again.



So far everything is working well with the inbound action and this transform map.   Thanks for everyone who offered advice and hope this helps others!


ServiceNow Employee
ServiceNow Employee

Do you have the contents of this script?     It does not seem to be attached to the article.     Thanks


ServiceNow Employee
ServiceNow Employee

It seems as though SncTriggerSynchronizer doesn't run in a scoped app.     Is there a potential workaround as the app I am working with is a scoped app


Tera Contributor

Sadly I am not familiar with scoped applications.   I'm not sure why it would limit this though.


Tera Guru

Hi,



I reviewed the thread here and was able to execute till the point where i have a new data source created with the attached file from the email.



i guess i'm missing something here, but I could not understand what is the next step? what trigger the transform map and actual load the data from the file.



Thank you!


Tera Contributor

Hi Eli,



Have you confirmed that it works manually if you import your data set, and do a transform this way? If that works, then in your inbound action, there is a line commented that states this is where it calls the sys_id of the transform map that is supposed to run.





Thanks,



Matt Payerle



This email contains confidential and proprietary information. It is for the intended recipient only. If an addressing or transmission error has misdirected this email, please notify the author by replying to this email. If you are not the intended recipient, you may not use, disclose, distribute, copy, or print this email.


Tera Guru

Hi Matt,



So yes, i was able to activate it manually - if i go to the newly created from mail data source, load the records and run the transform map, it is working fine.



so this is my inbound action, according to the begging for this thread:


============



if (current.getTableName() == "sys_data_source") {  


 


      current.name = email.subject.substring(3);  


      current.import_set_table_label = email.body.import_set_table_label;  


      current.import_set_table_name = email.body.import_set_table_name;  


      current.file_retrieval_method = email.body.file_retrieval_method;  


      current.format = email.body.format;  


 


      current.update();  


 


var r = new RESTMessage('Inbound Import Set Poster', 'get');  


r.setStringParameter('tableLabel', encodeURIComponent(current.name));  


r.setStringParameter('customDataSource', current.sys_id);  


              r.setStringParameter('tableName', current.import_set_table_name);  


r.execute();  


}  


==============



where should i add the sys_id of the trasform map?



appreciate your help


Tera Contributor

Ah, you are using the REST method from the first post. This is likely outdated based on the version of SN you are in. Check my more recent posts from this year.



https://community.servicenow.com/people/jason.petty/blog/2012/10/25/2634?et=blogs.comment.created#comment-27496


Then read down from there, I added more notes regarding the transform scripts you might need.





Thanks,



Matt Payerle



This email contains confidential and proprietary information. It is for the intended recipient only. If an addressing or transmission error has misdirected this email, please notify the author by replying to this email. If you are not the intended recipient, you may not use, disclose, distribute, copy, or print this email.


Tera Guru

Hi,



So i followed the steps and change the code, but seems like that again, the data source is created but not running.



Is there a certain run type i need to use in the scheduled import? for example   - i set it to run periodically starting tomorrow. can this be the reason why it does not running?


Tera Contributor

That shouldn't stop it, but you would certainly see that happening during that time regardless if there was data to import. I changed the data import to happen in 8 years from now, so it won't be an issue. I would change yours too so you can see if the failure is because of that or not.





Thanks,



Matt Payerle



This email contains confidential and proprietary information. It is for the intended recipient only. If an addressing or transmission error has misdirected this email, please notify the author by replying to this email. If you are not the intended recipient, you may not use, disclose, distribute, copy, or print this email.


Tera Guru

Ok, what would be the best way to see this failure? Because currently I check if the records in the attachment were add to the table im working on.



where can I see if the import / transform was running?



thano you!


Tera Contributor

Your best place would be the system logs. In your inbound action (if you copied the code I posted) then there are several lines that indicate placeholders in the log, for example:


gs.log ('TDI003 - Found Scheduled Import definition');



Your best bet is to send an email with the attachment, wait a few minutes for it to process, then go search your logs for subject contains TDI0 . This will pull up those log entries and tell you where it got to, and if it failed at any point. Then you can see where your breakdown is.




Thanks,



Matt Payerle



This email contains confidential and proprietary information. It is for the intended recipient only. If an addressing or transmission error has misdirected this email, please notify the author by replying to this email. If you are not the intended recipient, you may not use, disclose, distribute, copy, or print this email.


Tera Guru

HI Matt,



Thank you very much! i was able to set is and it is working great!



i had a small typo


Kilo Guru

Hello from Helsinki...



I followed the original instructions and was able to get the XLS Attachment imported and transformed using the following script:



if (current.getTableName() == "sys_data_source") {  


   


      current.name = email.subject.substring(3);  


      current.import_set_table_label = email.body.import_set_table_label;  


      current.import_set_table_name = email.body.import_set_table_name;  


      current.file_retrieval_method = email.body.file_retrieval_method;  


      current.format = email.body.format;  




      current.update();  


 


    var r = new RESTMessage('Inbound Import Set Poster', 'get');  


    r.setStringParameter('tableLabel', encodeURIComponent(current.name));  


    r.setStringParameter('customDataSource', current.sys_id);  


    r.setStringParameter('tableName', current.import_set_table_name);  


    r.execute();  


 




  var myNewDataSource = current.sys_id;


  gs.log ('TD002 - Data source inserted with sys_id - ' + myNewDataSource);


  var gr2 = new GlideRecord ('scheduled_import_set');


  gr2.query();


  if (gr2.next()) {


            gs.log ('TDI003 - Found Scheduled Import definition');


            gr2.data_source = myNewDataSource;


            gr2.update();


            gs.log ('TDI004 - Scheduled Import definition updated to point to data source just added');


            SncTriggerSynchronizer.executeNow(gr2);


  } else {


            gs.log('TDI005 - ERROR - Unable to locate scheduled import definition. Please contact your system administrator');


  }




  gs.log ('TDI007 - Inbound email processing complete');


}


ServiceNow Employee
ServiceNow Employee

michael.ritchie wrote up an updated method for Geneva, Helsinki, and Istanbul releases Loading data from an email attachment


Kilo Contributor

when i am trying to read Excel content ,I am seeing the data as like below



<��


��z{O*^� �7A   �yAÈ¢ >��y�S��e�����0 �V}5_#��/=t�F����;3�d�3�����i�u�f �{��'   �)M �����ޖ� �pJ� �!1� «ï¿½ ��'+� 5



Please correct my code to read Excel content line by line



var grAttach = new GlideRecord('sys_attachment');


//bec04983db3a0300e0fcd360cf961987---Text


//85071a1347c12200e0ef563dbb9a71c1---Excel


grAttach.addQuery('table_sys_id', '85071a1347c12200e0ef563dbb9a71c1');//


grAttach.orderByDesc('sys_updated_on');


grAttach.query();


var stringUtil = new GlideStringUtil();


if ( grAttach.next() ) {


var attachID = grAttach.sys_id;


// Get the contents of the file


var sa = new GlideSysAttachment();


var binData = sa.getBytes(grAttach);


gs.print(binData);


strData = Packages.java.lang.String(binData);


var csv_string = stringUtil.base64Decode(strData);


gs.print("content===>"+csv_string);


}


Kilo Guru

I think this may be a formatting of the XL document that the iRETRIEVAL METHOD does not understand.



If you have not already, please try an XLS instead of XLSX


Kilo Contributor

I tried but it is not working.I tried for CSV and txt ,it is working but for XLS or XLSX not working


Kilo Guru

Based upon this ==>


var csv_string = stringUtil.base64Decode(strData);



The purpose of the mechanism presented above is to extract data from an inbound-email ATTACHMENT (CSV, XLS, XLSX) into a DATA SOURCE so that you could run a TRANSFORM and push the data into a table. It appears to me that you're trying to read the DATA directly from the attachment as a string...



This is why its working for a CSV or TXT since they have no formatting BUT an XLS has GOBs of formatting which is why you're seeing all those goofy characters.





Tera Contributor

Hello ,

this post is amazing it gets the work done but i am struggling to a scenario when on one day if there are multiple individual emails triggered with CSV files multiple data source are being created but the schedule import data is being attached to only the last data souce is there a way that it can be attached to all the data source which are created ? please help me if any one has a solution..

 

Thank you in Advanced.