Use a macro ONLYOFFICE para preencher células com dados OpenAI

22 fevereiro 2023By Klaibson

A tecnologia de IA fez avanços significativos e se tornou uma ferramenta valiosa que pode automatizar nosso fluxo de trabalho. Em nosso post anterior, falamos sobre a macro ONLYOFFICE que pode gerar redações usando a API OpenAI. Nesta postagem do blog, mostraremos uma macro que preenche uma planilha com dados obtidos pelo OpenAI.

Use a macro ONLYOFFICE para preencher células com dados OpenAI

Usand OpenAI API

Da última vez, nos conectamos ao OpenAI API através da plataforma RapidAPI. É uma maneira rápida e conveniente de mediar solicitações de busca. No entanto, o plano básico oferece apenas 100 solicitações por mês. Então, desta vez, vamos aumentar o nível e criar nosso próprio servidor Node.js Express. Ele utilizará a biblioteca OpenAI para atender às solicitações de API diretamente para o modelo de linguagem apropriado. Isso também nos permitirá ignorar erros de CORS ao fazer uma solicitação de busca de um navegador.

Observação! Fazer solicitações diretamente ao OpenAI está disponível apenas mediante o registro de uma conta OpenAI e a aquisição de uma chave de API pessoal.

Configurando um servidor

Primeiro, criamos uma nova pasta para nosso servidor e configuramos um novo projeto Node.js executando o seguinte comando no terminal:

$ npm init -y

Em seguida, instalamos as seguintes dependências:

  • pacote expresso – é uma estrutura essencial que facilita a funcionalidade do servidor.
  • pacote cors – fornece middleware para habilitar o CORS.
  • pacote openai – fornece acesso conveniente à API OpenAI do Node.js.
  • pacote dotenv – carrega variáveis de ambiente de um arquivo .env para process.env.

Para instalá-los, execute o comando npm install no terminal:

$ npm install express
$ npm install openai
$ npm install dotenv --save
$ npm install cors

Depois disso, criamos o arquivo .env. Vamos armazenar nossas chaves de API lá:

OPEN_AI_API_KEY="<YourOpenAIkey"
SECOND_API_KEY="YourAPIkey"

O parâmetro OPEN_AI_API_KEY contém sua chave de API obtida do OpenAI, e o parâmetro SECOND_API_KEY é a chave de API para nosso servidor. Vamos incorporá-lo na solicitação de busca recebida para medidas de segurança. Em seguida, inicializamos os pacotes instalados no arquivo index.js:

const express = require('express');
const cors = require('cors');
const { Configuration, OpenAIApi } = require('openai');
require('dotenv').config();
const app = express();

const openai = new OpenAIApi(configuration);
app.use(cors());
app.use(express.json());

Uma solicitação bem-sucedida para OpenAI deve incluir a chave de API OpenAI. Para fazer isso, extraímos esta chave de API do arquivo .env e a armazenamos na variável de configuração:

const configuration = new Configuration({
  apiKey: process.env.OPEN_AI_API_KEY,
});

Em seguida, adicionamos uma rota de postagem a partir da qual enviaremos uma solicitação ao OpenAI:

app.post('/completion', async (req, res) => {
}

Também queremos implementar nossa chave de API para medidas de segurança. Essa segunda chave de API deve ser incluída em uma solicitação de busca. A esse respeito, nosso servidor precisa verificar a solicitação de busca recebida e validar a chave de API incluída. Para isso, adicionamos o seguinte código à nossa rota:

app.post('/completion', async (req, res) => {
  const requestApiKey = req.body.apiKey;
  
  if (!requestApiKey) {
    res.status(400).send({ error: "Error: API Key is missing." });
    return;
  }
  if (requestApiKey !== process.env.SECOND_API_KEY) {
    res.status(401).send({ error: "Error: API Key is incorrect." });
    return;
  }

Se a chave da API estiver correta, enviamos uma solicitação para OpenAI:

const completion = await openai.createCompletion({
    model: 'text-davinci-003',
    prompt: req.body.prompt,
    temperature: 0,
    max_tokens: 300,
  });
  res.json(completion.data.choices[0].text);
  • O parâmetro model especifica o nome do modelo de linguagem a ser usado para gerar texto. Neste caso, é text-davinci-003, que é o modelo mais avançado para geração de texto.
  • O parâmetro prompt especifica o texto ou o contexto do qual o modelo de idioma gerará o texto. Obteremos esse valor do corpo da solicitação de busca.
  • parâmetro de temperatura controla a aleatoriedade do texto gerado. Um valor de 0 significa que o texto é completamente determinístico, enquanto valores mais altos resultarão em um texto mais variado e inesperado.
  • O parâmetro max-tokens indica o comprimento máximo do texto gerado em tokens (ou seja, palavras ou subpalavras).

Por fim, configuramos nosso servidor para escutar na porta 3000:

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

Todo o código index.js é o seguinte:

const express = require('express');
const cors = require('cors');
const { Configuration, OpenAIApi } = require('openai');
require('dotenv').config();
const app = express();
const configuration = new Configuration({
  apiKey: process.env.OPEN_AI_API_KEY,
});
const openai = new OpenAIApi(configuration);
app.use(cors());
app.use(express.json());
app.post('/completion', async (req, res) => {
  const requestApiKey = req.body.apiKey;
  
  if (!requestApiKey) {
    res.status(400).send({ error: "Error: API Key is missing." });
    return;
  }
  if (requestApiKey !== process.env.SECOND_API_KEY) {
    res.status(401).send({ error: "Error: API Key is incorrect." });
    return;
  }
  const completion = await openai.createCompletion({
    model: 'text-davinci-003',
    prompt: req.body.prompt,
    temperature: 0,
    max_tokens: 300,
  });
  res.json(completion.data.choices[0].text);
});
app.listen(3000, () => {
  console.log('Server running on port 3000');
});

Construindo a macro

Primeiro, fazemos uma solicitação de busca ao nosso servidor:

fetch('http://<your_server_address>/completion', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt: 'List the 10 wealthiest countries in the world. Provide GPT figures',
apiKey: '<YourAPIkey>'
})
})

Especificamos os valores prompt e apiKey no corpo da solicitação. Observe que esses parâmetros serão diferentes dependendo dos dados que você deseja receber e da chave de API do servidor. Em seguida, analisamos a resposta como dados JSON:

.then(response => response.json())

Dividimos o texto da resposta por quebras de linha em uma matriz de strings e direcionamos para a planilha ativa:

.then(data => {
var arrAllRows = data.split(/\r?\n|\r/);
var wSheet = Api.GetActiveSheet()

Depois disso, criamos um loop aninhado que itera sobre as linhas e colunas da planilha, usando a função split(). Usamos o método SetValue para preencher cada célula com os dados da resposta e apará-la de espaços em branco:

var i = 0;
var j = 0;
  for (var singleRow = 0; singleRow < arrAllRows.length; singleRow++) {
            var rowCells = arrAllRows[singleRow].split('-');
            for (var rowCell = 0; rowCell < rowCells.length; rowCell++) {
                wSheet.GetCells(i,j).SetValue(rowCells[rowCell].trim());
                j = j + 1;
            } 
            i = i + 1;
            j = 1;
        }

Todo o código da macro é o seguinte:

(function()
{
   fetch('http://<your_server_address>/completion', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt: 'List the 10 wealthiest countries in the world. Provide GPT figures',
apiKey: 'dfhgsd63456efgdfhjikhfzf435332fdhd'
})
})
.then(response => response.json())
.then(data => {
var arrAllRows = data.split(/\r?\n|\r/);
var wSheet = Api.GetActiveSheet();
var i = 0;
var j = 0;
  for (var singleRow = 0; singleRow < arrAllRows.length; singleRow++) {
            var rowCells = arrAllRows[singleRow].split('-');
            for (var rowCell = 0; rowCell < rowCells.length; rowCell++) {
                wSheet.GetCells(i,j).SetValue(rowCells[rowCell].trim());
                j = j + 1;
            } 
            i = i + 1;
            j = 1;
        }
});
})();

Agora, vamos abrir o editor de planilhas e rodar nossa macro!

Esperamos que você utilize os conceitos descritos nesta postagem do blog e torne seu fluxo de trabalho mais eficiente. Incentivamos você a aproveitar nossos vários métodos de API e incorporá-los em suas tarefas de rotina diária.

Se você tiver alguma dúvida ou ideia para compartilhar, sinta-se à vontade para deixar comentários ou fale conosco. Estamos abertos para ouvir suas ideias e estamos ansiosos para colaborar com você. Boa sorte em seus esforços exploratórios!