mirror of
https://github.com/langgenius/dify-docs.git
synced 2026-03-27 13:28:32 +07:00
add: flomo plugin dev docs
This commit is contained in:
@@ -309,7 +309,8 @@
|
||||
"group": "Development Guides",
|
||||
"pages": [
|
||||
"plugin-dev-en/0432-develop-a-slack-bot-plugin",
|
||||
"plugin-dev-en/0432-endpoint"
|
||||
"plugin-dev-en/0432-endpoint",
|
||||
"plugin-dev-en/0432-develop-flomo-plugin"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
334
plugin-dev-en/0432-develop-flomo-plugin.mdx
Normal file
334
plugin-dev-en/0432-develop-flomo-plugin.mdx
Normal file
@@ -0,0 +1,334 @@
|
||||
---
|
||||
title: '10-Minute Guide to Building Dify Plugins'
|
||||
description: 'Learn how to build a functional Dify plugin that connects with Flomo note-taking service in just 10 minutes'
|
||||
language: en
|
||||
standard_title: 10-Minute Guide to Building Dify Plugins
|
||||
---
|
||||
|
||||
## What you'll build
|
||||
|
||||
By the end of this guide, you'll have created a Dify plugin that:
|
||||
|
||||
- Connects to the Flomo note-taking API
|
||||
- Allows users to save notes from AI conversations directly to Flomo
|
||||
- Handles authentication and error states properly
|
||||
- Is ready for distribution in the Dify Marketplace
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Time required" icon="clock">
|
||||
10 minutes
|
||||
</Card>
|
||||
<Card title="Prerequisites" icon="list-check">
|
||||
Basic Python knowledge and a Flomo account
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Step 1: Install the Dify CLI and create a project
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Dify CLI">
|
||||
<Tabs>
|
||||
<Tab title="Mac">
|
||||
```bash
|
||||
brew tap langgenius/dify
|
||||
brew install dify
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Linux">
|
||||
Get the latest Dify CLI from the [Dify GitHub releases page](https://github.com/langgenius/dify-plugin-daemon/releases)
|
||||
|
||||
```bash
|
||||
# Download appropriate version
|
||||
chmod +x dify-plugin-linux-amd64
|
||||
mv dify-plugin-linux-amd64 dify
|
||||
sudo mv dify /usr/local/bin/
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
Verify installation:
|
||||
```bash
|
||||
dify version
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Initialize a plugin project">
|
||||
Create a new plugin project using:
|
||||
|
||||
```bash
|
||||
dify plugin init
|
||||
```
|
||||
|
||||
Follow the prompts to set up your plugin:
|
||||
- Name it "flomo"
|
||||
- Select "tool" as the plugin type
|
||||
- Complete other required fields
|
||||
</Step>
|
||||
|
||||
<Step title="Navigate to the project">
|
||||
```bash
|
||||
cd flomo
|
||||
```
|
||||
|
||||
This will create the basic structure for your plugin with all necessary files.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Step 2: Define your plugin manifest
|
||||
|
||||
<Info>
|
||||
The manifest.yaml file defines your plugin's metadata, permissions, and capabilities.
|
||||
</Info>
|
||||
|
||||
Create a `manifest.yaml` file:
|
||||
|
||||
```yaml
|
||||
version: 0.0.4
|
||||
type: plugin
|
||||
author: yourname
|
||||
label:
|
||||
en_US: Flomo
|
||||
zh_Hans: Flomo 浮墨笔记
|
||||
created_at: "2023-10-01T00:00:00Z"
|
||||
icon: icon.png
|
||||
|
||||
resource:
|
||||
memory: 67108864 # 64MB
|
||||
permission:
|
||||
storage:
|
||||
enabled: false
|
||||
|
||||
plugins:
|
||||
tools:
|
||||
- flomo.yaml
|
||||
|
||||
meta:
|
||||
version: 0.0.1
|
||||
arch:
|
||||
- amd64
|
||||
- arm64
|
||||
runner:
|
||||
language: python
|
||||
version: 3.12
|
||||
entrypoint: main
|
||||
```
|
||||
|
||||
## Step 3: Create the tool definition
|
||||
|
||||
Create a `flomo.yaml` file to define your tool interface:
|
||||
|
||||
```yaml
|
||||
identity:
|
||||
author: yourname
|
||||
name: flomo
|
||||
label:
|
||||
en_US: Flomo Note
|
||||
zh_Hans: Flomo 浮墨笔记
|
||||
description:
|
||||
human:
|
||||
en_US: Add notes to your Flomo account directly from Dify.
|
||||
zh_Hans: 直接从Dify添加笔记到您的Flomo账户。
|
||||
llm: >
|
||||
A tool that allows users to save notes to Flomo. Use this tool when users want to save important information from the conversation. The tool accepts a 'content' parameter that contains the text to be saved as a note.
|
||||
credential_schema:
|
||||
api_url:
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: API URL
|
||||
zh_Hans: API URL
|
||||
human_description:
|
||||
en_US: Flomo API URL from your Flomo account settings.
|
||||
zh_Hans: 从您的Flomo账户设置中获取的API URL。
|
||||
tool_schema:
|
||||
content:
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: Note Content
|
||||
zh_Hans: 笔记内容
|
||||
human_description:
|
||||
en_US: Content to save as a note in Flomo.
|
||||
zh_Hans: 要保存为Flomo笔记的内容。
|
||||
```
|
||||
|
||||
## Step 4: Implement core utility functions
|
||||
|
||||
Create a utility module in `utils/flomo_utils.py` for API interaction:
|
||||
|
||||
<CodeGroup>
|
||||
```python utils/flomo_utils.py
|
||||
import requests
|
||||
|
||||
def send_flomo_note(api_url: str, content: str) -> None:
|
||||
"""
|
||||
Send a note to Flomo via the API URL. Raises requests.RequestException on network errors,
|
||||
and ValueError on invalid status codes or input.
|
||||
"""
|
||||
api_url = api_url.strip()
|
||||
if not api_url:
|
||||
raise ValueError("API URL is required and cannot be empty.")
|
||||
if not api_url.startswith('https://flomoapp.com/iwh/'):
|
||||
raise ValueError(
|
||||
"API URL should be in the format: https://flomoapp.com/iwh/{token}/{secret}/"
|
||||
)
|
||||
if not content:
|
||||
raise ValueError("Content cannot be empty.")
|
||||
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
response = requests.post(api_url, json={"content": content}, headers=headers, timeout=10)
|
||||
|
||||
if response.status_code != 200:
|
||||
raise ValueError(f"API URL is not valid. Received status code: {response.status_code}")
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Step 5: Implement the Tool Provider
|
||||
|
||||
The Tool Provider handles credential validation. Create `provider/flomo.py`:
|
||||
|
||||
<CodeGroup>
|
||||
```python provider/flomo.py
|
||||
from typing import Any
|
||||
from dify_plugin import ToolProvider
|
||||
from dify_plugin.errors.tool import ToolProviderCredentialValidationError
|
||||
import requests
|
||||
from utils.flomo_utils import send_flomo_note
|
||||
|
||||
class FlomoProvider(ToolProvider):
|
||||
def _validate_credentials(self, credentials: dict[str, Any]) -> None:
|
||||
try:
|
||||
api_url = credentials.get('api_url', '').strip()
|
||||
# Use utility for validation and sending test note
|
||||
send_flomo_note(api_url, "Hello, #flomo https://flomoapp.com")
|
||||
except ValueError as e:
|
||||
raise ToolProviderCredentialValidationError(str(e))
|
||||
except requests.RequestException as e:
|
||||
raise ToolProviderCredentialValidationError(f"Connection error: {str(e)}")
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Step 6: Implement the Tool
|
||||
|
||||
The Tool class handles actual API calls when the user invokes the plugin. Create `tools/flomo.py`:
|
||||
|
||||
<CodeGroup>
|
||||
```python tools/flomo.py
|
||||
from collections.abc import Generator
|
||||
from typing import Any
|
||||
from dify_plugin import Tool
|
||||
from dify_plugin.entities.tool import ToolInvokeMessage
|
||||
import requests
|
||||
from utils.flomo_utils import send_flomo_note
|
||||
|
||||
class FlomoTool(Tool):
|
||||
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
|
||||
content = tool_parameters.get("content", "")
|
||||
api_url = self.runtime.credentials.get("api_url", "")
|
||||
|
||||
try:
|
||||
send_flomo_note(api_url, content)
|
||||
except ValueError as e:
|
||||
yield self.create_text_message(str(e))
|
||||
return
|
||||
except requests.RequestException as e:
|
||||
yield self.create_text_message(f"Connection error: {str(e)}")
|
||||
return
|
||||
|
||||
# Return success message and structured data
|
||||
yield self.create_text_message(
|
||||
"Note created successfully! Your content has been sent to Flomo."
|
||||
)
|
||||
yield self.create_json_message({
|
||||
"status": "success",
|
||||
"content": content,
|
||||
})
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Warning>
|
||||
Always handle exceptions gracefully and return user-friendly error messages. Remember that your plugin represents your brand in the Dify ecosystem.
|
||||
</Warning>
|
||||
|
||||
## Step 7: Test your plugin
|
||||
|
||||
<Steps>
|
||||
<Step title="Set up debug environment">
|
||||
Copy the example environment file:
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Edit the `.env` file with your Dify environment details:
|
||||
```
|
||||
INSTALL_METHOD=remote
|
||||
REMOTE_INSTALL_HOST=debug-plugin.dify.dev
|
||||
REMOTE_INSTALL_PORT=5003
|
||||
REMOTE_INSTALL_KEY=your_debug_key
|
||||
```
|
||||
|
||||
You can find your debug key and host in the Dify dashboard: click the "Plugins" icon in the top right corner, then click the debug icon. In the pop-up window, copy the "API Key" and "Host Address".
|
||||
</Step>
|
||||
|
||||
<Step title="Install dependencies and run">
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
python -m main
|
||||
```
|
||||
|
||||
Your plugin will connect to your Dify instance in debug mode.
|
||||
</Step>
|
||||
|
||||
<Step title="Test functionality">
|
||||
In your Dify instance, navigate to plugins and find your debugging plugin (marked as "debugging").
|
||||
Add your Flomo API credentials and test sending a note.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Step 9: Package and distribute
|
||||
|
||||
When you're ready to share your plugin:
|
||||
|
||||
```bash
|
||||
dify plugin package ./
|
||||
```
|
||||
|
||||
This creates a `plugin.difypkg` file you can upload to the Dify Marketplace.
|
||||
|
||||
## Next steps
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Add more features" icon="plus">
|
||||
Consider adding hashtag support, note search, or other Flomo API features
|
||||
</Card>
|
||||
<Card title="Enhance error handling" icon="shield">
|
||||
Add more detailed error states and recovery flows
|
||||
</Card>
|
||||
<Card title="Automate releases" icon="rocket">
|
||||
Configure GitHub Actions for automated package and PR creation
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Accordion title="Common issues and troubleshooting">
|
||||
<AccordionItem title="Plugin doesn't appear in debug mode">
|
||||
Make sure your `.env` file is properly configured and you're using the correct debug key.
|
||||
</AccordionItem>
|
||||
|
||||
<AccordionItem title="API authentication errors">
|
||||
Double-check your Flomo API URL format. It should be in the form: `https://flomoapp.com/iwh/{token}/{secret}/`
|
||||
</AccordionItem>
|
||||
|
||||
<AccordionItem title="Packaging fails">
|
||||
Ensure all required files are present and the manifest.yaml structure is valid.
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
|
||||
## Summary
|
||||
|
||||
You've built a functioning Dify plugin that connects with an external API service! This same pattern works for integrating with thousands of services - from databases and search engines to productivity tools and custom APIs.
|
||||
|
||||
<Note>
|
||||
Remember to add a privacy policy if you plan to publish your plugin. You can create a simple PRIVACY.md file referencing Flomo's privacy policy.
|
||||
Remember to write the README.md file in English (en_US) to describe your plugin's functionality, setup instructions, and usage examples.
|
||||
For other languages, you can create additional README files like `readme/README_zh_Hans.md` for Simplified Chinese.
|
||||
</Note>
|
||||
Reference in New Issue
Block a user