Integration Functionの設定
Integration Functionを設定し、コードを追加します。
Integration Functionのディレクトリfunctions/GithubExtensionには以下が含まれます。
- MainClass.javaメインファンクションファイル
- com/handlersフォルダ内のハンドラーファイル
- catalyst-config.json設定ファイル
- libフォルダ内のJavaライブラリファイル
- .classpathと.projectの依存関係ファイル
handlersフォルダ内のBotHandler.java、CommandHandler.java、FunctionHandler.javaをコーディングします。また、このディレクトリに新しいクラスファイルGithubConstants.javaを作成し、コードを追加します。
以下のコードをコピーして、IDEを使用してプロジェクトのfunctions/GithubExtension/com/handlersディレクトリにある各ファイルに貼り付けて保存してください。
package com.handlers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import java.util.logging.Level;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zc.cliq.enums.ACTION_TYPE;
import com.zc.cliq.enums.BANNER_STATUS;
import com.zc.cliq.enums.BUTTON_TYPE;
import com.zc.cliq.enums.CHANNEL_OPERATION;
import com.zc.cliq.enums.SLIDE_TYPE;
import com.zc.cliq.objects.Action;
import com.zc.cliq.objects.ActionData;
import com.zc.cliq.objects.BotDetails;
import com.zc.cliq.objects.ButtonObject;
import com.zc.cliq.objects.Confirm;
import com.zc.cliq.objects.Message;
import com.zc.cliq.objects.Slide;
import com.zc.cliq.requests.BotCallHandlerRequest;
import com.zc.cliq.requests.BotContextHandlerRequest;
import com.zc.cliq.requests.BotMentionHandlerRequest;
import com.zc.cliq.requests.BotMenuActionHandlerRequest;
import com.zc.cliq.requests.BotMessageHandlerRequest;
import com.zc.cliq.requests.BotParticipationHandlerRequest;
import com.zc.cliq.requests.BotWebhookHandlerRequest;
import com.zc.cliq.requests.BotWelcomeHandlerRequest;
import com.zc.cliq.responses.BannerResponse;
import com.zc.cliq.responses.CoreResponse;
import com.zc.cliq.responses.WebhookHandlerResponse;
// import com.zc.cliq.util.ZCCliqUtil;
public class BotHandler implements com.zc.cliq.interfaces.BotHandler, CoreResponse {
Logger LOGGER = Logger.getLogger(BotHandler.class.getName());
@Override
public CoreResponse messageHandler(BotMessageHandlerRequest req) throws JSONException {
LOGGER.log(Level.SEVERE, "class BotHandler method messageHandler");
String message = req.getMessage();
String text;
if (message == null) {
text = "Hello! How can I help you?";
} else if (message.equalsIgnoreCase("hello")) {
text = "Hello! How can I help you?";
} else if (message.equalsIgnoreCase("webhooktoken")) {
Message msg = Message.getInstance("Click on the token generation button below!");
ButtonObject btnObj = new ButtonObject();
btnObj.setType(BUTTON_TYPE.GREEN_OUTLINE);
btnObj.setLabel("Create Webhook");
Action action = new Action();
action.setType(ACTION_TYPE.INVOKE_FUNCTION);
ActionData actionData = new ActionData();
actionData.setName("authenticate"); // ** ボタンファンクション名をここに入力 **
action.setData(actionData);
Confirm confirm = new Confirm();
confirm.setTitle("Generate Webhooks for a GitLab Project");
confirm.setDescription("Connect to GitLab Projects from within Cliq");
confirm.setInput("user_webhook_token");
action.setConfirm(confirm);
btnObj.setAction(action);
msg.addButton(btnObj);
return (CoreResponse) msg;
} else {
text = "Sorry, I'm not programmed yet to do this :sad:";
}
Message resp = Message.getInstance(text);
return (CoreResponse) resp;
}
@Override
public CoreResponse menuActionHandler(BotMenuActionHandlerRequest req) throws Exception {
LOGGER.log(Level.SEVERE, "class BotHandler method menuActionHandler");
Message msg = Message.getInstance();
BotDetails bot = BotDetails.getInstance(GithubConstants.BOT_NAME);
msg.setBot(bot);
if (req.getActionName().equals("Repos")) {
JSONArray reposArray = CommandHandler.getRepos();
if (reposArray.length() == 0) {
msg.setText("There aren't are repos created yet.");
} else {
Slide slide = Slide.getInstance();
msg.setText("Here's a list of the *repositories*");
slide.setType(SLIDE_TYPE.TABLE);
slide.setTitle("Repo details");
List<String> headers = new ArrayList<>();
headers.add("Name");
headers.add("Private");
headers.add("Open Issues");
headers.add("Link");
// JSONObjectの代わりにMapを使用
Map<String, Object> data = new HashMap<>();
data.put("headers", headers);
// JSONArrayの代わりにListを使用
List<Map<String, Object>> rows = new ArrayList<>();
for (int i = 0; i < reposArray.length(); i++) {
JSONObject repo = reposArray.optJSONObject(i);
Map<String, Object> row = new HashMap<>();
row.put("Name", repo.optString("name"));
row.put("Private", repo.optBoolean("private") ? "Yes" : "No");
row.put("Open Issues", repo.optString("open_issues_count"));
row.put("Link", "[Click here](" + repo.optString("html_url") + ")");
rows.add(row);
}
data.put("rows", rows);
slide.setData(data);
msg.addSlide(slide);
}
} else {
msg.setText("Menu action triggered :fist:");
}
return (CoreResponse) msg;
}
@Override
public WebhookHandlerResponse webhookHandler(BotWebhookHandlerRequest req) throws Exception {
LOGGER.log(Level.SEVERE, "class BotHandler method webhookHandler");
JSONObject reqBody = req.getBody();
LOGGER.info(reqBody.toString());
JSONObject commitJson = reqBody.optJSONArray("commits").optJSONObject(0);
/// メッセージ
Message msg = Message.getInstance("A commit has been pushed !");
msg.setBot(BotDetails.getInstance(GithubConstants.BOT_NAME));
/// コミットメッセージ
Slide commitMsg = Slide.getInstance();
commitMsg.setType(SLIDE_TYPE.TEXT);
commitMsg.setTitle("Commit message");
commitMsg.setData(commitJson.optString("message"));
msg.addSlide(commitMsg);
// スライド
Slide details = Slide.getInstance();
details.setType(SLIDE_TYPE.LABEL);
details.setTitle("Details");
JSONArray dataArray = new JSONArray();
JSONObject committer = new JSONObject();
committer.put("Committer", commitJson.optJSONObject("author").optString("username"));
dataArray.put(committer);
JSONObject repoName = new JSONObject();
repoName.put("Repo Name", reqBody.optJSONObject("repository").optString("name"));
dataArray.put(repoName);
JSONObject timestamp = new JSONObject();
timestamp.put("Timestamp", commitJson.optString("timestamp"));
dataArray.put(timestamp);
JSONObject compare = new JSONObject();
compare.put("Compare", "[Click here](" + reqBody.optString("compare") + ")");
dataArray.put(compare);
details.setData(dataArray);
LOGGER.log(Level.SEVERE, "printing array");
ObjectMapper mapper = new ObjectMapper();
LOGGER.log(Level.SEVERE, mapper.writeValueAsString(dataArray));
msg.addSlide(details);
return (WebhookHandlerResponse) msg;
}
@Override
public CoreResponse participationHandler(BotParticipationHandlerRequest req) throws Exception {
LOGGER.log(Level.SEVERE, "class BotHandler method participationHandler");
String text;
if (req.getOperation().equals(CHANNEL_OPERATION.ADDED)) {
text = "Hi. Thanks for adding me to the channel :smile:";
} else if (req.getOperation().equals(CHANNEL_OPERATION.REMOVED)) {
text = "Bye-Bye :bye-bye:";
} else {
text = "I'm too a participant of this chat :wink:";
}
Message msg = Message.getInstance(text);
return (CoreResponse) msg;
}
@Override
public Message welcomeHandler(BotWelcomeHandlerRequest req) {
LOGGER.log(Level.SEVERE, "class BotHandler method welcomeHandler");
String uName = req.getUser() != null ? req.getUser().getFirstName() : "user";
String text = "Hello " + uName + ". Thank you for subscribing :smile:";
Message msg = Message.getInstance(text);
return msg;
}
@Override
public CoreResponse contextHandler(BotContextHandlerRequest req) {
LOGGER.log(Level.SEVERE, "class BotHandler method contextHandler");
BannerResponse resp = new BannerResponse("", BANNER_STATUS.SUCCESS);
if (req.getContextId().equals("personal_details")) {
Map<String, String> answers = req.getAnswers();
StringBuilder str = new StringBuilder();
str.append("Name: ").append(answers.get("name")).append("\n");
str.append("Department: ").append(answers.get("dept")).append("\n");
resp = new BannerResponse("Nice ! I have collected your info: \n" + str.toString(), BANNER_STATUS.SUCCESS);
}
return (CoreResponse) resp;
}
@Override
public CoreResponse mentionHandler(BotMentionHandlerRequest req) {
LOGGER.log(Level.SEVERE, "class BotHandler method mentionHandler");
String text = "Hey *" + req.getUser().getFirstName()
+ "*, thanks for mentioning me here. I'm from Catalyst city";
BannerResponse resp = new BannerResponse(text, BANNER_STATUS.SUCCESS);
return (CoreResponse) resp;
}
@Override
public void callHandler(BotCallHandlerRequest req) throws Exception {
LOGGER.log(Level.SEVERE, "class BotHandler method callHandler");
return;
}
}
package com.handlers;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONObject;
import com.zc.api.APIConstants.RequestMethod;
import com.zc.api.APIRequest;
import com.zc.cliq.enums.SLIDE_TYPE;
import com.zc.cliq.objects.BotDetails;
import com.zc.cliq.objects.CommandSuggestion;
import com.zc.cliq.objects.Message;
import com.zc.cliq.objects.Slide;
import com.zc.cliq.requests.CommandHandlerRequest;
import com.zc.cliq.responses.CoreResponse;
import okhttp3.Response;
public class CommandHandler implements com.zc.cliq.interfaces.CommandHandler {
Logger LOGGER = Logger.getLogger(CommandHandler.class.getName());
@Override
public CoreResponse executionHandler(CommandHandlerRequest req) throws Exception {
LOGGER.log(Level.SEVERE, "class CommandHandler method executionHandler");
Message msg = Message.getInstance();
BotDetails bot = BotDetails.getInstance(GithubConstants.BOT_NAME);
msg.setBot(bot);
String commandName = req.getName();
if (commandName.equals("commits")) {
List<CommandSuggestion> repoSuggestions = req.getSelections();
if (repoSuggestions == null || repoSuggestions.isEmpty()) {
msg.setText("Please select a repo from the suggestions.");
} else {
String repoName = repoSuggestions.get(0).getTitle();
JSONArray commitsArray = getCommits(repoName);
if (commitsArray.length() == 0) {
msg.setText("There aren't are commits made yet.");
} else {
Slide slide = Slide.getInstance();
msg.setText("Here's a list of the latest " + GithubConstants.PER_PAGE
+ " commits made to the repository *" + repoName + "*.");
slide.setType(SLIDE_TYPE.TABLE);
slide.setTitle("Commit details");
List<String> headers = new ArrayList<>();
headers.add("Date");
headers.add("Commit message");
headers.add("Committed by");
headers.add("Link");
// JSONObjectの代わりにMapを使用
Map<String, Object> data = new HashMap<>();
data.put("headers", headers);
// JSONArrayの代わりにListを使用
List<Map<String, Object>> rows = new ArrayList<>();
for (int i = 0; i < commitsArray.length(); i++) {
JSONObject obj = commitsArray.optJSONObject(i);
JSONObject commit = obj.optJSONObject("commit");
JSONObject author = commit.optJSONObject("author");
Map<String, Object> row = new HashMap<>();
row.put("Date", author.optString("date"));
row.put("Commit message", commit.optString("message"));
row.put("Committed by", author.optString("name"));
row.put("Link", "[Click here](" + obj.optString("html_url") + ")");
rows.add(row);
}
data.put("rows", rows);
slide.setData(data);
msg.addSlide(slide);
}
}
} else if (commandName.equals("issues")) {
List<CommandSuggestion> repoSuggestions = req.getSelections();
if (repoSuggestions == null || repoSuggestions.isEmpty()) {
msg.setText("Please select a repo from the suggestions.");
} else {
String repoName = repoSuggestions.get(0).getTitle();
JSONArray issuesArray = getIssues(repoName);
if (issuesArray.length() == 0) {
msg.setText("There aren't are issues raised yet.");
} else {
Slide slide = Slide.getInstance();
msg.setText("Here's a list of the latest " + GithubConstants.PER_PAGE
+ " issues raised to the repository *" + repoName + "*");
slide.setType(SLIDE_TYPE.TABLE);
slide.setTitle("Issue details");
List<String> headers = new ArrayList<>();
headers.add("Created At");
headers.add("Title");
headers.add("Created By");
headers.add("Link");
// JSONObjectの代わりにMapを使用
Map<String, Object> data = new HashMap<>();
data.put("headers", headers);
// JSONArrayの代わりにListを使用
List<Map<String, Object>> rows = new ArrayList<>();
for (int i = 0; i < issuesArray.length(); i++) {
JSONObject issueObj = issuesArray.optJSONObject(i);
Map<String, Object> row = new HashMap<>();
row.put("Created At", issueObj.optString("created_at"));
row.put("Title", issueObj.optString("title"));
row.put("Created By", issueObj.optJSONObject("user").optString("login"));
row.put("Link", "[Click here](" + issueObj.optString("html_url") + ")");
rows.add(row);
}
data.put("rows", rows);
slide.setData(data);
msg.addSlide(slide);
}
}
} else {
msg.setText("Slash command executed");
}
return (CoreResponse) msg;
}
@Override
public List<CommandSuggestion> suggestionHandler(CommandHandlerRequest req) throws Exception {
LOGGER.log(Level.SEVERE, "class CommandHandler method suggestionHandler");
List<CommandSuggestion> suggestionList = new ArrayList<CommandSuggestion>();
JSONArray reposArray = getRepos();
List<String> repoNames = new ArrayList<>();
for (int i = 0; i < reposArray.length(); i++) {
JSONObject repo = reposArray.optJSONObject(i);
repoNames.add(repo.optString("name"));
}
if (req.getName().equals("commits") || req.getName().equals("issues")) {
repoNames.forEach((name) -> {
CommandSuggestion sugg = CommandSuggestion.getInstance();
sugg.setTitle(name);
suggestionList.add(sugg);
});
}
return suggestionList;
}
public static JSONArray getRepos() throws Exception {
APIRequest req = getRequestObj("https://api.github.com/user/repos");
req.executeRequest();
Response resp = req.getHttpResponse();
JSONArray reposArray = new JSONArray(resp.body().string());
return reposArray;
}
private String getUsername() throws Exception {
LOGGER.log(Level.SEVERE, "class CommandHandler method getUsername");
APIRequest req = getRequestObj("https://api.github.com/user");
JSONObject respJson = new JSONObject(req.getResponse().getResponseJSON().get(0).toString());
return respJson.get("login").toString();
}
private JSONArray getCommits(String repoName) throws Exception {
LOGGER.log(Level.SEVERE, "class CommandHandler method getCommits");
APIRequest req = getRequestObj("https://api.github.com/repos/" + getUsername() + "/" + repoName
+ "/commits?per_page=" + GithubConstants.PER_PAGE);
req.executeRequest();
Response resp = req.getHttpResponse();
JSONArray commitsArray = new JSONArray(resp.body().string());
return commitsArray;
}
private JSONArray getIssues(String repoName) throws Exception {
LOGGER.log(Level.SEVERE, "class CommandHandler method getIssues");
APIRequest req = getRequestObj("https://api.github.com/repos/" + getUsername() + "/" + repoName
+ "/issues?per_page=" + GithubConstants.PER_PAGE);
req.executeRequest();
Response resp = req.getHttpResponse();
JSONArray issuesArray = new JSONArray(resp.body().string());
return issuesArray;
}
private static APIRequest getRequestObj(String url) {
APIRequest req = new APIRequest();
req.setUrl(url);
req.setRequestMethod(RequestMethod.GET);
req.setAuthNeeded(false);
HashMap<String, String> headers = new HashMap<>();
headers.put("Authorization", "Token " + GithubConstants.PERSONAL_ACCESS_TOKEN);
req.setHeaders(headers);
return req;
}
}
package com.handlers;
import java.util.HashMap;
import java.util.Map;
import com.zc.cliq.objects.Form;
import com.zc.cliq.objects.FormChangeResponse;
import com.zc.cliq.objects.FormDynamicFieldResponse;
import com.zc.cliq.objects.Message;
import com.zc.cliq.objects.WidgetSection;
import com.zc.cliq.requests.ButtonFunctionRequest;
import com.zc.cliq.requests.FormFunctionRequest;
import com.zc.cliq.requests.WidgetFunctionRequest;
public class FunctionHandler implements com.zc.cliq.interfaces.FunctionHandler {
@SuppressWarnings(“unchecked”)
@Override
public Message buttonFunctionHandler(ButtonFunctionRequest req) throws Exception {
String text;
if (req.getName().equals(“authenticate”)) {
System.out.println(“Arguments: " + req.getArguments());
text = req.getArguments().get(“input”).toString();
} else {
text = “Button function executed”;
}
Message msg = Message.getInstance(text);
return msg;
}
@Override
public Message formSubmitHandler(FormFunctionRequest req) throws Exception {
return Message.getInstance("Form submitted successfully");
}
@Override
public FormChangeResponse formChangeHandler(FormFunctionRequest req) throws Exception {
FormChangeResponse resp = FormChangeResponse.getInstance();
return resp;
}
@Override
public FormDynamicFieldResponse formDynamicFieldHandler(FormFunctionRequest req) throws Exception {
FormDynamicFieldResponse resp = FormDynamicFieldResponse.getInstance();
return resp;
}
@Override
public Form formViewHandler(FormFunctionRequest req) throws Exception {
return Form.getInstance();
}
@Override
public WidgetSection widgetButtonHandler(WidgetFunctionRequest req) throws Exception {
return getButtonsSection();
}
private WidgetSection getButtonsSection() {
WidgetSection buttonSection = WidgetSection.getInstance();
return buttonSection;
}
}
次に、handlers/directoryに新しいJavaクラスファイルを作成し、GithubConstants.javaという名前を付けます。以下のコードをファイルに追加してください。
package com.handlers;
public class GithubConstants {
public static final String PERSONAL_ACCESS_TOKEN = “XXXXx”;
public static final Integer PER_PAGE = 10;
public static final String BOT_NAME = “github-bot”;
}
ファンクションディレクトリの設定が完了しました。
ハンドラークラスのコードを簡単に確認しましょう。ここで指定したコンポーネントの詳細については、エクステンションの設定で説明します。
-
BotHandler.javaクラスには、Cliqエクステンションで設定するGitHub Botコンポーネントのビジネスロジックが含まれています。チャットボットを有効にすると、GitHubへの接続を認証するためのwebhookトークンの生成、Gitリポジトリの詳細の一覧表示、リポジトリの最新コミットやIssueの詳細取得が可能になります。これらのアクションはこのクラスで定義されています。
-
CommandHandler.javaクラスは、issuesコマンドとcommitsコマンドで実行されるアクションを処理します。また、Gitアカウントのリポジトリを一覧表示するサジェスションハンドラーも定義しています。ユーザーはコマンドを入力した後、サジェスションからリポジトリを選択してコマンドを実行する必要があります。CommandHandler.javaは、Gitアカウントから他の情報を取得するためのAPIも定義しています。
-
FunctionHandler.javaクラスには、GitHubのwebhookトークンを認証するボタンファンクションのビジネスロジックが含まれています。
-
GitHubConstants.javaクラスファイルは、パーソナルアクセストークンやボット名など、ファンクションの定数値を格納しています。
最終更新日 2026-02-23 18:09:41 +0530 IST