diff --git a/src/main/java/org/eclipsefoundation/git/eca/service/impl/CachedUserService.java b/src/main/java/org/eclipsefoundation/git/eca/service/impl/CachedUserService.java
index 54e841859933d0621809aa88d4f2b3d9e5790266..45ad50178491186e32490dd7c31a49ed7ce24f21 100644
--- a/src/main/java/org/eclipsefoundation/git/eca/service/impl/CachedUserService.java
+++ b/src/main/java/org/eclipsefoundation/git/eca/service/impl/CachedUserService.java
@@ -81,8 +81,7 @@ public class CachedUserService implements UserService {
         if (StringUtils.isBlank(mail)) {
             return null;
         }
-        Optional<EclipseUser> u = cache.get(mail, new MultivaluedMapImpl<>(), EclipseUser.class,
-                () -> retrieveUser(mail));
+        Optional<EclipseUser> u = cache.get(mail, new MultivaluedMapImpl<>(), EclipseUser.class, () -> retrieveUser(mail));
         if (u.isPresent()) {
             LOGGER.debug("Found user with email {}", mail);
             return u.get();
@@ -96,8 +95,9 @@ public class CachedUserService implements UserService {
         if (StringUtils.isBlank(username)) {
             return null;
         }
-        Optional<EclipseUser> u = cache.get("gh:" + username, new MultivaluedMapImpl<>(), EclipseUser.class,
-                () -> accounts.getUserByGithubUname(getBearerToken(), username));
+        Optional<EclipseUser> u = cache
+                .get("gh:" + username, new MultivaluedMapImpl<>(), EclipseUser.class,
+                        () -> accounts.getUserByGithubUname(getBearerToken(), username));
         if (u.isPresent()) {
             LOGGER.debug("Found user with name {}", username);
             return u.get();
@@ -111,30 +111,39 @@ public class CachedUserService implements UserService {
         if (StringUtils.isBlank(mail)) {
             return false;
         }
+        // set the values used to validate whether user is a bot
+        final String checkedField;
+        final String checkedValue;
+        // check if email is a noreply address
+        if (patterns.stream().anyMatch(pattern -> pattern.matcher(mail.trim()).find())) {
+            checkedValue = extractNoReplyUserFromAddress(mail);
+            checkedField = "username";
+            LOGGER.trace("Checking {} for bot status using noreply logic", checkedValue);
+        } else {
+            checkedValue = mail;
+            checkedField = "email";
+            LOGGER.trace("Checking {} for bot status using standard logic", checkedValue);
+        }
+
+        // get the bots to be compared against
         List<JsonNode> botObjs = getBots();
         // if there are no matching projects, then check against all bots, not just
         // project bots
         if (filteredProjects == null || filteredProjects.isEmpty()) {
             return botObjs.stream().anyMatch(bot -> checkFieldsForMatchingMail(bot, mail));
         }
-        // for each of the matched projects, check the bot for the matching project ID
-        for (Project p : filteredProjects) {
+        // check if any of the projects match any of the bots
+        return filteredProjects.stream().anyMatch(p -> botObjs.stream().anyMatch(bot -> {
             LOGGER.debug("Checking project {} for matching bots", p.getProjectId());
-            for (JsonNode bot : botObjs) {
-                // if the project ID match, and one of the email fields matches, then user is
-                // bot
-                if (p.getProjectId().equalsIgnoreCase(bot.get("projectId").asText())
-                        && checkFieldsForMatchingMail(bot, mail)) {
-                    return true;
-                }
-            }
-        }
-        return false;
+            return p.getProjectId().equalsIgnoreCase(bot.get("projectId").asText())
+                    && checkFieldsForMatchingValue(bot, checkedValue, checkedField);
+        }));
+
     }
 
     /**
-     * Checks for standard and noreply email address matches for a Git user and
-     * converts to a Eclipse Foundation account object.
+     * Checks for standard and noreply email address matches for a Git user and converts to a Eclipse Foundation account
+     * object.
      * 
      * @param user the user to attempt account retrieval for.
      * @return the user account if found by mail, or null if none found.
@@ -164,13 +173,11 @@ public class CachedUserService implements UserService {
     }
 
     /**
-     * Checks git user for no-reply address, and attempts to ratify user through
-     * reverse lookup in API service. Currently, this service only recognizes Github
-     * no-reply addresses as they have a route to be mapped.
+     * Checks git user for no-reply address, and attempts to ratify user through reverse lookup in API service. Currently,
+     * this service only recognizes Github no-reply addresses as they have a route to be mapped.
      * 
      * @param user the Git user account to check for no-reply mail address
-     * @return the Eclipse user if email address is detected no reply and one can be
-     *         mapped, otherwise null
+     * @return the Eclipse user if email address is detected no reply and one can be mapped, otherwise null
      */
     private EclipseUser checkForNoReplyUser(String mail) {
         if (StringUtils.isBlank(mail)) {
@@ -180,20 +187,9 @@ public class CachedUserService implements UserService {
         LOGGER.debug("Checking user with mail {} for no-reply", mail);
         boolean isNoReply = patterns.stream().anyMatch(pattern -> pattern.matcher(mail.trim()).find());
         if (isNoReply) {
-            // get the username/ID string before the first @ symbol.
-            String noReplyUser = mail.substring(0, mail.indexOf("@", 0));
-            // split based on +, if more than one part, use second (contains user),
-            // otherwise, use whole string
-            String[] nameParts = noReplyUser.split("[\\+]");
-            String namePart;
-            if (nameParts.length > 1 && nameParts[1] != null) {
-                namePart = nameParts[1];
-            } else {
-                namePart = nameParts[0];
-            }
-            String uname = namePart.trim();
-            LOGGER.debug("User with mail {} detected as noreply account, checking services for username match on '{}'",
-                    mail, uname);
+            // get the user from the noreply address
+            String uname = extractNoReplyUserFromAddress(mail);
+            LOGGER.debug("User with mail {} detected as noreply account, checking services for username match on '{}'", mail, uname);
 
             // check github for no-reply (only allowed noreply currently)
             if (mail.endsWith("noreply.github.com")) {
@@ -209,18 +205,21 @@ public class CachedUserService implements UserService {
     }
 
     /**
-     * Checks JSON node to look for email fields, both at the root, and nested email
-     * fields.
+     * Checks JSON node to look for email fields, both at the root, and nested email fields.
      * 
-     * @param bot  the bots JSON object representation
+     * @param bot the bots JSON object representation
      * @param mail the email to match against
      * @return true if the bot has a matching email value, otherwise false
      */
     private boolean checkFieldsForMatchingMail(JsonNode bot, String mail) {
+        return checkFieldsForMatchingValue(bot, mail, "email");
+    }
+
+    private boolean checkFieldsForMatchingValue(JsonNode bot, String targetValue, String fieldName) {
         // check the root email for the bot for match
-        JsonNode botmail = bot.get("email");
-        if (mail != null && botmail != null && mail.equalsIgnoreCase(botmail.asText(""))) {
-            LOGGER.debug("Found matching bot at root level for '{}'", mail);
+        JsonNode botField = bot.get(fieldName);
+        if (targetValue != null && botField != null && targetValue.equalsIgnoreCase(botField.asText(""))) {
+            LOGGER.debug("Found matching bot at root level for '{}'", targetValue);
             return true;
         }
         Iterator<Entry<String, JsonNode>> i = bot.fields();
@@ -229,11 +228,11 @@ public class CachedUserService implements UserService {
             // check that our field is an object with fields
             JsonNode node = e.getValue();
             if (node.isObject()) {
-                LOGGER.debug("Checking {} for bot email", e.getKey());
+                LOGGER.debug("Checking {} for bot value in field {}", e.getKey(), fieldName);
                 // if the mail matches (ignoring case) user is bot
-                JsonNode botAliasMail = node.get("email");
-                if (mail != null && botAliasMail != null && mail.equalsIgnoreCase(botAliasMail.asText(""))) {
-                    LOGGER.debug("Found match for bot email {}", mail);
+                JsonNode botAliasField = node.get(fieldName);
+                if (targetValue != null && botAliasField != null && targetValue.equalsIgnoreCase(botAliasField.asText(""))) {
+                    LOGGER.debug("Found match for bot value {}", targetValue);
                     return true;
                 }
             }
@@ -241,9 +240,23 @@ public class CachedUserService implements UserService {
         return false;
     }
 
+    private String extractNoReplyUserFromAddress(String mail) {
+        // get the username/ID string before the first @ symbol.
+        String noReplyUser = mail.substring(0, mail.indexOf("@", 0));
+        // split based on +, if more than one part, use second (contains user),
+        // otherwise, use whole string
+        String[] nameParts = noReplyUser.split("[\\+]");
+        String namePart;
+        if (nameParts.length > 1 && nameParts[1] != null) {
+            namePart = nameParts[1];
+        } else {
+            namePart = nameParts[0];
+        }
+        return namePart.trim();
+    }
+
     private List<JsonNode> getBots() {
-        Optional<List<JsonNode>> allBots = cache.get("allBots", new MultivaluedMapImpl<>(), JsonNode.class,
-                () -> bots.getBots());
+        Optional<List<JsonNode>> allBots = cache.get("allBots", new MultivaluedMapImpl<>(), JsonNode.class, () -> bots.getBots());
         if (!allBots.isPresent()) {
             return Collections.emptyList();
         }
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 41425558d831a452d5b74a06245f4e10f8132292..c2a762554ee0fc27d80703f7c9e1d4a847d526aa 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -4,7 +4,7 @@ org.eclipsefoundation.git.eca.api.ProjectsAPI/mp-rest/url=https://projects.eclip
 org.eclipsefoundation.git.eca.api.BotsAPI/mp-rest/url=https://api.eclipse.org
 quarkus.rest-client."org.eclipsefoundation.git.eca.api.GitlabAPI".url=https://gitlab.eclipse.org/api/v4/
 
-eclipse.noreply.email-patterns=@users.noreply.github.com\$
+eclipse.noreply.email-patterns=@users.noreply.github.com\$,@noreply.github.com\$
 
 ## Base HTTP settings
 quarkus.http.enable-compression=true
diff --git a/src/test/java/org/eclipsefoundation/git/eca/service/impl/CachedUserServiceTest.java b/src/test/java/org/eclipsefoundation/git/eca/service/impl/CachedUserServiceTest.java
index 434fcec2bd044dff0a3de619f2649df1b2628451..87af6dec504161f92ef113dda57b2136ee99db81 100644
--- a/src/test/java/org/eclipsefoundation/git/eca/service/impl/CachedUserServiceTest.java
+++ b/src/test/java/org/eclipsefoundation/git/eca/service/impl/CachedUserServiceTest.java
@@ -28,8 +28,8 @@ import org.junit.jupiter.api.Test;
 import io.quarkus.test.junit.QuarkusTest;
 
 /**
- * Tests user service impl using test stub data available from API stubs. While
- * not a perfect test as there is no auth, it is good enough for unit testing.
+ * Tests user service impl using test stub data available from API stubs. While not a perfect test as there is no auth,
+ * it is good enough for unit testing.
  * 
  * @author Martin Lowe
  *
@@ -98,6 +98,11 @@ public class CachedUserServiceTest {
         Assertions.assertTrue(users.userIsABot("1.bot@eclipse.org", getTestProject()));
     }
 
+    @Test
+    void isUserABot_success_noreply() {
+        Assertions.assertTrue(users.userIsABot("123456789+projbot@noreply.github.com", getTestProject()));
+    }
+
     @Test
     void isUserABot_nullOrEmptyAddress() {
         Assertions.assertFalse(users.userIsABot(null, getTestProject()));
@@ -132,8 +137,7 @@ public class CachedUserServiceTest {
      * @return the sample.proj project in a list for use in tests.
      */
     private List<Project> getTestProject() {
-        Optional<Project> proj = projects.getProjects().stream().filter(p -> p.getProjectId().equals("sample.proj"))
-                .findFirst();
+        Optional<Project> proj = projects.getProjects().stream().filter(p -> p.getProjectId().equals("sample.proj")).findFirst();
         if (proj.isEmpty()) {
             Assertions.fail("Could not find one of the needed test projects for test, bad state.");
         }
diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties
index 98a247c88062082d6fb2bb77282ff0a327b0029c..4d28ba44717ead6563452e792698d6fb9dd5faa8 100644
--- a/src/test/resources/application.properties
+++ b/src/test/resources/application.properties
@@ -2,7 +2,7 @@
 org.eclipsefoundation.git.eca.api.ProjectsAPI/mp-rest/url=https://projects.eclipse.org
 org.eclipsefoundation.git.eca.api.BotsAPI/mp-rest/url=https://api.eclipse.org
 
-eclipse.noreply.email-patterns=@users.noreply.github.com\$
+eclipse.noreply.email-patterns=@users.noreply.github.com\$,@noreply.github.com\$
 eclipse.mail.allowlist=noreply@github.com
 eclipse.reports.access-key=samplekey
 eclipse.gitlab.access-token=token_val