无法通过node. aspx API运行apps脚本函数-找不到请求的实体

nszi6y05  于 2023-06-29  发布在  Node.js
关注(0)|答案(1)|浏览(73)

我想通过从node.js服务调用来运行Google Apps Script函数。
我已经在Google Cloud Console中启用了应用程序脚本API,创建了一个应用程序脚本项目,将其与我的服务帐户共享,并在www.example.com中创建了一个函数Code.gs,并将脚本部署为API可执行文件。
Code.gs

function myFunction() {
   return "hello world";
}

当我尝试从node.js服务调用函数时:

const { script } = await Google.getInstance();
  const request = {
    scriptId: '<my_script_id>',
    resource: {
      function: 'myFunction'
    }
  };
  const response = await script.scripts.run(request);

我得到以下错误:
API调用失败:GaxiosError:未找到请求的实体。
谷歌搜索表明这是一个权限问题,我的服务帐户没有该项目的权限。但是为了测试这是否是真的,我尝试了另一个API调用

const { script } = await Google.getInstance();
const response = await script.projects.get({
  scriptId: '<my_script_id>',
});

它成功地返回了我的项目的元数据:

{
  scriptId: '<my_script_id>',
  title: 'test 123',
  createTime: '2023-06-22T12:39:57.644Z',
  updateTime: '2023-06-22T12:55:56.291Z',
  creator: { photoUrl: 'https://lh3.googleusercontent.com/a/default-user=h128' },
  lastModifyUser: { photoUrl: 'https://lh3.googleusercontent.com/a/default-user=h128' }
}

这让我相信scriptId是正确的。
我还尝试取消与我的服务帐户共享项目,并再次调用script.projects.get函数,然后我得到另一个错误The caller does not have permission-但我仍然得到相同的Requested entity was not found错误,为什么调用script.scripts.run函数。
当我安装谷歌客户端时,我只添加了script.projects到范围:

const auth = new google.auth.GoogleAuth({
  keyFile: `${root}/config/google/credentials.json`,
  scopes: [
    'https://www.googleapis.com/auth/documents',
    'https://www.googleapis.com/auth/drive',
    'https://www.googleapis.com/auth/presentations',
    'https://www.googleapis.com/auth/script.projects',
    'https://www.googleapis.com/auth/spreadsheets'
  ]
});

这是在文档中的某个地方建议的,我还没有看到任何这样的示例:https://www.googleapis.com/auth/scripthttps://www.googleapis.com/auth/script.scripts。但我确实试图添加它们是为了实验。但这会创建一个无效的auth对象。无论我尝试使用包含任何一个的auth对象发出什么请求,我都会得到:Invalid Credentials
在谷歌自己的文档中,他们使用了一个auth对象,其作用域仅设置为drive,我认为这一定是一个错误。- 该文档中还有TODO注解,因此我认为它不可用。
你知道可能出了什么问题吗?谢谢你!

svdrlsy4

svdrlsy41#

我相信你的目标如下。

  • 您希望使用googleapis for Node.js的服务帐户运行Google Apps Script。

问题及解决方法:

在目前阶段,不幸的是,执行方法(Method:scripts.run)不能与服务帐户一起使用。官方文件如下所示,Ref
警告:Apps Script API不适用于服务帐户。
另一方面,方法“方法:projects.get”except for“方法:scripts.run”可以与服务帐户一起使用。我猜这就是你目前的情况,这就是你目前问题的原因。
但是,我认为有一种方法可以使用Googleapis for Node.js的服务帐户执行Google Apps Script,当Apps Script API未使用时。在这种情况下,作为一种变通方法,我建议使用Web Apps。当使用Web Apps时,用法如下。

用法:

1.准备Google Apps Script项目。

作为示例脚本,请将以下示例脚本复制并粘贴到脚本编辑器。

const doGet = e => ContentService.createTextOutput(JSON.stringify(e));
const doPost = e => ContentService.createTextOutput(JSON.stringify(e));

2.与服务账号共享Google Apps Script项目。

请以编写者身份与服务帐户共享上述Google Apps脚本项目。

3.部署Web应用。

详细的信息可以在官方文件中看到。
请使用脚本编辑器的新IDE进行设置。
1.在脚本编辑器上,在脚本编辑器的右上角,请单击“单击部署”->“新建部署”。
1.请点击“选择类型”->“Web App”。
1.请在“部署配置”下的字段中输入有关Web App的信息。
1.* * 执行方式请选择我**。

  • 请选择**“任何人与谷歌帐户”“谁有权访问”**。
  • 通过此设置,当您访问Web应用时,需要使用访问令牌。
  • 请单击“部署”按钮。
  • 当显示“Web App要求您授权访问您的数据”时,请单击“授权访问”按钮。还有,请授权使用望远镜。
  • 复制Web App的URL。就像https://script.google.com/macros/s/###/exec一样。此URL用于执行Google Apps脚本。
    **当您修改Web Apps的Google Apps脚本时,请将部署修改为新版本。这样,修改后的脚本将反映在Web Apps中。请注意这一点。**您可以在我的报告“Redeploying Web Apps without Changing URL of Web Apps for new IDE (Author: me)”中看到详细信息。

4.测试。

此示例脚本修改为my answer

const HTTPS = require("https");
const { google } = require("googleapis");

const webAppsURL = "https://script.google.com/macros/s/###/exec"; // Please set your Web Apps URL.

const auth = new google.auth.JWT(
  "###", // Please set client_email here.
  null,
  "-----BEGIN PRIVATE KEY-----\n###-----END PRIVATE KEY-----\n", // Please set private_key here,
  ["https://www.googleapis.com/auth/drive.readonly"],
  null
);

function req(token) {
  return new Promise((resolve, reject) => {
    const data = "sample value"; // This is a sample value.
    const options = {
      method: "POST",
      headers: { Authorization: "Bearer " + token },
    };
    const req = HTTPS.request(`${webAppsURL}?value=${data}`, options, (res) => {
      if (res.statusCode == 302) {
        HTTPS.get(res.headers.location, (res) => {
          if (res.statusCode == 200) {
            res.setEncoding("utf8");
            res.on("data", (r) => resolve(r));
          }
        });
      } else {
        res.setEncoding("utf8");
        res.on("data", (r) => resolve(r));
      }
    });
    req.on("error", (e) => {
      reject(e.message);
    });
    req.write(JSON.stringify(data));
    req.end();
  });
}

auth.getAccessToken().then(({ token }) => {
  req(token).then((e) => console.log(e)).catch((e) => console.log(e));
});
  • 在这种情况下,https://www.googleapis.com/auth/drive.readonly的作用域可用于访问Web Apps。
  • 使用method: "POST"运行此脚本时,将返回以下响应。在这种情况下,数据可以作为文本类型包括在请求主体中。
{"postData":{"contents":"\"sample value\"","length":14,"name":"postData","type":""},"parameter":{"value":"sample value"},"contextPath":"","parameters":{"value":["sample value"]},"queryString":"value=sample%20value","contentLength":14}
  • 使用method: "GET"运行此脚本时,将返回以下响应。在GET方法的情况下,只使用查询参数。请小心这件事。
{"parameters":{"value":["sample value"]},"contentLength":-1,"parameter":{"value":"sample value"},"contextPath":"","queryString":"value=sample%20value"}

注意:

*当您修改Web Apps的Google Apps脚本时,请将部署修改为新版本。这样,修改后的脚本将反映在Web Apps中。请注意这一点

参考资料:

相关问题