@guayaba/workflow-piece-google-drive 0.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/.babelrc +3 -0
  2. package/.eslintrc.json +18 -0
  3. package/README.md +5 -0
  4. package/assets/logo.png +0 -0
  5. package/package.json +28 -0
  6. package/src/i18n/ca.json +125 -0
  7. package/src/i18n/de.json +136 -0
  8. package/src/i18n/es.json +136 -0
  9. package/src/i18n/fr.json +136 -0
  10. package/src/i18n/hi.json +125 -0
  11. package/src/i18n/id.json +125 -0
  12. package/src/i18n/ja.json +136 -0
  13. package/src/i18n/nl.json +136 -0
  14. package/src/i18n/pt.json +136 -0
  15. package/src/i18n/ru.json +127 -0
  16. package/src/i18n/translation.json +137 -0
  17. package/src/i18n/vi.json +127 -0
  18. package/src/i18n/zh.json +136 -0
  19. package/src/index.ts +74 -0
  20. package/src/lib/action/add-permission.action.ts +78 -0
  21. package/src/lib/action/create-new-folder.ts +38 -0
  22. package/src/lib/action/create-new-text-file.ts +89 -0
  23. package/src/lib/action/delete-file.ts +31 -0
  24. package/src/lib/action/delete-permission.action.ts +80 -0
  25. package/src/lib/action/duplicate-file.action.ts +78 -0
  26. package/src/lib/action/get-file-by-id.ts +34 -0
  27. package/src/lib/action/list-files.action.ts +209 -0
  28. package/src/lib/action/move-file.ts +44 -0
  29. package/src/lib/action/read-file.ts +24 -0
  30. package/src/lib/action/save-file-as-pdf.action.ts +72 -0
  31. package/src/lib/action/search-folder-or-file.action.ts +108 -0
  32. package/src/lib/action/send-to-trash.ts +34 -0
  33. package/src/lib/action/set-public-access.ts +64 -0
  34. package/src/lib/action/upload-file.ts +72 -0
  35. package/src/lib/auth.ts +80 -0
  36. package/src/lib/common/get-file-content.ts +109 -0
  37. package/src/lib/common/index.ts +179 -0
  38. package/src/lib/triggers/new-file.ts +115 -0
  39. package/src/lib/triggers/new-folder.ts +74 -0
  40. package/tsconfig.json +16 -0
  41. package/tsconfig.lib.json +15 -0
@@ -0,0 +1,209 @@
1
+ import { HttpMethod, httpClient } from '@guayaba/workflows-common';
2
+ import { googleDriveAuth, getAccessToken } from '../auth';
3
+ import { Property, createAction } from "@guayaba/workflows-framework";
4
+ import querystring from 'querystring';
5
+ import { common } from '../common';
6
+ import { downloadFileFromDrive } from '../common/get-file-content';
7
+
8
+ interface ListFilesResult {
9
+ type: string;
10
+ incompleteSearch: boolean;
11
+ files: unknown[];
12
+ downloadedFiles?: string[];
13
+ }
14
+
15
+ interface FileWithLevel {
16
+ file: any;
17
+ level: number;
18
+ parentFolder?: string;
19
+ }
20
+
21
+ async function getFilesRecursively(
22
+ auth: any,
23
+ folderId: string,
24
+ maxLevel: number,
25
+ includeTrashed: boolean,
26
+ includeTeamDrives: boolean,
27
+ currentLevel = 0
28
+ ): Promise<FileWithLevel[]> {
29
+ const files: FileWithLevel[] = [];
30
+
31
+ if (currentLevel > maxLevel) {
32
+ return files;
33
+ }
34
+
35
+ const accessToken = await getAccessToken(auth);
36
+
37
+ let q = `'${folderId}' in parents`;
38
+ if (!includeTrashed) {
39
+ q += ' and trashed=false';
40
+ }
41
+
42
+ const params: Record<string, string> = {
43
+ q: q,
44
+ fields: 'nextPageToken,files(id,kind,mimeType,name,trashed,parents)',
45
+ supportsAllDrives: 'true',
46
+ includeItemsFromAllDrives: includeTeamDrives ? 'true' : 'false',
47
+ pageSize: '1000',
48
+ };
49
+
50
+ let response = await httpClient.sendRequest({
51
+ method: HttpMethod.GET,
52
+ url: `https://www.googleapis.com/drive/v3/files?${querystring.stringify(params)}`,
53
+ headers: {
54
+ Authorization: `Bearer ${accessToken}`,
55
+ },
56
+ });
57
+
58
+ // Add files from current level
59
+ for (const file of response.body.files) {
60
+ files.push({
61
+ file,
62
+ level: currentLevel,
63
+ parentFolder: folderId
64
+ });
65
+ }
66
+
67
+ // Handle pagination for current level
68
+ while (response.body.nextPageToken) {
69
+ params.pageToken = response.body.nextPageToken;
70
+ response = await httpClient.sendRequest({
71
+ method: HttpMethod.GET,
72
+ url: `https://www.googleapis.com/drive/v3/files?${querystring.stringify(params)}`,
73
+ headers: {
74
+ Authorization: `Bearer ${accessToken}`,
75
+ },
76
+ });
77
+
78
+ for (const file of response.body.files) {
79
+ files.push({
80
+ file,
81
+ level: currentLevel,
82
+ parentFolder: folderId
83
+ });
84
+ }
85
+ }
86
+
87
+ // If we haven't reached max level, recursively get files from subfolders
88
+ if (currentLevel + 1 < maxLevel) {
89
+ const subfolders = files.filter(f => f.file.mimeType === 'application/vnd.google-apps.folder');
90
+
91
+ for (const subfolder of subfolders) {
92
+ const subfolderFiles = await getFilesRecursively(
93
+ auth,
94
+ subfolder.file.id,
95
+ maxLevel,
96
+ includeTrashed,
97
+ includeTeamDrives,
98
+ currentLevel + 1
99
+ );
100
+ files.push(...subfolderFiles);
101
+ }
102
+ }
103
+
104
+ return files;
105
+ }
106
+
107
+ export const googleDriveListFiles = createAction({
108
+ auth: googleDriveAuth,
109
+ name: 'list-files',
110
+ displayName: 'List files',
111
+ description: 'List files from a Google Drive folder',
112
+ props: {
113
+ folderId: Property.ShortText({
114
+ displayName: 'Folder ID',
115
+ description: 'Folder ID coming from | New Folder -> id | (or any other source)',
116
+ required: true,
117
+ }),
118
+ include_team_drives: common.properties.include_team_drives,
119
+
120
+ includeTrashed: Property.Checkbox({
121
+ displayName: 'Include Trashed',
122
+ description: 'Include new files that have been trashed.',
123
+ required: false,
124
+ defaultValue: false
125
+ }),
126
+
127
+ depthLevel: Property.Number({
128
+ displayName: 'Depth Level',
129
+ description: 'How many levels deep to search for files. 1 = current folder only, 2 = current + next level, etc.',
130
+ required: false,
131
+ defaultValue: 1
132
+ }),
133
+
134
+ downloadFiles: Property.Checkbox({
135
+ displayName: 'Download Files',
136
+ description: 'Download all file contents in a list',
137
+ required: false,
138
+ defaultValue: false
139
+ }),
140
+ },
141
+ async run(context) {
142
+ const result: ListFilesResult = {
143
+ type: 'drive#fileList',
144
+ incompleteSearch: false,
145
+ files: [],
146
+ }
147
+
148
+ const depthLevel = context.propsValue.depthLevel || 1;
149
+
150
+ // Get files recursively based on depth level
151
+ const filesWithLevel = await getFilesRecursively(
152
+ context.auth,
153
+ context.propsValue.folderId,
154
+ depthLevel,
155
+ context.propsValue.includeTrashed ?? false,
156
+ context.propsValue.include_team_drives ?? false
157
+ );
158
+
159
+ // Extract just the file objects for backward compatibility
160
+ result.files = filesWithLevel.map(f => f.file);
161
+
162
+ // If downloadFiles is enabled, download each file and add URLs to array
163
+ if (context.propsValue.downloadFiles) {
164
+ const downloadedFiles: string[] = [];
165
+ const extensionMap: Record<string, string> = {
166
+ 'application/pdf': '.pdf',
167
+ 'image/jpeg': '.jpg',
168
+ 'image/png': '.png',
169
+ 'image/tiff': '.tiff',
170
+ 'text/plain': '.txt',
171
+ 'text/csv': '.csv',
172
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': '.docx',
173
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': '.xlsx'
174
+ };
175
+
176
+ for (const fileWithLevel of filesWithLevel) {
177
+ const file = fileWithLevel.file;
178
+ // Skip folders when downloading
179
+ if (file.mimeType === 'application/vnd.google-apps.folder') {
180
+ continue;
181
+ }
182
+
183
+ let safeName = file.name;
184
+ const correctExtension = extensionMap[file.mimeType];
185
+ if (correctExtension && !safeName.toLowerCase().endsWith(correctExtension)) {
186
+ // Check for the .jpeg edge case before appending .jpg
187
+ if (!(file.mimeType === 'image/jpeg' && safeName.toLowerCase().endsWith('.jpeg'))) {
188
+ safeName = safeName + correctExtension;
189
+ }
190
+ }
191
+
192
+ try {
193
+ const fileUrl = await downloadFileFromDrive(
194
+ context.auth,
195
+ context.files,
196
+ file.id,
197
+ safeName
198
+ );
199
+ downloadedFiles.push(fileUrl);
200
+ } catch (error) {
201
+ console.warn(`Failed to download file ${file.name}: ${error instanceof Error ? error.message : 'Download failed'}`);
202
+ }
203
+ }
204
+ result.downloadedFiles = downloadedFiles;
205
+ }
206
+
207
+ return result;
208
+ }
209
+ });
@@ -0,0 +1,44 @@
1
+ import { googleDriveAuth, createGoogleClient } from '../auth';
2
+ import { createAction, Property } from '@guayaba/workflows-framework';
3
+ import { common } from '../common';
4
+ import { google } from 'googleapis';
5
+
6
+ export const moveFileAction = createAction({
7
+ auth: googleDriveAuth,
8
+ name: 'google-drive-move-file',
9
+ displayName: 'Move File',
10
+ description: 'Moves a file from one folder to another.',
11
+ props: {
12
+ fileId: Property.ShortText({
13
+ displayName: 'File ID',
14
+ description: 'You can use **Search Folder/File** action to retrieve ID.',
15
+ required: true,
16
+ }),
17
+ include_team_drives: common.properties.include_team_drives,
18
+ folderId: common.properties.parentFolder,
19
+ },
20
+ async run(context) {
21
+ const fileId = context.propsValue.fileId;
22
+ const folderId = context.propsValue.folderId;
23
+
24
+ const authClient = await createGoogleClient(context.auth);
25
+
26
+ const drive = google.drive({ version: 'v3', auth: authClient });
27
+
28
+ const file = await drive.files.get({
29
+ fileId,
30
+ supportsAllDrives: context.propsValue.include_team_drives,
31
+ fields: 'id,parents',
32
+ });
33
+
34
+ const response = await drive.files.update({
35
+ fileId: fileId,
36
+ fields: '*',
37
+ removeParents: file.data.parents?.join(','),
38
+ addParents: folderId,
39
+ supportsAllDrives: context.propsValue.include_team_drives,
40
+ });
41
+
42
+ return response.data;
43
+ },
44
+ });
@@ -0,0 +1,24 @@
1
+ import { googleDriveAuth } from '../auth';
2
+ import { createAction, Property } from '@guayaba/workflows-framework';
3
+ import { downloadFileFromDrive } from '../common/get-file-content';
4
+
5
+ export const readFile = createAction({
6
+ auth: googleDriveAuth,
7
+ name: 'read-file',
8
+ displayName: 'Read File Content',
9
+ description: 'Read a selected file from google drive file',
10
+ props: {
11
+ fileId: Property.ShortText({
12
+ displayName: 'File ID',
13
+ description: 'File ID coming from | New File -> id |',
14
+ required: true,
15
+ }),
16
+ fileName: Property.ShortText({
17
+ displayName: 'Destination File name',
18
+ required: false,
19
+ }),
20
+ },
21
+ run: async ({ auth, propsValue, files }) => {
22
+ return downloadFileFromDrive(auth, files, propsValue.fileId, propsValue.fileName)
23
+ },
24
+ });
@@ -0,0 +1,72 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+
3
+ import { googleDriveAuth, createGoogleClient } from '../auth';
4
+ import { Property, createAction } from '@guayaba/workflows-framework';
5
+ import { google } from 'googleapis';
6
+ import { Stream } from 'stream';
7
+ import { common } from '../common';
8
+
9
+ export const saveFileAsPdf = createAction({
10
+ displayName: 'Save Document as PDF',
11
+ auth: googleDriveAuth,
12
+ name: 'save_file_as_pdf',
13
+ description: 'Save a document as PDF in a Google Drive folder',
14
+ props: {
15
+ documentId: Property.ShortText({
16
+ displayName: 'Document ID',
17
+ description: 'The ID of the document to export',
18
+ required: true,
19
+ }),
20
+ folderId: Property.ShortText({
21
+ displayName: 'Folder ID',
22
+ description: 'The ID of the folder where the file will be exported',
23
+ required: true,
24
+ }),
25
+ name: Property.ShortText({
26
+ displayName: 'Name',
27
+ description: 'The name of the new file (do not include the extension)',
28
+ required: true,
29
+ }),
30
+ include_team_drives: common.properties.include_team_drives,
31
+ },
32
+ async run(context) {
33
+ const authClient = await createGoogleClient(context.auth);
34
+
35
+ const documentId = context.propsValue.documentId;
36
+ const folderId = context.propsValue.folderId;
37
+ const nameForNewFile = context.propsValue.name;
38
+
39
+ const drive = google.drive({ version: 'v3', auth: authClient });
40
+
41
+ const result = await drive.files.export(
42
+ {
43
+ fileId: documentId,
44
+ mimeType: 'application/pdf',
45
+ },
46
+ {
47
+ responseType: 'arraybuffer',
48
+ }
49
+ );
50
+
51
+ const requestBody = {
52
+ name: nameForNewFile + '.pdf',
53
+ parents: [folderId],
54
+ };
55
+ const templateBuffer = Buffer.from(result.data as any, 'base64');
56
+
57
+ const stream = new Stream.PassThrough().end(templateBuffer);
58
+
59
+ const media = {
60
+ mimeType: 'application/pdf',
61
+ body: stream,
62
+ };
63
+
64
+ const file = await drive.files.create({
65
+ requestBody,
66
+ media: media,
67
+ supportsAllDrives: context.propsValue.include_team_drives,
68
+ });
69
+
70
+ return file.data;
71
+ },
72
+ });
@@ -0,0 +1,108 @@
1
+ import { googleDriveAuth, createGoogleClient } from '../auth';
2
+ import { Property, createAction } from '@guayaba/workflows-framework';
3
+ import { google } from 'googleapis';
4
+ import { common } from '../common';
5
+
6
+ export const googleDriveSearchFolder = createAction({
7
+ auth: googleDriveAuth,
8
+ name: 'search-folder',
9
+ displayName: 'Search',
10
+ description: 'Search a Google Drive folder for files/sub-folders',
11
+ props: {
12
+ queryTerm: Property.StaticDropdown({
13
+ displayName: 'Query Term',
14
+ description: 'The Query term or field of file/folder to search upon.',
15
+ defaultValue: 'name',
16
+ options: {
17
+ options: [
18
+ { label: 'File name', value: 'name' },
19
+ { label: 'Full text search', value: 'fullText' },
20
+ { label: 'Content type', value: 'mimeType' },
21
+ ],
22
+ },
23
+ required: true,
24
+ }),
25
+ operator: Property.StaticDropdown({
26
+ displayName: 'Operator',
27
+ description: 'The operator to create criteria.',
28
+ required: true,
29
+ options: {
30
+ options: [
31
+ { label: 'Contains', value: 'contains' },
32
+ { label: 'Equals', value: '=' },
33
+ ],
34
+ },
35
+ defaultValue: 'contains',
36
+ }),
37
+ query: Property.ShortText({
38
+ displayName: 'Value',
39
+ description: 'Value of the field of file/folder to search for.',
40
+ required: true,
41
+ }),
42
+ type: Property.StaticDropdown({
43
+ displayName: 'File Type',
44
+ description: '(Optional) Choose between files and folders.',
45
+ required: false,
46
+ options: {
47
+ options: [
48
+ { label: 'All', value: 'all' },
49
+ { label: 'Files', value: 'file' },
50
+ { label: 'Folders', value: 'folder' },
51
+ ],
52
+ },
53
+ defaultValue: 'all',
54
+ }),
55
+ parentFolder: common.properties.parentFolder,
56
+ include_team_drives: common.properties.include_team_drives,
57
+ },
58
+ async run(context) {
59
+ const authClient = await createGoogleClient(context.auth);
60
+
61
+ const drive = google.drive({ version: 'v3', auth: authClient });
62
+ const operator = context.propsValue.operator ?? 'contains';
63
+ const queryTerm = context.propsValue.queryTerm ?? 'name';
64
+ let finalQuery = `${queryTerm} ${operator} '${context.propsValue.query}'`;
65
+ if (context.propsValue.parentFolder) {
66
+ finalQuery = `${finalQuery} and '${context.propsValue.parentFolder}' in parents`;
67
+ }
68
+
69
+ const type = context.propsValue.type ?? 'all';
70
+ switch (type) {
71
+ case 'file':
72
+ finalQuery = `${finalQuery} and mimeType!='application/vnd.google-apps.folder'`;
73
+ break;
74
+ case 'folder':
75
+ finalQuery = `${finalQuery} and mimeType='application/vnd.google-apps.folder'`;
76
+ break;
77
+ default:
78
+ break;
79
+ }
80
+
81
+ const allFiles: any[] = [];
82
+ let pageToken: string | undefined = undefined;
83
+ do {
84
+ const listParams: Record<string, any> = {
85
+ q: finalQuery,
86
+ fields: 'nextPageToken, files(id, name, mimeType, createdTime, modifiedTime)',
87
+ includeItemsFromAllDrives: context.propsValue.include_team_drives,
88
+ supportsAllDrives: true,
89
+ pageSize: 1000,
90
+ };
91
+ if (pageToken) listParams.pageToken = pageToken;
92
+ const response = await drive.files.list(listParams);
93
+ if (response.status !== 200) {
94
+ console.error(response);
95
+ throw new Error('Error searching for the file/folder');
96
+ }
97
+ allFiles.push(...(response.data.files ?? []));
98
+ pageToken = response.data.nextPageToken ?? undefined;
99
+ } while (pageToken);
100
+
101
+ if (allFiles.length > 0) {
102
+ return allFiles;
103
+ } else {
104
+ console.log('Resource not found');
105
+ return [];
106
+ }
107
+ },
108
+ });
@@ -0,0 +1,34 @@
1
+ import { createAction, Property } from '@guayaba/workflows-framework';
2
+ import { googleDriveAuth, createGoogleClient } from '../auth';
3
+ import { common } from '../common';
4
+ import { google } from 'googleapis';
5
+
6
+ export const googleDriveTrashFile = createAction({
7
+ auth: googleDriveAuth,
8
+ name: 'trash_gdrive_file',
9
+ description: 'Move a file to the trash in your Google Drive',
10
+ displayName: 'Trash file',
11
+ props: {
12
+ fileId: Property.ShortText({
13
+ displayName: 'File ID',
14
+ description: 'The ID of the file to trash',
15
+ required: true,
16
+ }),
17
+ include_team_drives: common.properties.include_team_drives,
18
+ },
19
+ async run(context) {
20
+ const authClient = await createGoogleClient(context.auth);
21
+
22
+ const drive = google.drive({ version: 'v3', auth: authClient });
23
+ const body_value = {
24
+ trashed: true,
25
+ };
26
+ const response = await drive.files.update({
27
+ fileId: context.propsValue.fileId,
28
+ supportsAllDrives: context.propsValue.include_team_drives,
29
+ requestBody: body_value,
30
+ });
31
+
32
+ return response.data;
33
+ },
34
+ });
@@ -0,0 +1,64 @@
1
+ import { Property, createAction } from '@guayaba/workflows-framework';
2
+ import { googleDriveAuth, createGoogleClient } from '../auth';
3
+ import { google } from 'googleapis';
4
+ import { downloadFileFromDrive } from '../common/get-file-content';
5
+
6
+ export const setPublicAccess = createAction({
7
+ auth: googleDriveAuth,
8
+ name: 'set_public_access',
9
+ description: 'Set public access for a file or folder',
10
+ displayName: 'Set public access',
11
+ props: {
12
+ fileId: Property.ShortText({
13
+ displayName: 'File or Folder ID',
14
+ description: 'The ID of the file or folder to update permissions for',
15
+ required: true,
16
+ }),
17
+ role: Property.StaticDropdown({
18
+ displayName: 'Role',
19
+ description: 'The role to assign for public access',
20
+ options: {
21
+ options: [
22
+ { label: 'Reader', value: 'reader' },
23
+ { label: 'Commenter', value: 'commenter' },
24
+ { label: 'Editor', value: 'writer' },
25
+ ],
26
+ },
27
+ defaultValue: 'reader',
28
+ required: true,
29
+ }),
30
+ },
31
+ async run(context) {
32
+ const authClient = await createGoogleClient(context.auth);
33
+
34
+ const fileId = context.propsValue.fileId;
35
+ const role = context.propsValue.role;
36
+
37
+ const drive = google.drive({ version: 'v3', auth: authClient });
38
+ const permission = {
39
+ role,
40
+ type: 'anyone',
41
+ };
42
+ const res = await drive.permissions.create({
43
+ fileId: fileId,
44
+ requestBody: permission,
45
+ });
46
+
47
+ const file = await drive.files.get({
48
+ fileId: fileId,
49
+ fields: 'name,mimeType,webContentLink,webViewLink',
50
+ });
51
+
52
+ if (file.data.mimeType === 'application/vnd.google-apps.folder') {
53
+ return { ...res.data, webViewLink: file.data.webViewLink, downloadUrl: null };
54
+ }
55
+
56
+ const content = await downloadFileFromDrive(
57
+ context.auth,
58
+ context.files,
59
+ fileId,
60
+ file.data.name!
61
+ );
62
+ return { ...res.data, downloadUrl: content };
63
+ },
64
+ });
@@ -0,0 +1,72 @@
1
+ import { createAction, Property } from '@guayaba/workflows-framework';
2
+ import {
3
+ httpClient,
4
+ HttpMethod,
5
+ AuthenticationType,
6
+ } from '@guayaba/workflows-common';
7
+ import FormData from 'form-data';
8
+ import { googleDriveAuth, getAccessToken } from '../auth';
9
+ import mime from 'mime-types';
10
+ import { common } from '../common';
11
+
12
+ export const googleDriveUploadFile = createAction({
13
+ auth: googleDriveAuth,
14
+ name: 'upload_gdrive_file',
15
+ description: 'Upload a file in your Google Drive',
16
+ displayName: 'Upload file',
17
+ props: {
18
+ fileName: Property.ShortText({
19
+ displayName: 'File name',
20
+ description: 'The name of the file',
21
+ required: true,
22
+ }),
23
+ file: Property.File({
24
+ displayName: 'File',
25
+ description: 'The file URL or base64 to upload',
26
+ required: true,
27
+ }),
28
+ parentFolder: common.properties.parentFolder,
29
+ include_team_drives: common.properties.include_team_drives,
30
+ },
31
+ async run(context) {
32
+ const fileData = context.propsValue.file;
33
+ const mimeType = mime.lookup(fileData.extension ? fileData.extension : '');
34
+
35
+ const meta = {
36
+ mimeType: mimeType,
37
+ name: context.propsValue.fileName,
38
+ ...(context.propsValue.parentFolder
39
+ ? { parents: [context.propsValue.parentFolder] }
40
+ : {}),
41
+ };
42
+
43
+ const metaBuffer = Buffer.from(JSON.stringify(meta), 'utf-8');
44
+ const fileBuffer = Buffer.from(fileData.base64, 'base64');
45
+
46
+ const form = new FormData();
47
+ form.append('Metadata', metaBuffer, { contentType: 'application/json' });
48
+ form.append('Media', fileBuffer);
49
+
50
+ const result = await httpClient.sendRequest({
51
+ method: HttpMethod.POST,
52
+ url: `https://www.googleapis.com/upload/drive/v3/files`,
53
+ queryParams: {
54
+ uploadType: 'multipart',
55
+ supportsAllDrives: String(
56
+ context.propsValue.include_team_drives || false
57
+ ),
58
+ },
59
+ body: form,
60
+ headers: {
61
+ ...form.getHeaders(),
62
+ },
63
+ authentication: {
64
+ type: AuthenticationType.BEARER_TOKEN,
65
+ token: await getAccessToken(context.auth),
66
+ },
67
+ });
68
+
69
+ console.debug('File upload response', result);
70
+ return result.body;
71
+ },
72
+ });