编辑器操作
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
使用 Action 对象在 Google Workspace 加载项中构建互动行为。
操作对象用于定义当用户与插件界面中的 widget(例如按钮)互动时会发生什么。
如需将操作附加到 widget,请使用 widget 处理函数,该函数还会定义触发操作的条件。触发后,该操作会执行指定的回调函数。回调函数会收到一个事件对象,其中包含有关用户客户端互动的信息。您必须实现回调函数,并让其返回特定的响应对象。
如果您想向插件添加一个按钮,该按钮在点击时会构建并显示新卡片,请按以下步骤操作:
- 创建按钮 widget。
- 如需设置卡片构建操作,请添加按钮 widget 处理函数
setOnClickAction(action)
。
- 创建一个要执行的 Apps 脚本回调函数,并将其指定为 widget 处理函数中的
(action)
。在这种情况下,回调函数应构建所需的卡片并返回 ActionResponse
对象。响应对象会告知插件显示回调函数构建的卡片。
以下示例展示了如何创建按钮 widget。该操作代表插件请求当前文件的 drive.file
范围。
/**
* Adds a section to the Card Builder that displays a "REQUEST PERMISSION" button.
* When it's clicked, the callback triggers file scope permission flow. This is used in
* the add-on when the home-page displays basic data.
*/
function addRequestFileScopeButtonToBuilder(cardBuilder) {
var buttonSection = CardService.newCardSection();
// If the add-on does not have access permission, add a button that
// allows the user to provide that permission on a per-file basis.
var buttonAction = CardService.newAction()
.setFunctionName("onRequestFileScopeButtonClickedInEditor");
var button = CardService.newTextButton()
.setText("Request permission")
.setBackgroundColor("#4285f4")
.setTextButtonStyle(CardService.TextButtonStyle.FILLED)
.setOnClickAction(buttonAction);
buttonSection.addWidget(button);
cardBuilder.addSection(buttonSection);
}
/**
* Callback function for a button action. Instructs Docs to display a
* permissions dialog to the user, requesting `drive.file` scope for the
* current file on behalf of this add-on.
*
* @param {Object} e The parameters object that contains the document’s ID
* @return {editorFileScopeActionResponse}
*/
function onRequestFileScopeButtonClickedInEditor(e) {
return CardService.newEditorFileScopeActionResponseBuilder()
.requestFileScopeForActiveDocument().build();
REST API 的文件访问互动
扩展编辑器并使用 REST API 的 Google Workspace 加载项可以包含一个额外的 widget 操作来请求文件访问权限。此操作需要关联的操作回调函数返回一个专用响应对象:
如需使用此 widget 操作和响应对象,必须满足以下所有条件:
- 该插件使用 REST API。
- 插件使用
CardService.newEditorFileScopeActionResponseBuilder().requestFileScopeForActiveDocument().build();
方法显示请求文件范围对话框。
- 该插件在其清单中包含
https://www.googleapis.com/auth/drive.file
编辑器范围和 onFileScopeGranted
触发器。
请求当前文档的文件访问权限
如需为当前文档请求文件访问权限,请按以下步骤操作:
- 构建一个首页卡片,用于检查插件是否具有
drive.file
范围。
- 如果插件尚未获得
drive.file
范围,请构建一种方式来请求用户为当前文档授予 drive.file
范围。
示例:在 Google 文档中获取当前文档访问权限
以下示例构建了一个 Google 文档界面,用于显示当前文档的大小。如果该插件没有 drive.file
授权,则会显示一个按钮来启动文件范围授权。
/**
* Build a simple card that checks selected items' quota usage. Checking
* quota usage requires user-permissions, so this add-on provides a button
* to request `drive.file` scope for items the add-on doesn't yet have
* permission to access.
*
* @param e The event object passed containing information about the
* current document.
* @return {Card}
*/
function onDocsHomepage(e) {
return createAddOnView(e);
}
function onFileScopeGranted(e) {
return createAddOnView(e);
}
/**
* For the current document, display either its quota information or
* a button that allows the user to provide permission to access that
* file to retrieve its quota details.
*
* @param e The event containing information about the current document
* @return {Card}
*/
function createAddOnView(e) {
var docsEventObject = e['docs'];
var builder = CardService.newCardBuilder();
var cardSection = CardService.newCardSection();
if (docsEventObject['addonHasFileScopePermission']) {
cardSection.setHeader(docsEventObject['title']);
// This add-on uses the recommended, limited-permission `drive.file`
// scope to get granular per-file access permissions.
// See: https://developers.google.com/drive/api/v2/about-auth
// If the add-on has access permission, read and display its quota.
cardSection.addWidget(
CardService.newTextParagraph().setText(
"This file takes up: " + getQuotaBytesUsed(docsEventObject['id'])));
} else {
// If the add-on does not have access permission, add a button that
// allows the user to provide that permission on a per-file basis.
cardSection.addWidget(
CardService.newTextParagraph().setText(
"The add-on needs permission to access this file's quota."));
var buttonAction = CardService.newAction()
.setFunctionName("onRequestFileScopeButtonClicked");
var button = CardService.newTextButton()
.setText("Request permission")
.setOnClickAction(buttonAction);
cardSection.addWidget(button);
}
return builder.addSection(cardSection).build();
}
/**
* Callback function for a button action. Instructs Docs to display a
* permissions dialog to the user, requesting `drive.file` scope for the
* current file on behalf of this add-on.
*
* @param {Object} e The parameters object that contains the document’s ID
* @return {editorFileScopeActionResponse}
*/
function onRequestFileScopeButtonClicked(e) {
return CardService.newEditorFileScopeActionResponseBuilder()
.requestFileScopeForActiveDocument().build();
}
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-25。
[null,null,["最后更新时间 (UTC):2025-07-25。"],[[["\u003cp\u003eGoogle Workspace add-ons use Action objects to define interactive behavior triggered by user interactions with UI widgets.\u003c/p\u003e\n"],["\u003cp\u003eAn action's callback function executes when triggered and receives an event object containing interaction details, requiring a specific response object to be returned.\u003c/p\u003e\n"],["\u003cp\u003eAdd-ons extending Editors and using REST APIs can request file access using a widget action with a specialized response object returned by its callback function.\u003c/p\u003e\n"],["\u003cp\u003eRequesting file access involves building a homepage card to check for \u003ccode\u003edrive.file\u003c/code\u003e scope and providing a way for users to grant this scope if needed.\u003c/p\u003e\n"]]],["Action objects enable interactive behavior in Google Workspace add-ons by defining responses to user interactions with widgets. To implement actions, you must define a widget handler function that triggers a callback function upon a specific condition. This callback function then receives an event object with client-side interaction data and must return a specific response object. For file access, add-ons use a specialized response object, `EditorFileScopeActionResponse`, and need `drive.file` scope in the manifest.\n"],null,["# Editor actions\n\nUse [Action](/workspace/add-ons/concepts/actions) objects to build interactive\nbehavior into Google Workspace add-ons.\n\nAction objects define what happens when a user interacts with a widget\n(for example, a button) in the add-on UI.\n\nAdd an action to a widget\n-------------------------\n\nTo attach an action to a widget, use a [widget handler function](/workspace/add-ons/concepts/actions#widget_handler_functions),\nwhich also defines the condition that triggers the action. When triggered, the\naction executes a designated [callback function](/workspace/add-ons/concepts/actions#callback_functions).\nThe callback function is passed an [event object](/workspace/add-ons/concepts/event-objects)\nthat carries information about the user's client-side interactions. You must\nimplement the callback function and have it return a specific response object.\n\n### Example: Display a new card when a button is clicked\n\nIf you want to add a button to your add-on that builds and displays a new card\nwhen clicked, follow the steps below:\n\n1. Create a button [widget](/workspace/add-ons/concepts/widgets#user_interaction_widgets).\n2. To set a card-building action, add the button widget handler function [`setOnClickAction(action)`](/apps-script/reference/card-service/text-button#setOnClickAction(Action)).\n3. Create an Apps Script callback function to execute and specify it as the [`(action)`](/apps-script/reference/card-service/text-button#setOnClickAction(Action)) within the widget handler function. In this case, the callback function should build the card you want and return an [`ActionResponse`](/apps-script/reference/card-service/action-response) object. The response object tells the add-on to display the card the callback function built.\n\nThe following example shows the creation of a button widget. The action requests\nthe `drive.file` scope for the current file on behalf of the add-on. \n\n```gdscript\n/**\n * Adds a section to the Card Builder that displays a \"REQUEST PERMISSION\" button.\n * When it's clicked, the callback triggers file scope permission flow. This is used in\n * the add-on when the home-page displays basic data.\n */\nfunction addRequestFileScopeButtonToBuilder(cardBuilder) {\n var buttonSection = CardService.newCardSection();\n // If the add-on does not have access permission, add a button that\n // allows the user to provide that permission on a per-file basis.\n var buttonAction = CardService.newAction()\n .setFunctionName(\"onRequestFileScopeButtonClickedInEditor\");\n\n var button = CardService.newTextButton()\n .setText(\"Request permission\")\n .setBackgroundColor(\"#4285f4\")\n .setTextButtonStyle(CardService.TextButtonStyle.FILLED)\n .setOnClickAction(buttonAction);\n\n buttonSection.addWidget(button);\n cardBuilder.addSection(buttonSection);\n}\n\n/**\n * Callback function for a button action. Instructs Docs to display a\n * permissions dialog to the user, requesting `drive.file` scope for the \n * current file on behalf of this add-on.\n *\n * @param {Object} e The parameters object that contains the document's ID\n * @return {editorFileScopeActionResponse}\n */\nfunction onRequestFileScopeButtonClickedInEditor(e) {\n return CardService.newEditorFileScopeActionResponseBuilder()\n .requestFileScopeForActiveDocument().build();\n```\n\nFile access interactions for REST APIs\n--------------------------------------\n\nGoogle Workspace add-ons that extend the Editors and use REST APIs can include an\nadditional widget action to request file access. This action requires the\nassociated action callback function to return a specialized response object:\n\n| Action attempted | Callback function should return |\n|---------------------------------------------------------------------------------------|---------------------------------|\n| [Request file access for current_document](#request_file_access_for_current_document) | `EditorFileScopeActionResponse` |\n\nTo make use of this widget action and response object, all of the following must\nbe true:\n\n- The add-on uses REST APIs.\n- The add-on presents the request file scope dialog using the `CardService.newEditorFileScopeActionResponseBuilder().requestFileScopeForActiveDocument().build();` method.\n- The add-on includes the `https://www.googleapis.com/auth/drive.file` editor scope and `onFileScopeGranted` trigger in its manifest.\n\n### Request file access for current document\n\nTo request file access for the current document, follow these steps:\n\n1. Build a homepage card that checks whether the add-on has `drive.file` scope.\n2. For cases where the add-on hasn't been granted `drive.file` scope, build a way to request that users grant `drive.file` scope for the current document.\n\n#### Example: Get current document access in Google Docs\n\nThe following example builds an interface for Google Docs that displays the size\nof the current document. If the add-on doesn't have `drive.file` authorization,\nit displays a button to initiate the file scope authorization. \n\n /**\n * Build a simple card that checks selected items' quota usage. Checking\n * quota usage requires user-permissions, so this add-on provides a button\n * to request `drive.file` scope for items the add-on doesn't yet have\n * permission to access.\n *\n * @param e The event object passed containing information about the\n * current document.\n * @return {Card}\n */\n function onDocsHomepage(e) {\n return createAddOnView(e);\n }\n\n function onFileScopeGranted(e) {\n return createAddOnView(e);\n }\n\n /**\n * For the current document, display either its quota information or\n * a button that allows the user to provide permission to access that\n * file to retrieve its quota details.\n *\n * @param e The event containing information about the current document\n * @return {Card}\n */\n function createAddOnView(e) {\n var docsEventObject = e['docs'];\n var builder = CardService.newCardBuilder();\n\n var cardSection = CardService.newCardSection();\n if (docsEventObject['addonHasFileScopePermission']) {\n cardSection.setHeader(docsEventObject['title']);\n // This add-on uses the recommended, limited-permission `drive.file`\n // scope to get granular per-file access permissions.\n // See: https://developers.google.com/drive/api/v2/about-auth\n // If the add-on has access permission, read and display its quota.\n cardSection.addWidget(\n CardService.newTextParagraph().setText(\n \"This file takes up: \" + getQuotaBytesUsed(docsEventObject['id'])));\n } else {\n // If the add-on does not have access permission, add a button that\n // allows the user to provide that permission on a per-file basis.\n cardSection.addWidget(\n CardService.newTextParagraph().setText(\n \"The add-on needs permission to access this file's quota.\"));\n\n var buttonAction = CardService.newAction()\n .setFunctionName(\"onRequestFileScopeButtonClicked\");\n\n var button = CardService.newTextButton()\n .setText(\"Request permission\")\n .setOnClickAction(buttonAction);\n\n cardSection.addWidget(button);\n }\n return builder.addSection(cardSection).build();\n }\n\n /**\n * Callback function for a button action. Instructs Docs to display a\n * permissions dialog to the user, requesting `drive.file` scope for the\n * current file on behalf of this add-on.\n *\n * @param {Object} e The parameters object that contains the document's ID\n * @return {editorFileScopeActionResponse}\n */\n function onRequestFileScopeButtonClicked(e) {\n return CardService.newEditorFileScopeActionResponseBuilder()\n .requestFileScopeForActiveDocument().build();\n }"]]