Files
formbricks-formbricks/apps/web/lib/googleSheet/service.ts
Anshuman Pandey f888aa8a19 feat: MQP (#6901)
Co-authored-by: Matti Nannt <matti@formbricks.com>
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Dhruwang Jariwala <67850763+Dhruwang@users.noreply.github.com>
Co-authored-by: Dhruwang <dhruwangjariwala18@gmail.com>
2025-11-28 12:36:17 +00:00

135 lines
4.0 KiB
TypeScript

import "server-only";
import { Prisma } from "@prisma/client";
import { z } from "zod";
import { ZString } from "@formbricks/types/common";
import { DatabaseError, UnknownError } from "@formbricks/types/errors";
import {
TIntegrationGoogleSheets,
ZIntegrationGoogleSheets,
} from "@formbricks/types/integration/google-sheet";
import {
GOOGLE_SHEETS_CLIENT_ID,
GOOGLE_SHEETS_CLIENT_SECRET,
GOOGLE_SHEETS_REDIRECT_URL,
} from "@/lib/constants";
import { GOOGLE_SHEET_MESSAGE_LIMIT } from "@/lib/constants";
import { createOrUpdateIntegration } from "@/lib/integration/service";
import { truncateText } from "../utils/strings";
import { validateInputs } from "../utils/validate";
const { google } = require("googleapis");
export const writeData = async (
integrationData: TIntegrationGoogleSheets,
spreadsheetId: string,
responses: string[],
elements: string[]
) => {
validateInputs(
[integrationData, ZIntegrationGoogleSheets],
[spreadsheetId, ZString],
[responses, z.array(ZString)],
[elements, z.array(ZString)]
);
try {
const authClient = await authorize(integrationData);
const sheets = google.sheets({ version: "v4", auth: authClient });
const responsesMapped = {
values: [
responses.map((response) =>
response.length > GOOGLE_SHEET_MESSAGE_LIMIT
? truncateText(response, GOOGLE_SHEET_MESSAGE_LIMIT)
: response
),
],
};
const element = { values: [elements] };
sheets.spreadsheets.values.update(
{
spreadsheetId: spreadsheetId,
range: "A1",
valueInputOption: "RAW",
resource: element,
},
(err: Error) => {
if (err) {
throw new UnknownError(`Error while appending data: ${err.message}`);
}
}
);
sheets.spreadsheets.values.append(
{
spreadsheetId: spreadsheetId,
range: "A2",
valueInputOption: "RAW",
resource: responsesMapped,
},
(err: Error) => {
if (err) {
throw new UnknownError(`Error while appending data: ${err.message}`);
}
}
);
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
throw new DatabaseError(error.message);
}
throw error;
}
};
export const getSpreadsheetNameById = async (
googleSheetIntegrationData: TIntegrationGoogleSheets,
spreadsheetId: string
): Promise<string> => {
validateInputs([googleSheetIntegrationData, ZIntegrationGoogleSheets]);
try {
const authClient = await authorize(googleSheetIntegrationData);
const sheets = google.sheets({ version: "v4", auth: authClient });
return new Promise((resolve, reject) => {
sheets.spreadsheets.get({ spreadsheetId }, (err, response) => {
if (err) {
reject(new UnknownError(`Error while fetching spreadsheet data: ${err.message}`));
return;
}
const spreadsheetTitle = response.data.properties.title;
resolve(spreadsheetTitle);
});
});
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
throw new DatabaseError(error.message);
}
throw error;
}
};
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;
};