Java Quarkus
Integración servicio de correos Sendgrid
Este tutorial requiere una cuenta activa en el servicio de envio de correos electrónicos Sendgrid. La configuración básica de este servicio implica asociar un correo electrónico válido en el apartado 'Sender Authentication -> Single Sender Verification' y generar una 'API Key' para la implementación.
Utilizaremos el siguiente comando Maven para generar el aplicativo java:
mvn io.quarkus.platform:quarkus-maven-plugin:2.2.3.Final:create \
-DprojectGroupId=dev.failapp \
-DprojectArtifactId=mail-lab \
-DclassName="dev.failapp.lab.resource.EmailRest" \
-Dpath="/api/v1/email"
En el archivo 'pom.xml' se definen las dependencias de servicio sendgrid, servicios REST Json, ORM Panache y driver de base de datos de prueba (H2):
..
...
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
</dependency>
<dependency>
<groupId>com.sendgrid</groupId>
<artifactId>sendgrid-java</artifactId>
<version>4.7.4</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-panache</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
..
...
En el archivo 'application.properties' se configuran los parámetros básicos del ORM y la base de datos H2, junto al 'API Key' y correo asociado a servicio Sendgrid:
..
...
quarkus.datasource.db-kind=h2
quarkus.datasource.jdbc.url=jdbc:h2:file:~/mail;AUTO_SERVER=true;DB_CLOSE_DELAY=-1
quarkus.hibernate-orm.dialect=org.hibernate.dialect.H2Dialect
quarkus.hibernate-orm.database.generation=update
config.mail.service.api.key=AQUI_TU_API_KEY_SENDGRID
config.mail.service.from=contacto@failapp.dev
...
Creamos una clase para obtener los parámetros de configuración de nuestra aplicación, anotandola con 'ApplicationScoped' para poder injectarla a la capa de servicios:
@ApplicationScoped
public class EmailConfig {
@ConfigProperty(name = "config.mail.service.api.key", defaultValue = "")
private String mailApiKey;
@ConfigProperty(name = "config.mail.service.from")
private String mailFrom;
@Produces
public SendGrid sendGrid() {
return new SendGrid(mailApiKey);
}
public String getMailFrom() {
return mailFrom;
}
}
Agregamos una clase entidad sencilla y una clase 'repositorio' para temas de persistencia:
@Entity
public class EmailRequest {
@Id
@GeneratedValue
private Long id;
private String to;
private String subject;
private String body;
private String timestamp;
public EmailRequest() {
}
public EmailRequest(String to, String subject, String body) {
this.to = to;
this.subject = subject;
this.body = body;
}
// getters ..
// setters ..
}
@ApplicationScoped
public class EmailRepository implements PanacheRepository<EmailRequest> {
public Optional<EmailRequest> findByTo(String to) {
return find("to", to).firstResultOptional();
}
}
La clase encargada de implementar el servicio de correo tiene el siguiente aspecto:
@ApplicationScoped
public class EmailService {
private static final Logger log = Logger.getLogger(EmailService.class);
@Inject
private EmailRepository emailRepository;
@Inject
private SendGrid sendGrid;
@Inject
private EmailConfig emailConfig;
@Transactional
public boolean sendEmail(EmailRequest emailRequest) {
if (Optional.ofNullable(emailRequest).isEmpty())
return false;
try {
Email from = new Email(emailConfig.getMailFrom());
Email to = new Email(emailRequest.getTo());
String subject = emailRequest.getSubject();
Content content = new Content("text/plain", emailRequest.getBody());
Mail mail = new Mail(from, subject, to, content);
Request request = new Request();
request.setMethod(Method.POST);
request.setEndpoint("mail/send");
request.setBody(mail.build());
Response response = sendGrid.api(request);
log.infof("[x] response status code: %s", response.getStatusCode());
log.infof("[x] response body: %s", response.getBody());
log.infof("[x] response headers: %s", response.getHeaders());
if (response.getStatusCode() == 202) {
emailRequest.setTimestamp(LocalDateTime.now().format(Util.formatDateTime));
emailRepository.persist(emailRequest);
return true;
}
} catch (Exception ex) {
log.infof("[x] error: %s", ex.getMessage());
}
return false;
}
}
Por último, la clase que recibe el mensaje a través de metodo http post (/api/v1/email) e implementa el servicio:
@Path("/")
public class EmailRest {
@Inject
private EmailService emailService;
@POST
@Path("/api/v1/email")
public Response sendEmail(EmailRequest emailRequest) {
boolean success = emailService.sendEmail(emailRequest);
if (success) {
Map<String, Object> map = new HashMap<>();
map.put("mail to", emailRequest.getTo());
map.put("status", "send");
return Response.ok(map).build();
} else {
return Response.status(404).build();
}
}
}
Prueba rápida con curl en la consola:
curl -i -H "Content-Type: application/json" -X POST \
-d '{"to":"jrodriguez@failapp.dev","subject":"mail test", "body": "mensaje test.."}' \
http://localhost:8080/api/v1/email
Puedes descargar el código fuente completo de este ejemplo en el siguiente enlace.
¿Tienes alguna consulta?
Puedes contactarme enviándome un mensaje desde aquí.

diciembre 16, 2022 Backend

septiembre 19, 2022 Redes/Networking, Embedded Systems

julio 20, 2022 Cloud
- Backend(4)
- Redes/Networking(4)
- Embedded Systems(2)
- Cloud(2)
- Frontend(3)
- Microservicios(4)