Merge pull request #15 from Mineplex-LLC/feature/slack-api
Add a Slack API for sending messages through plugins.
This commit is contained in:
commit
e7245bcc11
@ -1,27 +1,21 @@
|
|||||||
package mineplex.core;
|
package mineplex.core;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.bukkit.scheduler.BukkitScheduler;
|
import org.bukkit.scheduler.BukkitScheduler;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|
||||||
import mineplex.core.command.CommandCenter;
|
import mineplex.core.command.CommandCenter;
|
||||||
import mineplex.core.command.ICommand;
|
import mineplex.core.command.ICommand;
|
||||||
import mineplex.core.common.util.F;
|
import mineplex.core.common.util.F;
|
||||||
import mineplex.core.common.util.NautHashMap;
|
import mineplex.core.common.util.NautHashMap;
|
||||||
import mineplex.core.common.util.UtilTime;
|
import mineplex.core.common.util.UtilTime;
|
||||||
import mineplex.core.common.util.UtilTime.TimeUnit;
|
import mineplex.core.common.util.UtilTime.TimeUnit;
|
||||||
|
import mineplex.core.thread.ThreadPool;
|
||||||
|
|
||||||
public abstract class MiniPlugin implements Listener
|
public abstract class MiniPlugin implements Listener
|
||||||
{
|
{
|
||||||
private static final ExecutorService threadPool = Executors.newCachedThreadPool(
|
|
||||||
new ThreadFactoryBuilder().setNameFormat("MiniPlugin Async %1$d").build());
|
|
||||||
|
|
||||||
protected String _moduleName = "Default";
|
protected String _moduleName = "Default";
|
||||||
protected JavaPlugin _plugin;
|
protected JavaPlugin _plugin;
|
||||||
protected NautHashMap<String, ICommand> _commands;
|
protected NautHashMap<String, ICommand> _commands;
|
||||||
@ -113,7 +107,7 @@ public abstract class MiniPlugin implements Listener
|
|||||||
public void runAsync(Runnable runnable)
|
public void runAsync(Runnable runnable)
|
||||||
{
|
{
|
||||||
// Instead of using
|
// Instead of using
|
||||||
threadPool.execute(runnable);
|
ThreadPool.ASYNC.execute(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void runAsync(Runnable runnable, long time)
|
public void runAsync(Runnable runnable, long time)
|
||||||
|
129
Plugins/Mineplex.Core/src/mineplex/core/slack/SlackAPI.java
Normal file
129
Plugins/Mineplex.Core/src/mineplex/core/slack/SlackAPI.java
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
package mineplex.core.slack;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import mineplex.core.thread.ThreadPool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An API for sending and handling Slack messages.
|
||||||
|
*/
|
||||||
|
public class SlackAPI
|
||||||
|
{
|
||||||
|
// Default emoji.
|
||||||
|
public static final String DEFAULT_ICON = ":mineplex:";
|
||||||
|
|
||||||
|
// Singular instance.
|
||||||
|
private static SlackAPI _instance;
|
||||||
|
|
||||||
|
// Don't allow instantiation elsewhere.
|
||||||
|
private SlackAPI() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message asynchronously to a Slack channel.
|
||||||
|
*
|
||||||
|
* @param team The team which contains the target channel.
|
||||||
|
* @param channel The target channel for the message.
|
||||||
|
* @param message The message to be displayed.
|
||||||
|
* @param customTitle Whether or not to use a custom title for the message.
|
||||||
|
* If <code>false</code> the default team title is used.
|
||||||
|
*/
|
||||||
|
public void sendMessage(SlackTeam team, String channel, SlackMessage message, boolean customTitle)
|
||||||
|
{
|
||||||
|
ThreadPool.ASYNC.execute(() ->
|
||||||
|
{
|
||||||
|
// Set message title.
|
||||||
|
if (!customTitle)
|
||||||
|
{
|
||||||
|
message.setUsername(team.getTitle());
|
||||||
|
message.setIcon(DEFAULT_ICON);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set message channel.
|
||||||
|
JsonObject msg = message.toJson();
|
||||||
|
msg.addProperty("channel", channel);
|
||||||
|
|
||||||
|
// Run the call.
|
||||||
|
runWebCall(team, msg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a web call to a specified Slack incoming-hook.
|
||||||
|
*
|
||||||
|
* @param team The team to run the call on.
|
||||||
|
* @param call The call to be run.
|
||||||
|
*/
|
||||||
|
private String runWebCall(SlackTeam team, JsonObject call)
|
||||||
|
{
|
||||||
|
HttpURLConnection connection = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Create connection.
|
||||||
|
URL url = new URL(team.getURL());
|
||||||
|
connection = (HttpURLConnection) url.openConnection();
|
||||||
|
connection.setRequestMethod("POST");
|
||||||
|
connection.setConnectTimeout(5000);
|
||||||
|
connection.setUseCaches(false);
|
||||||
|
connection.setDoInput(true);
|
||||||
|
connection.setDoOutput(true);
|
||||||
|
|
||||||
|
// Setup payload.
|
||||||
|
String payload = "payload=" + URLEncoder.encode(call.toString(), "UTF-8");
|
||||||
|
|
||||||
|
// Send request.
|
||||||
|
DataOutputStream dos = new DataOutputStream(connection.getOutputStream());
|
||||||
|
dos.writeBytes(payload);
|
||||||
|
dos.flush();
|
||||||
|
dos.close();
|
||||||
|
|
||||||
|
// Receive response.
|
||||||
|
InputStream is = connection.getInputStream();
|
||||||
|
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
|
||||||
|
String line;
|
||||||
|
String response = "";
|
||||||
|
while ((line = rd.readLine()) != null)
|
||||||
|
{
|
||||||
|
response += line + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
rd.close();
|
||||||
|
return response.toString();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (connection != null)
|
||||||
|
{
|
||||||
|
// Terminate connection.
|
||||||
|
connection.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "500 Error";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the singular instance of the Slack API.
|
||||||
|
*
|
||||||
|
* @return The {@link SlackAPI} instance.
|
||||||
|
*/
|
||||||
|
public static SlackAPI getInstance()
|
||||||
|
{
|
||||||
|
if (_instance == null)
|
||||||
|
{
|
||||||
|
_instance = new SlackAPI();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
139
Plugins/Mineplex.Core/src/mineplex/core/slack/SlackMessage.java
Normal file
139
Plugins/Mineplex.Core/src/mineplex/core/slack/SlackMessage.java
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
package mineplex.core.slack;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A message to be sent through the {@link SlackAPI}.
|
||||||
|
*/
|
||||||
|
public class SlackMessage
|
||||||
|
{
|
||||||
|
private String _username;
|
||||||
|
private String _icon;
|
||||||
|
|
||||||
|
private String _content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param content The content of the message.
|
||||||
|
*/
|
||||||
|
public SlackMessage(String content)
|
||||||
|
{
|
||||||
|
_icon = SlackAPI.DEFAULT_ICON;
|
||||||
|
_content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param username The username of the message.
|
||||||
|
* @param content The content of the message.
|
||||||
|
*/
|
||||||
|
public SlackMessage(String username, String content)
|
||||||
|
{
|
||||||
|
_username = username;
|
||||||
|
_icon = SlackAPI.DEFAULT_ICON;
|
||||||
|
_content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param username The username of the message.
|
||||||
|
* @param icon The icon/emoji of the message.
|
||||||
|
* @param content The content of the message.
|
||||||
|
*/
|
||||||
|
public SlackMessage(String username, String icon, String content)
|
||||||
|
{
|
||||||
|
_username = username;
|
||||||
|
_icon = ":" + icon + ":";
|
||||||
|
_content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the message to JSON format.
|
||||||
|
*
|
||||||
|
* @return The {@link SlackMessage} in the form of a {@link JsonObject}.
|
||||||
|
*/
|
||||||
|
public JsonObject toJson()
|
||||||
|
{
|
||||||
|
JsonObject msg = new JsonObject();
|
||||||
|
|
||||||
|
if (_username != null)
|
||||||
|
{
|
||||||
|
msg.addProperty("username", _username);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_icon != null)
|
||||||
|
{
|
||||||
|
msg.addProperty("icon_emoji", _icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_content != null)
|
||||||
|
{
|
||||||
|
msg.addProperty("text", _content);
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the username that displays as a title.
|
||||||
|
*
|
||||||
|
* @return The username in use.
|
||||||
|
*/
|
||||||
|
public String getUsername()
|
||||||
|
{
|
||||||
|
return _username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the username that displays as a title.
|
||||||
|
*
|
||||||
|
* @param username The username to use.
|
||||||
|
*/
|
||||||
|
public void setUsername(String username)
|
||||||
|
{
|
||||||
|
_username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the icon that displays with the title.
|
||||||
|
*
|
||||||
|
* @return The icon in use.
|
||||||
|
*/
|
||||||
|
public String getIcon()
|
||||||
|
{
|
||||||
|
return _icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the icon that displays with the title.
|
||||||
|
*
|
||||||
|
* @param icon The icon to use.
|
||||||
|
*/
|
||||||
|
public void setIcon(String icon)
|
||||||
|
{
|
||||||
|
_icon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the content of the message.
|
||||||
|
*
|
||||||
|
* @return The content of the message.
|
||||||
|
*/
|
||||||
|
public String getContent()
|
||||||
|
{
|
||||||
|
return _content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the content of the message.
|
||||||
|
*
|
||||||
|
* @param content The content of the message.
|
||||||
|
*/
|
||||||
|
public void setContent(String content)
|
||||||
|
{
|
||||||
|
_content = content;
|
||||||
|
}
|
||||||
|
}
|
79
Plugins/Mineplex.Core/src/mineplex/core/slack/SlackTeam.java
Normal file
79
Plugins/Mineplex.Core/src/mineplex/core/slack/SlackTeam.java
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package mineplex.core.slack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An enumeration of Mineplex Slack teams.
|
||||||
|
*/
|
||||||
|
public enum SlackTeam
|
||||||
|
{
|
||||||
|
// Dev team - mineplex.slack.com
|
||||||
|
DEVELOPER("Mineplex Dev", "T045RUM7F", "B0VK6GFKN", "6GxwJsDfEpbVnQl8pYuEyq5T"),
|
||||||
|
|
||||||
|
// QA team - mineplexqa.slack.com
|
||||||
|
QA("Mineplex QA", "todo", "todo", "todo"), // TODO: new details
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
private String _title;
|
||||||
|
private String _id1;
|
||||||
|
private String _id2;
|
||||||
|
private String _token;
|
||||||
|
|
||||||
|
SlackTeam(String title, String id1, String id2, String token)
|
||||||
|
{
|
||||||
|
_title = title;
|
||||||
|
_id1 = id1;
|
||||||
|
_id2 = id2;
|
||||||
|
_token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title that will be displayed that the top of each
|
||||||
|
* {@link SlackMessage}.
|
||||||
|
*
|
||||||
|
* @return The title of this team.
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return _title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the first ID of this Slack team.
|
||||||
|
*
|
||||||
|
* @return The individual first ID.
|
||||||
|
*/
|
||||||
|
public String getId1()
|
||||||
|
{
|
||||||
|
return _id1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the second ID of this Slack team.
|
||||||
|
*
|
||||||
|
* @return The individual second ID.
|
||||||
|
*/
|
||||||
|
public String getId2()
|
||||||
|
{
|
||||||
|
return _id2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the token key of this Slack team.
|
||||||
|
*
|
||||||
|
* @return The individual and <b>secret</b> token.
|
||||||
|
*/
|
||||||
|
public String getToken()
|
||||||
|
{
|
||||||
|
return _token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the web hook in the form of a URL.
|
||||||
|
*
|
||||||
|
* @return The URL as a string.
|
||||||
|
*/
|
||||||
|
public String getURL()
|
||||||
|
{
|
||||||
|
return "https://hooks.slack.com/services/" + getId1() + "/" + getId2() + "/" + getToken();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package mineplex.core.thread;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A collection of threads for different uses.
|
||||||
|
*/
|
||||||
|
public class ThreadPool
|
||||||
|
{
|
||||||
|
|
||||||
|
// Async Thread
|
||||||
|
public static ExecutorService ASYNC = Executors.newCachedThreadPool(
|
||||||
|
new ThreadFactoryBuilder().setNameFormat("MiniPlugin Async %1$d").build()
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user