Commit ea26e098 authored by Krzysztof Misztal's avatar Krzysztof Misztal Committed by daryl herzmann

Improved CallbackOnOffline plugin (#981)

* Sending message body inside of callback

* Updated version and readme.html

* Updated changelog

* Sending POST request. Better logs. sendBody property.

* Updated readme and changelog. v1.2

* Fixed small bug
parent 3f0091c6
......@@ -44,6 +44,21 @@
Callback on offline Plugin Changelog
</h1>
<p><b>1.2</b> -- December 15, 2017</p>
<ul>
<li>Sending POST request instead of GET</li>
<li>Parameters are send as JSON body instead of query params.</li>
<li>Added "plugin.callback_on_offline.send_body" to enable/disable sending message body. True by default.</li>
<li>Slightly improved logging.</li>
</ul>
<p><b>1.1</b> -- December 14, 2017</p>
<ul>
<li>Added message body to the request. </li>
</ul>
<p><b>1.0</b> -- August 16, 2015</p>
<ul>
......
......@@ -5,9 +5,9 @@
<name>CallbackOnOffline</name>
<description>Url is called when recipient is offline</description>
<author>Pavel Goski</author>
<version>1.0</version>
<date>08/16/2015</date>
<author>Pavel Goski / Krzysztof Misztal</author>
<version>1.2</version>
<date>12/15/2017</date>
<minServerVersion>2.3.0</minServerVersion>
</plugin>
......@@ -8,7 +8,7 @@
</parent>
<groupId>org.igniterealtime.openfire.plugins</groupId>
<artifactId>callbackOnOffline</artifactId>
<version>1.0</version>
<version>1.2</version>
<name>Callback on Offline Plugin</name>
<description>Url is called when recipient is offline</description>
......@@ -16,6 +16,9 @@
<developer>
<name>Pavel Goski</name>
</developer>
<developer>
<name>Krzysztof Misztal</name>
</developer>
</developers>
<build>
......@@ -33,5 +36,12 @@
<artifactId>jersey-client</artifactId>
<version>2.21</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<scope>runtime</scope>
<version>2.26</version>
</dependency>
</dependencies>
</project>
......@@ -46,6 +46,8 @@
#datatable .name {
background-color : #DCE2F5;
}
</style>
</head>
<body>
......@@ -57,13 +59,35 @@
<h2>Overview</h2>
<p>
The plugin loads url from 'plugin.callback_on_offline.url' property, adds 'to' & 'from' parameters and executes GET request. The request is async.
Sample link: http://localhost:8080/user/offline/callback/url?from=1%40fotsum.com&to=2%40fotsum.com
Plugin intercepts messages and checks if recipient is available. If not, plugin sends async POST request with JSON
body to defined url.
</p>
<p>
If something don't work, set "plugin.callback_on_offline.debug" property to true and check the debug log.
Example JSON body:
<pre>
<code>
{
"token":"21uh9d1h91d",
"from":"user@mychatapp.com",
"to":"user123@mychatapp.com",
"body":"Message body, so what user's typed"
}
</code>
</pre>
</p>
<h2>
Callback properties
</h2>
There are few properties that can be defined to change plugin behaviour:
<ul>
<li><code>plugin.callback_on_offline.debug</code> - enable debug logs. If something doesn't work set property to true</li>
<li><code>plugin.callback_on_offline.url</code> - url that will be called</li>
<li><code>plugin.callback_on_offline.token</code> - token to be send with request</li>
<li><code>plugin.callback_on_offline.send_body</code> - boolean value to determine if message's body will be send. True by default.</li>
</ul>
</body>
</html>
......@@ -20,6 +20,7 @@ import org.xmpp.packet.Packet;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import java.io.File;
......@@ -30,7 +31,14 @@ public class CallbackOnOffline implements Plugin, PacketInterceptor {
private static final Logger Log = LoggerFactory.getLogger(CallbackOnOffline.class);
private static final String PROPERTY_DEBUG = "plugin.callback_on_offline.debug";
private static final String PROPERTY_URL = "plugin.callback_on_offline.url";
private static final String PROPERTY_TOKEN = "plugin.callback_on_offline.token";
private static final String PROPERTY_SEND_BODY = "plugin.callback_on_offline.send_body";
private boolean debug;
private boolean sendBody;
private String url;
private String token;
private InterceptorManager interceptorManager;
......@@ -39,9 +47,15 @@ public class CallbackOnOffline implements Plugin, PacketInterceptor {
private Client client;
public void initializePlugin(PluginManager pManager, File pluginDirectory) {
debug = JiveGlobals.getBooleanProperty("plugin.callback_on_offline.debug", false);
debug = JiveGlobals.getBooleanProperty(PROPERTY_DEBUG, false);
sendBody = JiveGlobals.getBooleanProperty(PROPERTY_SEND_BODY, true);
url = getProperty(PROPERTY_URL, "http://localhost:8080/user/offline/callback/url");
token = getProperty(PROPERTY_TOKEN, UUID.randomUUID().toString());
if (debug) {
Log.debug("initialize CallbackOnOffline plugin. Start.");
Log.debug("Loaded properties: \nurl={}, \ntoken={}, \nsendBody={}", new Object[]{url, token, sendBody});
}
interceptorManager = InterceptorManager.getInstance();
......@@ -49,9 +63,6 @@ public class CallbackOnOffline implements Plugin, PacketInterceptor {
userManager = XMPPServer.getInstance().getUserManager();
client = ClientBuilder.newClient();
url = getProperty("plugin.callback_on_offline.url", "http://localhost:8080/user/offline/callback/url");
token = getProperty("plugin.callback_on_offline.token", UUID.randomUUID().toString());
// register with interceptor manager
interceptorManager.addInterceptor(this);
......@@ -87,33 +98,37 @@ public class CallbackOnOffline implements Plugin, PacketInterceptor {
&& packet.getTo() != null) {
Message msg = (Message) packet;
JID to = packet.getTo();
if (msg.getType() != Message.Type.chat) {
return;
}
try {
JID to = packet.getTo();
User userTo = userManager.getUser(to.getNode());
boolean available = presenceManager.isAvailable(userTo);
if (debug) {
Log.debug("intercepted message from {} to {}, recipient is available {}", new Object[] { packet.getFrom().toBareJID(), to.toBareJID(), available });
Log.debug("intercepted message from {} to {}, recipient is available {}", new Object[]{packet.getFrom().toBareJID(), to.toBareJID(), available});
}
if (!available) {
JID from = packet.getFrom();
String body = sendBody ? msg.getBody() : null;
WebTarget target = client.target(url)
.queryParam("token", token)
.queryParam("from", from.toBareJID())
.queryParam("to", to.toBareJID());
WebTarget target = client.target(url);
if (debug) {
Log.debug("sending request to url='{}'", target);
}
Future<Response> responseFuture = target.request().async().get();
MessageData data = new MessageData(token, from.toBareJID(), to.toBareJID(), body);
Future<Response> responseFuture = target
.request()
.async()
.post(Entity.json(data));
if (debug) {
try {
Response response = responseFuture.get();
......@@ -124,6 +139,9 @@ public class CallbackOnOffline implements Plugin, PacketInterceptor {
}
}
} catch (UserNotFoundException e) {
if (debug) {
Log.debug("can't find user with name: " + to.getNode());
}
}
}
}
......
package com.fotsum;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public final class MessageData {
private String token;
private String from;
private String to;
private String body;
MessageData(String token, String from, String to, String body) {
this.token = token;
this.from = from;
this.to = to;
this.body = body;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MessageData that = (MessageData) o;
if (!token.equals(that.token)) return false;
if (!from.equals(that.from)) return false;
if (!to.equals(that.to)) return false;
return body.equals(that.body);
}
@Override
public int hashCode() {
int result = token.hashCode();
result = 31 * result + from.hashCode();
result = 31 * result + to.hashCode();
result = 31 * result + body.hashCode();
return result;
}
@Override
public String toString() {
return "MessageData{" +
"token='" + token + '\'' +
", from='" + from + '\'' +
", to='" + to + '\'' +
", body='" + body + '\'' +
'}';
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment