Skip to content

Commit

Permalink
Add support private channel
Browse files Browse the repository at this point in the history
  • Loading branch information
Duy Luong committed Mar 26, 2019
1 parent fa18f2c commit 363782b
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 38 deletions.
19 changes: 9 additions & 10 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<groupId>com.katalon</groupId>
<artifactId>katalon-studio-slack-plugin</artifactId>
<version>1.0.6</version>
<version>1.0.7</version>

<packaging>bundle</packaging>

Expand All @@ -26,15 +26,14 @@

<!-- Slack plugin's dependencies -->
<dependency>
<groupId>com.github.seratch</groupId>
<artifactId>jslack</artifactId>
<version>1.1.6</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.7</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
</dependencies>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
package com.katalon.plugin.slack;

import java.io.IOException;

import org.osgi.service.event.Event;

import com.github.seratch.jslack.Slack;
import com.github.seratch.jslack.api.methods.SlackApiException;
import com.github.seratch.jslack.shortcut.Shortcut;
import com.github.seratch.jslack.shortcut.model.ApiToken;
import com.github.seratch.jslack.shortcut.model.ChannelName;
import com.katalon.platform.api.event.EventListener;
import com.katalon.platform.api.event.ExecutionEvent;
import com.katalon.platform.api.exception.ResourceException;
Expand All @@ -32,25 +25,23 @@ public void registerListener(EventListener listener) {

if (ExecutionEvent.TEST_SUITE_FINISHED_EVENT.equals(event.getTopic())) {
ExecutionEvent eventObject = (ExecutionEvent) event.getProperty("org.eclipse.e4.data");
Slack slack = Slack.getInstance();
ApiToken token = ApiToken.of(authToken);
Shortcut shortcut = slack.shortcut(token);

TestSuiteExecutionContext testSuiteContext = (TestSuiteExecutionContext) eventObject
.getExecutionContext();
TestSuiteStatusSummary testSuiteSummary = TestSuiteStatusSummary.of(testSuiteContext);
System.out.println("Slack: Start sending summary message to channel: " + channel);
shortcut.postAsBot(ChannelName.of(channel),
"Summary execution result of test suite: " + testSuiteContext.getSourceId()
+ "\nTotal test cases: " + Integer.toString(testSuiteSummary.getTotalTestCases())
+ "\nTotal passes: " + Integer.toString(testSuiteSummary.getTotalPasses())
+ "\nTotal failures: " + Integer.toString(testSuiteSummary.getTotalFailures())
+ "\nTotal errors: " + Integer.toString(testSuiteSummary.getTotalErrors())
+ "\nTotal skipped: " + Integer.toString(testSuiteSummary.getTotalSkipped()));
String message = "Summary execution result of test suite: " + testSuiteContext.getSourceId()
+ "\nTotal test cases: " + Integer.toString(testSuiteSummary.getTotalTestCases())
+ "\nTotal passes: " + Integer.toString(testSuiteSummary.getTotalPasses())
+ "\nTotal failures: " + Integer.toString(testSuiteSummary.getTotalFailures())
+ "\nTotal errors: " + Integer.toString(testSuiteSummary.getTotalErrors())
+ "\nTotal skipped: " + Integer.toString(testSuiteSummary.getTotalSkipped());
SlackUtil.sendMessage(authToken, channel, message);

System.out.println("Slack: Summary message has been successfully sent");
}
} catch (ResourceException | IOException | SlackApiException e) {
e.printStackTrace(System.out);
} catch (ResourceException | SlackException e) {
e.printStackTrace(System.err);
}
});
}
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/com/katalon/plugin/slack/SlackException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.katalon.plugin.slack;

public class SlackException extends Exception {

private static final long serialVersionUID = 1171601532588814667L;

public SlackException(String message) {
super(message, null);
}

public SlackException(Throwable throwable) {
super("", throwable);
}

public SlackException(String message, Throwable throwable) {
super(message, throwable);
}
}
14 changes: 5 additions & 9 deletions src/main/java/com/katalon/plugin/slack/SlackPreferencePage.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.katalon.plugin.slack;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.SWT;
Expand All @@ -15,10 +16,6 @@
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

import com.github.seratch.jslack.Slack;
import com.github.seratch.jslack.shortcut.Shortcut;
import com.github.seratch.jslack.shortcut.model.ApiToken;
import com.github.seratch.jslack.shortcut.model.ChannelName;
import com.katalon.platform.api.exception.ResourceException;
import com.katalon.platform.api.preference.PluginPreference;
import com.katalon.platform.api.service.ApplicationManager;
Expand Down Expand Up @@ -100,20 +97,19 @@ private void testSlackConnection(String token, String channel) {
lblConnectionStatus.setText("Connecting...");
thread = new Thread(() -> {
try {
Slack slack = Slack.getInstance();
ApiToken apiToken = ApiToken.of(token);
Shortcut shortcut = slack.shortcut(apiToken);
shortcut.postAsBot(ChannelName.of(channel), "This is a test message from Katalon Studio using Slack Plugin");
SlackUtil.sendMessage(token, channel, "This is a test message from Katalon Studio using Slack Plugin");
syncExec(() -> {
lblConnectionStatus
.setForeground(lblConnectionStatus.getDisplay().getSystemColor(SWT.COLOR_DARK_GREEN));
lblConnectionStatus.setText("Connection success");
});
} catch (Exception e) {
e.printStackTrace(System.err);
syncExec(() -> {
lblConnectionStatus
.setForeground(lblConnectionStatus.getDisplay().getSystemColor(SWT.COLOR_DARK_RED));
lblConnectionStatus.setText("Connection failed");
lblConnectionStatus
.setText("Connection failed. Reason: " + StringUtils.defaultString(e.getMessage()));
});
} finally {
syncExec(() -> btnTestConnection.setEnabled(true));
Expand Down
180 changes: 180 additions & 0 deletions src/main/java/com/katalon/plugin/slack/SlackUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
package com.katalon.plugin.slack;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import com.google.gson.stream.JsonReader;

public class SlackUtil {
public static final String RES_IS_OK = "isOk";

public static final String RES_ERROR_MSG = "errorMsg";

/**
* Send message to Slack for Team Collaboration
*
* @param msg String message to send
* @throws SlackException
*/
public static void sendMessage(String token, String channel, String msg) throws SlackException {
try {
Map<String, Object> response = getResponseFromSendingMsg(buildSlackUri(token, channel, msg));

boolean isOk = (boolean) response.get(RES_IS_OK);
if (!isOk) {
String errorMsg = (String) response.get(RES_ERROR_MSG);
throw new SlackException(errorMsg);
}
} catch (IOException | URISyntaxException e) {
throw new SlackException(e);
}
}

/**
* Slack URI builder which will encode user info and message into URI
*
* @param token the authentication token
* @param channel Channel name
* @param username Bot name
* @param asIssuedTokenUser if true, Bot name will be ignore. Otherwise, message will be sent using Bot name
* @param msg Message to send
* @return URI
* @throws URISyntaxException
* @throws Exception UnsupportedEncodingException
* @see UnsupportedEncodingException
* @see <a href="https://api.slack.com/web">Create Slack auth token</a>
*/
public static URI buildSlackUri(String token, String channel, String msg) throws URISyntaxException {
// scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]
URIBuilder uriBuilder = new URIBuilder().setScheme("https")
.setHost("slack.com")
.setPath("/api/chat.postMessage")
.addParameter("token", token)
.addParameter("channel", channel);
uriBuilder.addParameter("text", msg);
return uriBuilder.build();
}

/**
* Get response data from sending message to Slack
*
* @param uri URI to send GET request
* @return A Map object with 2 keys SlackUtil.RES_IS_OK and SlackUtil.RES_ERROR_MSG
* @throws ClientProtocolException
* @throws IOException
*/
public static Map<String, Object> getResponseFromSendingMsg(URI uri) throws ClientProtocolException, IOException {
boolean isOk = false;
String errorMsg = null;

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet(uri);
CloseableHttpResponse response = httpclient.execute(httpget);
try {
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStreamReader in = new InputStreamReader(entity.getContent());
try {
JsonReader reader = new JsonReader(in);
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (StringUtils.equals(name, "ok")) {
isOk = reader.nextBoolean();
} else if (StringUtils.equals(name, "error")) {
errorMsg = reader.nextString();
} else {
reader.skipValue(); // avoid some unhandled events
}
}
reader.endObject();
reader.close();
} finally {
in.close();
}
}
} finally {
response.close();
}

Map<String, Object> res = new HashMap<String, Object>();
res.put(RES_IS_OK, isOk);
res.put(RES_ERROR_MSG, errorMsg);
return res;
}

/**
* Slack Bold format text message
*
* @param msg String text message
* @return String Bold format text message
*/
public String fmtBold(String msg) {
return "*" + msg + "*";
}

/**
* Slack Italic format text message
*
* @param msg String text message
* @return String Italic format text message
*/
public String fmtItalic(String msg) {
return "_" + msg + "_";
}

/**
* Slack responded message status
*/
public static class SlackMsgStatus {
private static SlackMsgStatus _instance;

private static Map<String, String> msgMap;

public static SlackMsgStatus getInstance() {
if (_instance == null) {
_instance = new SlackMsgStatus();
}
return _instance;
}

public SlackMsgStatus() {
msgMap = new HashMap<String, String>();
msgMap.put("channel_not_found", StringConstants.SLACK_ERROR_MSG_CHANNEL_NOT_FOUND);
msgMap.put("not_in_channel", StringConstants.SLACK_ERROR_MSG_NOT_IN_CHANNEL);
msgMap.put("is_archived", StringConstants.SLACK_ERROR_MSG_IS_ARCHIVED);
msgMap.put("msg_too_long", StringConstants.SLACK_ERROR_MSG_MSG_TOO_LONG);
msgMap.put("no_text", StringConstants.SLACK_ERROR_MSG_NO_TEXT);
msgMap.put("rate_limited", StringConstants.SLACK_ERROR_MSG_RATE_LIMITED);
msgMap.put("not_authed", StringConstants.SLACK_ERROR_MSG_NOT_AUTHED);
msgMap.put("invalid_auth", StringConstants.SLACK_ERROR_MSG_INVALID_AUTH);
msgMap.put("account_inactive", StringConstants.SLACK_ERROR_MSG_ACCOUNT_INACTIVE);
}

public Map<String, String> getMsgMap() {
return msgMap;
}

public String getMsgDescription(String msgCode) {
if (getMsgMap().get(msgCode) == null) {
// No message description found
return msgCode;
}
return getMsgMap().get(msgCode);
}
}
}
14 changes: 14 additions & 0 deletions src/main/java/com/katalon/plugin/slack/StringConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.katalon.plugin.slack;


public class StringConstants {
public static final String SLACK_ERROR_MSG_CHANNEL_NOT_FOUND = "Invalid value passed for Channel/Group.";
public static final String SLACK_ERROR_MSG_NOT_IN_CHANNEL = "Unable to post user messages to a channel/group they are not in.";
public static final String SLACK_ERROR_MSG_IS_ARCHIVED = "Channel/Group has been archived.";
public static final String SLACK_ERROR_MSG_MSG_TOO_LONG = "Message text is too long.";
public static final String SLACK_ERROR_MSG_NO_TEXT = "No message text provided.";
public static final String SLACK_ERROR_MSG_RATE_LIMITED = "Application has posted too many messages.";
public static final String SLACK_ERROR_MSG_NOT_AUTHED = "No authentication token provided.";
public static final String SLACK_ERROR_MSG_INVALID_AUTH = "Invalid authentication token.";
public static final String SLACK_ERROR_MSG_ACCOUNT_INACTIVE = "Authentication token is for a deleted user or team.";
}

0 comments on commit 363782b

Please sign in to comment.