diff --git a/AppSheetApp.js b/AppSheetApp.gs similarity index 50% rename from AppSheetApp.js rename to AppSheetApp.gs index 3923db1..08bdcc2 100644 --- a/AppSheetApp.js +++ b/AppSheetApp.gs @@ -1,165 +1,219 @@ -/** - * Copyright 2023 Cloud Technology Solutions Ltd. All Rights Reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - - * http://www.apache.org/licenses/LICENSE-2.0 - - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -**/ - -/** @interface **/ - -/** - * Connect to an AppSheet App - * To enable the AppSheet API in your app: - * - * 1. Open the app in the app editor. - * 2. Select **Settings > Integrations**. - * 3. Under **IN: from cloud services to your app**, enable the **Enable** toggle. - * This enables the API for the application as a whole. - * 4. Ensure that at least one unexpired **Application Access Key** is present. - * Otherwise, click **Create Application Access Key**. - * 5. When you are done, save the app. +/** + * Copyright 2023 Cloud Technology Solutions Ltd. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + + * http://www.apache.org/licenses/LICENSE-2.0 + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +**/ + +/** @interface **/ + +/** + * Connect to an AppSheet App + * To enable the AppSheet API in your app: + * + * 1. Open the app in the app editor. + * 2. Select **Settings > Integrations**. + * 3. Under **IN: from cloud services to your app**, enable the **Enable** toggle. + * This enables the API for the application as a whole. + * 4. Ensure that at least one unexpired **Application Access Key** is present. + * Otherwise, click **Create Application Access Key**. + * 5. When you are done, save the app. * 6. Use your app ID and Access Key to connect Apps Script to your app - * - * @param {String} appId AppSheet App ID. + * + * @param {String} appId AppSheet App ID. * @param {String} applicationAccessKey AppSheet App Access Key. - * @return {AppSheetApp} - */ -function connect(appId, applicationAccessKey) { - return new AppSheetApp(appId, applicationAccessKey); -} - -/** - * Add records to a table - * - * @param {String} tableName - specifies the name of the table - * @param {Object[]} rows - One or more Rows elements. Each individual Row value must normally include the key field values of the record to be added. However, if the key field contains an Initial value, you can omit the key field value. For example, you should omit the key field value when the key field has an Initial value of UNIQUEID() or RANDBETWEEN(). The system will initialize the key field to the Initial value. - * @param {Object} properties - **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)] - * @returns {Object} AppSheet Response - */ -function Add(tableName, rows, properties = {}) { - return AppSheetApp._appSheetAPI(tableName, 'Add', rows, properties); -} - -/** - * Delete records from a table - * - * @param {String} tableName - specifies the name of the table - * @param {Object[]} rows - One or more Rows elements to be deleted. Each Row value may contain field values of the key field values of the record to be deleted. - * @param {Object} properties - **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)] - * @returns {Object} AppSheet Response - */ -function Delete(tableName, rows, properties = {}) { - return AppSheetApp._appSheetAPI(tableName, 'Delete', rows, properties); -} - -/** - * Update records in a table - * - * @param {String} tableName - specifies the name of the table - * @param {Object[]} rows - One or more Row values to be updated. Each individual Row value must include the key field values of the record to be updated. - * @param {Object} properties - **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)] - * @returns {Object} AppSheet Response - */ -function Edit(tableName, rows, properties = {}) { - return AppSheetApp._appSheetAPI(tableName, 'Edit', rows, properties); -} - -/** - * Read records from a table - * - * @param {String} tableName - specifies the name of the table - * @param {Object[]} rows - **Optional**. You can omit the Selector property and specify input Rows containing the key values of the records to be read. - * @param {Object} properties - **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)]. Additionally the optional `Selector` property can used to specify an expression to select and format the rows returned [[Ref](https://support.google.com/appsheet/answer/10105770#:~:text=Read-,selected%20rows,-In%20the%20Selector)]. - * @returns {Object} AppSheet Response - */ -function Find(tableName, rows, properties = {}) { - return AppSheetApp._appSheetAPI(tableName, 'Find', rows, properties); -} - -/** - * Invoke an action - * - * @param {String} tableName - specifies the name of the table + * @return {AppSheetApp} + */ +function connect(appId, applicationAccessKey) { + return new AppSheetApp(appId, applicationAccessKey); +} + +/** + * Add records to a table + * + * @param {String} tableName - specifies the name of the table + * @param {Object[]} rows - One or more Rows elements. Each individual Row value must normally include the key field values of the record to be added. However, if the key field contains an Initial value, you can omit the key field value. For example, you should omit the key field value when the key field has an Initial value of UNIQUEID() or RANDBETWEEN(). The system will initialize the key field to the Initial value. + * @param {Object} properties - **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)] + * @param {Boolean} isAsync - **Optional** return a AppSheet API request object instead of making an immediate API call + * @returns {Object} AppSheet Response + */ +function Add(tableName, rows, properties = {}, isAsync = false) { + return isAsync + ? AppSheetApp._appSheetParam(tableName, "Add", rows, properties) + : AppSheetApp._appSheetAPI(tableName, "Add", rows, properties); +} + +/** + * Delete records from a table + * + * @param {String} tableName - specifies the name of the table + * @param {Object[]} rows - One or more Rows elements to be deleted. Each Row value may contain field values of the key field values of the record to be deleted. + * @param {Object} properties - **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)] + * @param {Boolean} isAsync - **Optional** return a AppSheet API request object instead of making an immediate API call + * @returns {Object} AppSheet Response + */ +function Delete(tableName, rows, properties = {}, isAsync = false) { + return isAsync + ? AppSheetApp._appSheetParam(tableName, "Delete", rows, properties) + : AppSheetApp._appSheetAPI(tableName, "Delete", rows, properties); +} + +/** + * Update records in a table + * + * @param {String} tableName - specifies the name of the table + * @param {Object[]} rows - One or more Row values to be updated. Each individual Row value must include the key field values of the record to be updated. + * @param {Object} properties - **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)] + * @param {Boolean} isAsync - **Optional** if true, return a AppSheet API request object instead of making an immediate API call + * @returns {Object} AppSheet Response + */ +function Edit(tableName, rows, properties = {}, isAsync = false) { + return isAsync + ? AppSheetApp._appSheetParam(tableName, "Edit", rows, properties) + : AppSheetApp._appSheetAPI(tableName, "Edit", rows, properties); +} + +/** + * Read records from a table + * + * @param {String} tableName - specifies the name of the table + * @param {Object[]} rows - **Optional**. You can omit the Selector property and specify input Rows containing the key values of the records to be read. + * @param {Object} properties - **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)]. Additionally the optional `Selector` property can used to specify an expression to select and format the rows returned [[Ref](https://support.google.com/appsheet/answer/10105770#:~:text=Read-,selected%20rows,-In%20the%20Selector)]. + * @param {Boolean} isAsync - **Optional** if true, return a AppSheet API request object instead of making an immediate API call + * @returns {Object} AppSheet Response + */ +function Find(tableName, rows, properties = {}, isAsync = false) { + return isAsync + ? AppSheetApp._appSheetParam(tableName, "Find", rows, properties) + : AppSheetApp._appSheetAPI(tableName, "Find", rows, properties); +} + +/** + * Invoke an action + * + * @param {String} tableName - specifies the name of the table * @param {String} action - The action name. - * @param {Object[]} rows - One or more Rows elements specifying the key field values of the rows to which the action is to be applied. - * @param {Object} properties - **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)] - * @returns {Object} AppSheet Response - */ -function Action(tableName, action, rows, properties = {}) { - return AppSheetApp._appSheetAPI(tableName, action, rows, properties); -} - -/** - * AppSheetApp is used to interface the AppSheet API. - */ -class _AppSheet { - /** - * @constructor - * @param {String} appId - AppSheet Application ID. + * @param {Object[]} rows - One or more Rows elements specifying the key field values of the rows to which the action is to be applied. + * @param {Object} properties - **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)] + * @param {Boolean} isAsync - **Optional** if true, return a AppSheet API request object instead of making an immediate API call + * @returns {Object} AppSheet Response + */ +function Action(tableName, action, rows, properties = {}, isAsync = false) { + return isAsync + ? AppSheetApp._appSheetParam(tableName, action , rows, properties) + : AppSheetApp._appSheetAPI(tableName, action , rows, properties); +} + +/** + * @typedef {object} requestObject + * @property {String} action - The action name. + * @property {Object[]} rows - One or more Rows elements specifying the key field values of the rows to which the action is to be applied. + * @property {Object} properties - **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)] + * @property {Boolean} isAsync - **Optional** if true, return a AppSheet API request object instead of making an immediate API call + */ +/** + * Makes multiple requests to the AppSheet API. + * + * @param {...requestObject} params - A variable number of objects, where each object represents a single AppSheet API request. + * @returns {Object[]} An array of AppSheet API responses, with each response corresponding to a request in the order they were provided. + */ +function fetchAll(...params){ + try { + const responses = UrlFetchApp.fetchAll(params); + return responses.map(response => JSON.parse(response.getContentText())); + } catch (e) { + return e; + } +} + +/** + * AppSheetApp is used to interface the AppSheet API. + */ +class _AppSheet { + /** + * @constructor + * @param {String} appId - AppSheet Application ID. * @param {String} applicationAccessKey - AppSheet Access Key. - * @return {_AppSheet} - */ - constructor(appId, applicationAccessKey) { - this.appId = appId; - this.applicationAccessKey = applicationAccessKey; - } - - Add(tableName, rows, properties = {}) { - return this._appSheetAPI(tableName, 'Add', rows, properties); - } - - Delete(tableName, rows, properties = {}) { - return this._appSheetAPI(tableName, 'Delete', rows, properties); - } - - Edit(tableName, rows, properties = {}) { - return this._appSheetAPI(tableName, 'Edit', rows, properties); - } - - Find(tableName, rows, properties = {}) { - return this._appSheetAPI(tableName, 'Find', rows, properties); - } - - Action(tableName, action, rows, properties = {}) { - return this._appSheetAPI(tableName, action, rows, properties); - } - - _appSheetAPI(tableName, action, rows, properties) { - const self = this; - - // based on https://www.googlecloudcommunity.com/gc/Tips-Tricks/Call-AppSheet-API-from-Apps-Script/m-p/447165 - const body = { - 'Action': action, - 'Rows': rows, - "Properties": properties - }; - - // Values universal to AppSheet API calls - const url = `https://api.appsheet.com/api/v2/apps/${self.appId}/tables/${tableName}/Action`; - const method = 'POST'; - - const params = { - 'method': method, - 'contentType': 'application/json', - 'headers': { 'ApplicationAccessKey': self.applicationAccessKey }, - 'payload': JSON.stringify(body), - 'muteHttpExceptions': true - }; - - try { - const response = UrlFetchApp.fetch(url, params); - return JSON.parse(response.getContentText()); - } catch (e) { - return e; - } - } -} + * @return {_AppSheet} + */ + constructor(appId, applicationAccessKey) { + this.appId = appId; + this.applicationAccessKey = applicationAccessKey; + } + + Add(tableName, rows, properties = {}, isAsync = false ) { + return isAsync + ? this._appSheetParam(tableName, 'Add', rows, properties) + : this._appSheetAPI(tableName, 'Add', rows, properties) + } + + Delete(tableName, rows, properties = {}, isAsync = false ) { + return isAsync + ? this._appSheetParam(tableName, 'Delete', rows, properties) + : this._appSheetAPI(tableName, 'Delete', rows, properties); + } + + Edit(tableName, rows, properties = {}, isAsync = false) { + return isAsync + ? this._appSheetParam(tableName, 'Edit', rows, properties) + : this._appSheetAPI(tableName, 'Edit', rows, properties); + } + + Find(tableName, rows, properties = {}, isAsync = false) { + return isAsync + ? this._appSheetParam(tableName, 'Find', rows, properties) + : this._appSheetAPI(tableName, 'Find', rows, properties); + } + + Action(tableName, action, rows, properties = {}, isAsync = false) { + return isAsync + ? this._appSheetParam(tableName,action, rows, properties) + : this._appSheetAPI(tableName, action, rows, properties); + } + + fetchAll(...params){ + try { + const responses = UrlFetchApp.fetchAll(params); + return responses.map(response => JSON.parse(response.getContentText())); + } catch (e) { + return e; + } + } + + _appSheetAPI(tableName, action, rows, properties) { + const params = this._appSheetParam(tableName, action, rows, properties); + const url = params.url; + + // Remove the url from params to avoid sending it in the request + // This is necessary because UrlFetchApp does not support sending the url in the params object + // and it expects the url to be a separate parameter. + delete params.url; + + try { + const response = UrlFetchApp.fetch(url, params); + return JSON.parse(response.getContentText()); + } catch (e) { + return e; + } + } + + _appSheetParam(tableName, action, rows = [], properties = {}) { + return { + url: `https://api.appsheet.com/api/v2/apps/${this.appId}/tables/${tableName}/Action`, + method: 'post', + contentType: 'application/json', + headers: { ApplicationAccessKey: this.applicationAccessKey }, + payload: JSON.stringify({ Action: action, Rows: rows, Properties: properties }), + muteHttpExceptions: true + }; + } +} var AppSheetApp = _AppSheet; \ No newline at end of file diff --git a/README.md b/README.md index 7e4367d..64421d9 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,14 @@ The AppSheetApp service lets you access the AppSheet API using Apps Script. The - Read a table record - Update table records - Invoke an action you have defined in AppSheet (limited to certain action types) +- fetchAll methods in parallel > **Note:** The AppSheet API is supported for Enterprise plans only. `AppSheetApp` has been created by Martin Hawksey (https://g.dev/mhawksey), Collaboration Engineer at [CTS](https://cts.co/). +`fetchAll` has been added by Bien Lim, AppSheet enthusiast. + ## Enabling the AppSheet API To use the AppSheetApp service you need to generate an Application Access Key for your AppSheet app. To do this read the reference documentation on [enabling the API](https://support.google.com/appsheet/answer/10105769). @@ -22,7 +25,7 @@ This project is already published as an Apps Script library, making it easy to i 1. In the **Libraries** section click on the **Add a library** button (+) 2. In the **Script ID** text box, enter - `19UWd_F9ht9KuE4gxeNdFG8qIMdBeTu5gXyecmPqr8yOEoVO8UcxBYVsJ` and click the **Lookup** button. + `1aXPRqSO_ulCdptqlpKm12o81pdOHUlxnr9n6Gw3AIXk0K8Xc_cNCbx4B` and click the **Lookup** button. 3. Choose a version in the dropdown box (usually best to pick the latest version). 4. Click the **Add** button. @@ -42,7 +45,7 @@ Before you can start making calls to your AppSheet app you need to use the `conn Once you have connected to your app, you can use methods to add, delete, read, and update table records. The example below shows how to connect to your app and add two rows to a 'People' table: -``` +```javascript /** * Example function for connecting your AppSheet app */ @@ -76,7 +79,7 @@ function addRowsToTable() { The returned records include all field values. This includes virtual fields and field values computed by worksheet formulas. The following is an example of a response body that might be returned from an `Add` operation (when new records are created) or a `Find` operation (when records are retrieved). -``` +```javascript { "Rows": [ { @@ -110,11 +113,12 @@ For more detailed information on the data about the actions, properties, rows an | Method | Description | | :--------------------------------------------------------- | :------------------------------------- | | [`connect(appId, applicationAccessKey)`](#connect) | Connect to an AppSheet App. | -| [`Add(tableName, rows, properties = {})`](#Add) | Add records to a table. | -| [`Delete(tableName, rows, properties = {})`](#Delete) | Delete records from a table. | -| [`Edit(tableName, rows, properties = {})`](#Edit) | Update records in a table. | -| [`Find(tableName, rows, properties = {})`](#Find) | Read records from a table. | -| [`Action(tableName, action, rows, properties = {})`](#Action) | Invoke an action. | +| [`Add(tableName, rows, properties = {}, isAsync = false)`](#Add) | Add records to a table. | +| [`Delete(tableName, rows, properties = {}, isAsync = false)`](#Delete) | Delete records from a table. | +| [`Edit(tableName, rows, properties = {}, isAsync = false)`](#Edit) | Update records in a table. | +| [`Find(tableName, rows, properties = {}, isAsync = false)`](#Find) | Read records from a table. | +| [`Action(tableName, action, rows, properties = {}, isAsync = false)`](#Action) | Invoke an action. | +| [`fetchAll(...request)`](#fetchAll) | Run multiple method requests in parallel. | @@ -131,7 +135,7 @@ To enable the AppSheet API in your app: 1. Use your app ID and Access Key to connect Apps Script to your app -``` +```javascript const AppSheet = AppSheetApp.connect('YOUR_APP_ID', 'YOUR_ACCESS_KEY'); ``` @@ -142,7 +146,7 @@ const AppSheet = AppSheetApp.connect('YOUR_APP_ID', 'YOUR_ACCESS_KEY'); -## Add(tableName, rows, properties) ⇒ Object +## Add(tableName, rows, properties, isAsync) ⇒ Object Add records to a table | Param | Type | Description | @@ -150,11 +154,13 @@ Add records to a table | `tableName` | String | specifies the name of the table | | `rows` | Array.<Object> | One or more Rows elements. Each individual Row value must normally include the key field values of the record to be added. However, if the key field contains an Initial value, you can omit the key field value. For example, you should omit the key field value when the key field has an Initial value of UNIQUEID() or RANDBETWEEN(). The system will initialize the key field to the Initial value. | | `properties` | Object | **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)] | +| `isAsync` | Bool | **Optional** if true, return a AppSheet API request object instead of making an immediate API call | + **Returns**: Object - AppSheet Response -## Delete(tableName, rows, properties) ⇒ Object +## Delete(tableName, rows, properties, isAsync) ⇒ Object Delete records from a table | Param | Type | Description | @@ -162,12 +168,14 @@ Delete records from a table | `tableName` | String | specifies the name of the table | | `rows` | Array.<Object> | One or more Rows elements to be deleted. Each Row value may contain field values of the key field values of the record to be deleted. | | `properties` | Object | **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)] | +| `isAsync` | Bool | **Optional** if true, return a AppSheet API request object instead of making an immediate API call | + **Returns**: Object - AppSheet Response -## Edit(tableName, rows, properties) ⇒ Object +## Edit(tableName, rows, properties, isAsync) ⇒ Object Update records in a table @@ -176,6 +184,8 @@ Update records in a table | `tableName` | String | specifies the name of the table | | `rows` | Array.<Object> | One or more Row values to be updated. Each individual Row value must include the key field values of the record to be updated. | | `properties` | Object | **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)] | +| `isAsync` | Bool | **Optional** if true, return a AppSheet API request object instead of making an immediate API call | + **Returns**: Object - AppSheet Response @@ -195,7 +205,7 @@ In the `Selector` property, you can specify an expression to select and format t The `Find` is performed under the identity of the application owner by default. Your can override this by specifying the `RunAsUserEmail` property in the request properties. -``` +```javascript /** * Return rows from a People table where age is greater or equal to 21 * Run as user with the email an.example@email.com @@ -218,6 +228,7 @@ function findRowsInTable(){ | `tableName` | String | specifies the name of the table | | `rows` | Array.<Object> | **Optional**. You can omit the Selector property and specify input Rows containing the key values of the records to be read. | | `properties` | Object | **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)]. Additionally the optional `Selector` property can used to specify an expression to select and format the rows returned [[Ref](https://support.google.com/appsheet/answer/10105770#:~:text=Read-,selected%20rows,-In%20the%20Selector)]. | +| `isAsync` | Bool | **Optional** if true, return a AppSheet API request object instead of making an immediate API call | **Returns**: Object - AppSheet Response @@ -232,5 +243,64 @@ Invoke an action | `rows` | Array.<Object> | One or more Rows elements specifying the key field values of the rows to which the action is to be applied. | | `action` | String | The action name. | | `properties` | Object | **Optional**. Optional properties such as Locale, Location, Timezone, and UserId. [[Ref](https://support.google.com/appsheet/answer/10105398?hl=en#:~:text=for%20the%20table.-,Properties,-The%20properties%20of)] | +| `isAsync` | Bool | **Optional** if true, return a AppSheet API request object instead of making an immediate API call | **Returns**: Object - AppSheet Response + + + +## fetchAll(...request) +Run multiple method request in parallel. + +| Param | Type | Description | +| --- | --- | --- | +| `...request` | ...<Objects> | One or more AppSheet API request object | + +```javascript +/** + * Executes multiple AppSheet API requests in parallel. + * This example shows how to perform Add, Delete, Edit, and Find operations simultaneously. + */ +function parallelRequest(){ + // Replace with your actual App ID and Access Key + const AppSheet = new AppSheetApp('YOUR_APP_ID', 'YOUR_ACCESS_KEY'); + + // Placeholder data for demonstration + const properties = { "Locale": "en-US" }; + + // Sample data for adding a new record. The key field is usually omitted if it's auto-generated. + const dataToAdd = [{"Name": "John Doe", "Age": 30}]; + + // Sample data for editing an existing record. The key field is required to identify the row. + const dataToEdit = [{"ID": "unique-id-123", "Age": 31}]; + + // Sample data for deleting an existing record. The key field is required. + const dataToDelete = [{"ID": "unique-id-456"}]; + + // The fetchAll method takes multiple API calls as arguments. + // The 'true' argument tells each method to return a parameter object instead of + // making an immediate API call. These parameter objects are then passed to fetchAll(). + const responses = AppSheet.fetchAll( + AppSheet.Add('People', dataToAdd, properties, true), + AppSheet.Delete('People', dataToDelete, properties, true), + AppSheet.Edit('People', dataToEdit, properties, true), + AppSheet.Find('People', [], properties, true) + ); + + // The responses are returned in an array, in the same order as the requests. + const [ respFromAdd, respFromDelete, respFromEdit, respFromFind ] = responses; + + // You can now handle each response individually + console.log('Add Response:', respFromAdd); + console.log('Delete Response:', respFromDelete); + console.log('Edit Response:', respFromEdit); + console.log('Find Response:', respFromFind); +} + +``` + + + + + + diff --git a/appsscript.json b/appsscript.json index 9704d41..7398e43 100644 --- a/appsscript.json +++ b/appsscript.json @@ -1,9 +1,7 @@ -{ - "timeZone": "Europe/London", - "dependencies": {}, - "oauthScopes": [ - "https://www.googleapis.com/auth/script.external_request" - ], - "exceptionLogging": "STACKDRIVER", - "runtimeVersion": "V8" +{ + "timeZone": "Asia/Singapore", + "dependencies": { + }, + "exceptionLogging": "STACKDRIVER", + "runtimeVersion": "V8" } \ No newline at end of file