diff --git a/apps/web/app/(app)/environments/[environmentId]/integrations/google-sheets/actions.ts b/apps/web/app/(app)/environments/[environmentId]/integrations/google-sheets/actions.ts index d8130d46ac..3bdd6b4b33 100644 --- a/apps/web/app/(app)/environments/[environmentId]/integrations/google-sheets/actions.ts +++ b/apps/web/app/(app)/environments/[environmentId]/integrations/google-sheets/actions.ts @@ -6,10 +6,10 @@ import { authOptions } from "@formbricks/lib/authOptions"; import { hasUserEnvironmentAccess } from "@formbricks/lib/environment/auth"; import { getSpreadsheetNameById } from "@formbricks/lib/googleSheet/service"; import { AuthorizationError } from "@formbricks/types/errors"; -import { TIntegrationGoogleSheetsCredential } from "@formbricks/types/integration/googleSheet"; +import { TIntegrationGoogleSheets } from "@formbricks/types/integration/googleSheet"; export async function getSpreadsheetNameByIdAction( - credentials: TIntegrationGoogleSheetsCredential, + googleSheetIntegration: TIntegrationGoogleSheets, environmentId: string, spreadsheetId: string ) { @@ -19,5 +19,5 @@ export async function getSpreadsheetNameByIdAction( const isAuthorized = await hasUserEnvironmentAccess(session.user.id, environmentId); if (!isAuthorized) throw new AuthorizationError("Not authorized"); - return await getSpreadsheetNameById(credentials, spreadsheetId); + return await getSpreadsheetNameById(googleSheetIntegration, spreadsheetId); } diff --git a/apps/web/app/(app)/environments/[environmentId]/integrations/google-sheets/components/AddIntegrationModal.tsx b/apps/web/app/(app)/environments/[environmentId]/integrations/google-sheets/components/AddIntegrationModal.tsx index fa58755fd6..09430c8708 100644 --- a/apps/web/app/(app)/environments/[environmentId]/integrations/google-sheets/components/AddIntegrationModal.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/integrations/google-sheets/components/AddIntegrationModal.tsx @@ -71,9 +71,7 @@ export const AddIntegrationModal = ({ useEffect(() => { if (selectedSurvey) { const questionIds = selectedSurvey.questions.map((question) => question.id); - if (!selectedIntegration) { - setSelectedQuestions(questionIds); - } + setSelectedQuestions(questionIds); } }, [selectedIntegration, selectedSurvey]); @@ -106,7 +104,7 @@ export const AddIntegrationModal = ({ } const spreadsheetId = extractSpreadsheetIdFromUrl(spreadsheetUrl); const spreadsheetName = await getSpreadsheetNameByIdAction( - googleSheetIntegration.config.key, + googleSheetIntegration, environmentId, spreadsheetId ); @@ -231,7 +229,9 @@ export const AddIntegrationModal = ({ handleCheckboxChange(question.id); }} /> - {getLocalizedValue(question.headline, "default")} + + {getLocalizedValue(question.headline, "default")} + ))} diff --git a/apps/web/app/api/pipeline/lib/handleIntegrations.ts b/apps/web/app/api/pipeline/lib/handleIntegrations.ts index b4797882f5..a400fdb32d 100644 --- a/apps/web/app/api/pipeline/lib/handleIntegrations.ts +++ b/apps/web/app/api/pipeline/lib/handleIntegrations.ts @@ -59,8 +59,12 @@ const handleGoogleSheetsIntegration = async ( if (integration.config.data.length > 0) { for (const element of integration.config.data) { if (element.surveyId === data.surveyId) { - const values = await extractResponses(data, element.questionIds as string[], survey); - await writeData(integration.config.key, element.spreadsheetId, values); + const values = await extractResponses(data, element.questionIds, survey); + const integrationData = structuredClone(integration); + integrationData.config.data.forEach((data) => { + data.createdAt = new Date(data.createdAt); + }); + await writeData(integrationData, element.spreadsheetId, values); } } } diff --git a/packages/lib/googleSheet/service.ts b/packages/lib/googleSheet/service.ts index 601163701c..e410965f41 100644 --- a/packages/lib/googleSheet/service.ts +++ b/packages/lib/googleSheet/service.ts @@ -6,8 +6,8 @@ import { z } from "zod"; import { ZString } from "@formbricks/types/common"; import { DatabaseError, UnknownError } from "@formbricks/types/errors"; import { - TIntegrationGoogleSheetsCredential, - ZIntegrationGoogleSheetsCredential, + TIntegrationGoogleSheets, + ZIntegrationGoogleSheets, } from "@formbricks/types/integration/googleSheet"; import { @@ -15,23 +15,24 @@ import { GOOGLE_SHEETS_CLIENT_SECRET, GOOGLE_SHEETS_REDIRECT_URL, } from "../constants"; +import { createOrUpdateIntegration } from "../integration/service"; import { validateInputs } from "../utils/validate"; const { google } = require("googleapis"); export const writeData = async ( - credentials: TIntegrationGoogleSheetsCredential, + integrationData: TIntegrationGoogleSheets, spreadsheetId: string, values: string[][] ) => { validateInputs( - [credentials, ZIntegrationGoogleSheetsCredential], + [integrationData, ZIntegrationGoogleSheets], [spreadsheetId, ZString], [values, z.array(z.array(ZString))] ); try { - const authClient = authorize(credentials); + const authClient = await authorize(integrationData); const sheets = google.sheets({ version: "v4", auth: authClient }); const responses = { values: [values[0]] }; const question = { values: [values[1]] }; @@ -71,13 +72,13 @@ export const writeData = async ( }; export const getSpreadsheetNameById = async ( - credentials: TIntegrationGoogleSheetsCredential, + googleSheetIntegrationData: TIntegrationGoogleSheets, spreadsheetId: string ): Promise => { - validateInputs([credentials, ZIntegrationGoogleSheetsCredential]); + validateInputs([googleSheetIntegrationData, ZIntegrationGoogleSheets]); try { - const authClient = authorize(credentials); + const authClient = await authorize(googleSheetIntegrationData); const sheets = google.sheets({ version: "v4", auth: authClient }); return new Promise((resolve, reject) => { @@ -98,11 +99,25 @@ export const getSpreadsheetNameById = async ( } }; -const authorize = (credentials: any) => { +const authorize = async (googleSheetIntegrationData: TIntegrationGoogleSheets) => { const client_id = GOOGLE_SHEETS_CLIENT_ID; const client_secret = GOOGLE_SHEETS_CLIENT_SECRET; const redirect_uri = GOOGLE_SHEETS_REDIRECT_URL; const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uri); + const refresh_token = googleSheetIntegrationData.config.key.refresh_token; + oAuth2Client.setCredentials({ + refresh_token, + }); + const { credentials } = await oAuth2Client.refreshAccessToken(); + await createOrUpdateIntegration(googleSheetIntegrationData.environmentId, { + type: "googleSheets", + config: { + data: googleSheetIntegrationData.config?.data ?? [], + email: googleSheetIntegrationData.config?.email ?? "", + key: credentials, + }, + }); + oAuth2Client.setCredentials(credentials); return oAuth2Client;