From 49b5004a098058af2666ce2b8ef922587f17e646 Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Wed, 27 Mar 2024 00:16:34 +0300 Subject: [PATCH 1/3] app script for sending latest changes from googlesheet --- code.gs | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 code.gs diff --git a/code.gs b/code.gs new file mode 100644 index 0000000..9f092b2 --- /dev/null +++ b/code.gs @@ -0,0 +1,110 @@ +function onEdit(e) { + const range = e.range; + const editedRow = range.getRow(); + const editedColumn = range.getColumn(); + const newValue = e.value; + const oldValue = e.oldValue; + const user = e.user; + + // Fetch values for the specified row + const sheet = e.range.getSheet(); + const editRowRange = sheet.getRange(editedRow, 1, 1, sheet.getLastColumn()); + const editedRowValues = editRowRange.getValues()[0]; + const headerRow = 1; + const sheetRows = sheet.getRange(headerRow, 1, 1, sheet.getLastColumn()); + const headers = sheetRows.getValues()[0]; + + Logger.log('Edited Row Values: ' + editedRowValues); + + const task_id = editedRowValues[0]; + const columnName = headers[editedColumn - 1]; + + Logger.log( + 'Change detected in row ' + editedRow + ', column ' + editedColumn + ':' + ); + Logger.log('New value:' + newValue); + Logger.log('Old value:' + oldValue); + + // Get the stored changes or initialize an empty object + let storedChanges = + PropertiesService.getScriptProperties().getProperty('changes'); + storedChanges = storedChanges ? JSON.parse(storedChanges) : {}; + + // Store the change in the storedChanges object + storedChanges['headers'] = headers; + storedChanges[task_id] = [ + { + values: editedRowValues, + activity: { + row: editedRow, + column: editedColumn, + columnName, + user, + oldValue, + newValue, + }, + }, + ]; + + Logger.log('Updates' + JSON.stringify(storedChanges)); + + // Save the updated changes back to the PropertiesService + PropertiesService.getScriptProperties().setProperty( + 'changes', + JSON.stringify(storedChanges) + ); +} +// Function to create a custom menu +function onOpen() { + const ui = SpreadsheetApp.getUi(); + ui.createMenu('OpenFn ⚡️') + .addItem('Sync Changes 🔄', 'syncChangesToOpenFn') + .addToUi(); +} + +function syncChangesToOpenFn() { + // Access changes object from PropertiesService + let storedChanges = + PropertiesService.getScriptProperties().getProperty('changes'); + storedChanges = storedChanges ? JSON.parse(storedChanges) : {}; + Logger.log('storedChanges ' + JSON.stringify(storedChanges)); + + // Make a POST request to the REST API URL + const apiUrl = 'OPENFN_WEBHOOK_URL'; // Replace with your API endpoint URL + const options = { + method: 'post', + contentType: 'application/json', + payload: JSON.stringify(storedChanges), + }; + + try { + const response = UrlFetchApp.fetch(apiUrl, options); + Logger.log('Data synced successfully:', response.getContentText()); + //Clear stored changes after syncing + PropertiesService.getScriptProperties().deleteProperty('changes'); + } catch (error) { + Logger.log('Error syncing data:', error); + } +} + +function createDailyTrigger() { + // Delete existing triggers to prevent duplicates + var existingTriggers = ScriptApp.getProjectTriggers(); + for (var i = 0; i < existingTriggers.length; i++) { + if (existingTriggers[i].getHandlerFunction() == 'syncChangesToOpenFn') { + ScriptApp.deleteTrigger(existingTriggers[i]); + } + } + + // Set the time for triggering the syncToApi function + var triggerDay = new Date(); + triggerDay.setHours(23); // Set the hour to 23 (11 PM) - adjust as needed + triggerDay.setMinutes(55); // Set the minutes to 55 (55 minutes) - adjust as needed + + // Create the trigger to run syncToApi daily close to end of day + ScriptApp.newTrigger('syncChangesToOpenFn') + .timeBased() + .everyMinutes(1) // Change to .at(triggerDay) for daily execution + // .at(triggerDay) + .create(); +} From a2426c601234a2bf85b477d70faf62b860cbc2f5 Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Wed, 27 Mar 2024 15:30:56 +0300 Subject: [PATCH 2/3] create task comment --- code.gs | 40 +++++++++++++++++++++++++------------- createTaskComment.js | 46 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 createTaskComment.js diff --git a/code.gs b/code.gs index 9f092b2..82a900b 100644 --- a/code.gs +++ b/code.gs @@ -16,7 +16,7 @@ function onEdit(e) { Logger.log('Edited Row Values: ' + editedRowValues); - const task_id = editedRowValues[0]; + const uniqueId = editedRowValues[0]; const columnName = headers[editedColumn - 1]; Logger.log( @@ -30,21 +30,35 @@ function onEdit(e) { PropertiesService.getScriptProperties().getProperty('changes'); storedChanges = storedChanges ? JSON.parse(storedChanges) : {}; + if (!storedChanges[uniqueId]) { + storedChanges[uniqueId] = []; + } + + const comment = + user.nickname + + ' updated ' + + columnName + + ' for ' + + uniqueId + + ' from ' + + oldValue + + ' to ' + + newValue; // Store the change in the storedChanges object storedChanges['headers'] = headers; - storedChanges[task_id] = [ - { - values: editedRowValues, - activity: { - row: editedRow, - column: editedColumn, - columnName, - user, - oldValue, - newValue, - }, + storedChanges[uniqueId].push({ + values: editedRowValues, + activity: { + row: editedRow, + column: editedColumn, + columnName, + user, + oldValue, + newValue, }, - ]; + comment, + modified: new Date(), + }); Logger.log('Updates' + JSON.stringify(storedChanges)); diff --git a/createTaskComment.js b/createTaskComment.js new file mode 100644 index 0000000..0eb7b25 --- /dev/null +++ b/createTaskComment.js @@ -0,0 +1,46 @@ +fn(s => { + const taskIds = Object.keys(s.data).filter(i => i !== 'headers' && i !== ''); + const getStories = taskId => { + return s.data[taskId] + .filter(i => i !== 'headers') + .map(story => ({ + text: story.comment, + // html_text: `${story.comment}`, + is_pinned: false, + // sticker_name: 'dancing_unicorn', + })); + }; + + // Array of objects representing tasks with their respective stories + s.tasksWithStories = taskIds.map(task => { + return { + taskId: task, + stories: getStories(task), + }; + }); + + // console.log(s.tasksWithStories); + + return s; +}); + +each('$.tasksWithStories[*]', async state => { + const { taskId, stories } = state.data; + for (const story of stories) { + await createStoryForTask(taskId, { story })(state); + } + return state; +}); + +each('$.tasksWithStories[*]', async state => { + const { taskId, stories } = state.data; + for (const story of stories) { + await sendRequest(`tasks/${taskId}/stories`, { + query: { opt_fields: [] }, + body: { + data: story, + }, + })(state); + } + return state; +}); From 0574f5c5fd9652399a4684453e7421a393e5942d Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Wed, 27 Mar 2024 22:15:48 +0300 Subject: [PATCH 3/3] update functions name --- createTaskComment.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/createTaskComment.js b/createTaskComment.js index 0eb7b25..de2ae85 100644 --- a/createTaskComment.js +++ b/createTaskComment.js @@ -27,7 +27,7 @@ fn(s => { each('$.tasksWithStories[*]', async state => { const { taskId, stories } = state.data; for (const story of stories) { - await createStoryForTask(taskId, { story })(state); + await createTaskStory(taskId, { story })(state); } return state; }); @@ -35,7 +35,7 @@ each('$.tasksWithStories[*]', async state => { each('$.tasksWithStories[*]', async state => { const { taskId, stories } = state.data; for (const story of stories) { - await sendRequest(`tasks/${taskId}/stories`, { + await request(`tasks/${taskId}/stories`, { query: { opt_fields: [] }, body: { data: story,