feat: add Dify Batch Export functionality for dify.ai instance#1
feat: add Dify Batch Export functionality for dify.ai instance#1erbanku wants to merge 3 commits intoAuditAIH:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a new script (exprt-dify.ai.js) for batch-exporting Dify workflows specifically from the dify.ai hosted instance, working around security policies that block the existing export.js. Unlike the original script which relies on the external JSZip library, this new script implements a pure frontend ZIP builder (STORE mode) with no third-party dependencies.
Changes:
- Added
exprt-dify.ai.js: a self-contained browser console script that discovers the API base, authenticates via CSRF tokens or console tokens, paginates through all apps, exports each as YAML, and bundles them into a ZIP for download—all without external libraries. - Updated
README.mdwith a new "Dify.AI" section linking to the new script, and minor formatting fixes (heading levels adjusted).
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
exprt-dify.ai.js |
New self-contained export script for dify.ai with built-in ZIP implementation |
README.md |
Added usage instructions for the new dify.ai export script; minor heading adjustments |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| (() => { | ||
| const LOG = '[Dify Batch Export]'; | ||
| const encoder = new TextEncoder(); | ||
|
|
||
|
|
||
| const log = (...args) => console.log(LOG, ...args); | ||
| const err = (...args) => console.error(LOG, ...args); | ||
|
|
||
|
|
||
| const escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); |
There was a problem hiding this comment.
The file has excessive blank lines — almost every logical block is separated by two blank lines (the diff shows empty lines between virtually every statement). The existing export.js uses single blank lines for separation. This doubles the file length unnecessarily and hurts readability. Consider using single blank lines consistently, matching the convention in export.js.
| const crc = crc32(dataBytes); | ||
| const { dosTime, dosDate } = toDosTimeDate(file.date || new Date()); | ||
| const flags = 0x0800; | ||
| const compression = 0; |
There was a problem hiding this comment.
The ZIP implementation uses STORE mode (no compression, compression = 0), which means the resulting ZIP file will be essentially the same size as the raw YAML files combined. Since YAML is highly compressible text, using DEFLATE compression (or leveraging the browser's CompressionStream API) would significantly reduce the download size, especially for users with many workflows.
| for (let i = 0; i < apps.length; i++) { | ||
| const app = apps[i]; | ||
| try { | ||
| const payload = await fetchJson( | ||
| `${apiBase}/apps/${app.id}/export?include_secret=false` | ||
| ); | ||
|
|
||
|
|
||
| const yaml = payload.data; | ||
|
|
||
|
|
||
| if (typeof yaml !== 'string' || !yaml.trim()) { | ||
| throw new Error('Export result empty'); | ||
| } | ||
|
|
||
|
|
||
| const base = sanitizeFileName(app.name || `app-${app.id}`); | ||
| const fileName = uniqueFileName(usedNames, `${prefix}${base}`); | ||
|
|
||
|
|
||
| files.push({ | ||
| name: fileName, | ||
| data: yaml, | ||
| date: new Date() | ||
| }); | ||
|
|
||
|
|
||
| log(`Export success ${i + 1}/${apps.length}: ${fileName}`); | ||
| } catch (e) { | ||
| failed.push({ | ||
| app: app.name || app.id, | ||
| error: e.message | ||
| }); | ||
| err(`Export failed ${i + 1}/${apps.length}`, e); | ||
| } | ||
| } |
There was a problem hiding this comment.
The export loop makes requests sequentially with no delay between them. When exporting a large number of workflows from dify.ai, this could trigger rate limiting. Consider adding a small delay (e.g., 200-500ms) between requests to avoid being throttled.
README.md
Outdated
|
|
||
| ## Dify.AI | ||
|
|
||
| 复制源码 [export-dify.ai.js](./exprt-dify.ai.js) 内容,在dify工作流界面控制台运行即可批量导出dify工作流. |
There was a problem hiding this comment.
The filename exprt-dify.ai.js appears to be a typo — it's missing the 'o' in "export". The link text in the README says export-dify.ai.js but the href points to ./exprt-dify.ai.js. The file should be renamed to export-dify.ai.js for consistency and clarity.
| 复制源码 [export-dify.ai.js](./exprt-dify.ai.js) 内容,在dify工作流界面控制台运行即可批量导出dify工作流. | |
| 复制源码 [export-dify.ai.js](./export-dify.ai.js) 内容,在dify工作流界面控制台运行即可批量导出dify工作流. |
Previously, the export scripts were blocked by dify.ai’s security policies during export, preventing workflows from being exported.
I have implemented a workaround and am now able to export workflows from dify.ai.