226 lines
No EOL
8.5 KiB
TypeScript
226 lines
No EOL
8.5 KiB
TypeScript
import { docs_v1, drive_v3, google, sheets_v4 } from "googleapis";
|
|
import fs from "fs";
|
|
import { CREDENTIALS_PATH, DEBUG, FOLDER_MIMETYPE, LOG_SHEET_HEADER_VALUES, SHEET_MIMETYPE } from "../../serverConfig";
|
|
import z from "zod";
|
|
|
|
const SCOPES = ["https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/drive.file"]
|
|
const MAX_RETRY = 3;
|
|
|
|
export const LogRowDataSchema = z.object({
|
|
timestamp: z.string(),
|
|
meetingDate: z.string(),
|
|
title: z.string(),
|
|
matchedCompanyName: z.string(),
|
|
ownerName: z.string(),
|
|
meetingUrl: z.string(),
|
|
documentUrl: z.string(),
|
|
hubspotUrl: z.string(),
|
|
});
|
|
|
|
export type LogRowData = z.infer<typeof LogRowDataSchema>
|
|
|
|
export const googleDriveController = {
|
|
getAuth: async (): Promise<any> => {
|
|
try {
|
|
const credentials = JSON.parse(process.env.SEARVICE_ACCOUNT_CREDENTIALS || "{}");
|
|
console.log(credentials)
|
|
const auth = await new google.auth.GoogleAuth({
|
|
credentials: credentials,
|
|
scopes: SCOPES,
|
|
});
|
|
if (!auth) return null;
|
|
return auth;
|
|
} catch (error) {
|
|
console.error("Error obtaining Google Auth:", error);
|
|
return null;
|
|
}
|
|
},
|
|
getDriveClient: (auth: any): drive_v3.Drive => {
|
|
// console.log("Google Drive client authenticated.");
|
|
const drive = google.drive({ version: "v3", auth: auth });
|
|
return drive;
|
|
},
|
|
getSheetsClient: (auth: any): sheets_v4.Sheets => {
|
|
const sheets = google.sheets({ version: "v4", auth: auth });
|
|
return sheets;
|
|
},
|
|
getDocsClient: (auth: any): docs_v1.Docs => {
|
|
const docs = google.docs({ version: "v1", auth: auth });
|
|
return docs;
|
|
},
|
|
|
|
uploadFile: async (driveClient: drive_v3.Drive, filePath: string, folderId: string, fileName: string): Promise<any> => {
|
|
try {
|
|
console.log("Uploading file to Google Drive:", filePath);
|
|
const response = await driveClient.files.create({
|
|
requestBody: {
|
|
name: fileName,
|
|
parents: [folderId],
|
|
},
|
|
media: {
|
|
mimeType: "application/zip",
|
|
body: fs.createReadStream(filePath),
|
|
},
|
|
});
|
|
console.log("File uploaded, Id:", response.data.id);
|
|
fs.unlinkSync(filePath);
|
|
return response.data.id;
|
|
} catch (error) {
|
|
console.error("Error uploading file:", error);
|
|
fs.unlinkSync(filePath);
|
|
return null;
|
|
}
|
|
},
|
|
getFolderId: async (driveClient: drive_v3.Drive, folderId: string, fileName: string): Promise<string | null> => {
|
|
try {
|
|
const existsFolderId = await googleDriveController.searchFileIdByFileName(driveClient, folderId, fileName);
|
|
if(existsFolderId) return existsFolderId;
|
|
console.log('=== Create New Folder ===')
|
|
const newFolderId = googleDriveController.createNewFile(driveClient, folderId, fileName, FOLDER_MIMETYPE);
|
|
if(!newFolderId) return null;
|
|
return newFolderId;
|
|
} catch (error) {
|
|
console.error('Error searching files:', error);
|
|
return null;
|
|
}
|
|
},
|
|
searchFileIdByFileName: async (driveClient: drive_v3.Drive, folderId: string, fileName: string): Promise<string | null> => {
|
|
try {
|
|
const params = googleDriveController.getSearchFileParamsByDebugMode(folderId);
|
|
const res = await driveClient.files.list(params);
|
|
console.log("Files:");
|
|
console.log(res.data.files);
|
|
if(!res.data.files) return null;
|
|
|
|
for(const file of res.data.files) {
|
|
if(fileName === file.name) {
|
|
if(!file.id) return null;
|
|
return file.id;
|
|
}
|
|
}
|
|
return null;
|
|
} catch (error) {
|
|
console.error('Error searching files:', error);
|
|
return null;
|
|
}
|
|
},
|
|
getSearchFileParamsByDebugMode: (folderId: string): drive_v3.Params$Resource$Files$List => {
|
|
if(DEBUG) {
|
|
return {
|
|
corpora: 'user',
|
|
q: `'${folderId}' in parents`,
|
|
pageSize: 10,
|
|
fields: "files(id, name)",
|
|
includeItemsFromAllDrives: true,
|
|
includeTeamDriveItems: true,
|
|
supportsAllDrives: true
|
|
}
|
|
}
|
|
return {
|
|
corpora: 'drive',
|
|
driveId: process.env.GOOGLE_DRIVE_FOLDER_ID,
|
|
q: `'${folderId}' in parents`,
|
|
pageSize: 10,
|
|
fields: "files(id, name)",
|
|
includeItemsFromAllDrives: true,
|
|
includeTeamDriveItems: true,
|
|
supportsAllDrives: true
|
|
}
|
|
},
|
|
createNewFile: async (driveClient: drive_v3.Drive, folderId: string, fileName: string, mimeType: string): Promise<string | null> => {
|
|
try {
|
|
const requestBody = {
|
|
name: fileName,
|
|
parents: [folderId], // 作成したフォルダのIDを指定
|
|
mimeType: mimeType,
|
|
};
|
|
|
|
const file = await driveClient.files.create({
|
|
requestBody,
|
|
// fields: 'id',
|
|
});
|
|
|
|
console.log('File Id:', file.data);
|
|
if (!file.data.id) return null;
|
|
return file.data.id;
|
|
} catch (error) {
|
|
console.error('Error creating file:', error);
|
|
return null;
|
|
}
|
|
},
|
|
// CAUTION
|
|
deleteFile: async (driveClient: drive_v3.Drive, fileId: string) => {
|
|
try {
|
|
const body = { trashed: true }
|
|
const response = await driveClient.files.update({
|
|
fileId: fileId,
|
|
requestBody: body,
|
|
});
|
|
console.log('File deleted:', response.data);
|
|
} catch (error) {
|
|
console.error('Error deleting file:', error);
|
|
}
|
|
},
|
|
addContentToDocs: async (docsClient: docs_v1.Docs, documentId: string, content: string): Promise<boolean> => {
|
|
try {
|
|
const requestBody: docs_v1.Schema$BatchUpdateDocumentRequest = {
|
|
requests: [
|
|
{
|
|
insertText: {
|
|
text: content,
|
|
location: {
|
|
index: 1,
|
|
}
|
|
}
|
|
}
|
|
]
|
|
};
|
|
const response = await docsClient.documents.batchUpdate({
|
|
documentId: documentId,
|
|
requestBody: requestBody,
|
|
});
|
|
console.log('Content added to document:', response.data);
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Error adding content to document:', error);
|
|
return false;
|
|
}
|
|
},
|
|
|
|
getLogSheetId: async (driveClient: drive_v3.Drive, sheetsClient: sheets_v4.Sheets, folderId: string, fileName: string): Promise<string | null> => {
|
|
try {
|
|
const existsSheetId = await googleDriveController.searchFileIdByFileName(driveClient, folderId, fileName);
|
|
if(existsSheetId) return existsSheetId;
|
|
console.log('=== Create New Sheet ===')
|
|
const newSheetId = await googleDriveController.createNewFile(driveClient, folderId, fileName, SHEET_MIMETYPE);
|
|
if(!newSheetId) return null;
|
|
//
|
|
await googleDriveController.insertRowToSheet(sheetsClient, newSheetId, ['※シート名変更厳禁']);
|
|
await googleDriveController.insertRowToSheet(sheetsClient, newSheetId, LOG_SHEET_HEADER_VALUES);
|
|
return newSheetId;
|
|
} catch (error) {
|
|
console.error('Error searching files:', error);
|
|
return null;
|
|
}
|
|
},
|
|
|
|
insertRowToSheet: async (sheetsClient: sheets_v4.Sheets, sheetId: string, rowData: string[] ): Promise<boolean> => {
|
|
try {
|
|
const body = {
|
|
values: [rowData]
|
|
}
|
|
const params: sheets_v4.Params$Resource$Spreadsheets$Values$Append = {
|
|
spreadsheetId: sheetId,
|
|
range: 'Sheet1',
|
|
valueInputOption: 'USER_ENTERED',
|
|
insertDataOption: 'INSERT_ROWS',
|
|
requestBody: body,
|
|
}
|
|
await sheetsClient.spreadsheets.values.append(params);
|
|
return true;
|
|
} catch (error) {
|
|
console.log(error);
|
|
return false;
|
|
}
|
|
},
|
|
}; |