Como criar um “gerador de cotações de IA” com OpenAI e JavaScript

Neste tutorial, aprenderemos como criar um aplicativo “AI Quotes Generator” com JavaScript. Este aplicativo demonstrará como buscar dados da API OpenAI e gerar cotações envolventes para diferentes categorias ou ambientes personalizados.

Estrutura HTML

A estrutura HTML consistirá nos seguintes elementos:

  • Um botão no canto superior direito abrirá um modal que permite aos usuários adicionar sua chave de API OpenAI.
  • Uma entrada que permite aos usuários adicionar um clima personalizado
  • Várias opções preenchidas com categorias
  • Um botão que, ao ser clicado, gerará cotações da API OpenAI.

Como fizemos antes, usaremos a estrutura Bootstrap para fazer grande parte do trabalho pesado no que diz respeito à UI. A estrutura HTML ficará assim:

1
 class="position-absolute top-0 end-0 mt-2 me-3">
2
   
3
      id="api"
4
      type="button"
5
      class="btn btn-primary"
6
      data-bs-toggle="modal"
7
      data-bs-target="#myModal"
8
      >
9
   Add API Key
10
   
11

12
 class="container mt-5">
13
    class="message alert alert-danger text-center" role="alert">
14
   
15
      class="modal fade"
16
      id="myModal"
17
      tabindex="-1"
18
      aria-labelledby="exampleModalLabel"
19
      aria-hidden="true"
20
      >
21
       class="modal-dialog ">
22
          class="modal-content">
23
             class="modal-header">
24
                class="modal-title" id="exampleModalLabel">
25
                  Your API Key remains stored locally in your browser
26
               
27
            
28
             class="modal-body">
29
                class="form-group">
30
                   for="apikey">API KEY
31
                   type="text" class="form-control" id="apikey" />
32
               
33
            
34
             class="modal-footer">
35
               
36
                  type="button"
37
                  class="btn btn-secondary"
38
                  data-bs-dismiss="modal"
39
                  >
40
               Close
41
               
42
                type="button" class="btn btn-primary">Save
43
            
44
         
45
      
46
   
47
    class="header text-center display-2 fw-bold">AI Quote Generator
48
   
49
    class="d-md-flex h-md-100 my-5 align-items-center">
50
       class="col-md-6 p-0 h-md-100">
51
          class="d-md-flex align-items-center h-100 p-5 text-center justify-content-center category-wrapper">
52
             class="pt-5 pb-5">
53
                class="fs-5">
54
                  Create the perfect quote based on your current mood..
55
               

56
               
57
                  id="input"
58
                  name="mood"
59
                  type="text"
60
                  placeholder="Enter your current mood"
61
                  class="form-control mb-4 mx-auto w-75 text-center"
62
                  style="width: 60%; display: inline-block"
63
                  />
64
            
65
         
66
      
67
       class="col-md-6 p-0 h-md-100">
68
          class="d-md-flex align-items-center h-md-100 p-5 text-center justify-content-center vstack">
69
             class="fs-5">
70
               ..or choose from our custom categories
71
            

72
            
73
               class="quotes row justify-content-center mt-8 mb-4"
74
               >
75
               
76
            
77
         
78
      
79
   
80
   
81
    class="quotes-container text-center mt-4">
82
      
83
         id="generate"
84
         class="generate-btn btn btn-primary"
85
         type="submit"
86
         >
87
      Generate Quotes
88
      
89
       class="d-flex justify-content-center mt-3">
90
          id="loader" class="spinner-border" role="status">
91
         
92
      
93
   
94

95

96
 class="container text-center mt-5 mb-4">
97
    id="result" class="row">
98
      
99
   
100

Preencheremos as categorias de cotação dinamicamente com JavaScript e, assim que obtivermos as cotações da API OpenAI, elas serão preenchidas no contêiner de resultados.

Para este projeto, também usaremos as ferramentas jQuery do Bootstrap para habilitar a funcionalidade modal. Inclua os links CDN no cabeçalho.

1

2
 href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous" />
3

4

5

6

7

Estilo CSS

Graças ao Bootstrap, não precisaremos de muitos estilos personalizados. Mas vamos adicionar os estilos CSS personalizados de que precisamos, incluindo a fonte web DM Mono.

1
@import url("https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap");
2

3
body {
4
  font-family: "DM Mono", monospace;
5
}
6
.form-group {
7
  margin: 2rem 0;
8
}
9
label {
10
  margin-bottom: 1rem;
11
}
12
@media (min-width: 768px) {
13
  .category-wrapper {
14
    border-right: 2px solid #999;
15
  }
16
}
17

18
#loader,
19
.message,
20
.radio-group input[type="radio"]{
21
  display: none;
22
}
23
   

Armazenando API KEY no armazenamento local

Para que o aplicativo funcione conforme esperado, os usuários devem adicionar sua API KEY ao armazenamento local para garantir persistência e segurança. Para conseguir isso, temos o “Adicionar chave de API” botão no canto superior direito. O botão é configurado com o data-bs-target atributo definido como myModal indicando que clicar nele acionará o modal com o id “meuModal” a ser exibido.

1

2
   id="api"
3
   type="button"
4
   class="btn btn-primary"
5
   data-bs-toggle="modal"
6
   data-bs-target="#myModal"
7
   >
8
Add API Key
9

Assim que o modal for mostrado ao usuário, usaremos jQuery para anexar um ouvinte de evento para o shown.bs.modal evento. Na função de evento, faremos o seguinte:

  • Obtenha o valor da chave API do usuário.
  • salve o valor no armazenamento local,
  • ocultar o modal
1
$("#myModal").on("shown.bs.modal", function () {
2
  
3
  const saveButton = document.querySelector("#myModal .btn-primary");
4
  const apiKeyInput = document.querySelector("#apikey");
5

6
  saveButton.addEventListener("click", function () {
7
    const apiKeyValue = apiKeyInput.value;
8
    localStorage.setItem("API_KEY", apiKeyValue);
9
    $("#myModal").modal("hide");
10
  });
11
});

Então, quando você clica no botão “Adicionar CHAVE DE API“, o modal será exibido assim:

A próxima etapa é definir e mapear nossas categorias personalizadas para a interface. Aqui estão as categorias. Sinta-se à vontade para definir o seu próprio.

1
const categorias = [
2
  "motivation",
3
  "life",
4
  "hope",
5
  "funny",
6
  "love",
7
  "philosophy",
8
  "sadness",
9
];

Vamos pegar o elemento com as aspas da classe que abrigará as categorias.

1
const quotes = document.querySelector(".quotes");

A seguir, usaremos o map() método para gerar uma marcação HTML de um rótulo e um elemento de rádio de entrada para cada categoria; o elemento de entrada de rádio conterá o id e value da categoria, enquanto o rótulo conterá o name da categoria.

1
const mappedCategories = categories.map((category) => {
2
  capitalizeText = category.charAt(0).toUpperCase() + category.slice(1);
3
      return `
4
        type="radio"

5
        class="btn-check"

6
        name="mood"

7
        id="${category}"

8
        value="${category}"

9
        autocomplete="off"

10
      />

11
      
12
        class="btn btn-secondary align-items-center justify-content-center fs-5"

13
        for="${category}"

14
      >${capitalizeText}`;
15
});
16
quotes.innerHTML = mappedCategories.join("");

Agora o aplicativo está assim:

Configuração da API OpenAI

Implementamos a funcionalidade de adição de chave de API. Agora, vamos pegar a chave no site da OpenAI. Se você não tem uma conta, vá para o Site OpenAI e inscreva-se gratuitamente.

Depois de fornecer os detalhes necessários, navegue até o documentação. Clique em API KEY no canto superior esquerdo, crie sua chave de API, copie e cole a chave e armazene-a em um local seguro.

Usando a chave API

Crie uma função assíncrona chamada getData()que leva dois parâmetros, a saber prompt e API KEY,

1
const getData = async (prompt, API_KEY) => {
2
    
3
}

Dentro da função, queremos usar fetch() função para fazer uma solicitação à API OpenAI e exibir a resposta gerada ao usuário. Dentro de getData() função, adicione um try-catch bloco com o seguinte código.

1
const getData = async (prompt, API_KEY) => {
2
  
3
  try {
4
    const response = await fetch("https://api.openai.com/v1/chat/completions", {
5
      method: "POST",
6
      headers: {
7
        Authorization: `Bearer ${API_KEY}`,
8
        "Content-Type": "application/json",
9
      },
10
      body: JSON.stringify({
11
        model: "gpt-3.5-turbo",
12
        mensagens: [
13
          {
14
            role: "user",
15
            content: `Generate 10 quotes about ${prompt}`,
16
          },
17
        ],
18
        temperature: 0.7,
19
      }),
20
    });
21
    const data = await response.json();
22

23
    return data;
24
  } catch (error) {
25

26
    return error;
27
  }
28
};

Este é todo o código que precisamos para obter dados do OpenAI. Vamos analisar o código.

  • Nós usamos o fetch() função dentro do bloco try para fazer um assíncrono POST solicitação para o URL especificado.
  • No corpo da solicitação, especificamos gpt-3.5-turbo como modelo a ser utilizado;
  • A API OpenAI também espera um cabeçalho de autorização contendo o API KEY, e o corpo da solicitação deve ser um JSON objeto contendo parâmetros como o model, prompte temperature (indica aleatoriedade das respostas; valores mais altos indicam mais aleatoriedade das respostas).
  • Por fim, devolvemos o response.json objeto. Em caso de algum erro, também devolvemos o error objeto.

A resposta dos dados é assim;

Como você pode ver, os dados que precisamos exibir ao usuário estão contidos no arquivo choices variedade. Os dados serão formatados antes de serem exibidos ao usuário.

O getData() A função será chamada quando o usuário clicar no botão gerar cotações. Vamos adicionar um ouvinte de evento ao botão gerar.

1
const generateBtn = document.querySelector(".generate-btn");
2
generateBtn.addEventListener("click", async (e) => {
3
  e.preventDefault();
4
  
5
  }

Quando ocorre o evento click, queremos executar uma função que faça o seguinte:

  • Obtenha a API KEY do armazenamento local.
  • Se nenhuma API KEY for encontrada no armazenamento local, exibiremos um erro, informando ao usuário que ele deve adicionar sua API KEY.
  • Obtenha o prompt de uma categoria ou de um prompt personalizado.
  • Passe o prompt e a APIKEY para o getData() função.
  • Mostre um controle giratório quando o aplicativo estiver buscando os dados.
  • Depois de obter uma resposta, pare o botão giratório.
  • Formate os dados e exiba-os em cartões bootstrap.
  • Em caso de algum erro, exibiremos a mensagem de erro apropriada.

Atualize a função do ouvinte de eventos da seguinte maneira:

1
const generateBtn = document.querySelector(".generate-btn");
2
generateBtn.addEventListener("click", async (e) => {
3
  e.preventDefault();
4
  const key = localStorage.getItem("API_KEY");
5

6
  if (!key) {
7
    displayError("","Please add your OPENAI API Key, The KEY will be stored locally on your browser");
8
    return;
9
  }
10

11
  let prompt = "";
12
  let radio = document.querySelector('input[name="mood"]:checked');
13

14
  if (document.querySelector('input[name="mood"]:checked')) {
15
    radio = document.querySelector('input[name="mood"]:checked');
16
    prompt = radio.value;
17
  } else {
18
    CustomInput = document.getElementById("input");
19
    prompt = CustomInput.value; 
20
  }
21

22
  if (!prompt) {
23
    displayError(prompt,'Please choose a category or provide a custom mood"');
24
    return;
25
  }
26
  
27
  loader.style.display = "block";
28

29
  const data = await getData(prompt, key);
30

31
  if (data.choices) {
32
    const container = document.getElementById("result");
33
    //    data from aync

34
    const quotesArray = data.choices[0].message.content.split("\n");
35
    const mappedArray = quotesArray.map((quote) => {
36
      const trimmedQuote = quote.replace(/^\d+\.|"$/g, "").trim();
37

38
      return ` 
39
            
40
              
41
                

${trimmedQuote}

42
            

43
        

44
        `;
45
    });
46

47
    container.innerHTML = mappedArray.join("");
48
    
49
  } else {
50
    displayError("",data.error.message )
51
    
52
  }
53
  CustomInput.value = "";
54
});

Vamos detalhar o que está acontecendo acima:

  • Primeiro, evitamos a natureza padrão do navegador definindo e.preventDefault()
  • const key = localStorage.getItem("API_KEY"); obterá a API KEY do armazenamento local.
  • Se nenhuma chave for encontrada, passaremos uma mensagem de erro para o displayError() função.
  • let prompt = ""; declara uma string vazia que armazenará o valor do prompt do usuário.
  • if (document.querySelector('input[name="mood"]:checked')){...} : verifica se o usuário selecionou uma categoria e se for verdade, o valor da entrada de rádio selecionada é atribuído ao prompt.
  • No else instrução, o prompt será o valor de entrada personalizado se o usuário tiver inserido um clima personalizado.
  • Se o valor do prompt for null ou undefinedsignifica que o usuário não forneceu um aviso (seja selecionando uma categoria de humor ou inserindo um clima personalizado), exibiremos uma mensagem de erro.
  • Após toda a validação ter passado, exibiremos um elemento giratório com loader.style.display = "block";

getData() Função

A seguir, chamaremos o wait getData() função e passe o prompt e a chave API. Como a função é assíncrona, usamos await para garantir que a execução seja atrasada até que a busca de dados seja bem-sucedida.

Como vimos anteriormente, o objeto de dados retornado pela API se parece com isto:

O conteúdo que precisamos está contido no choices[0].message objeto.

  • data.choices[0].message.content.split("\n"); cria uma matriz de cotações chamada quotesArray dividindo-a onde \n aparece.
  • O quotesArray agora contém todas as citações, tudo o que precisamos fazer é usar o map() método e para cada cotação, remova qualquer espaço em branco à esquerda ou à direita com quote.replace(/^\d+\.|"$/g, "").trim(); e retorne uma marcação HTML para cada cotação representada por um cartão Bootstrap.
  • Por fim, definimos o innerHTML do quotes contêiner à marcação HTML concatenada de cada cotação.
  • Em caso de erro da API, displayError("",data.error.message ) exibe a mensagem de erro retornada.

Manipulação de erros

Em vez de repetir o processo de tratamento de erros, o displayError() função irá lidar com isso. Leva o valueText e um messageText como parâmetros, verifica se o valueText é nulo ou indefinido e exibe a mensagem de erro contida em messageText .

A mensagem de erro é exibida por 4 segundos e depois ocultada do usuário.

1
function displayError(valueText,messageText) {
2
  const message = document.querySelector(".message");
3
  if (valueText === "") {
4
  
5
    message.textContent = messageText;
6
    message.style.display = "block";
7
  }
8
  setTimeout(() => {
9
    message.textContent = "";
10
    message.style.display = "none";
11
  }, 4000);
12
  return;
13
}

Para a limpeza final, vamos garantir que se o usuário começar a digitar no campo de entrada personalizado, qualquer categoria selecionada anteriormente (por meio de botões de opção) será desmarcada.

1
const inputField = document.getElementById("input");
2
inputField.addEventListener("input", () => {
3
  const radio = document.querySelector('input[name="mood"]:checked');
4
  if (radio) {
5
    radio.checked = false;
6
  }
7
});

Conclusão

Uau! Foi muito para absorver, mas o resultado final vale a pena e você terá aprendido muito. Abordamos as etapas necessárias para criar seu próprio aplicativo AI Quote Generator com JavaScript. Agora você pode integrar IA ao seu aplicativo para gerar conteúdo exclusivo!

Vamos nos lembrar do produto final.

[ad_2]

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *