E aí, tudo bom?
Eu estava olhando alguns projetos no meu github e me deparei com um chatbot que criei recentemente usando o Google Gemini. A ideia era criar um assistente de idiomas, onde você conseguisse conversar com a IA para aprimorar suas habilidades no idioma que quisesse.
Então pensei: " Porque não compartilhar como eu fiz este projeto com todo mundo? ". E é por isso que estou escrevendo aqui, para te mostrar como fiz cada parte. Então vamos começar pelo front-end da aplicação.
Iniciando um novo projeto
Bom, para justificar algumas ações que vou tomar no projeto vou logo adiantando que iremos criar um "servidor" com express.js, onde forneceremos uma rota de api '/chat' que servirá para a comunicação entre o front-end e a API do Gemini.
Então, precisaremos iniciar nosso projeto com o comando npm init -y
. O resultado é um arquivo package.json
mais ou menos com essa cara:
{
"name": "chatbot-ia",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}
E também, vamos precisar organizar nossos arquivos da seguinte forma:
public
|__ index.html
|__ style.css
|__ script.js
package.json
Feito isso, vamos criar a parte visual do nosso chatbot. Vamos lá!
Criando o visual do Chat
Como a ideia era fazer um projeto para um live coding de 1h, resolvi criar uma interface bem simples usando HTML, CSS e JavaScript para o Chatbot. Sou bem ruim com design, então a fonte e as cores eu escolhi as que mais gosto. Então vamos lá, começando pelo HTML.
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Chatbot Assistente de Idiomas</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Roboto&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="chat-container">
<div id="chat-window" class="chat-box">
<!-- As mensagens vão aparecer aqui -->
</div>
<div class="input-container">
<form id="chat-form" class="chat-form">
<input
type="text"
id="user-input"
placeholder="Digite sua mensagem..."
autocomplete="off"
required
/>
<button id="send-button" type="submit">Enviar</button>
</form>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
E agora o CSS da página
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: "Roboto", sans-serif;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #f2f2f2;
}
.chat-container {
width: 100%;
max-width: 400px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.chat-box {
height: 300px;
max-height: 500px;
overflow-y: auto;
padding: 16px;
display: flex;
flex-direction: column;
}
.chat-form {
width: 100%;
display: flex;
justify-content: space-between;
}
.message {
padding: 10px;
margin-bottom: 8px;
border-radius: 20px;
width: auto;
display: inline-flex;
max-width: 50%;
word-wrap: break-word;
}
.model {
background-color: #e0e0e0;
color: #333;
align-self: flex-start;
justify-content: flex-start;
}
.user {
background-color: #4caf50;
color: white;
align-self: flex-end;
justify-content: flex-end;
margin-left: auto;
}
.input-container {
display: flex;
padding: 10px;
border-top: 1px solid #ddd;
}
#user-input {
flex: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 20px;
outline: none;
}
#send-button {
margin-left: 10px;
padding: 10px 15px;
background-color: #4caf50;
color: white;
border: none;
border-radius: 20px;
cursor: pointer;
}
#send-button:hover {
background-color: #45a049;
}
O resultado disso deve ser uma tela parecida com a mostrada abaixo:
Criando a lógica do cliente
Nossa aplicação é um chatbot que irá se comunicar com a API do Gemini. Então, precisamos criar a lógica que irá fazer essa comunicação. Para ficar claro o que devemos fazer, vou listar abaixo:
- Pegar o que for digitado pelo usuário
- Fazer uma requisição POST para a rota '/chat' que iremos criar
- Exibir a mensagem do usuário e do modelo (a IA) na tela do chat
Então vamos lá, primeiro vamos adicionar um ouvinte de eventos para executar nossa lógica apenas depois que o conteúdo do DOM for totalmente carregado:
// script.js
document.addEventListener("DOMContentLoaded", () => {
const chatForm = document.getElementById("chat-form");
const chatWindow = document.getElementById("chat-window");
const userInput = document.getElementById("user-input");
// ...
});
Criamos constantes para pegar os elementos que nos interessam, como o input onde o usuário digita, a janela onde irão aparecer as mensagens e o campo do formulário, pois vamos escutar quando ele for submetido e aí sim executar nossa lógica.
Continuando, vamos para o segundo passo que é fazer a requisição para a rota que criaremos enviando a mensagem do usuário.
chatForm.addEventListener("submit", async (e) => {
e.preventDefault();
const userMessage = userInput.value.trim();
if (!userMessage) return;
addMessage("user", userMessage);
try {
const modelResponse = await fetch("/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message: userMessage }),
});
const data = await modelResponse.json();
if (data && data.response) {
addMessage("model", data.response);
} else {
addMessage("model", "Erro: Resposta inválida do modelo.");
}
} catch (err) {
console.error(err);
addMessage("model", "Erro: Não foi possível processar sua mensagem.");
}
userInput.value = "";
});
Neste código, estamos escutando o evento de submit no elemento de formulário. Então, de início usamos o preventDefault
para evitar que a página faça reload sempre que enviarmos uma mensagem. Depois pegamos o que o usuário digitou, removendo os espaços em branco da mensagem, do início e fim com o trim()
e verificamos se a mensagem não é vazia, em branco. Se a mensagem for vazia a gente para nosso processo aí mesmo.
Agora, se tivermos a mensagem do usuário, exibimos ela na tela usando a função addMessage()
. Esta função é definida da seguinte forma:
function addMessage(role, text) {
const messageDiv = document.createElement("div");
messageDiv.className = `message ${role}`;
messageDiv.textContent = text;
chatWindow.appendChild(messageDiv);
chatWindow.scrollTop = chatWindow.scrollHeight;
}
Basicamente ela recebe quem enviou a mensagem e o texto da mensagem e exibe essa informação no chat, adicionando os estilos corretos do usuário e do model, o modelo de IA.
Beleza, agora voltando para a lógica da nossa requisição se tivermos uma mensagem do usuário precisamos fazer uma requisição POST usando o fetch API, e o corpo dessa requisição é a mensagem do usuário.
Por fim, se tivermos uma resposta dessa requisição iremos exibir a mensagem do modelo no chat. Caso contrário, pegamos o erro e exibimos no console, com o console.error()
ou exibimos uma mensagem no próprio chat de forma customizada. E para melhorar a usabilidade do chat, limpamos o input de mensagem do usuário com o userInput.value = "";
.
O arquivo script.js
fica com essa cara:
// script.js
document.addEventListener("DOMContentLoaded", () => {
const chatForm = document.getElementById("chat-form");
const chatWindow = document.getElementById("chat-window");
const userInput = document.getElementById("user-input");
chatForm.addEventListener("submit", async (e) => {
e.preventDefault();
const userMessage = userInput.value.trim();
if (!userMessage) return;
addMessage("user", userMessage);
try {
const modelResponse = await fetch("/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message: userMessage }),
});
const data = await modelResponse.json();
if (data && data.response) {
addMessage("model", data.response);
} else {
addMessage("model", "Erro: Resposta inválida do modelo.");
}
} catch (err) {
console.error(err);
addMessage("model", "Erro: Não foi possível processar sua mensagem.");
}
userInput.value = "";
});
function addMessage(role, text) {
const messageDiv = document.createElement("div");
messageDiv.className = `message ${role}`;
messageDiv.textContent = text;
chatWindow.appendChild(messageDiv);
chatWindow.scrollTop = chatWindow.scrollHeight;
}
});
E com isso a gente finaliza a parte do front-end do chatbot. O próximo passo será criar o nosso "servidor", realizar a comunicação com a API do Gemini e conversar com ele sobre a vida, o universo e tudo mais!
Até uma próxima!
Top comments (1)
Boa! No aguardo da parte 2!