fix: access token expiration issue in google sheet integration (#2667)

This commit is contained in:
Dhruwang Jariwala
2024-05-24 15:28:42 +05:30
committed by GitHub
parent af09e315c5
commit b56b2adb54
4 changed files with 38 additions and 19 deletions

View File

@@ -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);
}

View File

@@ -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);
}}
/>
<span className="ml-2">{getLocalizedValue(question.headline, "default")}</span>
<span className="ml-2 w-[30rem] truncate">
{getLocalizedValue(question.headline, "default")}
</span>
</label>
</div>
))}

View File

@@ -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);
}
}
}

View File

@@ -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<string> => {
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;