お知らせ:

当社は、お客様により充実したサポート情報を迅速に提供するため、本ページのコンテンツは機械翻訳を用いて日本語に翻訳しています。正確かつ最新のサポート情報をご覧いただくには、本内容の英語版を参照してください。

Integration Functionの設定

Integration Functionを設定し、コードを追加します。

Note: Cliq上でエクステンションを設定する前に、ファンクションをコーディングしてCatalystリモートコンソールにデプロイする必要があります。エクステンションをCatalystコンソールの既存のファンクションに関連付ける必要があるためです。

Integration Functionのディレクトリfunctions/GithubExtensionには以下が含まれます。

  • MainClass.javaメインファンクションファイル
  • com/handlersフォルダ内のハンドラーファイル
  • catalyst-config.json設定ファイル
  • libフォルダ内のJavaライブラリファイル
  • .classpath.projectの依存関係ファイル

handlersフォルダ内のBotHandler.javaCommandHandler.javaFunctionHandler.javaをコーディングします。また、このディレクトリに新しいクラスファイルGithubConstants.javaを作成し、コードを追加します。

Note: このセクションのコードを十分に理解するために、必ず目を通してください。コードの説明はこのセクションの最後で行います。

以下のコードをコピーして、IDEを使用してプロジェクトのfunctions/GithubExtension/com/handlersディレクトリにある各ファイルに貼り付けて保存してください。

BotHandler.java
copy
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;
}

}

View more

CommandHandler.java
copy
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;
}

}

View more

FunctionHandler.java
copy
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;
}

}

View more

次に、handlers/directoryに新しいJavaクラスファイルを作成し、GithubConstants.javaという名前を付けます。以下のコードをファイルに追加してください。

GithubConstants.java
copy
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”; }

View more

Note: このコードをコピー&ペーストした後、ステップ2でGitHubから取得したパーソナルアクセストークンをこのコードの6行目に貼り付けてください

ファンクションディレクトリの設定が完了しました。

ハンドラークラスのコードを簡単に確認しましょう。ここで指定したコンポーネントの詳細については、エクステンションの設定で説明します。

  • 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

関連リンク

Integration Functions