Unable to read gmail content using gmail plugin

Hi Team,

Could you please guide with gmail plugin, to read gmail multipart content. Below is the console msg:

2020-11-16 20:41:43.534 INFO com.kms.katalon.core.util.KeywordUtil - ***********************************************************
2020-11-16 20:41:43.538 INFO com.kms.katalon.core.util.KeywordUtil - This is the message envelope
2020-11-16 20:41:43.538 INFO com.kms.katalon.core.util.KeywordUtil - ---------------------------

2020-11-16 20:41:43.961 INFO com.kms.katalon.core.util.KeywordUtil - This is a Multipart
2020-11-16 20:41:43.962 INFO com.kms.katalon.core.util.KeywordUtil - ---------------------------
2020-11-16 20:41:44.041 INFO k.k.c.m.CustomKeywordDelegatingMetaClass - com.testwithhari.katalon.plugins.Gmail.readLatestEMailBodyContent is PASSED
2020-11-16 20:41:44.048 DEBUG 06_Verify Received Recover Password Link - 5: println(content)
javax.mail.internet.MimeMultipart@4b3fe06e
2020-11-16 20:41:44.052 DEBUG 06_Verify Received Recover Password Link - 6: closeBrowser()
Test Cases/Web Browser/016_Fogotten Password/TC006_Verify Received Recover Password Link
PASSED

Script view:

String Content = CustomKeywords. ‘com.testwithhari.katalon.plugins.Gmail.readLatestEMailBodyContent’ (GlobalVariable. Gmail_Address ,

GlobalVariable. Gmail_Password , GlobalVariable. Gmail_Label )

@ThanhTo

Gmail Code here

package com.mail

import javax.mail.Flags
import javax.mail.Folder
import javax.mail.Message
import javax.mail.MessagingException
import javax.mail.NoSuchProviderException
import javax.mail.Session
import javax.mail.Store
import javax.mail.Message.RecipientType
import javax.mail.search.AndTerm
import javax.mail.search.RecipientStringTerm
import javax.mail.search.SearchTerm
import javax.mail.search.SubjectTerm

import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element

import com.kms.katalon.core.annotation.Keyword
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI

import groovy.util.slurpersupport.Attributes
import internal.GlobalVariable

public class mailhandler {

//******************************************
//**    Mail Custom Keyword Definitions   **
//******************************************

@Keyword
def findEmailAndClickURL(String QAEmail, String QAPassword, String FolderPath, String EmailRecipient, String LinkKey, String Subject = "") {
	String url = findConfirmEmailURL(QAEmail, QAPassword, FolderPath, EmailRecipient, LinkKey, Subject)
	println "URL :" + url
	WebUI.openBrowser('')
	WebUI.navigateToUrl(url)
}

@Keyword
def findEmailAndGetSubject(String QAEmail, String QAPassword, String FolderPath, String EmailRecipient, String LinkKey, String Subject = "") {
	String rSubject = findConfirmEmailSubject(QAEmail, QAPassword, FolderPath, EmailRecipient, LinkKey, Subject)
	println "Subject :" + rSubject
	return rSubject
}

@Keyword
def findEmailAndGetSender(String QAEmail, String QAPassword, String FolderPath, String EmailRecipient, String LinkKey, String Subject = "") {
	String Sender = findConfirmEmailSender(QAEmail, QAPassword, FolderPath, EmailRecipient, LinkKey, Subject)
	println "Sender :" + Sender
	return Sender
}

@Keyword
def ClearEmailFolder(String QAEmail, String QAPassword, String FolderPath) {
	String url = clearEmail(QAEmail, QAPassword, FolderPath)
	println "URL :" + url
}


//******************************************
//**         Mail related methods         **
//******************************************
private String findConfirmEmailURL(String QAEmail, String QAPassword, String FolderPath, String EmailRecipient, String LinkKey, String Subject) throws MessagingException
{
	try {
		println(EmailRecipient)
		SearchTerm filter = createFilter(EmailRecipient, Subject);		// 1. Create mail search filter for our mailbox
		println(QAEmail + ", " + QAPassword)
		Store store = connect(QAEmail, QAPassword);				// 2. Connect to our mailbox
		String content = getMessageContent(store, FolderPath, filter);		// 3. Retrieve the message body from the received email
		println(content)
		String url = getURL(content, LinkKey);							// 4. Get the confirmation URL from the message body
		return url;
	} catch(Exception e) {
		println("Exception: ${e}")
	}
}

private String findConfirmEmailSubject(String QAEmail, String QAPassword, String FolderPath, String EmailRecipient, String LinkKey, String Subject) throws MessagingException
{
	try {
		println(EmailRecipient)
		SearchTerm filter = createFilter(EmailRecipient, Subject);		// 1. Create mail search filter for our mailbox
		println(QAEmail + ", " + QAPassword)
		Store store = connect(QAEmail, QAPassword);				// 2. Connect to our mailbox
		String content = getMessageSubject(store, FolderPath, filter);		// 3. Retrieve the message body from the received email
		println(content)
		return content;
	} catch(Exception e) {
		println("Exception: ${e}")
	}
}

private String findConfirmEmailSender(String QAEmail, String QAPassword, String FolderPath, String EmailRecipient, String LinkKey, String Subject) throws MessagingException
{
	try {
		println(EmailRecipient)
		SearchTerm filter = createFilter(EmailRecipient, Subject);		// 1. Create mail search filter for our mailbox
		println(QAEmail + ", " + QAPassword)
		Store store = connect(QAEmail, QAPassword);				// 2. Connect to our mailbox
		String content = getMessageSender(store, FolderPath, filter);		// 3. Retrieve the message body from the received email
		println(content)
		return content;
	} catch(Exception e) {
		println("Exception: ${e}")
	}
}

private String clearEmail(String QAEmail, String QAPassword, String FolderPath) throws MessagingException
{
	Store store
	try {
		println(QAEmail + ", " + QAPassword)
		store = connect(QAEmail, QAPassword);				// 2. Connect to our mailbox
		Folder emailFolder = store.getFolder(FolderPath);
		emailFolder.open(Folder.READ_WRITE);
		println("FolderPath: " + FolderPath)

		for (Message message in emailFolder.messages) {
			message.setFlag(Flags.Flag.DELETED, true);
		}
		emailFolder.close(true)
	} catch (MessagingException e) {
		e.printStackTrace();
	} catch (Exception e) {
		e.printStackTrace();
	}finally {
		store.close();
	}
}

private SearchTerm createFilter(String Recipient, String Subject){
	SearchTerm t1 = new RecipientStringTerm(RecipientType.TO, Recipient);
	SearchTerm st
	if(Subject != "")
	{
		SearchTerm t2 = new SubjectTerm(Subject);
		st = new AndTerm(t1, t2);
	}
	else
	{
		st = new AndTerm(t1);
	}
	return st;
}

private Store connect(String QAEmail, String QAPassword) throws MessagingException
{
	Properties props = new Properties();
	props.setProperty("mail.store.protocol", "imaps");
	Session session = Session.getDefaultInstance(props, null);
	Store store;

	try{
		store = session.getStore("imaps");
		store.connect("imap.gmail.com", QAEmail, QAPassword);
	}catch (NoSuchProviderException e) {
		e.printStackTrace();
		throw e;
	}catch (MessagingException e) {
		e.printStackTrace();
		throw e;
	}
	return store;
}

public String getMessageContent(Store store, String FolderPath, SearchTerm filter) throws MessagingException {
	String mailMessageContent = "";
	try{
		Folder emailFolder = store.getFolder(FolderPath);
		emailFolder.open(Folder.READ_ONLY);
		println("FolderPath: " + FolderPath)
		Message[] messages = emailFolder.search(filter);
		System.out.println("Matching Emails Found: " + messages.length);

		if(messages.length != 0){
			Message message = messages[0];
			String content = message.getContent().toString();
			mailMessageContent = content;
		}
		emailFolder.close(false);
	} catch (MessagingException e) {
		e.printStackTrace();
	} catch (Exception e) {
		e.printStackTrace();
	}finally {
		store.close();
	}
	return mailMessageContent;
}

public String getMessageSubject(Store store, String FolderPath, SearchTerm filter) throws MessagingException {
	String mailMessageSubject = "";
	try{
		Folder emailFolder = store.getFolder(FolderPath);
		emailFolder.open(Folder.READ_ONLY);
		println("FolderPath: " + FolderPath)
		Message[] messages = emailFolder.search(filter);
		System.out.println("Matching Emails Found: " + messages.length);

		if(messages.length != 0){
			Message message = messages[0];
			String subject = message.getSubject();
			String from = message.getFrom()[0].toString();
			String content = message.getContent().toString();
			mailMessageSubject = content;
		}
		emailFolder.close(false);
	} catch (MessagingException e) {
		e.printStackTrace();
	} catch (Exception e) {
		e.printStackTrace();
	}finally {
		store.close();
	}
	return mailMessageSubject;
}

public String getMessageSender(Store store, String FolderPath, SearchTerm filter) throws MessagingException {
	String mailMessageSender = "";
	try{
		Folder emailFolder = store.getFolder(FolderPath);
		emailFolder.open(Folder.READ_ONLY);
		println("FolderPath: " + FolderPath)
		Message[] messages = emailFolder.search(filter);
		System.out.println("Matching Emails Found: " + messages.length);

		if(messages.length != 0){
			Message message = messages[0];
			String Sender = message.getFrom()[0].toString();
			mailMessageSender = Sender;
		}
		emailFolder.close(false);
	} catch (MessagingException e) {
		e.printStackTrace();
	} catch (Exception e) {
		e.printStackTrace();
	}finally {
		store.close();
	}
	return mailMessageSender;
}

private String getURL(String content, String LinkKey){
	Document doc = Jsoup.parse(content);
	//org.jsoup.nodes.Attributes attributes = doc.getElementsByAttributeValueContaining("href", "ls/click?upn")[0].attributes()
	org.jsoup.nodes.Attributes attributes = doc.getElementsByAttributeValueContaining("href", LinkKey)[0].attributes()
	char[] href = attributes.get("href").value
	String URL = href.toString()
	return URL
}

}

1 Like

Hi, @qakatalon !

Can you please let us know where your code should be put in Katalon, how to get these

and provide some examples of how to use it from Katalon? Thanks!

You need to search for the appropriate jar file that contains the “import” files. Then you need to attach the jar file to Katalon Studio and then create a Keyword to house the code:

How to create a custom keyword using Katalon Studio | by Katalon | Katalon | Medium

Libraries management | Katalon Docs

Download javax.mail.jar : javax.mail « j « Jar File Download (java2s.com)

2 Likes

Still, does someone knows how to use it?

Also, what are String LinkKey, String FolderPath in your methods?

I got this

After reading this java - How to fix javax.mail.AuthenticationFailedException Invalid credentials - Stack Overflow

not sure how this is suposed to be handled. Any suggestions? Thanks.

Probably unrelated to your question, but my util class here will handle the link scraping part.

with this, you can just be like:

WebUI.navigateToUrl(EmailUtils.ProcessHTML(yourMessageString, // I leave this to you. my actual utils class uses the GMail API for Java, instead of the Gmail plugin
	"//${yourLinkXPath}/@href"));

although, with something like email-scraping, you might want to have some re-try mechanism for email message-link retrieval. For example, here is the one from my real codebase:

import java.util.concurrent.TimeUnit
// ...rest of imports

public final class EmailUtils { 

	//...rest of code base

	public static String ExtractSignUpLink() {
		String link;

		int retryAttempts;

		ActionHandler.Handle({
			link = this.ProcessHTML(this.GetLatestMessageBody(30),
					"//a[.//div[@class = 'sign-mail-btn-text']]/@href");
		}, { boolean success, ex ->
			if (success)
				return;
			if (((GoogleJsonResponseException)ex).getDetails().getCode() >= 400)
				throw ex;
			sleep(1000 * 2**retryAttempts++);
		}, TimeUnit.MINUTES.toSeconds(15))

		return link;
	}

	//...rest of code base
}

public final class ActionHandler {
    public static void Handle(Closure onAction, Closure onDone, long timeOut) {
        long startTime = System.currentTimeSeconds();
        while (System.currentTimeSeconds() < startTime + timeOut) {
            try {
                onDone(true, onAction());
                return;
            } catch (Exception ex) {
                onDone(false, ex);
            }
        }
    }
}

What happened when you tried the answer on there, and used the password as generated by the steps contained within?