### Install and start the Node.js app Source: https://developers.google.com/workspace/add-ons/chat/quickstart-pubsub Install dependencies and start the Node.js application to listen for Pub/Sub messages. ```bash npm install npm start ``` -------------------------------- ### Install Add-on Deployment Source: https://developers.google.com/workspace/add-ons/quickstart/alternate-runtimes Installs the 'quickstart' Google Workspace add-on deployment in development mode. ```bash gcloud workspace-add-ons deployments install quickstart ``` -------------------------------- ### Call onOpen from onInstall Source: https://developers.google.com/workspace/add-ons/concepts/editor-auth-lifecycle Use the `onInstall` function to call `onOpen` and perform additional setup when an add-on is installed. This ensures menus are created and initial configurations are run. ```javascript function onInstall(e) { onOpen(e); // Perform additional setup as needed. } ``` -------------------------------- ### Handle Add-on Installation Source: https://developers.google.com/workspace/add-ons/samples/clean-sheet This function is called when the add-on is installed. It ensures that the `onOpen` function is called immediately to create the necessary menu entries and perform any other initial setup. ```javascript /** * Runs when the add-on is installed; calls onOpen() to ensure menu creation and * any other initializion work is done immediately. This method is only used by * the desktop add-on and is never called by the mobile version. * * @param {object} e The event parameter for a simple onInstall trigger. */ function onInstall(e) { onOpen(e); } ``` -------------------------------- ### Install Deployment Source: https://developers.google.com/workspace/add-ons/reference/rest Installs a deployment to your account for testing. ```APIDOC ## POST /v1/{name=projects/*/deployments/*}:install ### Description Installs a deployment to your account for testing. ### Method POST ### Endpoint /v1/{name=projects/*/deployments/*}:install ``` -------------------------------- ### Complete Custom Resource Example Source: https://developers.google.com/workspace/add-ons/studio/custom-resources A comprehensive example demonstrating the configuration and message handling for custom resources, including resource retrieval and execution functions. ```javascript function onConfigResourceFunction() { let section = CardService.newCardSection() .addWidget( CardService.newTextParagraph() .setText("This is the Custom Resource Demo card") ); const card = CardService.newCardBuilder() .addSection(section) .build(); return card; } function onMessageResourceFunction(e) { console.log("Payload in onMessageResourceFunction: " + JSON.stringify(e)); var resource_id = e.workflow.resourceRetrieval.resourceReference.resourceId; let fieldValue_1; let fieldValue_2; // Using a if-condition to mock a database call. if (resource_id == "sample_resource_reference_id") { fieldValue_1 = AddOnsResponseService.newVariableData() .addStringValue("value1"); fieldValue_2 = AddOnsResponseService.newVariableData() .addStringValue("value2"); } else { fieldValue_1 = AddOnsResponseService.newVariableData() .addStringValue("field_1 value not found"); fieldValue_2 = AddOnsResponseService.newVariableData() .addStringValue("field_2 value not found"); } let resourceData = AddOnsResponseService.newResourceData() .addVariableData("field_1", fieldValue_1) .addVariableData("field_2", fieldValue_2) let workflowAction = AddOnsResponseService.newResourceRetrievedAction() .setResourceData(resourceData) let hostAppAction = AddOnsResponseService.newHostAppAction() .setWorkflowAction(workflowAction); return AddOnsResponseService.newRenderActionBuilder() .setHostAppAction(hostAppAction) .build(); } function onExecuteResourceFunction(e) { console.log("Payload in onExecuteResourceFunction: " + JSON.stringify(e)); let outputVariables = AddOnsResponseService.newVariableData() .addResourceReference("sample_resource_reference_id"); let workflowAction = AddOnsResponseService.newReturnOutputVariablesAction() .addVariableData("resource_data", outputVariables); let hostAppAction = AddOnsResponseService.newHostAppAction() .setWorkflowAction(workflowAction); return AddOnsResponseService.newRenderActionBuilder() .setHostAppAction(hostAppAction) .build(); } ``` -------------------------------- ### Java Conversion Example Source: https://developers.google.com/workspace/add-ons/reference/rpc/google.type Example demonstrating how to convert between the `com.google.type.Color` protocol buffer and `java.awt.Color` in Java. ```APIDOC ## Java Conversion Example ```java import com.google.type.Color; // ... public static java.awt.Color fromProto(Color protocolor) { float alpha = protocolor.hasAlpha() ? protocolor.getAlpha().getValue() : 1.0; return new java.awt.Color( protocolor.getRed(), protocolor.getGreen(), protocolor.getBlue(), alpha); } public static Color toProto(java.awt.Color color) { float red = (float) color.getRed(); float green = (float) color.getGreen(); float blue = (float) color.getBlue(); float denominator = 255.0; Color.Builder resultBuilder = Color .newBuilder() .setRed(red / denominator) .setGreen(green / denominator) .setBlue(blue / denominator); int alpha = color.getAlpha(); if (alpha != 255) { result.setAlpha( FloatValue .newBuilder() .setValue(((float) alpha) / denominator) .build()); } return resultBuilder.build(); } // ... ``` ``` -------------------------------- ### Install and Deploy ADK Agent Source: https://developers.google.com/workspace/add-ons/chat/quickstart-a2ui-agent Set up a Python virtual environment, install project dependencies using Poetry, and deploy the ADK agent. The `--create` flag initiates the deployment process. ```bash python3 -m venv myenv source myenv/bin/activate poetry install --with deployment python3 deployment/deploy.py --create ``` -------------------------------- ### projects.deployments.install Source: https://developers.google.com/workspace/add-ons/reference/rest/v1/projects.deployments/install Installs a deployment to your account for testing. ```APIDOC ## POST https://gsuiteaddons.googleapis.com/v1/{name=projects/*/deployments/*}:install ### Description Installs a specified add-on deployment to your account for testing purposes. ### Method POST ### Endpoint `https://gsuiteaddons.googleapis.com/v1/{name=projects/*/deployments/*}:install` ### Path Parameters * **name** (string) - Required. The full resource name of the deployment to install. Example: `projects/my_project/deployments/my_deployment`. ### Request Body The request body must be empty. ### Response Body If successful, the response body is an empty JSON object. ### Authorization Scopes * `https://www.googleapis.com/auth/cloud-platform` ``` -------------------------------- ### Install Deployment Source: https://developers.google.com/workspace/add-ons/reference/rpc/google.cloud.gsuiteaddons.v1 Installs a Google Workspace Add-on deployment for testing purposes. ```APIDOC ## InstallDeployment ### Description Installs a Google Workspace Add-on deployment for testing purposes. ### Method POST ### Endpoint /v1/{name=deployments/*}:install ### Parameters #### Path Parameters - **name** (string) - Required - The name of the deployment to install. #### Request Body - **addOnId** (string) - Required - The ID of the add-on to install. - **addressee** (string) - Required - The email address of the user to install the add-on for. ### Response #### Success Response (200) - **installStatus** (InstallStatus) - The status of the installation. #### Response Example ```json { "installStatus": { "state": "INSTALLED" } } ``` ``` -------------------------------- ### iOS/Obj-C Conversion Example Source: https://developers.google.com/workspace/add-ons/reference/rpc/google.type Example demonstrating how to convert between the `Color` protocol buffer and `UIColor` in iOS using Objective-C. ```APIDOC ## iOS/Obj-C Conversion Example ```objc // ... static UIColor* fromProto(Color* protocolor) { float red = [protocolor red]; float green = [protocolor green]; float blue = [protocolor blue]; FloatValue* alpha_wrapper = [protocolor alpha]; float alpha = 1.0; if (alpha_wrapper != nil) { alpha = [alpha_wrapper value]; } return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; } static Color* toProto(UIColor* color) { CGFloat red, green, blue, alpha; if (![color getRed:&red green:&green blue:&blue alpha:&alpha]) { return nil; } Color* result = [[Color alloc] init]; [result setRed:red]; [result setGreen:green]; [result setBlue:blue]; if (alpha <= 0.9999) { [result setAlpha:floatWrapperWithValue(alpha)]; } [result autorelease]; return result; } // ... ``` ``` -------------------------------- ### Example: Support case add-on manifest Source: https://developers.google.com/workspace/add-ons/guides/preview-links-smart-chips This is an example manifest for a Google Workspace add-on that supports link previews for support cases. ```json { "timeZone": "America/Los_Angeles", "dependencies": { "enabledAdvancedServices": [ { "userSymbol": "Drive", "serviceId": "drive", "version": "v2" } ] }, "exceptionLogging": "STACKDRIVER", "runtimeVersion": "V8", "urlLinkPreview": { "render": { "urlPatterns": [ "https://support.example.com/cases/*" ], "renderFunction": "onCaseUrlOpen" } } } ``` -------------------------------- ### Install Dependencies and Deploy ADK AI Agent Source: https://developers.google.com/workspace/add-ons/samples/travel-concierge Install necessary dependencies and deploy the ADK AI agent using the provided commands. This step initiates the agent's deployment process. ```bash uv sync --group deployment uv run python deployment/deploy.py --create ``` -------------------------------- ### InstallDeployment Source: https://developers.google.com/workspace/add-ons/reference/rpc/google.cloud.gsuiteaddons.v1 Installs a deployment for testing purposes. Requires the `gsuiteaddons.deployments.install` IAM permission. ```APIDOC ## InstallDeployment ### Description Installs a deployment for testing purposes. ### Request Body - **name** (string) - Required. The full resource name of the deployment to install. Example: `projects/my_project/deployments/my_deployment`. ### Authorization Requires the `gsuiteaddons.deployments.install` IAM permission on the specified resource `name`. ``` -------------------------------- ### JavaScript Conversion Example Source: https://developers.google.com/workspace/add-ons/reference/rpc/google.type Example demonstrating how to convert the `Color` protocol buffer to a CSS color string in JavaScript. ```APIDOC ## JavaScript Conversion Example ```javascript // ... var protoToCssColor = function(rgb_color) { var redFrac = rgb_color.red || 0.0; var greenFrac = rgb_color.green || 0.0; var blueFrac = rgb_color.blue || 0.0; var red = Math.floor(redFrac * 255); var green = Math.floor(greenFrac * 255); var blue = Math.floor(blueFrac * 255); if (!('alpha' in rgb_color)) { return rgbToCssColor(red, green, blue); } var alphaFrac = rgb_color.alpha.value || 0.0; var rgbParams = [red, green, blue].join(','); return ['rgba(', rgbParams, ',', alphaFrac, ')'].join(''); }; var rgbToCssColor = function(red, green, blue) { var rgbNumber = new Number((red << 16) | (green << 8) | blue); var hexString = rgbNumber.toString(16); var missingZeros = 6 - hexString.length; var resultBuilder = ['#']; for (var i = 0; i < missingZeros; i++) { resultBuilder.push('0'); } resultBuilder.push(hexString); return resultBuilder.join(''); }; // ... ``` ``` -------------------------------- ### Install Add-on Deployment Source: https://developers.google.com/workspace/add-ons/guides/debug Install the created add-on deployment to your Google Workspace environment using the gcloud command. This makes the add-on available for use. ```bash gcloud workspace-add-ons deployments install manageSupportCases ``` -------------------------------- ### Select Menu Examples Source: https://developers.google.com/workspace/add-ons/guides/css Markup for standard and disabled select menus with options. ```html
``` -------------------------------- ### Install Google Workspace Add-on Deployment Source: https://developers.google.com/workspace/add-ons/samples/travel-concierge Install the created Google Workspace add-on deployment. This makes the add-on accessible within Google Workspace applications. ```bash gcloud workspace-add-ons deployments install travel-concierge-addon ``` -------------------------------- ### Example: Support case add-on code Source: https://developers.google.com/workspace/add-ons/guides/preview-links-smart-chips This is an example Apps Script function for handling link previews of support cases. It fetches data and builds a card. ```javascript function onCaseUrlOpen(url) { const caseId = url.match(/cases\/(\d+)/)[1]; const caseData = getCaseData(caseId); const card = CardService.newCardBuilder() .setHeader(CardService.newCardHeader().setTitle(`Support Case: ${caseData.title}`)) .addSection(CardService.newCardSection() .addWidget(CardService.newTextParagraph().setText(`Status: ${caseData.status}`)) .addWidget(CardService.newTextParagraph().setText(`Description: ${caseData.description}`))) .build(); return card; } function getCaseData(caseId) { // Replace with actual data fetching logic return { title: `Case #${caseId}`, status: "Open", description: "This is a sample description for the support case." }; } ``` -------------------------------- ### GetInstallStatus Source: https://developers.google.com/workspace/add-ons/reference/rpc/google.cloud.gsuiteaddons.v1 Retrieves the installation status of a test deployment. Requires the `gsuiteaddons.deployments.installStatus` IAM permission. ```APIDOC ## GetInstallStatus ### Description Retrieves the installation status of a test deployment. ### Request Body - **name** (string) - Required. The full resource name of the deployment. Example: `projects/my_project/deployments/my_deployment/installStatus`. ### Authorization Requires the `gsuiteaddons.deployments.installStatus` IAM permission on the specified resource `name`. ``` -------------------------------- ### Get Install Status Source: https://developers.google.com/workspace/add-ons/reference/rest Gets the install status of a test deployment. ```APIDOC ## GET /v1/{name=projects/*/deployments/*/installStatus} ### Description Gets the install status of a test deployment. ### Method GET ### Endpoint /v1/{name=projects/*/deployments/*/installStatus} ``` -------------------------------- ### Set up and run the Python app Source: https://developers.google.com/workspace/add-ons/chat/quickstart-pubsub Create a virtual environment, install dependencies, and run the Python application to process Pub/Sub events. ```bash python -m venv env source env/bin/activate pip install -r requirements.txt -U python app.py ``` -------------------------------- ### Create Add-on Deployment Source: https://developers.google.com/workspace/add-ons/quickstart/alternate-runtimes Creates a Google Workspace add-on deployment named 'quickstart' using the specified deployment file. ```bash gcloud workspace-add-ons deployments create quickstart \ --deployment-file=deployment.json ``` -------------------------------- ### Get Install Status Source: https://developers.google.com/workspace/add-ons/reference/rpc/google.cloud.gsuiteaddons.v1 Retrieves the installation status of a Google Workspace Add-on deployment for a specific user. ```APIDOC ## GetInstallStatus ### Description Retrieves the installation status of a Google Workspace Add-on deployment for a specific user. ### Method POST ### Endpoint /v1/{name=deployments/*}:getInstallStatus ### Parameters #### Path Parameters - **name** (string) - Required - The name of the deployment to check. #### Request Body - **addressee** (string) - Required - The email address of the user. ### Response #### Success Response (200) - **installStatus** (InstallStatus) - The installation status of the add-on. #### Response Example ```json { "installStatus": { "state": "INSTALLED" } } ``` ``` -------------------------------- ### GetInstallStatus Source: https://developers.google.com/workspace/add-ons/reference/rpc Gets the install status of a test deployment. ```APIDOC ## GetInstallStatus ### Description Gets the install status of a test deployment. ### Method GET ### Endpoint /v1/{name=deployments/*}:getInstallStatus ### Parameters #### Path Parameters - **name** (string) - Required - The name of the deployment to get the install status for. ### Response #### Success Response (200) - **installed** (boolean) - Whether the deployment is installed. ### Request Example ```json { "name": "deployments/my-deployment" } ``` ### Response Example ```json { "installed": true } ``` ``` -------------------------------- ### Complete example: Support case add-on manifest Source: https://developers.google.com/workspace/add-ons/editors/gsao/preview-links This is the manifest file for a complete support case add-on that supports link previews. ```json { "timeZone": "America/Los_Angeles", "dependencies": { "enabledAdvancedServices": [ { "userSymbol": "CardService", "serviceId": "slides", "version": "v1" } ] }, "exceptionLogging": "STACKDRIVER", "runtimeVersion": "V8", "addOns": { "common": { "name": "Support Case Preview", "logoUrl": "https://ssl.gstatic.com/docs/script/images/logo/logo-docs.png", "layoutProperties": { "primaryColor": "#4285f4", "secondaryColor": "#4285f4" }, "useLocaleFromAddOnUi": true, "homepageTrigger": { "runFunction": "onHomepageOpen" } }, "docs": { "த்தனர்": [ { "unconditional": {}, "onTriggerFunction": "onDocsTrigger" } ] }, "sheets": { "த்தனர்": [ { "unconditional": {}, "onTriggerFunction": "onSheetsTrigger" } ] }, "slides": { "த்தனர்": [ { "unconditional": {}, "onTriggerFunction": "onSlidesTrigger" } ] } } } ``` -------------------------------- ### Clone AI Knowledge Assistant Chat App Code Source: https://developers.google.com/workspace/add-ons/samples/tutorial-ai-knowledge-assistant Clone the sample code repository from GitHub to get started with the AI knowledge assistant Chat app. ```bash git clone https://github.com/googleworkspace/add-ons-samples.git ``` ```bash cd add-ons-samples/node/chat/ai-knowledge-assistant ``` -------------------------------- ### Get Document Access in Docs Editor Action Source: https://developers.google.com/workspace/add-ons/editors/gsao/editor-actions This example builds an interface for Docs that displays the size of the current document. It includes logic to request `drive.file` authorization if the add-on doesn't already have it. ```javascript /** * Build a 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 lets the user 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 // lets the user 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(); } ``` -------------------------------- ### Apps Script: Translate Docs Add-on Core Logic Source: https://developers.google.com/workspace/add-ons/editors/docs/quickstart/translate This script handles the core functionality of the Google Docs add-on, including UI setup, text selection, preference management, and translation calls. It defines functions for opening the sidebar, getting selected text, and managing user language preferences. ```javascript /** * @OnlyCurrentDoc * * The above comment directs Apps Script to limit the scope of file * access for this add-on. It specifies that this add-on will only * attempt to read or modify the files in which the add-on is used, * and not all of the user's files. The authorization request message * presented to users will reflect this limited scope. */ /** * Creates a menu entry in the Google Docs UI when the document is opened. * This method is only used by the regular add-on, and is never called by * the mobile add-on version. * * @param {object} e The event parameter for a simple onOpen trigger. To * determine which authorization mode (ScriptApp.AuthMode) the trigger is * running in, inspect e.authMode. */ function onOpen(e) { DocumentApp.getUi() .createAddonMenu() .addItem("Start", "showSidebar") .addToUi(); } /** * Runs when the add-on is installed. * This method is only used by the regular add-on, and is never called by * the mobile add-on version. * * @param {object} e The event parameter for a simple onInstall trigger. To * determine which authorization mode (ScriptApp.AuthMode) the trigger is * running in, inspect e.authMode. (In practice, onInstall triggers always * run in AuthMode.FULL, but onOpen triggers may be AuthMode.LIMITED or * AuthMode.NONE.) */ function onInstall(e) { onOpen(e); } /** * Opens a sidebar in the document containing the add-on's user interface. * This method is only used by the regular add-on, and is never called by * the mobile add-on version. */ function showSidebar() { const ui = HtmlService.createHtmlOutputFromFile("sidebar").setTitle("Translate"); DocumentApp.getUi().showSidebar(ui); } /** * Gets the text the user has selected. If there is no selection, * this function displays an error message. * * @return {Array.} The selected text. */ function getSelectedText() { const selection = DocumentApp.getActiveDocument().getSelection(); const text = []; if (selection) { const elements = selection.getSelectedElements(); for (let i = 0; i < elements.length; ++i) { if (elements[i].isPartial()) { const element = elements[i].getElement().asText(); const startIndex = elements[i].getStartOffset(); const endIndex = elements[i].getEndOffsetInclusive(); text.push(element.getText().substring(startIndex, endIndex + 1)); } else { const element = elements[i].getElement(); // Only translate elements that can be edited as text; skip images and // other non-text elements. if (element.editAsText) { const elementText = element.asText().getText(); // This check is necessary to exclude images, which return a blank // text element. if (elementText) { text.push(elementText); } } } } } if (!text.length) throw new Error("Please select some text."); return text; } /** * Gets the stored user preferences for the origin and destination languages, * if they exist. * This method is only used by the regular add-on, and is never called by * the mobile add-on version. * * @return {Object} The user's origin and destination language preferences, if * they exist. */ function getPreferences() { const userProperties = PropertiesService.getUserProperties(); return { originLang: userProperties.getProperty("originLang"), destLang: userProperties.getProperty("destLang"), }; } /** * Gets the user-selected text and translates it from the origin language to the * destination language. The languages are notated by their two-letter short * form. For example, English is 'en', and Spanish is 'es'. The origin language * may be specified as an empty string to indicate that Google Translate should * auto-detect the language. * * @param {string} origin The two-letter short form for the origin language. * @param {string} dest The two-letter short form for the destination language. * @param {boolean} savePrefs Whether to save the origin and destination * language preferences. * @return {Object} Object containing the original text and the result of the * translation. */ function getTextAndTranslation(origin, dest, savePrefs) { if (savePrefs) { PropertiesService.getUserProperties() .setProperty("originLang", origin) .setProperty("destLang", dest); } ``` -------------------------------- ### Link Preview Card Example Source: https://developers.google.com/workspace/add-ons/reference/rpc/google.apps.card.v1 Configures a link preview with a smart chip title, a link preview title, and a preview card containing a header and text description. ```json { "action": { "linkPreview": { "title": "Smart chip title", "linkPreviewTitle": "Link preview title", "previewCard": { "header": { "title": "Preview card header" }, "sections": [ { "widgets": [ { "textParagraph": { "text": "Description of the link." } } ] } ] } } } } ``` -------------------------------- ### Implement CEL Validation for Text Inputs Source: https://developers.google.com/workspace/add-ons/studio/validate-inputs This Apps Script code demonstrates how to set up CEL validation to check if two text inputs have equal values. It defines conditions for success and failure, card-side event actions to start evaluation, and expression data with the CEL expression. This setup allows for real-time feedback to the user. ```javascript function onConfig() { // Create a Card let cardBuilder = CardService.newCardBuilder(); const textInput_1 = CardService.newTextInput() .setTitle("Input field 1") .setFieldName("value1"); // FieldName's value must match a corresponding ID defined in the inputs[] array in the manifest file. const textInput_2 = CardService.newTextInput() .setTitle("Input field 2") .setFieldName("value2"); // FieldName's value must match a corresponding ID defined in the inputs[] array in the manifest file. let sections = CardService.newCardSection() .setHeader("Enter same values for the two input fields") .addWidget(textInput_1) .addWidget(textInput_2); // CEL Validation // Define Conditions const condition_success = CardService.newCondition() .setActionRuleId("CEL_TEXTINPUT_SUCCESS_RULE_ID") .setExpressionDataCondition( CardService.newExpressionDataCondition() .setConditionType( CardService.ExpressionDataConditionType.EXPRESSION_EVALUATION_SUCCESS)); const condition_fail = CardService.newCondition() .setActionRuleId("CEL_TEXTINPUT_FAILURE_RULE_ID") .setExpressionDataCondition( CardService.newExpressionDataCondition() .setConditionType( CardService.ExpressionDataConditionType.EXPRESSION_EVALUATION_FAILURE)); // Define Card-side EventAction const expressionDataAction = CardService.newExpressionDataAction() .setActionType( CardService.ExpressionDataActionType.START_EXPRESSION_EVALUATION); // Define Triggers for each Condition respectively const trigger_success = CardService.newTrigger() .setActionRuleId("CEL_TEXTINPUT_SUCCESS_RULE_ID"); const trigger_failure = CardService.newTrigger() .setActionRuleId("CEL_TEXTINPUT_FAILURE_RULE_ID"); const eventAction = CardService.newEventAction() .setActionRuleId("CEL_TEXTINPUT_EVALUATION_RULE_ID") .setExpressionDataAction(expressionDataAction) .addPostEventTrigger(trigger_success) .addPostEventTrigger(trigger_failure); // Define ExpressionData for the current Card const expressionData = CardService.newExpressionData() .setId("expData_id") .setExpression("value1 == value2") // CEL expression .addCondition(condition_success) .addCondition(condition_fail) .addEventAction(eventAction); card = card.addExpressionData(expressionData); ``` -------------------------------- ### Implement Link Preview for Created Resource Source: https://developers.google.com/workspace/add-ons/guides/create-insert-resource-smart-chip Example implementation for generating a link preview for a resource created by the add-on. This code is typically part of the main handler for resource creation. ```python case_details["description"] = formInputs["description"]["stringInputs"]["value"][0] if "description" in formInputs else None case_details["priority"] = formInputs["priority"]["stringInputs"]["value"][0] if "priority" in formInputs else None case_details["impact"] = formInputs["impact"]["stringInputs"]["value"][0] if "impact" in formInputs else False errors = validate_form_inputs(case_details) if len(errors) > 0: return create_case_input_card(event, errors, True) # Update mode else: title = f'Case {case_details["name"]}' # Adds the case details as parameters to the generated link URL. url = "https://example.com/support/cases/?" + urlencode(case_details) return create_link_render_action(title, url) ``` -------------------------------- ### Get Deployment Source: https://developers.google.com/workspace/add-ons/reference/rest Gets the deployment with the specified name. ```APIDOC ## GET /v1/{name=projects/*/deployments/*} ### Description Gets the deployment with the specified name. ### Method GET ### Endpoint /v1/{name=projects/*/deployments/*} ``` -------------------------------- ### Initialize a Node.js project Source: https://developers.google.com/workspace/add-ons/chat/quickstart-pubsub Initialize a new Node.js project for your Chat app. Ensure Node.js 14 or greater and npm are installed. ```bash npm init ``` -------------------------------- ### Install Node.js Dependencies Source: https://developers.google.com/workspace/add-ons/guides/debug Install the project dependencies for your Node.js Google Workspace add-on. ```bash npm install ``` -------------------------------- ### Install Python Dependencies Source: https://developers.google.com/workspace/add-ons/guides/debug Install project dependencies for your Python Google Workspace add-on using pip. ```bash pip install -r requirements.txt ``` -------------------------------- ### Main Execution Logic Source: https://developers.google.com/workspace/add-ons/chat/quickstart-a2a-agent Handles command-line arguments for listing, creating, or deleting agents, and initializes Vertex AI with project and location details. Requires environment variables for project, location, and bucket. ```python def main(argv: list[str]) -> None: del argv # unused load_dotenv() project_id = ( FLAGS.project_id if FLAGS.project_id else os.getenv("GOOGLE_CLOUD_PROJECT") ) location = ( FLAGS.location if FLAGS.location else os.getenv("GOOGLE_CLOUD_LOCATION") ) bucket = ( FLAGS.bucket if FLAGS.bucket else os.getenv("GOOGLE_CLOUD_STORAGE_BUCKET") ) print(f"PROJECT: {project_id}") print(f"LOCATION: {location}") print(f"BUCKET: {bucket}") if not project_id: print("Missing required environment variable: GOOGLE_CLOUD_PROJECT") return elif not location: print("Missing required environment variable: GOOGLE_CLOUD_LOCATION") return elif not bucket: print( "Missing required environment variable: GOOGLE_CLOUD_STORAGE_BUCKET" ) return vertexai.init( project=project_id, location=location, staging_bucket=f"gs://{bucket}", ) if FLAGS.list: list_agents() elif FLAGS.create: create() elif FLAGS.delete: if not FLAGS.resource_id: print("resource_id is required for delete") return delete(FLAGS.resource_id) else: print("Unknown command") if __name__ == "__main__": app.run(main) ``` -------------------------------- ### Install nodemon for Node.js Source: https://developers.google.com/workspace/add-ons/guides/debug Install nodemon globally to enable auto-reloading during development. This tool is essential for Node.js projects. ```bash npm install -g nodemon ``` -------------------------------- ### Card Actions Example Source: https://developers.google.com/workspace/add-ons/reference/rpc/google.apps.card.v1 Example JSON for defining card actions that appear in the card's toolbar menu. ```APIDOC ## Card Actions ### Description This example demonstrates how to define actions for a card's toolbar menu, such as 'Settings' or 'Send Feedback'. ### JSON Structure ```json "cardActions": [ { "actionLabel": "Settings", "onClick": { "action": { "functionName": "goToView", "parameters": [ { "key": "viewType", "value": "SETTING" } ], "loadIndicator": "LoadIndicator.SPINNER" } } }, { "actionLabel": "Send Feedback", "onClick": { "openLink": { "url": "https://example.com/feedback" } } } ] ``` ``` -------------------------------- ### Delete Cloud Project Source: https://developers.google.com/workspace/add-ons/quickstart/alternate-runtimes To avoid charges, delete the Cloud project used for the quickstart. Replace PROJECT_ID with your actual project ID. You can find the project ID in the Google API Console. ```bash gcloud projects delete PROJECT_ID ``` -------------------------------- ### Set up Service Account Permissions Source: https://developers.google.com/workspace/add-ons/quickstart/alternate-runtimes Exports the project ID and service account name, then grants the Cloud Build Service Account role. ```bash export PROJECT_ID=$(gcloud config get project) export SERVICE_ACCOUNT_NAME=$(gcloud compute project-info describe \ --format="value(defaultServiceAccount)") ``` ```bash gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:$SERVICE_ACCOUNT_NAME" \ --role="roles/cloudbuild.builds.builder" ``` -------------------------------- ### Material Icon Example Source: https://developers.google.com/workspace/add-ons/reference/rpc/google.apps.card.v1 Display one of the Google Material Icons by specifying its name. For example, to display a checkbox icon, use 'check_box'. ```json "materialIcon": { "name": "check_box" } ``` -------------------------------- ### Building a Gmail Add-on Card with Message Details Source: https://developers.google.com/workspace/add-ons/gmail/extending-message-ui This example demonstrates how to build a simple card for a Gmail add-on. It activates Gmail scopes, retrieves message subject and sender, and constructs a card with this information using the CardService. ```javascript function onGmailMessageOpen(e) { // Activate temporary Gmail scopes, in this case to allow // message metadata to be read. var accessToken = e.gmail.accessToken; GmailApp.setCurrentMessageAccessToken(accessToken); var messageId = e.gmail.messageId; var message = GmailApp.getMessageById(messageId); var subject = message.getSubject(); var sender = message.getFrom(); // Create a card with a single card section and two widgets. // Be sure to execute build() to finalize the card construction. var exampleCard = CardService.newCardBuilder() .setHeader(CardService.newCardHeader() .setTitle('Example card')) .addSection(CardService.newCardSection() .addWidget(CardService.newDecoratedText() .setTopLabel('Subject') .setText(subject)) .addWidget(CardService.newDecoratedText() .setTopLabel('From') .setText(sender))) .build(); // Don't forget to build the Card! return [exampleCard]; } ``` -------------------------------- ### Card Message Example Source: https://developers.google.com/workspace/add-ons/reference/rpc/google.apps.card.v1 Example JSON structure for a card message in a Google Chat app, demonstrating header, sections, widgets, and actions. ```APIDOC ## Card Message Example ### Description This example shows how to construct a card message for a Google Chat app, including a header, a section with contact information, and interactive buttons. ### JSON Structure ```json { "cardsV2": [ { "cardId": "unique-card-id", "card": { "header": { "title": "Sasha", "subtitle": "Software Engineer", "imageUrl": "https://developers.google.com/workspace/chat/images/quickstart-app-avatar.png", "imageType": "CIRCLE", "imageAltText": "Avatar for Sasha" }, "sections": [ { "header": "Contact Info", "collapsible": true, "uncollapsibleWidgetsCount": 1, "widgets": [ { "decoratedText": { "startIcon": { "knownIcon": "EMAIL" }, "text": "sasha@example.com" } }, { "decoratedText": { "startIcon": { "knownIcon": "PERSON" }, "text": "Online" } }, { "decoratedText": { "startIcon": { "knownIcon": "PHONE" }, "text": "+1 (555) 555-1234" } }, { "buttonList": { "buttons": [ { "text": "Share", "onClick": { "openLink": { "url": "https://example.com/share" } } }, { "text": "Edit", "onClick": { "action": { "function": "goToView", "parameters": [ { "key": "viewType", "value": "EDIT" } ] } } } ] } } ] } ] } } ] } ``` ``` -------------------------------- ### Install Python Dependencies Source: https://developers.google.com/workspace/add-ons/chat/quickstart-pubsub List the necessary Python packages in `requirements.txt`. Ensure `google-cloud-pubsub` and `google-apps-chat` are included with compatible versions. ```text google-cloud-pubsub>=2.23.0 google-apps-chat==0.1.9 ```