IA em Java: Crie um Agente Inteligente que Analisa E-mails de Suporte
Imagine a cena: segunda-feira, 9h da manhã. Você abre a caixa de e-mails do suporte e dá de cara com uma avalanche de mensagens. Qual delas esconde um bug crítico? Qual cliente importante aguarda uma resposta urgente?
Se você é da área de tecnologia, sabe que esta não é uma imagem isolada — é a realidade de muitas equipes.
E se pudéssemos enfrentar esse caos de forma mais inteligente? E se um “funcionário digital incansável”, construído com a robustez do Java e potencializado por IA, pudesse fazer a triagem por nós?
Este artigo apresenta exatamente isso: um agente que trabalha 24/7 para transformar o caos de uma caixa de entrada em uma fila de trabalho clara e priorizada.
Essa não é uma visão do futuro — é uma solução prática que construiremos juntos, agora. Neste guia completo, você aprenderá a desenvolver um agente de IA com Java que se conecta a uma caixa de e-mails, analisa o conteúdo de cada mensagem e automatiza a criação de tickets de suporte.
Ao final, você terá em mãos uma nova e poderosa peça para seu portfólio de desenvolvedor, capaz de injetar eficiência no seu dia a dia e no de sua equipe.
A Inteligência por Trás da Automação: Como a IA Entende a Linguagem Humana?
Para um computador, um texto é apenas uma sequência de caracteres sem valor intrínseco. Uma frase, um e-mail, este artigo — tudo é visto como uma cadeia de bytes sem significado ou contexto. Como, então, ensinamos uma máquina a ler e, mais importante, a entender?
A resposta está no campo do Processamento de Linguagem Natural (PLN), uma subárea da Inteligência Artificial dedicada a dar às máquinas a capacidade de compreender a linguagem humana. O objetivo do PLN, como definido por autoridades no assunto, é criar sistemas que processem, analisem e extraiam significado de textos de forma útil (JURAFSKY; MARTIN, 2023)
Para o nosso agente de suporte, duas técnicas de PLN são fundamentais.
A primeira é a Análise de Sentimento. Com ela, a IA vai além das palavras e avalia o "humor" do texto, classificando-o como positivo, negativo ou neutro. Um e-mail que diz "Estou extremamente frustrado com este erro" é imediatamente sinalizado como de alta prioridade emocional, mesmo antes de analisarmos o problema técnico em si.
A segunda é o Reconhecimento de Intenção. Aqui, a IA busca identificar o objetivo do usuário. Ele quer relatar um bug
? Fazer uma pergunta sobre faturamento
? Ou solicitar um novo recurso
? Distinguir a intenção é crucial para direcionar o e-mail para a equipe correta.
A verdadeira magia acontece quando nosso agente Java combina essas duas análises. Ele não apenas "lê" o e-mail; ele o diagnostica.
É assim que transformamos uma caixa de entrada caótica em uma fila de trabalho inteligente: não com truques, mas com a aplicação prática e direcionada do Processamento de Linguagem Natural.
A Arquitetura da Nossa Solução de IA com Java: Do E‑mail ao Ticket
Agora que entendemos como a IA pode interpretar a linguagem humana, vamos desenhar a solução prática que iremos construir. Antes de escrever uma única linha de código, uma boa engenharia começa com uma arquitetura clara. Isso garante que todos possam acompanhar o processo e entender como cada peça se conecta.
Esta seção é o mapa do nosso projeto: uma aplicação Java que recebe e-mails, os processa com Inteligência Artificial e, por fim, automatiza a criação de tickets de suporte priorizados.
Para transformar o caos em ordem, nosso agente seguirá um fluxo de trabalho lógico e sequencial:
- Passo 1: Conexão e Leitura. O agente se conecta ao servidor de e-mails via IMAP e coleta todas as mensagens não lidas.
- Passo 2: Extração de Dados. De cada e-mail, a aplicação Java extrai as informações essenciais — remetente, assunto e o corpo do texto — para análise pela IA.
- Passo 3: Análise com Inteligência Artificial. O conteúdo do e-mail é enviado para nosso modelo de PLN. A IA então retorna uma análise estruturada, detectando o sentimento (o "humor" do cliente) e a intenção (o objetivo do e-mail).
- Passo 4: Tomada de Decisão. Com a análise em mãos, a lógica de negócio do agente é acionada. Um e-mail com
Sentimento: NEGATIVO
eIntenção: BUG TÉCNICO
recebe prioridade máxima. UmaIntenção: DÚVIDA GERAL
entra em uma fila de menor urgência. - Passo 5: Ação Final. Com base na decisão, o agente cria automaticamente o ticket em nosso sistema de suporte (simulado), já classificado e priorizado, pronto para a ação da equipe humana.
Com esta arquitetura em mente, estamos prontos para começar a construir.
Preparando o Terreno: Configurando seu Projeto Java com Maven/Gradle
Com a arquitetura definida, é hora de "sujar as mãos" e começar a construir. O primeiro passo para transformar uma boa ideia em uma solução prática é montar um ambiente de desenvolvimento limpo e reprodutível. Nesta seção, vamos organizar toda a estrutura necessária para receber nosso agente inteligente, garantindo que cada linha de código futura esteja ancorada em uma base sólida.
🛠️ Pré-requisitos
Antes de começar, certifique-se de ter todas as ferramentas instaladas e configuradas:
- Java Development Kit (JDK 17 ou superior): A versão 17 (LTS) do JDK garante estabilidade e compatibilidade para o nosso projeto.
- Maven: Será nosso gerenciador de dependências e automação de build para organizar e empacotar o projeto.
- IDE de sua preferência: Use IntelliJ IDEA, Eclipse ou Visual Studio Code (com o Extension Pack for Java) para editar e executar o código.
- Chave de API de IA: Você precisará de uma chave de acesso para o modelo de linguagem escolhido (OpenAI, Gemini, etc.). Lembre-se de mantê-la em um local seguro.
📁 Estrutura do Projeto
Vamos adotar o padrão de diretórios do Maven, que promove uma organização clara entre código-fonte e recursos:
nosso-agente-ia/
├── pom.xml
└── src/
└── main/
├── java/
│ └── br/com/dio/agent/
└── resources/
src/main/java/
: Contém todas as classes Java do projeto.src/main/resources/
: Ideal para arquivos de configuração. É aqui que guardaremos um arquivo.properties
para carregar nossa chave de API de forma segura, sem expô-la diretamente no código.
⚙️ Adicionando as Dependências com Maven
O arquivo pom.xml
é o coração do projeto. Nele, declaramos todas as "ferramentas" externas que nosso agente usará.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>br.com.dio</groupId>
<artifactId>nosso-agente-ia</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.angus</groupId>
<artifactId>angus-mail</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.6</version>
</dependency>
</dependencies>
</project>
🔑 Por que essas dependências são essenciais?
- Angus Mail: É a implementação moderna do Jakarta Mail. Com ela, nosso agente poderá se conectar, autenticar e ler e-mails de um servidor de forma simples e segura.
- Jackson Databind: A resposta da IA virá no formato JSON. Jackson é a ferramenta padrão do ecossistema Java para transformar esse texto em objetos Java prontos para uso (desserialização), economizando tempo e evitando erros.
- OkHttp: Para conversar com a IA, precisamos fazer chamadas de rede (HTTP). O OkHttp é uma biblioteca limpa e robusta que simplifica o envio de requisições e o recebimento de respostas.
- Logback: Em vez de
System.out.println()
, usaremos um framework de logging profissional. Isso nos dará um controle muito maior sobre as mensagens que nosso agente exibe, facilitando o diagnóstico de problemas e o acompanhamento de sua execução.
Passo 1: O Ouvido do Agente — Lendo E‑mails com Java e Jakarta Mail
Com o esqueleto do projeto montado, é hora de dar ao nosso agente seu primeiro sentido: a audição. Nesta seção, vamos implementar o código que permitirá à nossa aplicação "ouvir" a caixa de entrada, capturando as mensagens que se tornarão o insumo para a análise da nossa IA.
🔐 Configurando o Acesso de Forma Segura
A regra número um da engenharia de software é nunca expor credenciais (senhas, chaves de API) diretamente no código. Para isso, vamos centralizá-las em um arquivo de propriedades, o application.properties
, que deve ser mantido fora do controle de versão (ex: no .gitignore
), evitando que vaze para repositórios como o GitHub.
Crie o arquivo em src/main/resources/application.properties
com o seguinte conteúdo:
# Configurações do Servidor de E-mail (Exemplo para Gmail)
mail.store.protocol=imaps
mail.imaps.host=imap.gmail.com
mail.imaps.port=993
mail.imaps.ssl.enable=true
# Credenciais do Usuário
mail.user=seu-email@gmail.com
mail.password=sua-senha-de-app
⚠️ Alerta de Segurança: Não utilize sua senha pessoal do e‑mail. A maioria dos provedores, como o Google, bloqueia tentativas de login de aplicações menos seguras. Em vez disso, crie uma "Senha de App" — uma credencial de 16 dígitos, descartável e segura, gerada especificamente para esta aplicação. para aprender a gerar a sua.
📧 Criando o Serviço de Leitura de E‑mails
Vamos centralizar toda a lógica de conexão e leitura em uma única classe de serviço. Isso torna nosso código mais organizado, testável e fácil de evoluir.
Crie a classe EmailReaderService.java
no pacote br.com.dio.agent
:
package br.com.dio.agent;
import jakarta.mail.*;
import jakarta.mail.internet.MimeMultipart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Properties;
public class EmailReaderService {
private static final Logger logger = LoggerFactory.getLogger(EmailReaderService.class);
public void readUnreadEmails() {
Properties props = loadProperties();
final String username = props.getProperty("mail.user");
final String password = props.getProperty("mail.password");
try (Store store = Session.getInstance(props).getStore()) {
store.connect(username, password);
logger.info("Conexão com o servidor de e-mail estabelecida com sucesso.");
try (Folder inbox = store.getFolder("INBOX")) {
inbox.open(Folder.READ_ONLY);
FlagTerm unreadFilter = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
Message[] messages = inbox.search(unreadFilter);
logger.info("Encontrados {} e-mails não lidos.", messages.length);
for (Message message : messages) {
logger.debug("---- Processando Novo E-mail ----");
logger.debug("De: {}", message.getFrom()[0]);
logger.debug("Assunto: {}", message.getSubject());
String content = getTextFromMessage(message);
logger.debug("Conteúdo extraído ({} caracteres).", content.length());
// Futuramente, aqui chamaremos o serviço de IA
}
}
} catch (MessagingException | IOException e) {
logger.error("Erro ao ler e-mails: {}", e.getMessage(), e);
}
}
private String getTextFromMessage(Message message) throws MessagingException, IOException {
if (message.isMimeType("text/plain")) {
return message.getContent().toString();
}
if (message.isMimeType("multipart/*")) {
MimeMultipart mimeMultipart = (MimeMultipart) message.getContent();
StringBuilder result = new StringBuilder();
for (int i = 0; i < mimeMultipart.getCount(); i++) {
BodyPart bodyPart = mimeMultipart.getBodyPart(i);
if (bodyPart.isMimeType("text/plain")) {
result.append(bodyPart.getContent().toString());
break; // Pega apenas a primeira parte de texto plano
}
}
return result.toString();
}
return "";
}
private Properties loadProperties() {
Properties props = new Properties();
try (var input = getClass().getClassLoader().getResourceAsStream("application.properties")) {
if (input == null) {
logger.error("Arquivo 'application.properties' não encontrado no classpath.");
throw new IOException("Arquivo de propriedades não encontrado.");
}
props.load(input);
} catch (IOException ex) {
logger.error("Falha ao carregar o arquivo de propriedades.", ex);
throw new RuntimeException(ex);
}
return props;
}
}
✅ O que esta classe faz?
loadProperties()
: Carrega as configurações doapplication.properties
, isolando dados sensíveis e permitindo que o agente seja configurado sem alterar o código.readUnreadEmails()
: É o coração desta etapa. Ele se conecta ao servidor, acessa a caixa de entrada e, usando umFlagTerm
, filtra e retorna apenas as mensagens não lidas. O uso dotry-with-resources
garante que as conexões (Store
eFolder
) sejam sempre fechadas corretamente.getTextFromMessage()
: Um método utilitário crucial. E-mails podem ter múltiplos formatos (MIME types). Este método inspeciona a mensagem e extrai apenas o conteúdo de texto puro (text/plain
), garantindo que nossa IA receba um texto limpo para análise.Logging com Logback
: SubstituímosSystem.out.println()
por umLogger
profissional. Isso nos dá um controle granular sobre as mensagens, permitindo exibir informações deINFO
,DEBUG
ouERROR
, o que é fundamental em aplicações reais.
🚀 Testando Nosso Agente
Crie a classe Main.java
para executar nosso serviço:
package br.com.dio.agent;
public class Main {
public static void main(String[] args) {
System.out.println("Iniciando o agente de leitura de e-mails...");
EmailReaderService reader = new EmailReaderService();
reader.readUnreadEmails();
System.out.println("Processo finalizado.");
}
}
👇 O que esperar no console?
Ao executar a classe Main
, você verá os logs do nosso agente em ação. Para uma melhor visualização, adicione um arquivo logback.xml
em src/main/resources
para formatar a saída.
21:15:10.112 [main] INFO br.com.dio.agent.EmailReaderService - Conexão com o servidor de e-mail estabelecida com sucesso.
21:15:11.345 [main] INFO br.com.dio.agent.EmailReaderService - Encontrados 2 e-mails não lidos.
21:15:11.350 [main] DEBUG br.com.dio.agent.EmailReaderService - ---- Processando Novo E-mail ----
21:15:11.351 [main] DEBUG br.com.dio.agent.EmailReaderService - De: Maria Silva <maria.s@exemplo.com>
21:15:11.351 [main] DEBUG br.com.dio.agent.EmailReaderService - Assunto: Problema crítico no sistema
21:15:11.358 [main] DEBUG br.com.dio.agent.EmailReaderService - Conteúdo extraído (112 caracteres).
21:15:11.360 [main] DEBUG br.com.dio.agent.EmailReaderService - ---- Processando Novo E-mail ----
21:15:11.361 [main] DEBUG br.com.dio.agent.EmailReaderService - De: João Souza <joao.souza@exemplo.com>
21:15:11.361 [main] DEBUG br.com.dio.agent.EmailReaderService - Assunto: Dúvida sobre fatura
21:15:11.365 [main] DEBUG br.com.dio.agent.EmailReaderService - Conteúdo extraído (89 caracteres).
Passo 2: O Cérebro do Agente — Integrando uma Poderosa IA Generativa
Nosso agente já sabe ouvir, mas ainda não entende o que escuta. Nesta etapa, vamos construir seu cérebro. Conectaremos nosso serviço Java a uma API de Inteligência Artificial capaz de interpretar a intenção e o sentimento por trás de cada mensagem. Com isso, o agente deixará de ser apenas um receptor passivo para se tornar um analisador inteligente, abrindo espaço para automações mais precisas e decisões automatizadas.
🎯 A Arte do Prompt Engineering: Pedindo da Forma Certa
A qualidade da resposta da IA depende diretamente de como formulamos nossa pergunta, o famoso prompt. Para garantir robustez e previsibilidade, vamos instruir a IA a agir como um especialista em suporte técnico, retornando sempre um JSON estruturado com campos específicos:
Você é um especialista em análise de e-mails de suporte ao cliente. Analise o texto a seguir e retorne exclusivamente um objeto JSON com os seguintes campos:
— sentimento
: "POSITIVO", "NEGATIVO" ou "NEUTRO"
— categoria
: "PROBLEMA_TECNICO", "DUVIDA_FINANCEIRA", "FEEDBACK" ou "OUTROS"
— resumo
: um resumo de uma frase do pedido do cliente
Texto do e-mail:
"""
[AQUI ENTRARÁ O TEXTO DO E-MAIL]
"""
Esse padrão padronizado facilita a interpretação automática dos dados retornados e evita ambiguidades comuns em respostas livres.
🤖 Criando o Serviço de Análise com IA
Vamos implementar a classe AIService.java
no pacote br.com.dio.agent
, responsável por enviar o conteúdo do e-mail para a API de IA e receber a análise em JSON.
Antes, adicione a chave da API no arquivo application.properties
:
ia.api.key=sua-chave-aqui
Para evitar a duplicação do método loadProperties()
em várias classes, vamos criar uma classe utilitária simples. Isso segue o princípio DRY (Don't Repeat Yourself) e torna nosso código mais limpo e fácil de manter.
Crie uma nova classe ConfigLoader.java
:
package br.com.dio.agent;
import java.io.IOException;
import java.util.Properties;
public class ConfigLoader {
private static final Properties props = new Properties();
static {
try (var input = ConfigLoader.class.getClassLoader().getResourceAsStream("application.properties")) {
if (input == null) {
throw new IOException("Arquivo 'application.properties' não encontrado no classpath.");
}
props.load(input);
} catch (IOException ex) {
throw new RuntimeException("Falha ao carregar o arquivo de propriedades.", ex);
}
}
public static String getProperty(String key) {
return props.getProperty(key);
}
}
Em vez de formatar o JSON da requisição manualmente com Strings (o que é frágil e propenso a erros de escape), usaremos o poder do Jackson também para criar o JSON a partir de objetos Java (DTOs). Isso torna o código mais seguro e legível.
🤖 Criando o Serviço de Análise com IA (Versão Refatorada)
Agora, vamos à versão atualizada da classe AIService.java
, que utiliza nossos refinamentos.
package br.com.dio.agent;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.List;
// DTOs para Request e Response
record AnaliseEmail(String sentimento, String categoria, String resumo) {}
record MensagemIA(String role, String content) {}
record RequisicaoIA(String model, List<MensagemIA> messages, double temperature) {}
public class AIService {
private static final Logger logger = LoggerFactory.getLogger(AIService.class);
private final OkHttpClient client = new OkHttpClient();
private final ObjectMapper mapper = new ObjectMapper();
private static final String API_URL = "https://api.openai.com/v1/chat/completions";
public AnaliseEmail analisarConteudoEmail(String conteudo) {
try {
String apiKey = ConfigLoader.getProperty("ia.api.key");
String prompt = montarPrompt(conteudo);
var requestDto = new RequisicaoIA(
"gpt-3.5-turbo",
List.of(new MensagemIA("user", prompt)),
0.3
);
String requestBody = mapper.writeValueAsString(requestDto);
RequestBody body = RequestBody.create(requestBody, MediaType.get("application/json"));
Request request = new Request.Builder()
.url(API_URL)
.header("Authorization", "Bearer " + apiKey)
.post(body)
.build();
logger.debug("Enviando requisição para a API de IA...");
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
String errorBody = response.body() != null ? response.body().string() : "Sem corpo de resposta";
logger.error("Falha na chamada à API: {}", errorBody);
throw new IOException("Código inesperado da API: " + response);
}
String responseBody = response.body().string();
String jsonContent = extrairConteudoJson(responseBody);
logger.debug("Resposta JSON recebida e extraída: {}", jsonContent);
return mapper.readValue(jsonContent, AnaliseEmail.class);
}
} catch (IOException e) {
logger.error("Erro ao se comunicar com a API de IA.", e);
return null;
}
}
private String extrairConteudoJson(String responseBody) {
try {
return mapper.readTree(responseBody).at("/choices/0/message/content").asText();
} catch (IOException e) {
logger.error("Erro ao parsear JSON da resposta da IA", e);
return "{}";
}
}
private String montarPrompt(String conteudo) {
// O prompt continua exatamente o mesmo
return """
Você é um especialista em análise de e-mails de suporte...
Texto do e-mail:
\"\"\"
%s
\"\"\"
""".formatted(conteudo);
}
}
📝 Explicando o Código
ConfigLoader
: Agora, em vez de cada serviço carregar suas próprias propriedades, simplesmente chamamosConfigLoader.getProperty("ia.api.key")
. Nosso código está mais limpo e centralizado.- DTOs para Requisição: Criamos os
records
MensagemIA
eRequisicaoIA
para modelar exatamente a estrutura JSON que a API espera. - Construção Segura de JSON: A linha
String requestBody = mapper.writeValueAsString(requestDto);
substitui a formatação manual de String. Agora, o Jackson cuida de criar um JSON válido e seguro a partir dos nossos objetos Java, eliminando qualquer risco de erro de sintaxe. - O Restante do Fluxo: A chamada com OkHttp, a extração do JSON da resposta e a conversão para o nosso DTO
AnaliseEmail
continuam com a mesma lógica robusta que você já havia criado.
🔄 Integração e Teste
Para fechar o ciclo, podemos modificar o EmailReaderService
para chamar o AIService
logo após extrair o texto do e-mail. Por exemplo:
AIService aiService = new AIService();
for (Message message : messages) {
String texto = getTextFromMessage(message);
AnaliseEmail analise = aiService.analisarConteudoEmail(texto);
logger.info("Análise da IA: {}", analise);
}
Na classe Main.java
, apenas invoque o método readUnreadEmails()
normalmente e observe o resultado dos logs.
🦾 Passo 3: Da Análise à Ação — A Tomada de Decisão do Agente
Ouvir e pensar são apenas parte do processo. O verdadeiro valor do nosso agente está em sua capacidade de agir com base no que entende. Nesta etapa final da lógica, implementamos o cérebro de decisão que traduz a análise da IA em ações concretas, criando tickets de suporte estruturados e prontos para a equipe.
🎫 Modelando a Ação: O DTO do Ticket
Para representar a ação final do agente de forma clara, criamos um modelo de dados para o nosso ticket de suporte usando um record
do Java.
// em Ticket.java
package br.com.dio.agent;
public record Ticket
( String autorEmail,
String categoria,
String prioridade,
String resumo,
String status
) {}
🔥 Criando o Serviço de Decisão
Centralizamos todas as regras de negócio em uma classe DecisionService
, mantendo nosso código limpo, organizado e fácil de evoluir.
// em DecisionService.java
package br.com.dio.agent;
// ... imports
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DecisionService {
private static final Logger logger = LoggerFactory.getLogger(DecisionService.class);
public Ticket criarTicket(String autor, AnaliseEmail analise) {
String prioridade = determinarPrioridade(analise);
String status = "ABERTO";
logger.info("Decidindo prioridade '{}' para a categoria '{}'", prioridade, analise.categoria());
return new Ticket(autor, analise.categoria(), prioridade, analise.resumo(), status);
}
private String determinarPrioridade(AnaliseEmail analise) {
return switch (analise.categoria()) {
case "PROBLEMA_TECNICO" -> "NEGATIVO".equals(analise.sentimento()) ? "ALTA" : "MÉDIA";
case "DUVIDA_FINANCEIRA" -> "ALTA";
case "FEEDBACK" -> "BAIXA";
default -> "MÉDIA";
};
}
}
💡 Lógica de Negócio Implementada:
determinarPrioridade()
: Usa umswitch
para definir a prioridade com base na análise da IA.- 🔥 PROBLEMA_TECNICO + NEGATIVO: Prioridade ALTA.
- 💳 DUVIDA_FINANCEIRA: Prioridade ALTA.
- 👍 FEEDBACK: Prioridade BAIXA.
- ⚡️ Outros casos: Prioridade MÉDIA.
criarTicket()
: Orquestra a lógica, montando o objetoTicket
final.
🔗 Orquestrando o Fluxo Final no EmailReaderService
Finalmente, unimos todas as peças. O EmailReaderService
agora coordena o fluxo completo: ler o e-mail, chamar o AIService
para análise e, por fim, acionar o DecisionService
para criar o ticket.
🛠️ Ação — Método readUnreadEmails()
Final e Completo:
// Dentro da classe EmailReaderService.java
public class EmailReaderService {
private static final Logger logger = LoggerFactory.getLogger(EmailReaderService.class);
private final AIService aiService = new AIService();
private final DecisionService decisionService = new DecisionService();
public void readUnreadEmails() {
Properties props = ConfigLoader.loadProperties();
final String username = ConfigLoader.getProperty("mail.user");
final String password = ConfigLoader.getProperty("mail.password");
try (Store store = Session.getInstance(props).getStore()) {
store.connect(username, password);
logger.info("Conexão com o servidor de e-mail estabelecida com sucesso.");
try (Folder inbox = store.getFolder("INBOX")) {
inbox.open(Folder.READ_ONLY);
FlagTerm unreadFilter = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
Message[] messages = inbox.search(unreadFilter);
logger.info("Encontrados {} e-mails não lidos.", messages.length);
for (Message message : messages) {
try {
logger.debug("---- Processando Novo E-mail de: {} ----", message.getFrom()[0]);
String content = getTextFromMessage(message);
if (content.isBlank()) {
logger.warn("Conteúdo do e-mail está vazio, pulando análise.");
continue;
}
// Passo 2: Analisar com IA
AnaliseEmail analise = aiService.analisarConteudoEmail(content);
if (analise == null) {
logger.error("Não foi possível analisar o e-mail de {}. Pulando.", message.getFrom()[0]);
continue;
}
// Passo 3: Criar Ticket
Ticket novoTicket = decisionService.criarTicket(message.getFrom()[0].toString(), analise);
logger.info("✅ TICKET CRIADO COM SUCESSO: {}", novoTicket);
} catch (MessagingException | IOException e) {
logger.error("Erro ao processar uma mensagem de e-mail específica.", e);
}
}
}
} catch (MessagingException e) {
logger.error("Erro geral ao ler e-mails: {}", e.getMessage(), e);
}
}
private String getTextFromMessage(Message message) throws MessagingException, IOException {
// ... (código do método permanece o mesmo)
}
}
👀 Observando o Agente em Ação
Agora é só executar novamente a Main.java
. O console irá exibir toda a cadeia de operações:
👇 Exemplo de Saída Final no Console
21:30:45.123 [main] INFO br.com.dio.agent.DecisionService - Decidindo prioridade 'ALTA' para a categoria 'PROBLEMA_TECNICO'
21:30:45.125 [main] INFO br.com.dio.agent.EmailReaderService - ✅ TICKET CRIADO COM SUCESSO: Ticket[autorEmail=Maria Silva <maria.s@exemplo.com>, categoria=PROBLEMA_TECNICO, prioridade=ALTA, resumo=O sistema de pagamentos não está funcionando desde esta manhã, status=ABERTO]
⚖️ Desafios Éticos e de Implementação
Embora tenhamos construído um agente funcional e inteligente, é vital refletir sobre as implicações e responsabilidades desse tipo de tecnologia.
🔐 Privacidade de Dados
Nosso agente tem acesso direto ao conteúdo de e‑mails para realizar sua tarefa. Isso requer extremo cuidado para garantir que dados sensíveis não sejam vazados ou armazenados indevidamente. Políticas de conformidade com a LGPD e GDPR devem guiar todas as implementações.
🧠 Viés da IA
Modelos de IA não são infalíveis e podem carregar vieses embutidos nos dados usados para treiná‑los. A intervenção humana e a contínua validação são essenciais para garantir que as classificações não prejudicarão usuários ou clientes.
⏳ Confiabilidade
E se a IA classificar erroneamente um e‑mail urgente como de baixa prioridade? O impacto poderia ser significativo. Por isso, é vital estabelecer métricas de confiança e realizar amostragens periódicas para verificar a qualidade das decisões tomadas pela IA.
💰 Custos
Embora a automação inteligente traga ganhos de eficiência e velocidade, não podemos ignorar o custo associado às chamadas para as APIs de IA. Em larga escala, esse custo pode tornar‑se significativo, e estratégias de caching ou modelos locais poderão ser caminhos para otimização.
🚀 Conclusão: O Futuro da Automação é Inteligente
Ao longo desta jornada, construímos um agente inteligente que ouve, pensa e age. Partimos da simples conexão à caixa de e‑mails, evoluímos para extrair e interpretar seu conteúdo com IA, e finalizamos com a estrutura necessária para transformar uma mensagem em um ticket de suporte estruturado e priorizado.
Esta não é apenas uma prova de conceito, mas uma prova clara de que a combinação de Java, Jakarta Mail e Inteligência Artificial Generativa não é uma tendência passageira — é uma nova maneira de solucionar desafios de negócio, ampliando a eficiência e a assertividade de operações antes manuais e sujeitas a erros.
💡 “A automação inteligente não substitui o pensamento humano, mas o amplifica, libertando‑nos para focarmos no que realmente importa.”
👉 Próximos Passos
💡 Quer ir além? Experimente:
- Integrar a lógica com uma API do Trello ou Jira, para transformar tickets automaticamente em tarefas.
- Adicionar mais categorias e melhorar o prompt para aumentar a acurácia.
- Melhorar o modelo de priorização para considerar dados históricos e tornar o sistema preditivo.
Se este conteúdo lhe foi útil, dê um ⭐️ no repositório, comente e compartilhe! Sua interação ajuda a tornar esta comunidade de automação inteligente cada dia mais forte.