@pipedream/google_drive 1.6.2 → 1.6.3
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.
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Per https://developers.google.com/workspace/drive/api/guides/ref-export-formats,
|
|
2
|
+
// only six Google Workspace types have documented export MIME mappings.
|
|
3
|
+
// The defaults below prefer Microsoft Office equivalents where one exists.
|
|
4
|
+
export const defaultExportMimeBySource = {
|
|
5
|
+
"application/vnd.google-apps.document":
|
|
6
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
7
|
+
"application/vnd.google-apps.spreadsheet":
|
|
8
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
9
|
+
"application/vnd.google-apps.presentation":
|
|
10
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
11
|
+
"application/vnd.google-apps.drawing": "image/png",
|
|
12
|
+
"application/vnd.google-apps.script":
|
|
13
|
+
"application/vnd.google-apps.script+json",
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// Workspace types with no export path via `files.export`.
|
|
17
|
+
// Source: the absence of these types from
|
|
18
|
+
// https://developers.google.com/workspace/drive/api/guides/ref-export-formats.
|
|
19
|
+
export const unsupportedWorkspaceMimes = {
|
|
20
|
+
"application/vnd.google-apps.folder":
|
|
21
|
+
"Folders can't be downloaded as files. Use a folder-zip action or list the folder's contents instead.",
|
|
22
|
+
"application/vnd.google-apps.form":
|
|
23
|
+
"Google Forms can't be exported via the Drive API. Use the Google Forms API to fetch form content or responses.",
|
|
24
|
+
"application/vnd.google-apps.map":
|
|
25
|
+
"My Maps can't be exported via the Drive API. Export manually from the My Maps UI as KMZ if needed.",
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Used to append a file extension when deriving a default filePath from the
|
|
29
|
+
// file's name. Covers every MIME in google-workspace-export-formats.mjs plus
|
|
30
|
+
// the Office defaults above.
|
|
31
|
+
export const extensionByMime = {
|
|
32
|
+
"application/epub+zip": "epub",
|
|
33
|
+
"application/pdf": "pdf",
|
|
34
|
+
"application/rtf": "rtf",
|
|
35
|
+
"application/vnd.google-apps.script+json": "json",
|
|
36
|
+
"application/vnd.oasis.opendocument.presentation": "odp",
|
|
37
|
+
"application/vnd.oasis.opendocument.spreadsheet": "ods",
|
|
38
|
+
"application/vnd.oasis.opendocument.text": "odt",
|
|
39
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "pptx",
|
|
40
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
|
|
41
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
|
|
42
|
+
"application/x-vnd.oasis.opendocument.spreadsheet": "ods",
|
|
43
|
+
"application/zip": "zip",
|
|
44
|
+
"image/jpeg": "jpg",
|
|
45
|
+
"image/png": "png",
|
|
46
|
+
"image/svg+xml": "svg",
|
|
47
|
+
"text/csv": "csv",
|
|
48
|
+
"text/html": "html",
|
|
49
|
+
"text/markdown": "md",
|
|
50
|
+
"text/plain": "txt",
|
|
51
|
+
"text/tab-separated-values": "tsv",
|
|
52
|
+
"text/x-markdown": "md",
|
|
53
|
+
};
|
|
@@ -5,6 +5,13 @@ import { GOOGLE_DRIVE_MIME_TYPE_PREFIX } from "../../common/constants.mjs";
|
|
|
5
5
|
import { toSingleLineString } from "../../common/utils.mjs";
|
|
6
6
|
import googleDrive from "../../google_drive.app.mjs";
|
|
7
7
|
import googleWorkspaceExportFormats from "../common/google-workspace-export-formats.mjs";
|
|
8
|
+
import {
|
|
9
|
+
defaultExportMimeBySource,
|
|
10
|
+
extensionByMime,
|
|
11
|
+
unsupportedWorkspaceMimes,
|
|
12
|
+
} from "../common/google-workspace-default-export-formats.mjs";
|
|
13
|
+
|
|
14
|
+
const SHORTCUT_MIME_TYPE = "application/vnd.google-apps.shortcut";
|
|
8
15
|
|
|
9
16
|
/**
|
|
10
17
|
* Uses Google Drive API to download files to a `filePath` in the /tmp
|
|
@@ -17,8 +24,14 @@ import googleWorkspaceExportFormats from "../common/google-workspace-export-form
|
|
|
17
24
|
export default {
|
|
18
25
|
key: "google_drive-download-file",
|
|
19
26
|
name: "Download File",
|
|
20
|
-
description: "Download a file
|
|
21
|
-
|
|
27
|
+
description: "Download a file from Google Drive to the `/tmp` directory or return its contents as a buffer."
|
|
28
|
+
+ " Use to fetch a file's contents for processing in downstream steps — e.g., parsing a CSV, extracting text from a PDF, or re-uploading to another service."
|
|
29
|
+
+ " For Google Workspace files (Docs, Sheets, Slides, Drawings, Apps Script), exports to an Office-compatible format by default:"
|
|
30
|
+
+ " Docs → `.docx`, Sheets → `.xlsx`, Slides → `.pptx`, Drawings → PNG, Apps Script → JSON."
|
|
31
|
+
+ " Pass `mimeType` to force a specific format. Shortcuts are resolved to their target automatically."
|
|
32
|
+
+ " Folders, Forms, and My Maps cannot be downloaded via this action."
|
|
33
|
+
+ " [See the documentation](https://developers.google.com/drive/api/v3/manage-downloads)",
|
|
34
|
+
version: "0.1.24",
|
|
22
35
|
annotations: {
|
|
23
36
|
destructiveHint: false,
|
|
24
37
|
openWorldHint: true,
|
|
@@ -32,6 +45,7 @@ export default {
|
|
|
32
45
|
googleDrive,
|
|
33
46
|
"watchedDrive",
|
|
34
47
|
],
|
|
48
|
+
description: "The shared drive the file is in, if any. Leave empty for files in My Drive.",
|
|
35
49
|
optional: true,
|
|
36
50
|
},
|
|
37
51
|
fileId: {
|
|
@@ -42,7 +56,7 @@ export default {
|
|
|
42
56
|
drive: c.drive,
|
|
43
57
|
}),
|
|
44
58
|
],
|
|
45
|
-
description: "The file to download",
|
|
59
|
+
description: "The Google Drive file to download. Accepts a file ID (opaque Drive identifier). If a shortcut is passed, the target file is resolved and downloaded automatically.",
|
|
46
60
|
},
|
|
47
61
|
filePath: {
|
|
48
62
|
type: "string",
|
|
@@ -50,7 +64,10 @@ export default {
|
|
|
50
64
|
description: toSingleLineString(`
|
|
51
65
|
The destination file name or path [in the \`/tmp\`
|
|
52
66
|
directory](https://pipedream.com/docs/workflows/steps/code/nodejs/working-with-files/#the-tmp-directory)
|
|
53
|
-
(e.g., \`/tmp/myFile.csv\`)
|
|
67
|
+
(e.g., \`/tmp/myFile.csv\`). Defaults to \`/tmp/<file name>\` if omitted.
|
|
68
|
+
**Note:** if you set this for a Google Workspace file, the extension you
|
|
69
|
+
choose should match the Conversion Format; otherwise the file contents
|
|
70
|
+
may not match the extension.
|
|
54
71
|
`),
|
|
55
72
|
optional: true,
|
|
56
73
|
},
|
|
@@ -59,7 +76,9 @@ export default {
|
|
|
59
76
|
label: "Conversion Format",
|
|
60
77
|
description: toSingleLineString(`
|
|
61
78
|
The format to which to convert the downloaded file if it is a [Google Workspace
|
|
62
|
-
document](https://developers.google.com/drive/api/v3/ref-export-formats)
|
|
79
|
+
document](https://developers.google.com/drive/api/v3/ref-export-formats).
|
|
80
|
+
If omitted, defaults per source type: Docs → \`.docx\`, Sheets → \`.xlsx\`,
|
|
81
|
+
Slides → \`.pptx\`, Drawings → PNG, Apps Script → JSON.
|
|
63
82
|
`),
|
|
64
83
|
optional: true,
|
|
65
84
|
async options() {
|
|
@@ -98,47 +117,76 @@ export default {
|
|
|
98
117
|
type: "dir",
|
|
99
118
|
accessMode: "write",
|
|
100
119
|
sync: true,
|
|
120
|
+
optional: true,
|
|
101
121
|
},
|
|
102
122
|
getBufferResponse: {
|
|
103
123
|
type: "boolean",
|
|
104
124
|
label: "Get Buffer Response",
|
|
105
|
-
description: "
|
|
125
|
+
description: "If true, returns the file content as a buffer in the output (useful for passing directly to another step) instead of writing it to `/tmp`. Defaults to false.",
|
|
106
126
|
optional: true,
|
|
107
127
|
},
|
|
108
128
|
},
|
|
109
129
|
async run({ $ }) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
130
|
+
let fileMetadata = await this.googleDrive.getFile(this.fileId, {
|
|
131
|
+
fields: "name,mimeType,shortcutDetails,webViewLink",
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Shortcuts point at a target file; resolve and download the target instead.
|
|
135
|
+
let downloadFileId = this.fileId;
|
|
136
|
+
let resolvedFromShortcut = false;
|
|
137
|
+
if (fileMetadata.mimeType === SHORTCUT_MIME_TYPE) {
|
|
138
|
+
const targetId = fileMetadata.shortcutDetails?.targetId;
|
|
139
|
+
if (!targetId) {
|
|
140
|
+
throw new Error(`Shortcut "${fileMetadata.name}" has no target file and cannot be downloaded.`);
|
|
141
|
+
}
|
|
142
|
+
downloadFileId = targetId;
|
|
143
|
+
resolvedFromShortcut = true;
|
|
144
|
+
fileMetadata = await this.googleDrive.getFile(targetId, {
|
|
145
|
+
fields: "name,mimeType,webViewLink",
|
|
146
|
+
});
|
|
113
147
|
}
|
|
114
148
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
149
|
+
const sourceMimeType = fileMetadata.mimeType;
|
|
150
|
+
|
|
151
|
+
if (unsupportedWorkspaceMimes[sourceMimeType]) {
|
|
152
|
+
throw new Error(
|
|
153
|
+
`Cannot download file of type "${sourceMimeType}": ${unsupportedWorkspaceMimes[sourceMimeType]}`,
|
|
154
|
+
);
|
|
155
|
+
}
|
|
120
156
|
|
|
121
|
-
const isWorkspaceDocument =
|
|
122
|
-
|
|
123
|
-
|
|
157
|
+
const isWorkspaceDocument = sourceMimeType.includes(GOOGLE_DRIVE_MIME_TYPE_PREFIX);
|
|
158
|
+
|
|
159
|
+
// Fallback: user value -> static default -> runtime getExportFormats().
|
|
160
|
+
let effectiveMimeType = this.mimeType;
|
|
161
|
+
if (isWorkspaceDocument && !effectiveMimeType) {
|
|
162
|
+
effectiveMimeType = defaultExportMimeBySource[sourceMimeType];
|
|
163
|
+
if (!effectiveMimeType) {
|
|
164
|
+
const exportFormats = await this.googleDrive.getExportFormats();
|
|
165
|
+
effectiveMimeType = exportFormats[sourceMimeType]?.[0];
|
|
166
|
+
}
|
|
167
|
+
if (!effectiveMimeType) {
|
|
168
|
+
throw new Error(
|
|
169
|
+
`No export format available for "${sourceMimeType}". Set Conversion Format explicitly.`,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
124
172
|
}
|
|
125
|
-
|
|
126
|
-
//
|
|
127
|
-
// See https://developers.google.com/drive/api/v3/mime-types for a list of Google MIME types.
|
|
128
|
-
// Google Workspace format to MIME type map:
|
|
129
|
-
// https://developers.google.com/drive/api/v3/ref-export-formats
|
|
173
|
+
|
|
174
|
+
// See https://developers.google.com/drive/api/v3/mime-types for Google MIME types.
|
|
130
175
|
const file = isWorkspaceDocument
|
|
131
|
-
? await this.googleDrive.downloadWorkspaceFile(
|
|
132
|
-
mimeType:
|
|
176
|
+
? await this.googleDrive.downloadWorkspaceFile(downloadFileId, {
|
|
177
|
+
mimeType: effectiveMimeType,
|
|
133
178
|
})
|
|
134
|
-
: await this.googleDrive.getFile(
|
|
179
|
+
: await this.googleDrive.getFile(downloadFileId, {
|
|
135
180
|
alt: "media",
|
|
136
181
|
});
|
|
137
182
|
|
|
183
|
+
const summaryPrefix = resolvedFromShortcut
|
|
184
|
+
? "Resolved shortcut and downloaded"
|
|
185
|
+
: "Successfully downloaded";
|
|
186
|
+
|
|
138
187
|
if (this.getBufferResponse) {
|
|
139
|
-
$.export("$summary",
|
|
188
|
+
$.export("$summary", `${summaryPrefix} raw content for file "${fileMetadata.name}"`);
|
|
140
189
|
|
|
141
|
-
// Convert stream to buffer
|
|
142
190
|
const chunks = [];
|
|
143
191
|
for await (const chunk of file) {
|
|
144
192
|
chunks.push(chunk);
|
|
@@ -148,20 +196,34 @@ export default {
|
|
|
148
196
|
return {
|
|
149
197
|
fileId: this.fileId,
|
|
150
198
|
fileMetadata,
|
|
199
|
+
webViewLink: fileMetadata.webViewLink,
|
|
151
200
|
content: buffer,
|
|
152
201
|
};
|
|
153
202
|
}
|
|
154
203
|
|
|
155
|
-
|
|
204
|
+
let filePath;
|
|
205
|
+
if (this.filePath) {
|
|
206
|
+
filePath = this.filePath.includes("tmp/")
|
|
207
|
+
? this.filePath
|
|
208
|
+
: `/tmp/${this.filePath}`;
|
|
209
|
+
} else {
|
|
210
|
+
let defaultName = fileMetadata.name;
|
|
211
|
+
if (isWorkspaceDocument) {
|
|
212
|
+
const ext = extensionByMime[effectiveMimeType];
|
|
213
|
+
if (ext && !defaultName.toLowerCase().endsWith(`.${ext.toLowerCase()}`)) {
|
|
214
|
+
defaultName = `${defaultName}.${ext}`;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
filePath = `/tmp/${defaultName}`;
|
|
218
|
+
}
|
|
219
|
+
|
|
156
220
|
const pipeline = promisify(stream.pipeline);
|
|
157
|
-
const filePath = this.filePath.includes("tmp/")
|
|
158
|
-
? this.filePath
|
|
159
|
-
: `/tmp/${this.filePath}`;
|
|
160
221
|
await pipeline(file, fs.createWriteStream(filePath));
|
|
161
|
-
$.export("$summary",
|
|
222
|
+
$.export("$summary", `${summaryPrefix} the file, "${fileMetadata.name}"`);
|
|
162
223
|
return {
|
|
163
224
|
fileId: this.fileId,
|
|
164
225
|
fileMetadata,
|
|
226
|
+
webViewLink: fileMetadata.webViewLink,
|
|
165
227
|
filePath,
|
|
166
228
|
};
|
|
167
229
|
},
|