From 03b357393ed399cd0af849d134880bad94d84ea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C4=B1dvan=20Akca?= Date: Thu, 15 Jun 2023 14:04:45 +0300 Subject: [PATCH] feat(google-sheets): add new or updated spreadsheet rows trigger --- .../apps/google-sheets/dynamic-data/index.ts | 3 +- .../dynamic-data/list-columns/index.ts | 70 +++++++++++ .../src/apps/google-sheets/triggers/index.ts | 8 +- .../new-or-updated-spreadsheet-rows/index.ts | 109 ++++++++++++++++++ .../new-or-updated-spreadsheet-rows.ts | 50 ++++++++ 5 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 packages/backend/src/apps/google-sheets/dynamic-data/list-columns/index.ts create mode 100644 packages/backend/src/apps/google-sheets/triggers/new-or-updated-spreadsheet-rows/index.ts create mode 100644 packages/backend/src/apps/google-sheets/triggers/new-or-updated-spreadsheet-rows/new-or-updated-spreadsheet-rows.ts diff --git a/packages/backend/src/apps/google-sheets/dynamic-data/index.ts b/packages/backend/src/apps/google-sheets/dynamic-data/index.ts index ac008c09..83e1c37d 100644 --- a/packages/backend/src/apps/google-sheets/dynamic-data/index.ts +++ b/packages/backend/src/apps/google-sheets/dynamic-data/index.ts @@ -1,5 +1,6 @@ import listDrives from './list-drives'; import listSpreadsheets from './list-spreadsheets'; import listWorksheets from './list-worksheets'; +import listColumns from './list-columns'; -export default [listDrives, listSpreadsheets, listWorksheets]; +export default [listDrives, listSpreadsheets, listWorksheets, listColumns]; diff --git a/packages/backend/src/apps/google-sheets/dynamic-data/list-columns/index.ts b/packages/backend/src/apps/google-sheets/dynamic-data/list-columns/index.ts new file mode 100644 index 00000000..5fd62f90 --- /dev/null +++ b/packages/backend/src/apps/google-sheets/dynamic-data/list-columns/index.ts @@ -0,0 +1,70 @@ +import { IGlobalVariable, IJSONObject } from '@automatisch/types'; + +type TSheetsResponse = { + sheets: { + properties: { + sheetId: string; + title: string; + }; + }[]; +}; + +function getColumnNameByNumber(columnNumber: number) { + let columnName = ''; + while (columnNumber > 0) { + const modulo = (columnNumber - 1) % 26; + columnName = String.fromCharCode(65 + modulo) + columnName; + columnNumber = Math.floor((columnNumber - modulo) / 26); + } + return columnName; +} + +export default { + name: 'List columns', + key: 'listColumns', + + async run($: IGlobalVariable) { + const spreadsheetId = $.step.parameters.spreadsheetId as string; + + const headers: { + data: IJSONObject[]; + } = { + data: [], + }; + + if (!spreadsheetId) { + return headers; + } + + const { + data: { sheets }, + } = await $.http.get( + `/v4/spreadsheets/${$.step.parameters.spreadsheetId}` + ); + + const selectedSheet = sheets.find( + (sheet) => sheet.properties.sheetId === $.step.parameters.worksheetId + ); + + if (!selectedSheet) return; + + const sheetName = selectedSheet.properties.title; + + const range = `${sheetName}!1:1`; + + const { data } = await $.http.get( + `v4/spreadsheets/${$.step.parameters.spreadsheetId}/values/${range}` + ); + + if (data.values?.length) { + for (let number = 0; number < data.values[0].length; number++) { + headers.data.push({ + value: getColumnNameByNumber(number + 1), + name: data.values[0][number], + }); + } + } + + return headers; + }, +}; diff --git a/packages/backend/src/apps/google-sheets/triggers/index.ts b/packages/backend/src/apps/google-sheets/triggers/index.ts index cd9d065a..5f53fbce 100644 --- a/packages/backend/src/apps/google-sheets/triggers/index.ts +++ b/packages/backend/src/apps/google-sheets/triggers/index.ts @@ -1,5 +1,11 @@ import newSpreadsheets from './new-spreadsheets'; import newWorksheets from './new-worksheets'; import newSpreadsheetRows from './new-spreadsheet-rows'; +import newOrUpdatedSpreadsheetRows from './new-or-updated-spreadsheet-rows'; -export default [newSpreadsheets, newWorksheets, newSpreadsheetRows]; +export default [ + newSpreadsheets, + newWorksheets, + newSpreadsheetRows, + newOrUpdatedSpreadsheetRows, +]; diff --git a/packages/backend/src/apps/google-sheets/triggers/new-or-updated-spreadsheet-rows/index.ts b/packages/backend/src/apps/google-sheets/triggers/new-or-updated-spreadsheet-rows/index.ts new file mode 100644 index 00000000..7916326e --- /dev/null +++ b/packages/backend/src/apps/google-sheets/triggers/new-or-updated-spreadsheet-rows/index.ts @@ -0,0 +1,109 @@ +import defineTrigger from '../../../../helpers/define-trigger'; +import newOrUpdatedSpreadsheetRows from './new-or-updated-spreadsheet-rows'; + +export default defineTrigger({ + name: 'New or updated spreadsheet rows', + key: 'newOrUpdatedSpreadsheetRows', + pollInterval: 15, + description: 'Triggers when a new row is added or modified in a spreadsheet.', + arguments: [ + { + label: 'Drive', + key: 'driveId', + type: 'dropdown' as const, + required: false, + description: + 'The Google Drive where your spreadsheet resides. If nothing is selected, then your personal Google Drive will be used.', + variables: false, + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listDrives', + }, + ], + }, + }, + { + label: 'Spreadsheet', + key: 'spreadsheetId', + type: 'dropdown' as const, + required: true, + dependsOn: ['parameters.driveId'], + description: 'The spreadsheets in your Google Drive.', + variables: false, + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listSpreadsheets', + }, + { + name: 'parameters.driveId', + value: '{parameters.driveId}', + }, + ], + }, + }, + { + label: 'Worksheet', + key: 'worksheetId', + type: 'dropdown' as const, + required: true, + dependsOn: ['parameters.spreadsheetId'], + description: + 'The worksheets in your selected spreadsheet. You must have column headers.', + variables: false, + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listWorksheets', + }, + { + name: 'parameters.spreadsheetId', + value: '{parameters.spreadsheetId}', + }, + ], + }, + }, + { + label: 'Trigger Column', + key: 'triggerColumnIndex', + type: 'dropdown' as const, + required: false, + dependsOn: ['parameters.worksheetId'], + description: + 'Triggers on changes to cells in this column only. Leave this field blank if you want the flow to trigger on changes to any cell within the row. Please note: All new rows will trigger the flow even if the Trigger column is empty.', + variables: false, + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listColumns', + }, + { + name: 'parameters.spreadsheetId', + value: '{parameters.spreadsheetId}', + }, + { + name: 'parameters.worksheetId', + value: '{parameters.worksheetId}', + }, + ], + }, + }, + ], + + async run($) { + await newOrUpdatedSpreadsheetRows($); + }, +}); diff --git a/packages/backend/src/apps/google-sheets/triggers/new-or-updated-spreadsheet-rows/new-or-updated-spreadsheet-rows.ts b/packages/backend/src/apps/google-sheets/triggers/new-or-updated-spreadsheet-rows/new-or-updated-spreadsheet-rows.ts new file mode 100644 index 00000000..356b786d --- /dev/null +++ b/packages/backend/src/apps/google-sheets/triggers/new-or-updated-spreadsheet-rows/new-or-updated-spreadsheet-rows.ts @@ -0,0 +1,50 @@ +import { IGlobalVariable } from '@automatisch/types'; + +type TSheetsResponse = { + sheets: { + properties: { + sheetId: string; + title: string; + }; + }[]; +}; + +const newOrUpdatedSpreadsheetRows = async ($: IGlobalVariable) => { + const { + data: { sheets }, + } = await $.http.get( + `/v4/spreadsheets/${$.step.parameters.spreadsheetId}` + ); + + const selectedSheet = sheets.find( + (sheet) => sheet.properties.sheetId === $.step.parameters.worksheetId + ); + + if (!selectedSheet) return; + + const sheetName = selectedSheet.properties.title; + + let range = sheetName; + + if ($.step.parameters.triggerColumnIndex) { + range = `${sheetName}!${$.step.parameters.triggerColumnIndex}:${$.step.parameters.triggerColumnIndex}`; + } + + const { data } = await $.http.get( + `v4/spreadsheets/${$.step.parameters.spreadsheetId}/values/${range}` + ); + + if (data.values?.length) { + for (let index = data.values.length - 1; index > 0; index--) { + const value = data.values[index]; + $.pushTriggerItem({ + raw: { row: value }, + meta: { + internalId: `${value}-${index.toString()}`, + }, + }); + } + } +}; + +export default newOrUpdatedSpreadsheetRows;