How to retrieve link from email message using the Gmail plugin/GMail API for Java/Jakarta Mail API/

Assuming you successfully have the message string, here’s how you can retrieve the link from it, assuming that your email message retrival method call returns HTML string.

To save you some clicking:

import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.xpath.XPathFactory

import org.w3c.dom.Element

// feel free to make this your own :)
public final class EmailUtils {
/**
	 * **NOTE**: forked from https://stackoverflow.com/a/2269464/2027839 , and then refactored
	 * 
	 * Processes HTML, using XPath
	 * 
	 * @param html
	 * @param xpath
	 * @return the result 
	 */
	public static String ProcessHTML(String html, String xpath) {

		final String properHTML = this.ToProperHTML(html);

		final Element document = DocumentBuilderFactory.newInstance()
				.newDocumentBuilder()
				.parse(new ByteArrayInputStream( properHTML.bytes ))
				.documentElement;
		return XPathFactory.newInstance()
				.newXPath()
				.evaluate( xpath, document );
	}

	private static String ToProperHTML(String html) {
		// SOURCE: https://stackoverflow.com/a/19125599/2027839
		String properHTML = html.replaceAll( "(&(?!amp;))", "&" );

		if (properHTML.contains('<!DOCTYPE html'))
			return properHTML;


		return """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
	<head></head>
	<body>
		${properHTML}
	</body>
</html>
""";
	}
}

From there, you’ll have to log out your HTML message string (or put debug breakpoint around your method call and extract it from debugger), pretty print it, and from there, you can use your web-testing skills to create some xpath selector string for the actual link.

Then, you use my code like:

WebUI.navigateToUrl(yourEmailMessageContent, "${yourLinkXPath}/@href");

To be fair, email messages can take some time to hit inboxes. Hence you might also want to have some retry logic in place. Here is example from my real project code base:

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;
			// handle ex
			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);
            }
        }
    }
}

I’m a little confused by your response.

I posted this to help people out that are using Katalon Studio to retrieve email messages and links from them, can retrieve them, but are stuck on retrieving/navigating to the links…

1 Like

Ok, thank you for good sharing. Thank you!

1 Like