Ủy quyền API Google Apps Script cho DriveApp.getFileById

Oct 07 2020

Tôi có Dự án nền tảng đám mây của Google (GCP) chạy trực tiếp hầu hết tất cả các tập lệnh / chức năng, nhưng một số thông qua API. Mọi thứ chỉ có thể truy cập nội bộ đối với miền G Suite và Loại ứng dụng trên màn hình chấp thuận OAuth là "Nội bộ".

Tôi có một tập lệnh, không được gọi qua API mà trực tiếp trên bộ hẹn giờ cứ x phút một lần. Nó thực hiện một

DriveApp.getFileByID(pictureID)

Điều này hoạt động tuyệt vời! Không vấn đề gì.

Tôi cũng có một tập lệnh khác, trong cùng một Dự án GCP, tập lệnh này thay vì chạy được kích hoạt bởi bộ đếm thời gian, lại chạy bằng cách được gọi thông qua một API. Đây là dòng mã gọi nó (không thực sự quan trọng):

var result = UrlFetchApp.fetch(url, options);

Tập lệnh API chạy tuyệt vời! Cho đến khi nó đi đến các dòng sau:

      try { var file = DriveApp.getFileById(pictureID); }
      catch (e) {
        Logger.log('e = ' + JSON.stringify(e));
        return;
      }

Kết quả của nhật ký là

e = {"name":"Exception"}

Tôi đã xác minh rằng ID hình ảnh giống như ID hình ảnh trong tập lệnh không phải API hoạt động. Tôi đang thực hiện "thử" trong tập lệnh chạy API này để đảm bảo rằng phần mềm có quyền truy cập vào tệp chứ không phải truy cập thực sự.

Tôi khá chắc chắn rằng đây là vấn đề ủy quyền. Tôi chỉ mới sử dụng GCP được một thời gian, có một số kinh nghiệm về ủy quyền, nhưng không nhiều.

Dưới đây là một số chi tiết xung quanh việc ủy ​​quyền ...

Tập lệnh của dự án Thuộc tính dự án (Thuộc tính tệp / dự án) cho thấy rằng nó cần các Phạm vi OAuth sau:

Theo tài liệu của Google tại https://developers.google.com/apps-script/reference/drive/drive-app#getfilebyidid,

Scripts that use this method require authorization with one or more of the following scopes: 

https://www.googleapis.com/auth/drive.readonly
https://www.googleapis.com/auth/drive

Dưới đây là các phạm vi mà tôi đã xác định bây giờ trên màn hình chấp thuận GCP Oauth:

Như bạn có thể thấy, tôi đã thêm drive, drive.readonly, & drive.file (dường như không thực sự cần thiết).

Trên hết, tệp hình ảnh cụ thể này được lưu trữ trong Google Drive của chủ sở hữu Dự án GCP, tập lệnh và quản trị viên cấp cao nhất của miền G Suite. Điều đó sẽ không phải lúc nào cũng đúng, vì người dùng sẽ chia sẻ hình ảnh từ Google Drive của riêng họ với chủ sở hữu phần mềm / GCP này. Tuy nhiên, tôi có cảm giác rằng ngay cả bây giờ tập lệnh được kích hoạt bởi bộ đếm thời gian sẽ hoạt động với các tệp do người dùng chia sẻ đó, nhưng không phải tập lệnh được gọi thông qua một API.

Tôi khá chắc rằng đây là vấn đề về Auth, nhưng tôi đang thiếu thứ gì đó ở đâu đó.

Cảm ơn sự giúp đỡ của bạn!

Cập nhật:

Đây là mã từ tập lệnh GỌI tập lệnh API (đã thay đổi một số để bảo mật), vì tôi đang tự hỏi liệu có lẽ vấn đề có thể không nằm ở phía máy khách / bên gọi hay không. Có lẽ tôi nhận được OAuthToken không chính xác? Hoặc mã thông báo không có quyền chính xác?

  var token = ScriptApp.getOAuthToken();
  
  var header = {
    "Content-Type": "application/json",
    "Authorization": "Bearer " + token,
  };
  
  var parms = [id];
  
  var data = {
    "function": "updateSettings",
    "parameters": parms,
    "devMode": true,
  }
  
  var options = {
    "method":"POST",
    "headers": header,
    "muteHttpExceptions": true,
    "payload": JSON.stringify(data)
  };
  
  // Call the API
  var result = UrlFetchApp.fetch(url, options);

Trả lời

Chris Oct 07 2020 at 22:27

Tôi đã tìm ra nó sau khi liên hệ với Google và rất tiếc là không nhận được nhiều sự trợ giúp và thêm vài giờ cố gắng và nghiên cứu ...

Điều tôi còn thiếu là thêm "oathScope" vào tệp kê khai / appsscript.json. Tôi đã thử với các phạm vi cần thiết và kết thúc với hai phạm vi sau được hiển thị bên dưới. Tôi đã tìm ra giải pháp bằng cách xem câu trả lời sau: Sử dụng AuthToken có được qua ScriptApp.getAuthToken () để gọi các ứng dụng web trong GAS .

Bên trong trình chỉnh sửa tập lệnh, đi tới Xem / Hiển thị tệp kê khai.

Đây là những gì nó trông giống như trước đây:

{
  "timeZone": "America/New_York",
  "dependencies": {
  },
  "webapp": {
    "access": "MYSELF",
    "executeAs": "USER_DEPLOYING"
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}

và đây là những gì nó trông như bây giờ ...

{
  "timeZone": "America/New_York",
  "dependencies": {
  },
  "webapp": {
    "access": "MYSELF",
    "executeAs": "USER_DEPLOYING"
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/drive",
    "https://www.googleapis.com/auth/script.external_request"
    ]
}

Sau khi thêm, tôi đã lưu appsscript.json. Sau đó, tôi đã truy cập trình kích hoạt runOnEdit của mình (tập lệnh gọi), xóa và thêm lại nó. Tuy nhiên, điều đó gây ra một lỗi trông khó chịu:

Tôi đã tra cứu và tìm thấy bài đăng này: Lỗi nhận được khi tạo trình kích hoạt mới trên Apps Script . Vì vậy, tôi đã chạy mã trong trình chỉnh sửa tập lệnh, và thực sự nó hiển thị màn hình xác thực. Tôi đã chấp thuận, thêm lại trình kích hoạt và bây giờ mọi thứ hoạt động tốt khi gọi API!