-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4a41363
commit bfbc9e4
Showing
11 changed files
with
324 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
# out-of-office-alert-zimlet | ||
This Classic UI Zimlets displays an alert as soon as you enter an email address in to/cc/bcc of someone with an active out of office reply. | ||
# Out Of Office Alert Zimlet | ||
|
||
This Classic UI Zimlets displays an alert as soon as you enter an email address in to/cc/bcc of someone with an active out of office reply. Avoid putting time in writing an email just to be greeted with an out-of-office message after sending an email. | ||
|
||
![](screenshots/out-of-office-alert.png) | ||
|
80 changes: 80 additions & 0 deletions
80
com_zimbra_outofoffice_alert/com_zimbra_outofoffice_alert.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
function com_zimbra_outofoffice_alert_HandlerObject() { | ||
com_zimbra_outofoffice_alert_HandlerObject.settings = {}; | ||
}; | ||
|
||
com_zimbra_outofoffice_alert_HandlerObject.prototype = new ZmZimletBase(); | ||
com_zimbra_outofoffice_alert_HandlerObject.prototype.constructor = com_zimbra_outofoffice_alert_HandlerObject; | ||
var outOfOfficeAlertZimlet = com_zimbra_outofoffice_alert_HandlerObject; | ||
|
||
outOfOfficeAlertZimlet.prototype.init = function () { | ||
AjxDispatcher.require(["MailCore"]); | ||
try { | ||
ZmRecipients.prototype._bubblesChangedCallback = | ||
function() { | ||
if (this._resetContainerSize) { | ||
this._resetContainerSize(); // body size might change due to change in size of address field (due to new bubbles). | ||
} | ||
outOfOfficeAlertZimlet.prototype.bubblesChanged(this); | ||
}; | ||
} catch (e) {console.log(e);} | ||
}; | ||
|
||
/* status method show a Zimbra status message | ||
* */ | ||
outOfOfficeAlertZimlet.prototype.status = function(text, type) { | ||
var transitions = [ ZmToast.FADE_IN, ZmToast.PAUSE, ZmToast.FADE_OUT ]; | ||
appCtxt.getAppController().setStatusMsg(text, type, null, transitions); | ||
}; | ||
|
||
outOfOfficeAlertZimlet.prototype.bubblesChanged = function(ZmRecipients) { | ||
var zimletInstance = appCtxt._zimletMgr.getZimletByName('com_zimbra_outofoffice_alert').handlerObject; | ||
var rawAddresses = ZmRecipients.getRawAddrFields(); | ||
var allAddresses = rawAddresses.TO + " " + rawAddresses.CC; | ||
if(rawAddresses.BCC) | ||
{ | ||
allAddresses = allAddresses + " " + rawAddresses.BCC; | ||
} | ||
allAddresses = allAddresses.replaceAll('<', ' '); | ||
var regex = /\S+[a-z0-9]@[a-z0-9\.]+/img; | ||
var recipients = allAddresses.match(regex); | ||
|
||
var requestData = {} | ||
requestData.accounts = recipients; | ||
var request = new XMLHttpRequest(); | ||
var url = '/service/extension/outofofficebanner'; | ||
var formData = new FormData(); | ||
formData.append("jsondata", JSON.stringify(requestData)); | ||
request.open('POST', url); | ||
request.onreadystatechange = function (e) { | ||
if (request.readyState == 4) { | ||
if (request.status == 200) { | ||
var response = JSON.parse(request.responseText); | ||
var hasOoo = false; | ||
var recipientsWithOoo = ""; | ||
for (var key in response) { | ||
if (response.hasOwnProperty(key)) { | ||
if(response[key] == true) | ||
{ | ||
hasOoo = true; | ||
recipientsWithOoo = recipientsWithOoo + key; | ||
} | ||
} | ||
} | ||
if(hasOoo) | ||
{ | ||
var zimletInstance = appCtxt._zimletMgr.getZimletByName('com_zimbra_outofoffice_alert').handlerObject; | ||
zimletInstance.status(zimletInstance.getMessage('outOfOfficeAlertZimlet_message') + " " + recipientsWithOoo); | ||
} | ||
} | ||
} | ||
} | ||
request.send(formData); | ||
}; | ||
|
||
/* status method show a Zimbra status message | ||
* */ | ||
outOfOfficeAlertZimlet.prototype.status = function(text, type) { | ||
var transitions = [ ZmToast.FADE_IN, ZmToast.PAUSE, ZmToast.PAUSE, ZmToast.PAUSE, ZmToast.FADE_OUT ]; | ||
appCtxt.getAppController().setStatusMsg(text, type, null, transitions); | ||
}; | ||
|
3 changes: 3 additions & 0 deletions
3
com_zimbra_outofoffice_alert/com_zimbra_outofoffice_alert.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Unicode conversion see: http://itpro.cz/juniconv/ | ||
|
||
outOfOfficeAlertZimlet_message = The following recipient(s) are out of office: |
4 changes: 4 additions & 0 deletions
4
com_zimbra_outofoffice_alert/com_zimbra_outofoffice_alert.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<zimlet name="com_zimbra_outofoffice_alert" version="0.0.1" description="Display an alert when composing an email when someone in the To field has an active out of office reply." target="main view-window"> | ||
<include>com_zimbra_outofoffice_alert.js</include> | ||
<handlerObject>com_zimbra_outofoffice_alert_HandlerObject</handlerObject> | ||
</zimlet> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
build | ||
lib | ||
outofofficebanner.jar | ||
.idea | ||
*.iml | ||
openjdk* | ||
java* | ||
out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Manifest-Version: 1.0 | ||
Zimbra-Extension-Class: com.zimbra.outofofficebanner.OutOfOfficeBannerExtension | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<project name="outofofficebanner" default="jar" basedir="."> | ||
<description> | ||
Build file for the Zimbra Extension. | ||
</description> | ||
|
||
<property name="lib" value="lib/"/> | ||
<property name="build" value="build/"/> | ||
<property name="src" value="src/"/> | ||
<property name="jar" value="outofofficebanner.jar"/> | ||
|
||
<path id="libraries"> | ||
<fileset dir="${lib}" > | ||
<include name="*.jar"/> | ||
</fileset> | ||
</path> | ||
|
||
<target name="clean"> | ||
<delete dir="${build}"/> | ||
<delete file="mytest.jar"/> | ||
<mkdir dir="${build}"/> | ||
</target> | ||
|
||
<target name="compile" | ||
depends="clean"> | ||
<javac srcdir="${src}" | ||
destdir="${build}" | ||
includeantruntime="false" | ||
debug="true" | ||
debuglevel="lines,vars,source" | ||
target="17" | ||
source="17"> | ||
<classpath> | ||
<path refid="libraries" /> | ||
</classpath> | ||
</javac> | ||
</target> | ||
|
||
<target name="jar" | ||
depends="compile"> | ||
<jar jarfile="${jar}" | ||
compress="false" | ||
basedir="${build}"> | ||
<manifest> | ||
<attribute name="Zimbra-Extension-Class" value="com.zimbra.outofofficebanner.OutOfOfficeBannerExtension" /> | ||
</manifest> | ||
<fileset dir="${build}" /> | ||
</jar> | ||
</target> | ||
|
||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
all: extension | ||
|
||
extension: | ||
ant jar | ||
|
||
clean: | ||
rm -f outofofficebanner.jar | ||
|
||
.PHONY: all extension |
123 changes: 123 additions & 0 deletions
123
extension/src/com/zimbra/outofofficebanner/OutOfOfficeBanner.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
package com.zimbra.outofofficebanner; | ||
|
||
import com.zimbra.cs.account.Account; | ||
import com.zimbra.cs.account.Provisioning; | ||
import com.zimbra.cs.extension.ExtensionHttpHandler; | ||
import com.zimbra.cs.account.AuthToken; | ||
import com.zimbra.cs.servlet.util.AuthUtil; | ||
|
||
import java.io.*; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.*; | ||
|
||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
|
||
import org.apache.commons.io.IOUtils; | ||
import org.json.JSONArray; | ||
import org.json.JSONObject; | ||
|
||
public class OutOfOfficeBanner extends ExtensionHttpHandler { | ||
|
||
/** | ||
* @return path | ||
*/ | ||
@Override | ||
public String getPath() { | ||
return "/outofofficebanner"; | ||
} | ||
|
||
/** | ||
* Processes HTTP GET requests. | ||
* | ||
* @param req request message | ||
* @param resp response message | ||
*/ | ||
@Override | ||
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { | ||
resp.getOutputStream().print("com.zimbra.outofofficebanner is installed."); | ||
} | ||
|
||
/** | ||
* Processes HTTP POST requests. | ||
* | ||
* @param req request message | ||
* @param resp response message | ||
*/ | ||
|
||
/* This extension works with aliasses as well. */ | ||
/* | ||
let testData = {} | ||
testData.accounts = ["[email protected]", "[email protected]"]; | ||
var request = new XMLHttpRequest(); | ||
var url = '/service/extension/outofofficebanner'; | ||
var formData = new FormData(); | ||
formData.append("jsondata", JSON.stringify(testData)); | ||
request.open('POST', url); | ||
request.onreadystatechange = function (e) { | ||
if (request.readyState == 4) { | ||
if (request.status == 200) { | ||
const Response = JSON.parse(request.responseText); | ||
console.log(Response); | ||
} | ||
if (request.status == 400) { | ||
const Response = JSON.parse(request.responseText); | ||
console.log(Response); | ||
} | ||
} | ||
} | ||
request.send(formData); | ||
* */ | ||
@Override | ||
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { | ||
//all authentication is done by AuthUtil.getAuthTokenFromHttpReq, returns null if unauthorized | ||
final AuthToken authToken = AuthUtil.getAuthTokenFromHttpReq(req, resp, false, true); | ||
if (authToken != null) { | ||
try { | ||
//Get the jsondata field from the multipart request send to the server and parse it to JSON Object. | ||
JSONObject receivedJSON = new JSONObject(IOUtils.toString(req.getPart("jsondata").getInputStream(), StandardCharsets.UTF_8)); | ||
JSONArray reqAccounts = receivedJSON.getJSONArray("accounts"); | ||
JSONObject responseJSON = new JSONObject(); | ||
|
||
//loop to get all json objects from data json array | ||
for (int i = 0; i < reqAccounts.length(); i++) { | ||
//use of toLowerCase to prevent people from using this endpoint to determine if accounts exist on server (privacy). | ||
String reqAccount = reqAccounts.get(i).toString(); | ||
|
||
boolean replyInEffect = false; | ||
try { | ||
Account account = Provisioning.getInstance().getAccountByName(reqAccount); | ||
boolean replyEnabled = account.isPrefOutOfOfficeReplyEnabled(); | ||
|
||
// Check if we are in any configured out of office interval | ||
Date now = new Date(); | ||
Date fromDate = account.getGeneralizedTimeAttr(Provisioning.A_zimbraPrefOutOfOfficeFromDate, null); | ||
Date untilDate = account.getGeneralizedTimeAttr(Provisioning.A_zimbraPrefOutOfOfficeUntilDate, null); | ||
|
||
if (replyEnabled && (fromDate != null && !now.before(fromDate))) { | ||
if (untilDate == null) { | ||
replyInEffect = true; | ||
} else if (untilDate != null && !now.after(untilDate)) { | ||
replyInEffect = true; | ||
} else { | ||
replyInEffect = false; | ||
} | ||
} | ||
responseJSON.put(reqAccount, replyInEffect); | ||
|
||
} catch (Exception e) { | ||
responseJSON.put(reqAccount, false); | ||
} | ||
|
||
} | ||
resp.setContentType("application/json"); | ||
resp.setCharacterEncoding("UTF-8"); | ||
resp.getOutputStream().print(responseJSON.toString()); | ||
|
||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
extension/src/com/zimbra/outofofficebanner/OutOfOfficeBannerExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.zimbra.outofofficebanner; | ||
|
||
import com.zimbra.common.service.ServiceException; | ||
import com.zimbra.cs.extension.ExtensionDispatcherServlet; | ||
import com.zimbra.cs.extension.ZimbraExtension; | ||
|
||
/** | ||
* This extension registers a custom HTTP handler with <code>ExtensionDispatcherServlet<code> | ||
* | ||
* @author vmahajan | ||
*/ | ||
public class OutOfOfficeBannerExtension implements ZimbraExtension { | ||
|
||
/** | ||
* Defines a name for the extension. It must be an identifier. | ||
* | ||
* @return extension name | ||
*/ | ||
public String getName() { | ||
return "OutOfOfficeBannerExtension"; | ||
} | ||
|
||
/** | ||
* Initializes the extension. Called when the extension is loaded. | ||
* | ||
* @throws com.zimbra.common.service.ServiceException | ||
*/ | ||
public void init() throws ServiceException { | ||
ExtensionDispatcherServlet.register(this, new OutOfOfficeBanner()); | ||
} | ||
|
||
/** | ||
* Terminates the extension. Called when the server is shut down. | ||
*/ | ||
public void destroy() { | ||
ExtensionDispatcherServlet.unregister(this); | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.