Skip to Content
Technical Articles
Author's profile photo Diana Matache

SAP Intelligent RPA: Search in the body of emails for key words

Introduction

This is a submission of the Enhance your bot building with templates blog post series.

In this post I will show you how to automate a process in which you have to search for keywords in Outlook emails. The emails that fit the criteria will be then collected so they can be used for other activities.

What you will learn in this tutorial:

  • How to use the Outlook Library;
  • How to search for a keyword in your emails;
  • How to use wildcards in your search;
  • How to display some details about the emails in the console;

Steps to follow:

1.Create a new workflow;

2.Import Outlook Library Scripts;

3.Add activities in your workflow;

4.Enrich the generated code by your workflow with your custom logic;

Prerequisites:

Microsoft Outlook

Desktop Studio 1.0.8.36

Instructions:

1.Create a new workflow

Create a new project and give it a name.

Go to ‘Workflow’ perspective and create a new workflow.

2.Import Outlook Library Scripts

In the workspace of your new workflow you can use different functions for accessing and manipulating Microsoft Outlook files. In order for your project to compile and run without errors, you first have to enable the Outlook Library scripts in your project:

  • go to “Scripts” perspective;
  • select “Project” tab(bottom-left corner);
  • right click anywhere in the Panel;
  • select “Include library Script”: The “Add Library Script” window pops;
  • enable “Outlook integration”;
  • click on “Save”;

3.Add activities in your workflow

The first activity that you need to add in your workflow is a Custom activity so you can use the functions in the Outlook library. You can give a name and a description for this activity, so you can distinguish better its purpose. I will name mine “SearchKeyWord”. I used the same name for its corresponding step. Using suggestive names will also allow you to better organize your code.

The second activity you should include is an End scenario which indicates that your scenario has ended.

Your workflow should now look like this:

Important: Before you can continue with the rest of the functionalities, you need to build your project. This way the script for the workflow will be generated and we can enhance it.

4.Enrich the generated code by your workflow with your custom logic

After you have built your project, you can proceed to the Scripts perspective and open the script generated by your workflow ( it will have the same name ). Search for your custom activity and step by their name ( here is where the suggestive name comes in handy). You can write the rest of the logic in this step. For this example, I’m searching for emails containing the word “test” anywhere in their body, using wildcards. The function I created contains (in comments) all the possible parameters you can use to search for an email. Please keep in mind that the search is performed in the Outlook accounts you are currently logged in.

Below you can find my code for this step and my comments for each step:

// ----------------------------------------------------------------
//   Step: SearchKeyWord
// ----------------------------------------------------------------
GLOBAL.step({
    SearchKeyWord: function(ev, sc, st) {
        var rootData = sc.data;
        ctx.workflow('searchKeyWord', '31e9eec8-fe99-4262-8db7-279548fff558');

        // Initializes “Microsoft Outlook” application.
        ctx.outlook.init();

        var mails = [];
        var i;

        // Resets the working mails list.
        ctx.outlook.mail.resetMailCollection();

        // Search the body of email for a keyword. Other criteria are also available.
        ctx.outlook.mail.searchByCriteria({
            //fromEmail: "",
            //subject: "",
            //sender: "",
            textDescription: "%test%",
            //read: 0,
            //hasAttachment: 0,
            //date: {after : new Date("MM/JJ/AAAA"),before : new Date("MM/JJ/AAAA")},
            //maxRow: 10
            dontThrowExceptionIfNoMailFound: true
        });

        // Get the list of mail information for the mails that fit the criteria.
        mails = ctx.outlook.mail.getFilteredTable();

        // Build the working mails list by retrieving each mail
        if (mails.length) {
            for (i = 0; i < mails.length; i++) {
                ctx.outlook.mail.retrieveMail({
                    EntryID: mails[i]['EntryID'],
                    StoreID: mails[i]['StoreID']
                });
            }

            // Display some info about each email.
            ctx.log("---------------------------------------------------------");
            for (i = 0; i < ctx.outlook.mail.getCollectionLength(); i++) {
                ctx.log("Mail no: " + i);
                ctx.log("Date: " + mails[i]['Date']);
                ctx.log("From: " + mails[i]['Sender']);
                ctx.log("Subject: " + ctx.outlook.mail.getSubject(i));
                ctx.log("---------------------------------------------------------");

            }
        }

        // Ends “Microsoft Outlook” application.
        ctx.outlook.end();

        sc.endStep(); // end Scenario
        return;
    }
});

Conclusion

This blog post should help you to understand the use of the ‘Outlook Library’ and how to search for emails using different criteria. At the end, you should be able to understand these functionalities and use them in your scenarios.

Assigned Tags

      19 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Vijay Sharma
      Vijay Sharma

      Diana Matache

      Thanks Diana for sharing!!

      I have a question, how can i fetch some data from the email body? lets say my email body includes a table

      EmpID Name  Asset No 
      xyz ABC 123
      uvw ijk 456

      Regards

      Vijay

      Author's profile photo Diana Matache
      Diana Matache
      Blog Post Author

      Hi Vijay,

      You can fetch the content of an email body using the following syntax:

      res = ctx.outlook.mail.getBody( 0 );

      , where ‘0’ is the mail index from the working mail collection.

      This method however will return a string value. For example, I have received the following email that contains your table:

       

       

       

       

      I have used the bot I created in this post: SAP Intelligent RPA: Search for e-mails with different criteria  to search for the email above and the email content is displayed like this:

      As you see, the text in the table is structured row by row.

      Kind regards,

      Diana

      Author's profile photo Vijay Sharma
      Vijay Sharma

      Diana Matache

      Thanks Diana for response.

      Yeah, we will get the email body as string. My question was specifically if we could extract the required  key value pairs from that string. Is there any way?

      I don't find the available string functions also much useful for this.

      Regards

      Vijay

      Author's profile photo Avinash Y
      Avinash Y

      Hi Vijay Sharma

      Did u get the response for the above ?

      i am also facing the similar issue can you help me on this please.

      i am getting the email body but unable to split to fetch the information from the body.

      Body of the email looks like ,

      Hi,

      Customer Name: YYYYY

      Order Type: OR

      Sales Org : Sales Org. 0001

      Division: Medicine

      Ship-to-party: FAA6

       

      i want to read the values and store it in different variables.

      Regards,

      Avinash

      Author's profile photo Vijay Sharma
      Vijay Sharma

      Hi Avinash Y,

      No perfect solution yet other then using some OCR capabilities.

      Although, if the position of you Variables is  fixed, you can extract the values using substring function

      var xyz = ctx.string.subString( mailbody, string start position, string end position);

      Thanks

      Vijay

      Author's profile photo Avinash Y
      Avinash Y

      Hi Vijay Sharma

      Thanks for your quick response

      i tried using sub string but its throwing error.i am attaching the flow.can you just have a look and suggest any other way to split and get the values to store in respective variables .

      error%20after%20using%20substring

      error after using substring

      Output of the body :

      Hi,

      Customer Name: xxxxxx

      Order Type: OR

      Sales Org : Sales Org. 0001

      Division: Medicine

      Ship-to-party: FAA6

       

      i want to split it and store it in individual variables.please suggest

      Thanks

      Author's profile photo Vijay Sharma
      Vijay Sharma

      you need to enable string utilities library

      Author's profile photo Avinash Y
      Avinash Y

      Thanks Vijay Sharma , it worked.

      Have another question,i am fetching the values but i want to pass them to the variables created in the context .

      Can you help me on this please,because the above fetching the values is completely done using custom code.

      Regards,

      Avinash

      Author's profile photo Vijay Sharma
      Vijay Sharma

      try like this

      rootData.<your context variable name> = ctx.string.subString( mailbody, string start position, string end position);

      Author's profile photo Vinay Joshi
      Vinay Joshi

      Hi Diana Matache,

       

      I followed your blog (apart from popup scenario as my requirement is simply to read email from inbox) but facing timeout issue while executing the script. Please find below code snippet

       

      ctx.outlook.init();

      var mails = []; // will contain mail information
      var i; // contor
      var dataset = []; // array of arrays in which we insert the mail information

      // Resets the working mails list.
      ctx.outlook.mail.resetMailCollection();

      // Build the search function
      try {
      ctx.outlook.mail.search({
      filter : "urn:schemas:httpmail:subject like 'SAP iRPA - Trigger Email'" + " AND " +
      "urn:schemas:httpmail:read=1",
      maxRow : 5,
      storeName : 'xxx@xxx.com', (My email id from which mail is to be read)
      dontThrowExceptionIfNoMailFound: true
      });

      // Get the list of mail information for the mails that fit the criteria.
      mails = ctx.outlook.mail.getFilteredTable();

      // Build the working mails list by retrieving each mail
      if(mails.length) {
      for(i=0; i<mails.length; i++) {
      ctx.outlook.mail.retrieveMail({EntryID : mails[i]['EntryID'], StoreID : mails[i]['StoreID']});
      }

      // Display some info about each email that fit the criteria.
      ctx.log("---------------------------------------------------------");
      for(i=0; i<ctx.outlook.mail.getCollectionLength(); i++) {
      ctx.log("Mail no: " + i);
      ctx.log("From: " + mails[i]['Sender']);
      ctx.log("Date: " + mails[i]['Date']);
      // Covert the date to a string so it can be loaded into the table.
      var date = String(mails[i]['Date']);
      ctx.log("Aici"+String(mails[i]['Date']));
      ctx.log("Subject: " + ctx.outlook.mail.getSubject(i));
      ctx.log("---------------------------------------------------------");

      // Load the details of the current email into the final array (dataset).
      dataset.push([date, mails[i]['Sender'], ctx.outlook.mail.getSubject(i), ctx.outlook.mail.getBody(i)]);
      }

      // Provide the final array of details as datasource for the table.
      //POPUPS.outputTable.finalTable.set(dataset);

      // Open the popup to display the table.
      //POPUPS.outputTable.open();
      }
      } catch (err) {
      ctx.log("Fail (" + err.description + ").");
      return e.error.KO;
      }

      ctx.outlook.end();
      sc.endStep(); // end Scenario
      return;

       

      Error SS

      Can you please help here.

       

      Thanks and Regards,

      Vinay

      Author's profile photo Diana Matache
      Diana Matache
      Blog Post Author

      Hi Vinay,

       

      Search through your code for the following code snippet (you should find it under GLOBAL.scenario):

      sc.onTimeout(30000, function(sc, st) { sc.endScenario(); }); // Default timeout handler for each step.

       

      Here either increase the time, either comment the whole line of code. The search through the email might take a while and probably this is why you get the timeout.

      Let me know if it works

       

      Kind regards,

      Diana

      Author's profile photo Vinay Joshi
      Vinay Joshi

      Hi Diana Matache ,

       

      I increased the time period to 100000 but still the execution is running into error. When debugging the code it goes to catch section when ctx.outlook.mail.search is executed and the catch section does not give the error description. Please find below code snippets along with debugger screenshot.

      Timeout setting

      InboxVinayJoshiG.scenario({ readEmailNew: function(ev, sc) {
      var rootData = sc.data;

      sc.setMode(e.scenario.mode.clearIfRunning);
      sc.setScenarioTimeout(600000); // Default timeout for global scenario.
      sc.onError(function(sc, st, ex) { sc.endScenario(); }); // Default error handler.
      sc.onTimeout(100000, function(sc, st) { sc.endScenario(); }); // Default timeout handler for each step.
      sc.step(InboxVinayJoshiG.steps.SearchEmail_1);
      }}, ctx.dataManagers.rootData).setId('f2daf9dc-7d46-4870-b2d3-d1ca0895574f') ;

       

      Mail search code

      ctx.outlook.mail.search({
      filter : "urn:schemas:httpmail:subject like 'SAP iRPA - Trigger Email'" + " AND " +
      "urn:schemas:httpmail:read=1",
      maxRow : 5,
      storeName : 'xxxx@xxxx.com',
      dontThrowExceptionIfNoMailFound: true
      });

       

      Catch section

      ctx.log("Fail (" + err.description + ").");
      return e.error.KO;

       

      Debugger screenshot

      Author's profile photo Diana Matache
      Diana Matache
      Blog Post Author

      Hi Vinay,

      The error says "timeout" so the time period you used it's not enough. Try to comment the sc.onTimeout and then run your bot again.

       

      Kind regards,

      Diana

      Author's profile photo Vinay Joshi
      Vinay Joshi

      Hi Diana Matache

       

      Same result again. Can it be possible that company security policy doesnot allow bot to read email ? If so is there any way we can find that if this issue is due to policy ?

       

      Code Snippet

      InboxVinayJoshiG.scenario({ readEmailNew: function(ev, sc) {
      var rootData = sc.data;

      sc.setMode(e.scenario.mode.clearIfRunning);
      sc.setScenarioTimeout(600000); // Default timeout for global scenario.
      sc.onError(function(sc, st, ex) { sc.endScenario(); }); // Default error handler.
      //sc.onTimeout(100000, function(sc, st) { sc.endScenario(); }); // Default timeout handler for each step.
      sc.step(InboxVinayJoshiG.steps.SearchEmail_1);
      }}, ctx.dataManagers.rootData).setId('f2daf9dc-7d46-4870-b2d3-d1ca0895574f') ;

       

      Debugger Screenshot

      Author's profile photo Sulagna Chakraborty
      Sulagna Chakraborty

      Hi

      Is it possible to send the subject in regular expression. Like if I want to search one word in the subject line.

      Kindly help me out in this.

      Thanks

      Sulagna Chakraborty

      Author's profile photo Diana Matache
      Diana Matache
      Blog Post Author

      Hi,

       

      Yes, it's possible, the subject is one of the  parameters in the searchByCriteria method. Have a look at the documentation for all the available options.

       

      Kind regards,

      Diana

      Author's profile photo Sulagna Chakraborty
      Sulagna Chakraborty

      Yes Diana..

      It works.. also i found that this is case insensitive.. Is there a way to check for 2 strings in the subject.. something like this as denoted below.

      How to denote "and" or "or" in the below example

      var subject = "%"+string1+"%" and "%"+another string+"%"

      Thanks

      Sulagna Chakraborty

       

      Author's profile photo Diana Matache
      Diana Matache
      Blog Post Author

      For simple use cases try subject: "%string1 string2%". For more complex requirements you could try regex to see if it works for you.

      Author's profile photo Jose Mera
      Jose Mera

      Hello.

      How to mark an email as read?