2
0
Files
bot/packages/bot-engine/blocks/integrations/googleSheets/getRow.ts

113 lines
3.4 KiB
TypeScript
Raw Normal View History

import {
SessionState,
GoogleSheetsGetOptions,
VariableWithValue,
ChatLog,
} from '@typebot.io/schemas'
import { isNotEmpty, byId, isDefined } from '@typebot.io/lib'
import { getAuthenticatedGoogleDoc } from './helpers/getAuthenticatedGoogleDoc'
import { ExecuteIntegrationResponse } from '../../../types'
import { matchFilter } from './helpers/matchFilter'
import { deepParseVariables } from '@typebot.io/variables/deepParseVariables'
import { updateVariablesInSession } from '@typebot.io/variables/updateVariablesInSession'
2022-11-29 10:02:40 +01:00
export const getRow = async (
state: SessionState,
{
outgoingEdgeId,
options,
}: { outgoingEdgeId?: string; options: GoogleSheetsGetOptions }
): Promise<ExecuteIntegrationResponse> => {
const logs: ChatLog[] = []
const { variables } = state.typebotsQueue[0].typebot
const { sheetId, cellsToExtract, filter, ...parsedOptions } =
deepParseVariables(variables)(options)
if (!sheetId) return { outgoingEdgeId }
2022-11-29 10:02:40 +01:00
const doc = await getAuthenticatedGoogleDoc({
credentialsId: options.credentialsId,
spreadsheetId: options.spreadsheetId,
})
try {
await doc.loadInfo()
2023-07-15 10:46:36 +02:00
const sheet = doc.sheetsById[Number(sheetId)]
2022-11-29 10:02:40 +01:00
const rows = await sheet.getRows()
const filteredRows = getTotalRows(
options.totalRowsToExtract,
rows.filter((row) =>
'referenceCell' in parsedOptions && parsedOptions.referenceCell
? row.get(parsedOptions.referenceCell?.column as string) ===
parsedOptions.referenceCell?.value
: matchFilter(row, filter)
)
2022-11-29 10:02:40 +01:00
)
if (filteredRows.length === 0) {
logs.push({
status: 'info',
description: `Couldn't find any rows matching the filter`,
details: JSON.stringify(filter, null, 2),
2022-11-29 10:02:40 +01:00
})
return { outgoingEdgeId, logs }
2022-11-29 10:02:40 +01:00
}
const extractingColumns = cellsToExtract
?.map((cell) => cell.column)
.filter(isNotEmpty)
const selectedRows = filteredRows
.map((row) =>
extractingColumns?.reduce<{ [key: string]: string }>(
(obj, column) => ({ ...obj, [column]: row.get(column) }),
{}
)
)
.filter(isDefined)
if (!selectedRows) return { outgoingEdgeId }
2022-11-29 10:02:40 +01:00
const newVariables = options.cellsToExtract?.reduce<VariableWithValue[]>(
2022-11-29 10:02:40 +01:00
(newVariables, cell) => {
const existingVariable = variables.find(byId(cell.variableId))
const value = selectedRows.map((row) => row[cell.column ?? ''])
2022-11-29 10:02:40 +01:00
if (!existingVariable) return newVariables
return [
...newVariables,
{
...existingVariable,
value: value.length === 1 ? value[0] : value,
2022-11-29 10:02:40 +01:00
},
]
},
[]
)
if (!newVariables) return { outgoingEdgeId }
const newSessionState = updateVariablesInSession(state)(newVariables)
2022-11-29 10:02:40 +01:00
return {
outgoingEdgeId,
newSessionState,
}
} catch (err) {
logs.push({
status: 'error',
description: `An error occurred while fetching the spreadsheet data`,
details: err,
2022-11-29 10:02:40 +01:00
})
}
return { outgoingEdgeId, logs }
2022-11-29 10:02:40 +01:00
}
const getTotalRows = <T>(
totalRowsToExtract: GoogleSheetsGetOptions['totalRowsToExtract'],
rows: T[]
): T[] => {
switch (totalRowsToExtract) {
case 'All':
case undefined:
return rows
case 'First':
return rows.slice(0, 1)
case 'Last':
return rows.slice(-1)
case 'Random':
return [rows[Math.floor(Math.random() * rows.length)]]
}
}