import * as z from "zod" import { defineAction } from "../../../automation/actions" import { getGoogleSheetsApi, normalizeSpreadsheetId, normalizeValueUpdate, toGoogleDateTimeRender, toGoogleMajorDimension, toGoogleValueRender, } from "../lib/google-sheets" import { GOOGLE_SHEETS_WRITE_REQUIREMENT } from "../lib/scopes" import { APPEND_VALUES_RESULT_SCHEMA, CELL_VALUES_SCHEMA, DATE_TIME_RENDER_SCHEMA, MAJOR_DIMENSION_SCHEMA, SPREADSHEET_REFERENCE_SCHEMA, VALUE_INPUT_MODE_SCHEMA, VALUE_RENDER_SCHEMA, } from "../lib/schemas" /** Appends a matrix after the logical table detected within an A1 range. */ export const appendGoogleSheetsValues = defineAction( "Append Google Sheets values", ) .describe("Appends raw row- or column-major values to a detected table.") .account("google", GOOGLE_SHEETS_WRITE_REQUIREMENT) .input( z.object({ /** Whether updated values should be included in the result. */ includeValues: z.boolean().optional(), /** Whether new rows are inserted or existing cells may be overwritten. */ insertMode: z.enum(["insertRows", "overwrite"]).optional(), /** Whether strings are parsed like UI input or stored literally. */ inputMode: VALUE_INPUT_MODE_SCHEMA.optional(), /** Whether the outer array represents rows or columns. */ majorDimension: MAJOR_DIMENSION_SCHEMA.optional(), /** A1 range used to detect the logical table to append to. */ range: z.string().min(1), /** Date and time representation in returned values. */ responseDateTimeRender: DATE_TIME_RENDER_SCHEMA.optional(), /** Representation used for returned values. */ responseValueRender: VALUE_RENDER_SCHEMA.optional(), /** Spreadsheet ID or standard Google Sheets URL. */ spreadsheet: SPREADSHEET_REFERENCE_SCHEMA, /** Values appended to the detected table. */ values: CELL_VALUES_SCHEMA.min(1), }), ) .output(APPEND_VALUES_RESULT_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { const { data } = await getGoogleSheetsApi( account.secret, ).spreadsheets.values.append({ includeValuesInResponse: input.includeValues ?? false, insertDataOption: input.insertMode === "overwrite" ? "OVERWRITE" : "INSERT_ROWS", range: input.range, requestBody: { majorDimension: toGoogleMajorDimension(input.majorDimension), values: input.values.map((row) => row.map((value) => value ?? "")), }, responseDateTimeRenderOption: toGoogleDateTimeRender( input.responseDateTimeRender, ), responseValueRenderOption: toGoogleValueRender(input.responseValueRender), spreadsheetId: normalizeSpreadsheetId(input.spreadsheet), valueInputOption: input.inputMode === "raw" ? "RAW" : "USER_ENTERED", }) return { spreadsheetId: data.spreadsheetId ?? "", tableRange: data.tableRange ?? undefined, ...normalizeValueUpdate(data.updates ?? {}), } })