
fr.wseduc.webutils.email.SendInBlueSender Maven / Gradle / Ivy
/*
* Copyright © WebServices pour l'Éducation, 2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fr.wseduc.webutils.email;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import fr.wseduc.webutils.eventbus.ResultMessage;
import fr.wseduc.webutils.exception.InvalidConfigurationException;
import fr.wseduc.webutils.Either;
import static fr.wseduc.webutils.Utils.isNotEmpty;
import org.vertx.java.core.Handler;
import org.vertx.java.core.Vertx;
import org.vertx.java.core.buffer.Buffer;
import org.vertx.java.core.eventbus.Message;
import org.vertx.java.core.http.HttpClient;
import org.vertx.java.core.http.HttpClientRequest;
import org.vertx.java.core.http.HttpClientResponse;
import org.vertx.java.core.json.DecodeException;
import org.vertx.java.core.json.JsonArray;
import org.vertx.java.core.json.JsonObject;
import org.vertx.java.core.logging.Logger;
import org.vertx.java.core.logging.impl.LoggerFactory;
import org.vertx.java.platform.Container;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public class SendInBlueSender extends NotificationHelper implements EmailSender {
private static final Logger log = LoggerFactory.getLogger(SendInBlueSender.class);
private final HttpClient httpClient;
private final String apiKey;
private final String dedicatedIp;
private final boolean splitRecipients;
private final ObjectMapper mapper;
private static final String DATE_FORMAT = "yyyy-MM-dd";
public SendInBlueSender(Vertx vertx, Container container, JsonObject config)
throws InvalidConfigurationException, URISyntaxException {
super(vertx, container);
if (config != null && isNotEmpty(config.getString("uri")) && isNotEmpty(config.getString("api-key"))) {
URI uri = new URI(config.getString("uri"));
httpClient = vertx.createHttpClient()
.setHost(uri.getHost())
.setPort(uri.getPort())
.setMaxPoolSize(16)
.setSSL("https".equals(uri.getScheme()))
.setKeepAlive(false);
apiKey = config.getString("api-key");
dedicatedIp = config.getString("ip");
splitRecipients = config.getBoolean("split-recipients", false);
mapper = new ObjectMapper();
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
} else {
throw new InvalidConfigurationException("missing.parameters");
}
}
@Override
public void hardBounces(Date date, Handler>> handler) {
hardBounces(date, null, handler);
}
@Override
public void hardBounces(Date startDate, Date endDate, final Handler>> handler) {
if (startDate == null) {
handler.handle(new Either.Left>("invalid.date"));
return;
}
final DateFormat df = new SimpleDateFormat(DATE_FORMAT);
final JsonObject payload = new JsonObject().putString("event", "hard_bounce");
final String start = df.format(startDate);
if (endDate != null) {
payload.putString("start_date", start).putString("end_date", df.format(endDate));
} else {
payload.putString("date", start);
}
HttpClientRequest req = httpClient.post("/v2.0/report", new Handler() {
@Override
public void handle(final HttpClientResponse resp) {
resp.bodyHandler(new Handler() {
@Override
public void handle(Buffer buffer) {
try {
JsonObject res = new JsonObject(buffer.toString());
if ("success".equals(res.getString("code"))) {
JsonArray l = res.getArray("data");
if (l == null || l.size() == 0) {
handler.handle(new Either.Right>(
Collections.emptyList()));
return;
}
List bounces = mapper.readValue(l.encode(),
new TypeReference>(){});
handler.handle(new Either.Right>(bounces));
} else {
handler.handle(new Either.Left>(
res.getValue("message").toString()));
}
} catch (RuntimeException | IOException e) {
handler.handle(new Either.Left>(e.getMessage()));
log.error(e.getMessage(), e);
}
}
});
}
});
req.putHeader("api-key", apiKey);
req.end(payload.encode());
}
@Override
protected void sendEmail(JsonObject json, final Handler> handler) {
if (json == null || json.getArray("to") == null || json.getString("from") == null ||
json.getString("subject") == null || json.getString("body") == null) {
handler.handle(new ResultMessage().error("invalid.parameters"));
return;
}
if (splitRecipients && json.getArray("to").size() > 1) {
final AtomicInteger count = new AtomicInteger(json.getArray("to").size());
final AtomicBoolean success = new AtomicBoolean(true);
final JsonArray errors = new JsonArray();
final Handler> h = new Handler>() {
@Override
public void handle(Message message) {
if (!"ok".equals(message.body().getString("status"))) {
success.set(false);
errors.addString(message.body().getString("message"));
}
if (count.decrementAndGet() == 0) {
if (success.get()) {
handler.handle(new ResultMessage());
} else {
handler.handle(new ResultMessage().error(errors.encode()));
}
}
}
};
for (Object to: json.getArray("to")) {
send(json.copy().putArray("to", new JsonArray().addString(to.toString())), h);
}
} else {
send(json, handler);
}
}
private void send(JsonObject json, final Handler> handler) {
HttpClientRequest req = httpClient.post("/v2.0/email", new Handler() {
@Override
public void handle(HttpClientResponse resp) {
if (resp.statusCode() == 200) {
handler.handle(new ResultMessage());
} else {
resp.bodyHandler(new Handler() {
@Override
public void handle(Buffer buffer) {
try {
JsonObject err = new JsonObject(buffer.toString());
handler.handle(new ResultMessage().error(err.getString("message")));
} catch (DecodeException e) {
handler.handle(new ResultMessage().error(buffer.toString()));
}
}
});
}
}
});
req.putHeader("api-key", apiKey);
JsonObject to = new JsonObject();
for (Object o: json.getArray("to")) {
to.putString(o.toString(), "");
}
JsonObject payload = new JsonObject()
.putObject("to", to)
.putArray("from", new JsonArray().add(json.getString("from")))
.putString("subject", json.getString("subject"))
.putString("html", json.getString("body"));
JsonObject headers = new JsonObject();
if (isNotEmpty(dedicatedIp)) {
headers.putString("X-Mailin-IP", dedicatedIp);
}
if (json.getArray("headers") != null) {
for (Object o: json.getArray("headers")) {
if (!(o instanceof JsonObject)) continue;
JsonObject h = (JsonObject) o;
headers.putString(h.getString("name"), h.getString("value"));
}
}
if (headers.size() > 0) {
payload.putObject("headers", headers);
}
if (json.getArray("cc") != null && json.getArray("cc").size() > 0) {
JsonObject cc = new JsonObject();
for (Object o: json.getArray("cc")) {
cc.putString(o.toString(), "");
}
payload.putObject("cc", cc);
}
if (json.getArray("bcc") != null && json.getArray("bcc").size() > 0) {
JsonObject bcc = new JsonObject();
for (Object o: json.getArray("bcc")) {
bcc.putString(o.toString(), "");
}
payload.putObject("bcc", bcc);
}
req.end(payload.encode());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy