ONLYOFFICE-Makro für die Füllung der Zellen mit OpenAI-Daten

28 Februar 2023By Vlad

Die KI-Technologie hat erhebliche Fortschritte gemacht und ist zu einem wertvollen Tool geworden, das unsere Arbeitsabläufe automatisieren kann. In unserem letzten Beitrag haben wir über das ONLYOFFICE-Makro gesprochen, das mit Hilfe der OpenAI-API Aufsätze erstellen kann. In diesem Blogbeitrag zeigen wir Ihnen ein Makro, das eine Tabellenkalkulation mit den von OpenAI erhaltenen Daten auffüllt.

Use ONLYOFFICE macro to populate cells with OpenAI data

Verwendung von OpenAI API

Letztes Mal haben wir eine Verbindung zur OpenAI über die RapidAPI-Plattform hergestellt. Es ist eine schnelle und einfache Möglichkeit, Abrufanfragen zu vermitteln. Allerdings bietet der Basisplan nur 100 Anfragen pro Monat. Dieses Mal werden wir also einen Schritt weiter gehen und unseren eigenen Node.js Express-Server erstellen. Er wird die OpenAI-Bibliothek nutzen, um die API-Anfragen direkt an das entsprechende Sprachmodell weiterzuleiten. Außerdem können wir damit CORS-Fehler umgehen, wenn wir eine Abrufanfrage von einem Browser stellen.

Hinweis! Direkte Anfragen an OpenAI sind nur nach Registrierung eines OpenAI-Kontos und dem Erwerben eines persönlichen API-Schlüssels möglich.

Bereitstellung eines Servers

Zunächst erstellen wir einen neuen Ordner für unseren Server und richten ein neues Node.js-Projekt ein, indem wir den folgenden Befehl im Terminal ausführen:

$ npm init -y

Dann installieren wir die folgenden Abhängigkeiten:

  • express ist ein wesentliches Framework, das die Serverfunktionalität erleichtert.
  • cors bietet Middleware zur Ermöglichung von CORS.
  • openai bietet bequemen Zugriff auf die OpenAI-API von Node.js aus.
  • dotenv lädt Umgebungsvariablen aus einer .env-Datei in process.env.

Um sie zu installieren, führen Sie den Befehl npm instal im Terminal aus:

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

Danach erstellen wir die .env-Datei. Dort werden wir unsere API-Schlüssel speichern:

OPEN_AI_API_KEY="<YourOpenAIkey"
SECOND_API_KEY="YourAPIkey"

Der Parameter OPEN_AI_API_KEY enthält Ihren API-Schlüssel, den Sie von OpenAI erhalten haben, und der Parameter SECOND_API_KEY ist der API-Schlüssel für unseren Server. Wir werden ihn aus Sicherheitsgründen in die eingehende Abrufanforderung einfügen.

Dann initialisieren wir die installierten Pakete in der Datei 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());

Eine erfolgreiche Anfrage an OpenAI muss den OpenAI-API-Schlüssel enthalten. Dazu extrahieren wir diesen API-Schlüssel aus der .env-Datei und speichern ihn in der Konfigurationsvariablen:

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

Dann fügen wir eine post-Route hinzu, von der aus wir eine Anfrage an OpenAI senden werden:

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

Wir wollen auch unseren API-Schlüssel für Sicherheitsmaßnahmen implementieren. Dieser zweite API-Schlüssel soll in eine Abrufanfrage aufgenommen werden. In diesem Zusammenhang muss unser Server die eingehende Abrufanfrage prüfen und den enthaltenen API-Schlüssel validieren. Um dies zu erreichen, fügen wir folgenden Code zu unserer Route hinzu:

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;
  }

Wenn der API-Schlüssel korrekt ist, senden wir eine Anfrage an 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);
  • Der Parameter model gibt den Namen des Sprachmodells an, das für die Texterstellung verwendet werden soll. In diesem Fall ist es text-davinci-003, das fortschrittlichste Modell für die Texterstellung.
  • Der Parameter prompt gibt den Text oder den Kontext an, aus dem das Sprachmodell den Text generieren soll. Dieser Wert wird aus dem Textkörper der Fetch-Anfrage entnommen.
  • Der Parameter temperature steuert die Zufälligkeit des generierten Textes. Ein Wert von 0 bedeutet, dass der Text vollständig deterministisch ist, während höhere Werte zu abwechslungsreicheren und unerwarteten Texten führen.
  • Der Parameter max-tokens gibt die maximale Länge des generierten Textes in Token (d. h. Wörtern oder Teilwörtern) an.

Zum Schluss richten wir unseren Server so ein, dass er auf Port 3000 hört:

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

Der gesamte index.js-Code lautet wie folgt:

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');
});

Erstellung eines Makros

Zunächst stellen wir eine Abrufanfrage an unseren Server:

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>'
})
})

Wir haben die Werte prompt und apiKey im Anfragetext angegeben. Beachten Sie, dass diese Parameter je nach den Daten, die Sie erhalten möchten, und dem API-Schlüssel Ihres Servers unterschiedlich sind.

Als Nächstes wird die Antwort als JSON-Daten verarbeitet:

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

Wir teilen den Antworttext durch Zeilenumbrüche in ein Array von Strings auf und richten die aktive Tabellenkalkulation:

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

Danach erstellen wir eine verschachtelte Schleife, die die Zeilen und Spalten der Tabellenkalkulation unter Verwendung der Funktion split() durchläuft. Wir verwenden die SetValue-Methode, um jede Zelle mit den Daten aus der Antwort zu füllen und sie von Leerzeichen zu befreien:

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;
        }

Der gesamte Makrocode lautet wie folgt:

(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;
        }
});
})();

Öffnen wir nun den Tabellenkalkulations-Editor und führen unser Makro aus!

Wir hoffen, dass dieses Makro neue faszinierende KI-Technologien in Ihren Arbeitsablauf einbringt und lästige Routineaufgaben erleichtert. Wir fordern Entwickler auf, die Möglichkeiten, die unsere API-Methoden bieten, zu nutzen und eigene Makros zu erstellen.

Wenn Sie Fragen oder Ideen haben, können Sie uns gerne einen Kommentar hinterlassen oder uns direkt kontaktieren. Wir sind offen für Ihre Ideen und freuen uns auf die Zusammenarbeit mit Ihnen. Viel Glück bei Ihren Experimenten!