diff --git a/.difyignore b/.difyignore index 265737f..8fc6579 100644 --- a/.difyignore +++ b/.difyignore @@ -9,3 +9,4 @@ __pycache__/ *.difypkg tests/ pyproject.toml +docs/ diff --git a/README.md b/README.md index 27b2c04..f791ec3 100644 --- a/README.md +++ b/README.md @@ -1,80 +1,121 @@ -# Suno for Dify +# Suno for Dify: step-by-step guide -Use the Ace Data Cloud Suno APIs in Dify workflows. Maintained by Ace Data Cloud. The plugin is free; API calls require your own authorized account and use the current service pricing. +Generate instrumental music and retrieve the completed audio. This guide takes you from your first API key to the result in a Dify Workflow. Screenshots use Dify CE 1.17.1 in English; later versions may move the same controls. -## Setup +[Read in Simplified Chinese](https://github.com/AceDataCloud/SunoDify/blob/main/readme/README_zh_Hans.md) · [API and pricing](https://platform.acedata.cloud/models) -1. Activate the service at [Ace Data Cloud](https://platform.acedata.cloud/console/applications), check [current pricing](https://platform.acedata.cloud/models), and create an API token with the required service access. -2. Install from [Dify Marketplace](https://marketplace.dify.ai/plugin/acedatacloud/suno). This version is published and was installed through the official Marketplace flow in Dify CE 1.17.1 with signature verification enabled. Installation is optional; this does not mean Dify preinstalls the plugin. -3. In Dify's **Plugins / Tools** page, authorize this provider with **Bearer Token** (`acedata_bearer_token`). Do not include credentials in prompts or exported workflows. Credential validation never generates media. Authorization performs a read-only task query. +## 1. Install the correct plugin -## Tools +Open [Suno by acedatacloud](https://marketplace.dify.ai/plugin/acedatacloud/suno) in Dify Marketplace. Check the author is **acedatacloud**, choose **Install**, and select your Dify workspace. In your Dify workspace, open **Integrations → Tools → Tool Plugin** and select **Suno**. Its card should say **From Marketplace**. -| Tool | API | +If your Dify server cannot open Marketplace, ask its administrator to enable outbound access and plugin installation. The plugin needs HTTPS to `api.acedata.cloud`. + +![Installed plugin in Dify](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/01-installed.png) + +## 2. Get an API key with the correct access + +1. Sign in at [Ace Data Cloud → Applications](https://platform.acedata.cloud/console/applications). +2. Open **General application**. Its API key can access multiple services your account is entitled to use. A service-specific key is limited to that service. For this tutorial, check **Suno** access and current pricing/balance before generating. +3. To reuse the selected key, click the copy icon marked **1** below. To create a separate Dify key, click **Manage Keys** marked **2**, then **Create**. + +![Copy an existing API key or open Manage Keys](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/get-api-key-en.png) + +4. Give the new key a name, such as `Dify tutorial`. Set expiration and usage/API restrictions only as needed, then click **Create**. Return to the key list or application card and copy the key. If **Allowed APIs** is enabled, include both the generation and task-query APIs used here: `/suno/audios`, `/suno/tasks`. + +![Create an optional separate key](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/create-api-key-en.png) + +Copy only the token string. Do not add `Bearer `, quotation marks, or the screenshot's redacted characters. A platform management token (for example, a `platform-...` token) is not the generation API key this plugin expects. Confirm service access and a sufficient balance before the first run. + +## 3. Authorize Suno in Dify + +1. Open **Integrations → Tools → Tool Plugin → Suno**. +2. Click **API Key Authorization Configuration**. If an authorization already exists, click **1 Authorization** first, then the configuration button. +3. Enter an **Authorization Name**, such as `Ace Data Cloud`, and paste the copied token into **Ace Data Cloud Bearer Token**. +4. Choose who may use the credential and click **Save**. Never put a key in a prompt or workflow export. + +![Dify tool authorization dialog](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/02-authorize.png) + +## 4. Build your first Workflow + +Open **Studio → Create → Create from Blank → Workflow**, name it, and create this path by dragging from each node's right connector to the next node: + +**Start → Suno Generate Audios → Suno Retrieve Task → Output**. + +Use the **+** button to add a **Tool**, select this plugin, and choose the exact action above. Rename the generation node **Suno** and the query node **Retrieve completed task** to match the screenshots. Leave Start inputs empty for this fixed first example. Keep **Retry on Failure** off on the generation node. + +![Workflow connections](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/03-workflow.png) + +Select **Suno Generate Audios** and set these fields. Leave unmentioned optional fields empty. + +| Dify field | First-run value | |---|---| -| `suno_generate_audios` | `POST /suno/audios` | -| `suno_generate_lyrics` | `POST /suno/lyrics` | -| `suno_upload_reference_audio` | `POST /suno/upload` | -| `suno_get_mp4` | `POST /suno/mp4` | -| `suno_get_mp3` | `POST /suno/mp3` | -| `suno_get_wav` | `POST /suno/wav` | -| `suno_get_midi` | `POST /suno/midi` | -| `suno_get_timing` | `POST /suno/timing` | -| `suno_create_vox_audio` | `POST /suno/vox` | -| `suno_enhance_style` | `POST /suno/style` | -| `suno_mashup_lyrics` | `POST /suno/mashup-lyrics` | -| `suno_create_voice` | `POST /suno/voices` | -| `suno_create_persona` | `POST /suno/persona` | -| `suno_list_personas` | `GET /suno/persona` | -| `suno_delete_persona` | `DELETE /suno/persona` | -| `suno_custom_models` | `POST /suno/custom-models` | -| `suno_projects` | `POST /suno/projects` | -| `suno_task_retrieve` | `POST /suno/tasks` | -| `suno_tasks_retrieve_batch` | `POST /suno/tasks` | +| Model (`model`) | `chirp-v6` | +| Instrumental (`instrumental`) | `true` | +| Duration (`duration`) | `10` | -See [CAPABILITIES.md](CAPABILITIES.md) for the current MCP comparison and parameter equivalents. All exposed inputs follow the current published API; model combinations and availability still depend on the service. +**Prompt** (`prompt`): -## Run a workflow +```text +A short gentle instrumental piano melody for a sunrise, no vocals. +``` -For generation, use **Start → generation tool → task retrieval → Output**. Fill the prompt/text and model, and enter arrays/objects as JSON. Optional values can be left empty. The example requests in [tests/contract-examples.json](https://github.com/AceDataCloud/SunoDify/blob/main/tests/contract-examples.json) show valid shapes; example.org URLs are placeholders that must be replaced with your own accessible media. +Turn **Instrumental** on for this first run. Duration is a target, not a guaranteed track length. Custom vocal music needs lyrics or a lyric prompt. A playable preview while running is not a final result. -A submission can return `status=pending` with `task_id`. Save that ID, then use the retrieval tool with `wait_seconds=0` to read once, or 1–240 for a bounded wait. If still pending, query the same task again. Disable automatic retries on generation nodes. No paid request is automatically retried and no substitute model is selected. +![Fill the generation or search parameters](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/03-configure.png) -`status`, `success`, `task_id`, `trace_id`, `media_urls`, `data`, and `result` are available as Dify variables. Only a terminal successful result has `success=true`; intermediate previews remain pending. Batch queries preserve the state of each item. Terminal task failures raise a tool error. Synchronous search, text and management results are returned directly in `data`/`result`. The plugin does not execute model-generated tools. +## 5. Wait for the same task and map the result -Includes music actions, lyrics, media formats, voices, personas, custom models and projects. Voice/custom-model operations require authorized source recordings. Model creation has its own API price; review current pricing before use. +Select **Suno Retrieve Task**. In **Task ID**, click the variable picker (or type `/`) and choose **Suno → task_id**. It must be the output variable from the generation node, not its name typed as plain text. Set **Wait up to seconds** to `240`; leave Trace ID empty for this example. -Task/query calls retry transport failures at most twice. Generation has one attempt and a 10-second connect / 60-second read timeout. After a timeout, inspect [request history](https://platform.acedata.cloud/console/usages) before resubmitting; the accepted task may still be running. Delete/archive operations require `confirm=true`. +![Task ID variable binding](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/04-task-id.png) -## Branding and privacy +Select **Output**, click **+** to add output fields, and choose the variables below from **Retrieve completed task**: -The plugin uses the exact existing system asset recorded in [branding provenance](https://github.com/AceDataCloud/SunoDify/blob/main/tests/branding-source.json), for both light and dark icons. No logo was generated or redrawn. Asset SHA256: `d2ccb1c0039519a68913ad447114f8f9ecca161ffc2105cd61c414e06f8747d9`. +| Output name | Select from query node | Type | +|---|---|---| +| status | status | String | +| success | success | Boolean | +| task_id | task_id | String | +| media_urls | media_urls | Array[String] | +| result | result | Object | -Requests go directly to `https://api.acedata.cloud`. The plugin passes reference URLs to that API and returns media links; it does not fetch arbitrary reference URLs. Dify may fetch/render output links under its own policies. Never submit media you lack permission to process. See [PRIVACY.md](PRIVACY.md). +![Map the query outputs](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/05-output.png) -API charges are recorded in Credits in your Ace Data Cloud account. Check the actual usage ledger; Dify execution counts are not a billing ledger. USD = Credits × your current package price / amount. +Click **Test Run → Start Run**. Generation may finish before the bounded wait expires; otherwise `status=pending` is normal. **Do not rerun the whole workflow while it is pending**, because that submits a new generation. Copy its task ID and create a separate **Start → Suno Retrieve Task → Output** workflow with that ID and a wait of 0 or 240. Query the same ID until `status=succeeded` and `success=true`; then open the links in `media_urls`. A green Dify workflow alone is not proof that the service task finished. -## Development and evidence +## 6. Check the expected output -Python 3.12 is required. Install `requirements.txt`, then run: +A completed result has this shape (the URL below illustrates the field; use your own returned URL): -```sh -python -m pytest tests -q -ruff check . -ruff format --check . -dify plugin package . +```json +{ + "status": "succeeded", + "success": true, + "media_urls": [ + "https://.../result.mp3" + ] +} ``` -Source contracts, MCP mappings, brand provenance and offline cases are in `tests/`. Recorded real Dify results state their exact coverage; they do not establish all models/options or Dify Cloud/Marketplace installation. See [tests/README.md](https://github.com/AceDataCloud/SunoDify/blob/main/tests/README.md). +![Actual completed Dify result](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/06-result.png) + +Actual run example; your task ID and media URL will differ. + +## Troubleshooting + +| What you see | What to do | +|---|---| +| Authorization fails / 401 or 403 | Copy the full API token, remove `Bearer `, check service access, balance, expiration and Allowed APIs. | +| Invalid parameter / 400 | Copy the exact example model, action, resolution and JSON shape. Do not combine unrelated action fields. | +| `pending` or an empty media list | Query the same task ID again. Never regenerate just to poll. | +| HTTP 429 | Wait, reduce concurrency and check service limits; do not enable automatic paid retries. | +| Timeout / 5xx / failed task | Inspect the original task or request history before resubmitting. Contact support with task/trace ID, never your key. | +| Media link will not load | Check the task is terminal and the returned link is accessible from the Dify server/browser. | -- Source: https://github.com/AceDataCloud/SunoDify -- Issues: https://github.com/AceDataCloud/SunoDify/issues -- Contact: dev@acedata.cloud -- License: MIT -- [Simplified Chinese](readme/README_zh_Hans.md) +[Download the ready-to-import workflow](https://github.com/AceDataCloud/SunoDify/raw/refs/heads/main/docs/quickstart.dify.yml). Import it in Studio, then configure your own key; the file contains no credentials. -## Official Marketplace verification +## Privacy, cost and support -[Install from Dify Marketplace](https://marketplace.dify.ai/plugin/acedatacloud/suno). Version 0.0.1 was downloaded and installed through the official Marketplace flow on October 8, 2026, with signature verification enabled and no remote-debug process. The installed plugin then completed the recorded real Dify workflow. [Verification data](tests/marketplace-acceptance.json) and [original Dify screenshot](tests/evidence/marketplace-20261008.png) document the exact scope. This proves optional Marketplace availability, not default installation or featured placement. +The free plugin sends your chosen inputs and token to `api.acedata.cloud`; API calls follow current service pricing. Keys stay in Dify credential storage. See [Privacy](https://github.com/AceDataCloud/SunoDify/blob/main/PRIVACY.md). Only submit content you have permission to process. -The installed tool queried a previously generated, completed task and returned its final media. The generation itself was not repeated; earlier generation evidence remains separate. +[Source](https://github.com/AceDataCloud/SunoDify) · [Report a problem](https://github.com/AceDataCloud/SunoDify/issues) · dev@acedata.cloud · [Advanced capabilities](https://github.com/AceDataCloud/SunoDify/blob/main/CAPABILITIES.md). Development and test evidence live in the source repository, separate from this first-run guide. diff --git a/_assets/tutorial/01-installed.png b/_assets/tutorial/01-installed.png new file mode 100644 index 0000000..5d45dad Binary files /dev/null and b/_assets/tutorial/01-installed.png differ diff --git a/_assets/tutorial/02-authorize.png b/_assets/tutorial/02-authorize.png new file mode 100644 index 0000000..b924278 Binary files /dev/null and b/_assets/tutorial/02-authorize.png differ diff --git a/_assets/tutorial/03-configure.png b/_assets/tutorial/03-configure.png new file mode 100644 index 0000000..16b96b4 Binary files /dev/null and b/_assets/tutorial/03-configure.png differ diff --git a/_assets/tutorial/03-workflow.png b/_assets/tutorial/03-workflow.png new file mode 100644 index 0000000..99a368f Binary files /dev/null and b/_assets/tutorial/03-workflow.png differ diff --git a/_assets/tutorial/04-task-id.png b/_assets/tutorial/04-task-id.png new file mode 100644 index 0000000..0035aa3 Binary files /dev/null and b/_assets/tutorial/04-task-id.png differ diff --git a/_assets/tutorial/05-output.png b/_assets/tutorial/05-output.png new file mode 100644 index 0000000..d6920ae Binary files /dev/null and b/_assets/tutorial/05-output.png differ diff --git a/_assets/tutorial/06-result.png b/_assets/tutorial/06-result.png new file mode 100644 index 0000000..d395868 Binary files /dev/null and b/_assets/tutorial/06-result.png differ diff --git a/_assets/tutorial/create-api-key-en.png b/_assets/tutorial/create-api-key-en.png new file mode 100644 index 0000000..cf1504e Binary files /dev/null and b/_assets/tutorial/create-api-key-en.png differ diff --git a/_assets/tutorial/get-api-key-en.png b/_assets/tutorial/get-api-key-en.png new file mode 100644 index 0000000..0cbf417 Binary files /dev/null and b/_assets/tutorial/get-api-key-en.png differ diff --git a/_assets/tutorial/key-screenshots-provenance.json b/_assets/tutorial/key-screenshots-provenance.json new file mode 100644 index 0000000..9d847b4 --- /dev/null +++ b/_assets/tutorial/key-screenshots-provenance.json @@ -0,0 +1,25 @@ +{ + "captured_at": "2026-10-08T17:15:13.782Z", + "source_url": "https://platform.acedata.cloud/console/applications", + "auth": "Existing authorized account, own identity", + "privacy": "Balance, application ID and complete/partial token are opaque-masked before screenshot capture. Dialog crops omit unrelated UI.", + "edits": "Crop + numbered callouts on live screenshot only; no UI data or success state fabricated.", + "capture_actions": "Read application page, open Manage Keys, open Create, fill example name, cancel; no credential created and no billable API call.", + "instructions": { + "1": "Copy the selected existing key. The screenshot redacts it. Paste only token in Dify, not the Bearer label.", + "2": "Manage Keys, then Create; use own key name and appropriate restrictions. Return to the list/application page to copy." + }, + "files": [ + { + "file": "create-api-key-en.png", + "sha256": "977c06780b36ca33f2fb3ba546e2594efe5895400e4cb58d842eb564c3bb09da", + "bytes": 25251 + }, + { + "file": "get-api-key-en.png", + "sha256": "b63787f2bd15af82fef9ab61c99e11c454355ac86e91f7f94559386b795069b7", + "bytes": 33708 + } + ], + "published_screenshot_language": "English only in every locale, per explicit user instruction" +} \ No newline at end of file diff --git a/docs/quickstart.dify.yml b/docs/quickstart.dify.yml new file mode 100644 index 0000000..597683d --- /dev/null +++ b/docs/quickstart.dify.yml @@ -0,0 +1,231 @@ +app: + description: Real Dify integration verification with Ace Data Cloud + icon: null + icon_background: null + icon_type: emoji + mode: workflow + name: Suno Step-by-step Tutorial + use_icon_as_answer_icon: false +dependencies: +- current_identifier: null + type: marketplace + value: + marketplace_plugin_unique_identifier: acedatacloud/suno:0.0.1@57cee3e163cb5044b8fa2684baa394d5a3fd40ec1ba6640f8ef9ff7681f21d0d + version: null +kind: app +version: 0.7.0 +workflow: + conversation_variables: [] + environment_variables: [] + features: + file_upload: {} + sensitive_word_avoidance: + enabled: false + text_to_speech: + enabled: false + language: '' + voice: '' + graph: + edges: + - data: + isInIteration: false + isInLoop: false + sourceType: start + targetType: tool + id: start-generate + source: start + sourceHandle: source + target: generate + targetHandle: target + type: custom + zIndex: 0 + - data: + isInIteration: false + isInLoop: false + sourceType: tool + targetType: tool + id: generate-wait + source: generate + sourceHandle: source + target: wait + targetHandle: target + type: custom + zIndex: 0 + - data: + isInIteration: false + isInLoop: false + sourceType: tool + targetType: end + id: wait-end + source: wait + sourceHandle: source + target: end + targetHandle: target + type: custom + zIndex: 0 + nodes: + - data: + desc: '' + selected: false + title: Start + type: start + variables: [] + height: 73 + id: start + position: + x: 0 + y: 100 + positionAbsolute: + x: 0 + y: 100 + selected: false + sourcePosition: right + targetPosition: left + type: custom + width: 242 + zIndex: 0 + - data: + desc: '' + plugin_unique_identifier: acedatacloud/suno:0.0.1@57cee3e163cb5044b8fa2684baa394d5a3fd40ec1ba6640f8ef9ff7681f21d0d + provider_id: acedatacloud/suno/suno + provider_name: acedatacloud/suno/suno + provider_type: builtin + retry_config: + max_retries: 0 + retry_enabled: false + retry_interval: 1000 + selected: false + title: Suno + tool_configurations: + action: + type: constant + value: generate + custom: + type: constant + value: false + duration: + type: constant + value: 10 + instrumental: + type: constant + value: true + model: + type: constant + value: chirp-v6 + tool_label: Suno Generate Audios + tool_name: suno_generate_audios + tool_node_version: '2' + tool_parameters: + prompt: + type: constant + value: A short gentle instrumental piano melody for a sunrise, no vocals. + type: tool + height: 192 + id: generate + position: + x: 300 + y: 100 + positionAbsolute: + x: 300 + y: 100 + selected: false + sourcePosition: right + targetPosition: left + type: custom + width: 242 + zIndex: 0 + - data: + desc: '' + plugin_unique_identifier: acedatacloud/suno:0.0.1@57cee3e163cb5044b8fa2684baa394d5a3fd40ec1ba6640f8ef9ff7681f21d0d + provider_id: acedatacloud/suno/suno + provider_name: acedatacloud/suno/suno + provider_type: builtin + retry_config: + max_retries: 0 + retry_enabled: false + retry_interval: 1000 + selected: false + title: Retrieve completed task + tool_configurations: + task_id: + type: mixed + value: '{{#generate.task_id#}}' + wait_seconds: + type: constant + value: 240 + tool_label: Suno Retrieve Task + tool_name: suno_task_retrieve + tool_node_version: '2' + tool_parameters: {} + type: tool + height: 114 + id: wait + position: + x: 600 + y: 100 + positionAbsolute: + x: 600 + y: 100 + selected: false + sourcePosition: right + targetPosition: left + type: custom + width: 242 + zIndex: 0 + - data: + desc: '' + outputs: + - value_selector: + - wait + - status + variable: status + - value_selector: + - wait + - success + variable: success + - value_selector: + - wait + - task_id + variable: task_id + - value_selector: + - wait + - trace_id + variable: trace_id + - value_selector: + - wait + - media_urls + variable: media_urls + - value_selector: + - wait + - data + variable: data + - value_selector: + - wait + - result + variable: result + - value_selector: + - wait + - files + variable: files + selected: true + title: Output + type: end + height: 270 + id: end + position: + x: 900 + y: 100 + positionAbsolute: + x: 900 + y: 100 + selected: true + sourcePosition: right + targetPosition: left + type: custom + width: 242 + zIndex: 0 + viewport: + x: 60 + y: 160 + zoom: 0.8 + rag_pipeline_variables: [] diff --git a/manifest.yaml b/manifest.yaml index 0730bbd..04c67c2 100644 --- a/manifest.yaml +++ b/manifest.yaml @@ -1,4 +1,4 @@ -version: 0.0.1 +version: 0.0.2 type: plugin author: acedatacloud name: suno @@ -23,7 +23,7 @@ plugins: tools: - provider/suno.yaml meta: - version: 0.0.1 + version: 0.0.2 minimum_dify_version: 1.17.1 arch: - amd64 diff --git a/readme/README_zh_Hans.md b/readme/README_zh_Hans.md index 401e6c9..dcad225 100644 --- a/readme/README_zh_Hans.md +++ b/readme/README_zh_Hans.md @@ -1,61 +1,121 @@ -# Suno Dify 插件 +# Suno Dify 插件:手把手教程 -在 Dify 中使用 Ace Data Cloud 的 Suno API。插件免费,API 需要自己的账号和服务权限,并按当前价格扣费。 +生成纯音乐,并查询完成后的音频。从获取 Key 开始,按下面步骤在 Dify 中看到第一次结果。截图来自 Dify CE 1.17.1 英文界面;新版本可能调整菜单位置。 -## 安装与授权 +[English](https://github.com/AceDataCloud/SunoDify/blob/main/README.md) · [当前模型和价格](https://platform.acedata.cloud/models) -1. 在 [Ace Data Cloud](https://platform.acedata.cloud/console/applications) 开通服务并创建 API Token;使用前核对[当前模型与价格](https://platform.acedata.cloud/models)。 -2. 可从 [Dify 官方 Marketplace](https://marketplace.dify.ai/plugin/acedatacloud/suno) 安装。0.0.1 已上架,并通过开启签名校验的 Dify CE 1.17.1 安装验证;这属于可选安装,不代表默认预装。 -3. 在 Dify 的插件或工具页填写 Bearer Token(`acedata_bearer_token`)。凭据检查不会生成内容。授权使用只读任务查询。 +## 1. 安装正确的插件 -## 工具与工作流 +打开 [Suno 官方市场页](https://marketplace.dify.ai/plugin/acedatacloud/suno),确认作者是 **acedatacloud**,点击 **Install(安装)**并选择你的 Dify 工作区。回到 Dify,进入 **Integrations(集成)→ Tools(工具)→ Tool Plugin(工具插件)**,找到 **Suno**,卡片应显示 **From Marketplace**。 -| Tool | API | +如果无法访问市场,请让 Dify 管理员检查安装权限和网络;插件需要能通过 HTTPS 连接 `api.acedata.cloud`。 + +![Installed plugin in Dify](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/01-installed.png) + +## 2. 获取能调用该服务的 API Key + +1. 登录 [Ace Data Cloud → 我的应用](https://platform.acedata.cloud/console/applications)。 +2. 找到 **通用应用**。通用应用 Key 可用于账号有权使用的多个服务;服务专用 Key 仅限对应服务。本教程需要核对 **Suno** 的调用权限、余额和当前价格。 +3. 要用已有 Key,点击图中 **①复制**。要给 Dify 单独创建一个 Key,点击 **②管理密钥**,再点右上角 **创建**。 + +![复制已有Key或打开管理密钥](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/get-api-key-en.png) + +4. 填名称,例如 `Dify tutorial`,按需设置用量、过期时间和 API 限制,点击 **创建**,再从列表或应用页复制 Key。如果启用了 **Allowed APIs / 允许的 API**,应同时包含本例所需的生成和任务查询接口:`/suno/audios`, `/suno/tasks`。 + +![创建独立的Dify凭据](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/create-api-key-en.png) + +Dify 只粘贴复制出的 Token 字符串,不加 `Bearer `、引号或截图中的遮挡字符。不要用 `platform-...` 一类平台管理 Token 代替调用服务的 API Key。首次运行前确认服务权限和余额。 + +## 3. 在 Dify 中保存凭据 + +1. 进入 **Integrations → Tools → Tool Plugin → Suno**。 +2. 点击 **API Key Authorization Configuration(API Key 授权配置)**。如果已有凭据,先点 **1 Authorization**,再进入配置。 +3. **Authorization Name(授权名称)**填写 `Ace Data Cloud`;**Ace Data Cloud Bearer Token** 填刚复制的 Key。 +4. 选择谁可以使用该凭据,点 **Save(保存)**。不要把 Key 放进提示词或导出的工作流。 + +![Dify工具授权窗口](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/02-authorize.png) + +## 4. 创建最小工作流并填参数 + +打开 **Studio(工作室)→ Create from Blank(从空白创建)→ Workflow(工作流)**,输入名称。点击节点旁的 **+** 添加 Tool,在本插件下选择准确的工具名称。按顺序拖动节点右侧连接点: + +**Start → Suno Generate Audios(Suno 生成歌曲) → Suno Retrieve Task(查询任务) → Output**。 + +把生成节点重命名为 **Suno**,查询节点命名为 **Retrieve completed task**,便于对照截图。首跑先用固定参数,Start 不用加输入。生成节点的 **Retry on Failure(失败重试)**保持关闭。 + +![节点连线总览](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/03-workflow.png) + +选中生成/调用节点,按表填写;没有列出的可选参数先留空。 + +| Dify 字段 | 首跑值 | |---|---| -| `suno_generate_audios` | `POST /suno/audios` | -| `suno_generate_lyrics` | `POST /suno/lyrics` | -| `suno_upload_reference_audio` | `POST /suno/upload` | -| `suno_get_mp4` | `POST /suno/mp4` | -| `suno_get_mp3` | `POST /suno/mp3` | -| `suno_get_wav` | `POST /suno/wav` | -| `suno_get_midi` | `POST /suno/midi` | -| `suno_get_timing` | `POST /suno/timing` | -| `suno_create_vox_audio` | `POST /suno/vox` | -| `suno_enhance_style` | `POST /suno/style` | -| `suno_mashup_lyrics` | `POST /suno/mashup-lyrics` | -| `suno_create_voice` | `POST /suno/voices` | -| `suno_create_persona` | `POST /suno/persona` | -| `suno_list_personas` | `GET /suno/persona` | -| `suno_delete_persona` | `DELETE /suno/persona` | -| `suno_custom_models` | `POST /suno/custom-models` | -| `suno_projects` | `POST /suno/projects` | -| `suno_task_retrieve` | `POST /suno/tasks` | -| `suno_tasks_retrieve_batch` | `POST /suno/tasks` | +| 模型 (`model`) | `chirp-v6` | +| 纯音乐 (`instrumental`) | `true` | +| 时长 (`duration`) | `10` | + +**提示词** (`prompt`): + +```text +A short gentle instrumental piano melody for a sunrise, no vocals. +``` + +首跑打开 **Instrumental**(纯音乐)。Duration 是目标时长,并不保证成品精确等长。自定义人声歌曲需要歌词或歌词提示词;运行中的试听链接不代表最终完成。 + +![填写实际参数](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/03-configure.png) -完整 MCP 对照、参数别名和适用范围见 [CAPABILITIES.md](../CAPABILITIES.md)。复杂参数填写 JSON,示例见 [contract-examples.json](https://github.com/AceDataCloud/SunoDify/blob/main/tests/contract-examples.json);其中 example.org 链接须替换成自己的可访问媒体。 +## 5. 绑定同一个任务并等待结果 -生成工作流连接 **开始 → 生成工具 → 查询任务 → 输出**。提交返回 `pending` 时,保存 `task_id`,并使用同一 ID 查询。`wait_seconds=0` 查询一次,1–240 表示最多等待相应秒数。仍在运行时继续查询原任务,不重新提交生成。请关闭生成节点的自动重试。 +选中 **Suno Retrieve Task**。在 **Task ID(任务 ID)**框点击变量选择器(或输入 `/`),选择 **Suno → task_id**。必须选生成节点的输出变量,不能把变量名称作为普通文字输入。**Wait up to seconds(最长等待秒数)**填 `240`,本例 Trace ID 留空。 -输出包含 `status`、`success`、`task_id`、`trace_id`、`media_urls`、`data` 和 `result`。只有任务最终完成才返回成功;预览链接不算完成。批量查询分别保留每个任务的状态。同步操作直接返回结果。删除或归档需要设置 `confirm=true`。插件不会执行模型返回的工具调用。 +![选择生成节点的task_id变量](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/04-task-id.png) -本版补充了当前服务接口的参数和操作;不同 MCP 函数可能合并为操作选项或结构化输入。图片接口固定返回 URL,流式接口使用 Dify 可处理的完整响应及异步任务查询。每个高级操作和模型是否已真实验证,以测试证据记录为准。 +选中 **Output**,点击 **+** 添加以下输出,并从 **Retrieve completed task** 节点选择对应变量: -## Logo、隐私与费用 +| 输出名称 | 查询节点变量 | 类型 | +|---|---|---| +| status | status | String | +| success | success | Boolean | +| task_id | task_id | String | +| media_urls | media_urls | Array[String] | +| result | result | Object | -浅色和深色图标复用系统中已有的官方服务资产,未经重绘;来源和 SHA256 见 [branding-source.json](https://github.com/AceDataCloud/SunoDify/blob/main/tests/branding-source.json)。 +![输出变量映射](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/05-output.png) -插件仅直接连接 `api.acedata.cloud`,把用户选择的文本、参数、参考媒体 URL 和任务 ID 发给 API,并向 Dify 返回结果。只提交已获授权的媒体。音色和自定义模型创建涉及对应的训练或克隆处理,须先核对素材权限和价格。详见 [隐私说明](../PRIVACY.md)。 +点击 **Test Run → Start Run**。如果 240 秒内未生成完,返回 `status=pending` 是正常情况。**不要重跑整个工作流**,否则会再次提交生成。复制已有 task_id,另建 **Start → Suno Retrieve Task → Output**,Task ID 填原来的值,等待填 0 或 240;只查询这个任务,直到 `status=succeeded` 且 `success=true`,再打开 `media_urls` 中的链接。Dify 流程绿色成功不等于服务任务已经完成。 -使用记录以 Ace Data Cloud 的账单为准,单位为 Credits;USD = Credits × 当前套餐价格 / 额度。生成超时后先检查请求历史,避免重复扣费。插件没有自动付费重试或模型替换。 +## 6. 检查预期输出 -## 源码与验证 +完成后结果形态如下;示例 URL 只说明字段位置,要使用你自己返回的链接: + +```json +{ + "status": "succeeded", + "success": true, + "media_urls": [ + "https://.../result.mp3" + ] +} +``` + +![真实Dify成功结果](https://raw.githubusercontent.com/AceDataCloud/SunoDify/8d3d03570e73324220f111f7fe343da0792a8071/_assets/tutorial/06-result.png) + +实际运行示例;你的任务 ID 和链接会不同。 + +## 常见问题 + +| 现象 | 处理方法 | +|---|---| +| 授权失败、401/403 | 重新复制完整 API Token,去掉 `Bearer `;检查服务权限、余额、过期时间和允许的 API。 | +| 参数错误、400 | 核对示例中的模型、操作、分辨率和 JSON 格式,不要混用不同操作的字段。 | +| `pending` / 媒体列表为空 | 继续查原任务 ID,不重新生成。 | +| 429 限流 | 稍后再试并降低并发;不要打开付费生成的自动重试。 | +| 超时、5xx、任务失败 | 先看原任务与请求历史,再决定是否重提;联系支持只提供 task_id/trace_id,不提供 Key。 | +| 链接打不开 | 先确认任务最终成功,再检查 Dify 服务器/浏览器是否能访问返回的链接。 | -- 源码:https://github.com/AceDataCloud/SunoDify -- 问题反馈:https://github.com/AceDataCloud/SunoDify/issues -- 联系:dev@acedata.cloud +[下载可导入工作流](https://github.com/AceDataCloud/SunoDify/raw/refs/heads/main/docs/quickstart.dify.yml)。在 Studio 导入后配置自己的凭据;文件不含任何 Key。 -需要 Python 3.12。运行 `python -m pytest tests -q`、`ruff check .`、`ruff format --check .` 和 `dify plugin package .`。真实 Dify 截图与结果、未覆盖项见 tests 目录;单元测试通过不等于所有模型真实调用通过,市场上架和安装另行验收。 +## 隐私、费用与支持 -## 官方市场安装验收 +插件免费,API 按当前服务价格计费。插件把所选输入与凭据发送至 `api.acedata.cloud`,凭据由 Dify 保存;详见[隐私说明](https://github.com/AceDataCloud/SunoDify/blob/main/PRIVACY.md)。只提交有权处理的内容。 -2026-10-08 已从[官方市场](https://marketplace.dify.ai/plugin/acedatacloud/suno)安装签名包,并完成记录中的真实 Dify 工作流。未使用 remote-debug。[验收数据](../tests/marketplace-acceptance.json)与[原始截图](../tests/evidence/marketplace-20261008.png)记录了准确范围;此前主流程和高级功能证据继续保留。本次复用已有成功任务验证查询与媒体输出,没有重复生成。 +[源码](https://github.com/AceDataCloud/SunoDify) · [问题反馈](https://github.com/AceDataCloud/SunoDify/issues) · dev@acedata.cloud · [高级功能](https://github.com/AceDataCloud/SunoDify/blob/main/CAPABILITIES.md)。开发、品牌来源和验证材料位于源码仓库,不影响以上首跑步骤。 diff --git a/tests/tutorial-assets.json b/tests/tutorial-assets.json new file mode 100644 index 0000000..825cc3b --- /dev/null +++ b/tests/tutorial-assets.json @@ -0,0 +1,68 @@ +{ + "captured": "2026-10-09", + "provenance": "Live Dify configuration screenshots and prior real successful results; no new paid generation. Sidebar/identity areas redacted; no success state modified.", + "key_source": { + "captured_at": "2026-10-08T17:15:13.782Z", + "source_url": "https://platform.acedata.cloud/console/applications", + "auth": "Existing authorized account, own identity", + "privacy": "Balance, application ID and complete/partial token are opaque-masked before screenshot capture. Dialog crops omit unrelated UI.", + "edits": "Crop + numbered callouts on live screenshot only; no UI data or success state fabricated.", + "capture_actions": "Read application page, open Manage Keys, open Create, fill example name, cancel; no credential created and no billable API call.", + "instructions": { + "1": "Copy the selected existing key. The screenshot redacts it. Paste only token in Dify, not the Bearer label.", + "2": "Manage Keys, then Create; use own key name and appropriate restrictions. Return to the list/application page to copy." + }, + "files": [ + { + "file": "create-api-key-en.png", + "sha256": "977c06780b36ca33f2fb3ba546e2594efe5895400e4cb58d842eb564c3bb09da", + "bytes": 25251 + }, + { + "file": "get-api-key-en.png", + "sha256": "b63787f2bd15af82fef9ab61c99e11c454355ac86e91f7f94559386b795069b7", + "bytes": 33708 + } + ], + "published_screenshot_language": "English only in every locale, per explicit user instruction" + }, + "files": [ + { + "path": "_assets/tutorial/02-authorize.png", + "sha256": "5de57fb2f4ad948d785a3bf5696ad664cc9f3f234e06b538c8449e8366df1570" + }, + { + "path": "_assets/tutorial/03-workflow.png", + "sha256": "06e7111b940d1b110342f505c8405c287def6353e7332a0a0fc360164728d64b" + }, + { + "path": "_assets/tutorial/03-configure.png", + "sha256": "d5d4946678244551856ce63cd044eb3fbbac447e95a51da0f21537170fc96291" + }, + { + "path": "_assets/tutorial/create-api-key-en.png", + "sha256": "977c06780b36ca33f2fb3ba546e2594efe5895400e4cb58d842eb564c3bb09da" + }, + { + "path": "_assets/tutorial/01-installed.png", + "sha256": "06c249de3ce5503f8367030d8c93ea612c1864cb2b62a5081f29d306b94f1405" + }, + { + "path": "_assets/tutorial/06-result.png", + "sha256": "2691193fdbc7b71b5c9404181723927eda0bb8ded9e2a697335793017f5a3b08" + }, + { + "path": "_assets/tutorial/04-task-id.png", + "sha256": "9cab554e6cc82cbe0594de0424cdb4687a11ba6e313ed62afab0e99fc4966efb" + }, + { + "path": "_assets/tutorial/05-output.png", + "sha256": "952e20414a98f18e82a03853b4e9e594fdf060a9b4713a40b76eedeeb07818a1" + }, + { + "path": "_assets/tutorial/get-api-key-en.png", + "sha256": "b63787f2bd15af82fef9ab61c99e11c454355ac86e91f7f94559386b795069b7" + } + ], + "published_screenshot_language": "English only" +} \ No newline at end of file