Skip to Content
Technical Articles

SAP Intelligent RPA: Exploring the Outlook Library

SAP Intelligent Robotic Process Automation (SAP Intelligent RPA) is a  three-component product that allows users to build and direct process execution bots in various modes to automate business processes.

To build bots, we use different extensions, one of those is the Microsoft Outlook Extension

This library is a collection of functions for accessing and manipulating Microsoft Outlook files. The global variables and functions are used to handle the Outlook instance: start, maintain and stop the Outlook engine. The mail functions are used to manipulate mails in the outlook application.

Some technical points:

  • A mail collection contains mails that have been created and/or created.
  • Search in outlook folder uses an intermediate filter table allowing faster filtering.
  • Retrieving a mail is based on EntryID and optionally storeID.

To get the most of this library, here are a few code examples that will increase in complexity from sending a simple email to encoding an image and then attached it to an email.

First make sure you have the Outlook Library. To check, go to Libraries and check Outlook Integration library.


Let’s review how to send basic emails, we use ctx.outlook.mail.send to do so.  Below the example code:

function sendBasicMail() {
// Initializes “Microsoft Outlook” application.
  ctx.outlook.init();
// Creates a basic mail.
  ctx.outlook.mail.create({To:'name@company.com', Subject:'Test mail from SAP', Body:'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'});
  try {
// Sends the mail.
    var res = ctx.outlook.mail.send(0);  
  } catch (err) {
  ctx.log("Sending of “Microsoft Outlook” mail in failure (" + err.description + ").");
  return e.error.KO;
  }
// Ends “Microsoft Outlook” application.
  ctx.outlook.end();
}

To send emails using another account, you need to use the sendUsingAccount method where you add the email that you want to send from:

function sendMailFromAnotherStore() {
	ctx.outlook.init();
	ctx.outlook.mail.create( {
		To:'example@sap.com,',
		Subject:'[OUTLOOK LIBRARY TEST] - from another store',
		Body:'[OUTLOOK LIBRARY TEST] - Body from another store'
	});
	ctx.outlook.mail.sendUsingAccount(0, 'example@sap.eu');
	ctx.outlook.end();
}

 

If you run into the below error, please make sure the email has been written correctly.


 

To move mail in another store, you need to use the resetMailCollection method, see below:

function moveMailInAnotherStore() {
	var mails = [];
	var i = 0;


	ctx.outlook.init();
	ctx.outlook.mail.resetMailCollection();
	ctx.outlook.mail.searchByCriteria( {
		subject : "Documentation - Wiki - Installation guide - Proxy"
	});


	mails = ctx.outlook.mail.getFilteredTable();
	if (mails.length) {

		for (i = 0; i< mails.length; i++) {
			ctx.outlook.mail.retrieveMail( {
				EntryID : mails[i]['EntryID'], StoreID : mails[i]['StoreID']
			});
		}

		ctx.log("---------------------------------------------------------");
		for (i = 0; i< ctx.outlook.mail.getCollectionLength(); i++) {
			ctx.log("Mail n°" + i);
			ctx.log("From: " + mails[i]['Sender']);
			ctx.log("Subject: " + ctx.outlook.mail.getSubject(i));
			ctx.log("Importance: " + ctx.outlook.mail.getImportance(i));
			ctx.log("---------------------------------------------------------");
		}
		ctx.outlook.mail.moveToSpecificStore(0, 'example@sap.eu', 'Inbox\\Testu');
	}
	ctx.outlook.end();
}


If you want to search an email by criteria and would like to avoid the exception if there is no email with such criteria. You will use some functions from the ctx.outlook.application. This class contains a set of functions that manipulate mail items in Outlook.

function dontThrowException() {

            var mails = [];
            var i = 0;
            ctx.outlook.init();
            ctx.outlook.mail.resetMailCollection();
            ctx.outlook.mail.searchByCriteria( {

                        subject : "Narf", dontThrowExceptionIfNoMailFound: true

            });

            //

            mails = ctx.outlook.mail.getFilteredTable();
            if (mails.length) {

                        for (i = 0; i< mails.length; i++) {
                                    ctx.outlook.mail.retrieveMail( {
                                               EntryID : mails[i]['EntryID'], StoreID : mails[i]['StoreID']
                                   });
                        }

                        ctx.log("---------------------------------------------------------");

                        for (i = 0; i< ctx.outlook.mail.getCollectionLength(); i++) {

                                   ctx.log("Mail n°" + i);

                                   ctx.log("From: " + mails[i]['Sender']);

                                   ctx.log("Subject: " + ctx.outlook.mail.getSubject(i));

                                   ctx.log("Importance: " + ctx.outlook.mail.getImportance(i));

                                   ctx.log("---------------------------------------------------------");

                        }

                        ctx.outlook.mail.moveToSpecificStore(0, 'example@sap.eu', 'Inbox\\Testu');

            }

            ctx.outlook.end();

}

 

To reply to an email and attached the body of the email you are replying, you need to use ctx.outlook.mail.reply(0), which replies to the indexed mail.

function replyInsertBody() {
	var mails = [];
	var i = 0;


	ctx.outlook.init();
	ctx.outlook.mail.resetMailCollection();
	ctx.outlook.mail.searchByCriteria( {
		subject : "Test appendBody"
	});
	// 

	mails = ctx.outlook.mail.getFilteredTable();
	if (mails.length) {

		for (i = 0; i< mails.length; i++) {
			ctx.outlook.mail.retrieveMail( {
				EntryID : mails[i]['EntryID'], StoreID : mails[i]['StoreID']
			});
		}

		ctx.log("---------------------------------------------------------");
		for (i = 0; i< ctx.outlook.mail.getCollectionLength(); i++) {
			ctx.log("Mail n°" + i);
			ctx.log("From: " + mails[i]['Sender']);
			ctx.log("Subject: " + ctx.outlook.mail.getSubject(i));
			ctx.log("Importance: " + ctx.outlook.mail.getImportance(i));
			ctx.log("---------------------------------------------------------");
		}
		ctx.outlook.mail.reply(0);
		var index = ctx.outlook.mail.getCollectionLength() -1;
		ctx.outlook.mail.appendBody(index, "New body");
		ctx.outlook.mail.send(index);
	}
	ctx.outlook.end();
}

If you want to search for emails in another account, you use the ctx.outlook.mail.search method, which searches for mail information with user-defined filter in object parameter. As shown below,  always wrap up this method with a try…catch statement for best practice.

function searchInAnotherAccount() {
	var mails = [];
	var i = 0;

	// Initializes “Microsoft Outlook” application.
	ctx.outlook.init();
	// Resets the working mails list.
	ctx.outlook.mail.resetMailCollection();
	// Sets a filter to retrieve all unread mails (with max set to 10).
	try {
		ctx.outlook.mail.search( {
			filter : "\"" + "urn:schemas:httpmail:read" + "\"" + "= 0",
			maxRow : 10, storeName : 'example@sap.eu'
		});
	} catch (ex) {
		ctx.log("no email found");
		return e.error.KO;
	}
	// Retrieves the result of search.
	mails = ctx.outlook.mail.getFilteredTable();
	if (mails.length) {
		// Build the working mails list by retrieving the detail of each mail.
		for (i = 0; i< mails.length; i++)
			try {
			ctx.outlook.mail.retrieveMail( {
				EntryID : mails[i]['EntryID'], StoreID : mails[i]['StoreID']
			});
		} catch (ex) {
			ctx.log("could not retrieve an email");
		}
		// Displays some information of each mail in debug prints.
		ctx.log("---------------------------------------------------------");
		for (i = 0; i< ctx.outlook.mail.getCollectionLength(); i++) {
			ctx.log("Mail n°" + i);
			ctx.log("From: " + mails[i]['Sender']);
			ctx.log("Subject: " + ctx.outlook.mail.getSubject(i));
			ctx.log("Importance: " + ctx.outlook.mail.getImportance(i));
			ctx.log("---------------------------------------------------------");
		}
	}
	// Ends “Microsoft Outlook” application.
	ctx.outlook.end();
}

If you want to search an email in a specific folder, in this example we also use the search method but the parameters are different. We use folderName instead. The search method takes string typed filters used to search for mail.

function searchInFolder() {
	var mails = [];
	var i = 0;

	// Initializes “Microsoft Outlook” application.
	ctx.outlook.init();
	// Resets the working mails list.
	ctx.outlook.mail.resetMailCollection();
	// Sets a filter to retrieve all unread mails (with max set to 10).
	try {
		ctx.outlook.mail.search( {
			filter : "urn:schemas:httpmail:subject like '%remboursement%' AND urn:schemas:httpmail:read = 0 ",
			maxRow : 10, folderName : 'Mutuelle'
		});
	} catch (ex) {
		ctx.log("no email found");
		return e.error.KO;
	}
	// Retrieves the result of search.
	mails = ctx.outlook.mail.getFilteredTable();
	if (mails.length) {
		// Build the working mails list by retrieving the detail of each mail.
		for (i = 0; i< mails.length; i++)
			try {
			ctx.outlook.mail.retrieveMail( {
				EntryID : mails[i]['EntryID'], StoreID : mails[i]['StoreID']
			});
		} catch (ex) {
			ctx.log("could not retrieve an email");
		}
		// Displays some information of each mail in debug prints.
		ctx.log("---------------------------------------------------------");
		for (i = 0; i< ctx.outlook.mail.getCollectionLength(); i++) {
			ctx.log("Mail n°" + i);
			ctx.log("From: " + mails[i]['Sender']);
			ctx.log("Subject: " + ctx.outlook.mail.getSubject(i));
			ctx.log("Importance: " + ctx.outlook.mail.getImportance(i));
			ctx.log("---------------------------------------------------------");
		}
	}
	// Ends “Microsoft Outlook” application.
	ctx.outlook.end();
}

Finally, if you want to send an email with an image in the body. To do so we use var txt = ctx.fso.file.read( file, e.file.encoding.ASCII ) to read the file and e.file.encoding.Binary to encode the image.

function sendMailWithImageInBody() {
	var imagePath = "C:\\ProgramData\\SAP\\Intelligent RPA\\SDK 2.0.2.6\\templates\\resources\\bmp64\\agent128.png";
	
	ctx.outlook.init();
	ctx.outlook.mail.create( {
		To:'example@sap.com', Subject:'Test email with image'
	});
	var body_text = '<!DOCTYPE html>';
	body_text += '<html>';
	body_text += ' <head>';
	body_text += '<title>HTML img Tag</title>';
	body_text += '</head>';
	body_text += '<body>';
	body_text += '<img src="data:image/png;base64,' + ctx.base64.encodeStream(ctx.fso.file.read(imagePath, e.file.encoding.Binary)) + '">';
	body_text += '</body>';
	body_text += '</html>';
	try {
		ctx.outlook.mail.setBodyHtml(0, body_text);
		var res = ctx.outlook.mail.send(0);
	} catch (err) {
		ctx.log("error : " + err);
	}
	ctx.outlook.end();
}

These were some examples on all the things you can do with the outlook library in order to extract and manipulate mails. I hope you find these examples helpful, let me know if I should add other ones.

4 Comments
You must be Logged on to comment or reply to a post.
  • Hi Rose,

    very informative and useful article.

    I had a question on the “search for emails in another account” case.

    How is the authentication handled?

    i.e. when I access outlook from my bot, it defaults to my account (say “abc@sap.com”) and does not ask for additional authentication. But if it the bot has to access another Outlook account, such as “example@sap.com”, I suppose authentication has to be provided for that account.

    (I do not presently have an additional account to check this out, but wanted to understand how this works)

    • Hi Jawanth Vytheeswaran

       

      Using Outlook, you can add accounts, using the option “Account Settings”. There, you might need to provide the password of the account you want to access to.

      Once it is done, the account is automatically loaded in your Outlook, and directly available by your bot. So you don’t have to authenticate with your bot, as it was already done once directly in Outlook

       

      J.

  • Thanks for the article!

    I have an issue with the following method :

    ctx.outlook.mail.reply(0);
    ctx.outlook.mail.appendBody(index, "New body");

     

    The reply() method is not actually “replying” to the mail. It is just appending the text “New Body” to the existing mail body and sending the same mail again.

    What am I missing here?

     

     

     

     

     

  • Nice Article 🙂

     

    Do you have any idea how to use below function of outlook.

     

    ctx.outlook.mail.move(oIndex, Object);

     

    Can you give an example of it.

     

    Thanks,

    Abhijeet