All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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