Support tagging ChatGPT bot via its primary email
Right now to ask questions to ChatGPT it's required to provide the bot
username in the comment.
In the regular workflow with Gerrit, typing `@` following by a single
letter opens user auto-suggestion dropdown. From which the user can
be selected. This also applies to the ChatGPT user.
Unfortunately, this won't trigger the plugin action,
as auto-suggestion is inserting the primary email address of the user.
This change updates the regular expression for finding questions to
ChatGPT to also work with the ChatGPT user's preferred email address.
To make it work, we extend the `Configuration` class to also include
ChatGPT user email address. This is because the `ConfigurationCreator`
class is the last place where we can use Guice injections, as from
that point class instances are created manually either with `new`
operator or via `SingletonManager`. With that in place, we can then
update the bot mention pattern in `ClientMessage`.
Change-Id: I89500741600bc584ee749f3ff0cea2f7cc23f292
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/common/ClientMessage.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/common/ClientMessage.java
index 25f92d8..82cb931 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/common/ClientMessage.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/common/ClientMessage.java
@@ -77,9 +77,16 @@
}
private Pattern getBotMentionPattern() {
- String escapedUserName = Pattern.quote(config.getGerritUserName());
- String emailRegex = "@" + escapedUserName + "(?:@[A-Za-z0-9.-]+\\.[A-Za-z]{2,})?\\b";
+ String emailRegex = "@" + getUserNameOrEmail() + "(?:@[A-Za-z0-9.-]+\\.[A-Za-z]{2,})?\\b";
return Pattern.compile(emailRegex);
}
+ private String getUserNameOrEmail() {
+ String escapedUserName = Pattern.quote(config.getGerritUserName());
+ String userEmail = config.getGerritUserEmail();
+ if (userEmail.isBlank()) {
+ return escapedUserName;
+ }
+ return escapedUserName + "|" + Pattern.quote(userEmail);
+ }
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/config/ConfigCreator.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/config/ConfigCreator.java
index 5bf274e..4a17d31 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/config/ConfigCreator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/config/ConfigCreator.java
@@ -2,6 +2,12 @@
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.account.AccountManager;
+import com.google.gerrit.server.account.AccountState;
+import com.google.gerrit.server.account.Accounts;
+import com.google.gerrit.server.account.externalids.ExternalId;
+import com.google.gerrit.server.account.externalids.ExternalIds;
import com.google.gerrit.server.config.PluginConfig;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.project.NoSuchProjectException;
@@ -9,18 +15,22 @@
import com.google.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
+import java.util.Optional;
+
@Singleton
@Slf4j
public class ConfigCreator {
private final String pluginName;
+ private final AccountCache accountCache;
private final PluginConfigFactory configFactory;
@Inject
- ConfigCreator(@PluginName String pluginName, PluginConfigFactory configFactory) {
+ ConfigCreator(@PluginName String pluginName, AccountCache accountCache, PluginConfigFactory configFactory) {
this.pluginName = pluginName;
this.configFactory = configFactory;
+ this.accountCache = accountCache;
}
public Configuration createConfig(Project.NameKey projectName)
@@ -29,7 +39,12 @@
log.debug("These configuration items have been set in the global configuration: {}", globalConfig.getNames());
PluginConfig projectConfig = configFactory.getFromProjectConfig(projectName, pluginName);
log.debug("These configuration items have been set in the project configuration: {}", projectConfig.getNames());
- return new Configuration(globalConfig, projectConfig);
+ return new Configuration(globalConfig, projectConfig, getGerritUserEmail(globalConfig));
}
+ private String getGerritUserEmail(PluginConfig globalConfig) {
+ String gptUser = globalConfig.getString(Configuration.KEY_GERRIT_USERNAME);
+ Optional<AccountState> gptAccount = accountCache.getByUsername(gptUser);
+ return gptAccount.map(a -> a.account().preferredEmail()).orElse("");
+ }
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/config/Configuration.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/config/Configuration.java
index 2498191..5a9c2cf 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/config/Configuration.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/config/Configuration.java
@@ -83,10 +83,10 @@
public static final String KEY_GPT_COMMENT_TEMPERATURE = "gptCommentTemperature";
public static final String KEY_VOTING_MIN_SCORE = "votingMinScore";
public static final String KEY_VOTING_MAX_SCORE = "votingMaxScore";
+ public static final String KEY_GERRIT_USERNAME = "gerritUserName";
private static final String KEY_GPT_TOKEN = "gptToken";
private static final String KEY_GERRIT_AUTH_BASE_URL = "gerritAuthBaseUrl";
- private static final String KEY_GERRIT_USERNAME = "gerritUserName";
private static final String KEY_GERRIT_PASSWORD = "gerritPassword";
private static final String KEY_GPT_DOMAIN = "gptDomain";
private static final String KEY_GPT_MODEL = "gptModel";
@@ -120,10 +120,17 @@
private final PluginConfig globalConfig;
@Getter
private final PluginConfig projectConfig;
+ @Getter
+ private final String gerritUserEmail;
public Configuration(PluginConfig globalConfig, PluginConfig projectConfig) {
+ this(globalConfig, projectConfig, "");
+ }
+
+ public Configuration(PluginConfig globalConfig, PluginConfig projectConfig, String gerritUserEmail) {
this.globalConfig = globalConfig;
this.projectConfig = projectConfig;
+ this.gerritUserEmail = gerritUserEmail;
}
public String getGptToken() {