由于 Apps Script 项目位于 Google 云端硬盘上,因此开发者可以使用 Google Drive API(请勿与 Apps Script 中的 Drive 服务混淆)导入和导出 Apps Script 源代码。
例如,开发者可以使用自己喜爱的代码编辑器在本地计算机上编写新的 Apps Script 代码,并使用 Git 等版本控制系统与其他开发者协作。确定版本后,她可以使用 REST API 将文件上传(导入)到 Google 云端硬盘,在那里,这些文件的使用方式与任何其他 Apps 脚本项目一样。
您可以在本地版本中进行代码更改,并使用 Google Drive API 将更改同步到 Apps 脚本项目。您可以将现有项目从 Google 云端硬盘下载(导出)到本地计算机。
功能和限制
如果您想使用 Google Drive API 导入或导出项目,请注意以下事项:
- 服务器端脚本文件应以“.gs”结尾。您可能希望使用 .js 文件在本地进行开发,但请务必在导入 Google 云端硬盘之前重命名为包含 .gs 扩展名的文件。
- 客户端脚本文件的扩展名必须为“.html”。这包括客户端 .html、.js 或 .css 文件。再次提醒一下,您可以使用其他扩展程序在本地进行开发,但请务必先将扩展程序改为 .html 扩展名,然后再导入到 Google 云端硬盘。
- 将项目文件导入 Google 云端硬盘后,这些文件中的所有现有数据都将被覆盖。您无法附加或插入部分文本;必须更新整个文件。
- 服务器端脚本文件必须包含有效的 JavaScript。如果服务器 .js 文件中存在错误,Google Drive API 更新调用将失败并显示 5xx 错误。您可以通过在导入之前对代码进行 lint 检查来防止这种情况。
- 无法导入空文件。如果您尝试上传空文件,Google 云端硬盘 API 更新调用将失败并返回 5xx 错误。
- 只能导入或导出独立脚本。您无法通过 Google Drive API 访问绑定到容器的脚本。
- 只能导入或导出源代码。项目属性或日志等资源也不会通过 Google Drive API 公开。您无法通过 Google Drive API 执行脚本版本控制、发布或执行脚本等操作。
- 您不必局限于单个服务器
Code.gs
文件。您可以将服务器代码分散到多个文件中,以便于开发。所有服务器文件都会加载到同一全局命名空间中,因此,如果您想提供安全的封装,请使用 JavaScript 类。
Drive API
借助 Google Drive API,开发者可以通过编程方式访问 Google 云端硬盘中的文件。此 API 使用 GET
下载文件,使用 PUT/POST
上传文件。如需查看详细文档和快速入门,请参阅 Google Drive API 概览页面。
本指南将重点介绍如何使用以下调用通过 Files 资源列出和移动文件:
授权
向 Google Drive API 发出的所有请求都必须由经过身份验证的用户通过 OAuth 2.0 协议授权。如需了解详情,请参阅 Google Drive API 授权文档。
除了应用可能需要的其他范围(例如 https://www.googleapis.com/auth/drive
)之外,所有尝试导入或导出 Google Apps 脚本项目的应用都必须请求以下特殊范围:
https://www.googleapis.com/auth/drive.scripts
列出现有项目
如需列出云端硬盘中的所有 Apps Script 项目,请使用 Files 资源查询 MIME 类型为 application/vnd.google-apps.script
的文件。如需过滤响应以仅包含您拥有的文件,请添加搜索参数 'me' in owners
。
以下是请求和响应示例,显示了通过 JSON 响应返回的 Apps Script 项目数组。
GET https://www.googleapis.com/drive/v2/files?q=mimeType%3D'application%2Fvnd.google-apps.script'+and+'me'+in+owners Authorization: Bearer ya29.fakebearerstring
{ "kind": "drive#fileList", "etag": "\"kjsas92/f3zGUXczKMxEB_9ZTMRFOF3d1ZU\"", "selfLink": "https://www.googleapis.com/drive/v2/files?q=mimeType%3D'application/vnd.google-apps.script'+and+'me'+in+owners", "items": [ { "kind": "drive#file", "id": "1vi0uwcMdHsRv1YFtgq7XdiTGSdqgjIYpdQNC0A_Udn79LOhH0vYL132D", "etag": "\"kjsas92/MTM3MDk3ODY5ODQyNg\"", "selfLink": "https://www.googleapis.com/drive/v2/files/1vi0uwcMdHsRv1YFtgq7XdiTGSdqgjIYpdQNC0A_Udn79LOhH0vYL132D", "alternateLink": "https://script.google.com/a/google.com/d/1vi0uwcMdHsRv1YFtgq7XdiTGSdqgjIYpdQNC0A_Udn79LOhH0vYL132D/edit?usp=drivesdk", "iconLink": "https://ssl.gstatic.com/docs/doclist/images/icon_11_script_list.png", "title": "Mail merge", "mimeType": "application/vnd.google-apps.script", "description": "", "labels": { "starred": false, "hidden": false, "trashed": true, "restricted": false, "viewed": true }, "createdDate": "2013-06-11T19:24:45.188Z", "modifiedDate": "2013-06-11T19:24:58.426Z", "modifiedByMeDate": "2013-06-11T19:24:58.426Z", "lastViewedByMeDate": "2013-06-11T19:24:58.426Z", "parents": [ { "kind": "drive#parentReference", "id": "0APdyIOzo7bWDUk9PVA", "selfLink": "https://www.googleapis.com/drive/v2/files/1vi0uwcMdHsRv1YFtgq7XdiTGSdqgjIYpdQNC0A_Udn79LOhH0vYL132D/parents/0APdyIOzo7bWDUk9PVA", "parentLink": "https://www.googleapis.com/drive/v2/files/0APdyIOzo7bWDUk9PVA", "isRoot": true } ], "exportLinks": { "application/json": "https://script.google.com/feeds/download/export?id=1234567890abcefghijklmnopqrstuvwxyz&format=json" }, "userPermission": { "kind": "drive#permission", "etag": "\"kjsas92/259X2r5DVstv1CcIQTjt_RQPSW8\"", "id": "me", "selfLink": "https://www.googleapis.com/drive/v2/files/1vi0uwcMdHsRv1YFtgq7XdiTGSdqgjIYpdQNC0A_Udn79LOhH0vYL132D/permissions/me", "role": "owner", "type": "user" }, "quotaBytesUsed": "0", "ownerNames": [ "John Doe" ], "owners": [ { "kind": "drive#user", "displayName": "John Doe", "picture": { "url": "https://lh4.googleusercontent.com/-yd1rIb6Pe2Y/AAAAAAAAAAI/AAAAAAAAAGs/PP5vTuZonik/s64/photo.jpg" }, "isAuthenticatedUser": true, "permissionId": "1234566789" } ], "lastModifyingUserName": "John Doe", "lastModifyingUser": { "kind": "drive#user", "displayName": "John Doe", "picture": { "url": "https://lh4.googleusercontent.com/-yd1rIb6Pe2Y/AAAAAAAAAAI/AAAAAAAAAGs/PP5vTuZonik/s64/photo.jpg" }, "isAuthenticatedUser": true, "permissionId": "1234566789" }, "editable": true, "writersCanShare": true, "shared": false, "explicitlyTrashed": true, "appDataContents": false } ] }
如果您知道某个 Apps 脚本项目的文件 ID,则可以使用以下 API 调用直接提取该文件:
GET https://www.googleapis.com/drive/v2/files/1234567890abcefghijklmnopqrstuvwxyz
Authorization: Bearer ya29.fakebearerstring
从云端硬盘导出项目
从 API 返回 File
资源后,exportLinks
属性将包含一个网址,用于提取项目内容以 JSON 数据的形式。此网址可能如下所示:
https://script.google.com/feeds/download/export?id=1234567890abcefghijklmnopqrstuvwxyz&format=json
向此网址发出请求以检索项目本身的内容。确保您添加的 Authorization
标头包含相同的 OAuth Bearer
令牌
以下是请求和响应示例:
GET https://script.google.com/feeds/download/export?id=1234567890abcefghijklmnopqrstuvwxyz&format=json Authorization: Bearer ya29.fakebearerstring
{ "files": [ { "id":"9basdfbd-749a-4as9b-b9d1-d64basdf803", "name":"Code", "type":"server_js", "source":"function doGet() {\n return HtmlService.createHtmlOutputFromFile(\u0027index\u0027);\n}\n" }, { "id":"3asf7c0d-1afb-4a9-8431-5asdfc79e7ae", "name":"index", "type":"html", "source":"\u003chtml\u003e\n \u003cbody\u003e\n Hello, world!\n \u003c/body\u003e\n\u003c/html\u003e" } ] }
上述示例包含 HTML Service 指南中的一个简单 Web 应用的代码。请注意,您会收到一个 Files
数组,每个 Files
都具有以下 4 个属性:
id |
项目中文件的内部标识符,用于在更新期间引用此文件。 |
name |
不带扩展名的文件名,如脚本编辑器中所显示。 |
type |
这两种文件分别是 server_js 和 html。 |
source |
文件中包含的编码源代码。 |
将项目导入云端硬盘
如需更新现有项目,请使用适当的 fileId
对文件 update
API 进行 HTTP PUT
调用。以下示例展示了媒体上传部分的示例事务。使用某个客户端库,您的应用可以轻松地在同一上传调用中包含元数据和媒体内容。请注意,在本例中,Content-Type
标头用于指定上传内容的类型。
PUT https://www.googleapis.com/upload/drive/v2/files/1234567890abcefghijklmnopqrstuvwxyz Authorization: Bearer ya29.fakebearerestring Content-Type: application/vnd.google-apps.script+json
{ "files": [ { "id":"9basdfbd-749a-4as9b-b9d1-d64basdf803", "name":"Code", "type":"server_js", "source":"function doGet() {\n return HtmlService.createHtmlOutputFromFile(\u0027index\u0027);\n}\n" }, { "id":"3asf7c0d-1afb-4a9-8431-5asdfc79e7ae", "name":"index", "type":"html", "source":"\u003chtml\u003e\n \u003cbody\u003e\n New message!!\n \u003c/body\u003e\n\u003c/html\u003e" } ] }
在项目中创建新文件
如需在项目中创建新文件,请发送一个不含 id
属性的文件 PUT
请求。如果您添加的文件包含未知标识符,系统会抛出错误消息。
删除项目中的文件
如需从项目中删除文件,请发送不包含该文件(但包含项目中的所有其他文件)的 PUT
请求。导入过程中未发回的任何文件都将从服务器中删除。
重命名项目中的文件
如需重命名项目中的文件,请发送 PUT
请求,其中包含现有的 id
但使用新的 name
。请注意,服务器会忽略任何尝试更改为 type
的操作。
新建项目
如需创建新项目,请向文件 insert
API 发送 POST
请求。与 update
调用非常相似,您可以使用客户端库添加项目名称和说明等元数据。
以下是媒体上传的示例交易。这将在您的云端硬盘中创建一个名为“Untitled”的项目。网址中的 convert
参数为必需参数。与 update
调用一样,Content-Type
标头是必需的。
POST https://www.googleapis.com/upload/drive/v2/files?convert=true Authorization: Bearer ya29.fakebearerestring Content-Type: application/vnd.google-apps.script+json
{ "files": [ { "name":"Code", "type":"server_js", "source":"function doGet() {\n return HtmlService.createHtmlOutputFromFile(\u0027index\u0027);\n}\n" }, { "name":"index", "type":"html", "source":"\u003chtml\u003e\n \u003cbody\u003e\n Hello, world!!\n \u003c/body\u003e\n\u003c/html\u003e" } ] }