AI 技术现已取得重大进展,同时也成为了颇具价值的工具,可帮助我们自动化工作流。在之前的帖子中,我们提到过可使用 OpenAI 生成文章的 ONLYOFFICE 宏。那么在本文中,我们将为您演示一个可将通过 OpenAI 获取的数据填入电子表格的宏。
使用 OpenAI API
上次我们选择了通过 RapidAPI 平台连接 OpenAI API。这是一种获取请求的快速、简单方式。不过其基础版本每月仅提供 100 次请求。所以这次我们将更进一步:自建 Node.js Express 服务器。其将使用 OpenAI 库来直接将 API 请求提供给适当的语言模型。同时还允许我们在从浏览器中发出获取请求时绕过 CORS 错误。
注意!直接向 OpenAI 发送请求的功能仅在具有 OpenAI 账户并使用个人 API Key 的话就可用。
建立服务器
首先,我们为服务器创建一个新的文件夹并设置新的 Node.js 项目。在终端中执行以下代码即可:
$ npm init -y
然后安装下列依赖:
- express 包 - 服务器功能基本框架。
- cors 包 - 提供启用 CORS 所需的中间件。
- openai 包 - 提供从 Node.js 访问 OpenAI API 的便捷访问权限。
- dotenv 包 - 从 .env 文件中向 process.env 加载环境变量。
如需安装,请在终端中运行 npm instal:
$ npm install express
$ npm install openai
$ npm install dotenv --save
$ npm install cors
之后我们来创建 .env 文件。其将被用于保存 API Key:
OPEN_AI_API_KEY="<YourOpenAIkey"
SECOND_API_KEY="YourAPIkey"
OPEN_AI_API_KEY 参数中包含从 OpenAI 处获取的 API Key,SECOND_API_KEY 参数则是服务器的 API Key。出于安全考虑,我们会将其纳入传入获取请求中。
接下来在 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());
对于 OpenAI 的成功请求中必须包括 OpenAI API Key。为此,我们需要从 .env 文件中提取这一 API Key,然后将其存储在 configuration 变量中:
const configuration = new Configuration({
apiKey: process.env.OPEN_AI_API_KEY,
});
然后添加向 OpenAI 发送请求的 post 路径:
app.post('/completion', async (req, res) => {
}
出于安全考虑,我们还会纳入自己的 API Key。第二个 API Key 应被纳入获取请求中。在这一方面,我们的服务器需要检查传入的获取请求并验证所包含的 API Key。为了实现这一特性,我们需要将以下代码添加至路径中:
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;
}
如果 API Key 正确,则会向 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);
- model 参数指定了用于生成文本的语言模型名称。在本案例中是 text-davinci-003——文本生成领域中最先进的模型。
- prompt 参数声明了要从中生成文本的语言模型文本或上下文信息。我们将从获取请求正文中取得该值。
- temperature 参数控制着已生成文本的随机性。0 值表示文本将是完全确定的,较高的值将带来变化更多、更令人意外的文本。
- max-tokens 参数指定了 token 中生成文本的最大长度(即:单词数后子单词数)。
最后我们将服务器设置为监听 3000 端口:
app.listen(3000, () => {
console.log('Server running on port 3000');
});
完整的 index.js 代码如下:
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');
});
构建宏
首先,我们向服务器发出获取请求:
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>'
})
})
我们在请求正文中声明了 prompt 与 apiKey 值。注意,这些参数将需要根据您要接收的数据和服务器 API Key 变化。
接下来我们将响应解析为 JSON 数据:
.then(response => response.json())
我会根据换行符将相应文本拆分为字符串数组,同时将其目标设置为活动电子表格:
.then(data => {
var arrAllRows = data.split(/\r?\n|\r/);
var wSheet = Api.GetActiveSheet()
之后我们来使用 split() 函数创建一个嵌套循环,对电子表格的行和列进行遍历。此处会使用 SetValue 方法填充各个单元格并修剪空格:
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;
}
完整的宏代码如下:
(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;
}
});
})();
下面我们就打开电子表格编辑器并运行宏!
希望这篇博文中简要介绍的概念能够帮助您提高工作流效率。在此也鼓励您去多多尝试我们提供的各类 API 方法,并将其纳入到日常任务中。
如果您有任何疑问,或是有些想法想要分享,欢迎随时留下评论。我们很乐意聆听您的想法,同时期待着与您开展合作。祝您的探索之旅一帆风顺!