Skip to Content
Technical Articles

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.

18 Comments
You must be Logged on to comment or reply to a post.
  • 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

    • 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

      • 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

        • 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

          • 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

          • 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

          • /
          • 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

          • try like this

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

  • 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

    /
    • 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

      • 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

        /
        • 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

          • 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

            /
  • 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

      • 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

         

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