Files
momentry_core/docs/API_EXAMPLES.md

772 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Momentry Core API 使用範例總覽
| 項目 | 內容 |
|------|------|
| 版本 | V2.1 |
| 日期 | 2026-03-26 |
| Base URL (本地) | `http://localhost:3002` |
| Base URL (外部) | `https://api.momentry.ddns.net` |
---
## 版本歷史
| 版本 | 日期 | 目的 | 操作人 |
|------|------|------|--------|
| V2.0 | 2026-03-25 | 創建完整範例總覽 | OpenCode |
| V2.1 | 2026-03-26 | 更新API回應格式 (media_url→file_path) 與認證標頭 | OpenCode |
---
## 快速參考
### 環境 URL 選擇
| 環境 | URL | 用途 |
|------|-----|------|
| **本地開發** | `http://localhost:3002` | 開發/測試,直接訪問 API |
| **外部訪問** | `https://api.momentry.ddns.net` | n8n、WordPress、curl 生產環境 |
### 所有可用端點
| 方法 | 端點 | 說明 |
|------|------|------|
| GET | `/health` | 健康檢查 |
| GET | `/health/detailed` | 詳細健康檢查 |
| POST | `/api/v1/search` | 語意搜尋(標準格式) |
| POST | `/api/v1/n8n/search` | 語意搜尋n8n 格式) |
| POST | `/api/v1/search/hybrid` | 混合搜尋 |
| POST | `/api/v1/register` | 註冊影片 |
| POST | `/api/v1/probe` | 探測影片資訊 |
| GET | `/api/v1/videos` | 列出所有影片 |
| GET | `/api/v1/lookup` | 查詢影片 |
| GET | `/api/v1/progress/:uuid` | 處理進度 |
| GET | `/api/v1/jobs` | 任務列表 |
| GET | `/api/v1/jobs/:uuid` | 任務詳情 |
---
## 認證
### API Key
所有 `/api/v1/*` 端點需要 API Key 認證。
```bash
# 添加 API Key Header
curl -H "X-API-Key: your-api-key" http://localhost:3002/api/v1/videos
# 範例
curl -H "X-API-Key: muser_f08e13ba967e4d8ea8fc542ad9f99ac8_1774416728_90472a35" \
http://localhost:3002/api/v1/videos
```
### 響應狀態
| 狀態碼 | 說明 |
|--------|------|
| 200 | 成功 |
| 401 | 未授權(缺少或無效 API Key |
| 500 | 伺服器錯誤 |
### 建立 API Key
```bash
./target/release/momentry api-key create "My Key" --key-type user
```
---
## 1. curl 範例
### 基本語法
```bash
# 格式
curl [OPTIONS] URL
# 常用選項
-X METHOD # HTTP 方法 (GET, POST, etc.)
-H HEADER # 添加 HTTP 標頭
-d DATA # POST 請求體
-s # 靜默模式
-w FORMAT # 輸出額外信息
```
### 1.1 健康檢查
```bash
# 基本健康檢查
curl http://localhost:3002/health
# 詳細健康檢查
curl http://localhost:3002/health/detailed
```
**回應**:
```json
{"status":"ok","version":"0.1.0","uptime_ms":123456}
```
### 1.2 語意搜尋
```bash
# 標準格式搜尋
curl -X POST http://localhost:3002/api/v1/search \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"query": "charade", "limit": 5}'
# n8n 格式搜尋(推薦)
curl -X POST http://localhost:3002/api/v1/n8n/search \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"query": "charade", "limit": 5}'
# 混合搜尋
curl -X POST http://localhost:3002/api/v1/search/hybrid \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"query": "charade", "limit": 5}'
```
**標準格式回應**:
```json
{
"results": [
{
"uuid": "a1b10138a6bbb0cd",
"chunk_id": "sentence_0001",
"chunk_type": "sentence",
"start_time": 48.8,
"end_time": 55.44,
"text": "fun plot twists...",
"score": 0.92
}
],
"query": "charade"
}
```
**n8n 格式回應**:
```json
{
"query": "charade",
"count": 1,
"hits": [
{
"id": "sentence_0001",
"vid": "a1b10138a6bbb0cd",
"start": 48.8,
"end": 55.44,
"title": "Chunk sentence_0001",
"text": "fun plot twists...",
"score": 0.92,
"file_path": "/Users/accusys/momentry/var/sftpgo/data/demo/video.mp4"
}
]
}
```
### 1.3 影片管理
```bash
# 列出所有影片
curl -H "X-API-Key: YOUR_API_KEY" http://localhost:3002/api/v1/videos
# 查詢特定影片(依 UUID
curl -H "X-API-Key: YOUR_API_KEY" "http://localhost:3002/api/v1/lookup?uuid=a1b10138a6bbb0cd"
# 查詢特定影片(依路徑)
curl -H "X-API-Key: YOUR_API_KEY" "http://localhost:3002/api/v1/lookup?path=/path/to/video.mp4"
# 取得處理進度
curl -H "X-API-Key: YOUR_API_KEY" http://localhost:3002/api/v1/progress/a1b10138a6bbb0cd
# 探測影片(不註冊)
curl -X POST http://localhost:3002/api/v1/probe \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"path": "/path/to/video.mp4"}'
# 註冊影片
curl -X POST http://localhost:3002/api/v1/register \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"path": "/path/to/video.mp4"}'
```
### 1.4 批次測試腳本
```bash
#!/bin/bash
# api_test.sh - API 測試腳本
API_URL="http://localhost:3002"
echo "=== 健康檢查 ==="
curl -s "$API_URL/health" | jq .
echo -e "\n=== 語意搜尋 ==="
curl -s -X POST "$API_URL/api/v1/search" \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"query": "charade", "limit": 3}' | jq .
echo -e "\n=== 影片列表 ==="
curl -s -H "X-API-Key: YOUR_API_KEY" "$API_URL/api/v1/videos" | jq '.videos | length'
```
### 1.5 外部 URL 範例
```bash
# 使用外部 URL需網路可達
curl https://api.momentry.ddns.net/health
# 外部搜尋
curl -X POST https://api.momentry.ddns.net/api/v1/n8n/search \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"query": "charade", "limit": 5}'
```
---
## 2. n8n 範例
### 2.1 HTTP Request Node 設定
```
Node: HTTP Request
├── URL: https://api.momentry.ddns.net/api/v1/n8n/search
├── Method: POST
├── Authentication: None
├── Send Body: ✓ (checked)
├── Content Type: JSON
├── Body:
│ {
│ "query": "={{ $json.query }}",
│ "limit": "={{ $json.limit || 10 }}"
│ }
├── Send Headers: ✓ (checked)
└── Header Parameters:
└── X-API-Key: {{ $env.MOMENTRY_API_KEY }}
```
### 2.2 基本搜尋 Workflow
```json
{
"name": "Momentry Video Search",
"nodes": [
{
"parameters": {},
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"position": [250, 300]
},
{
"parameters": {
"url": "https://api.momentry.ddns.net/api/v1/n8n/search",
"method": "POST",
"sendBody": true,
"contentType": "json",
"body": {
"query": "charade",
"limit": 3
}
},
"name": "Search Video API",
"type": "n8n-nodes-base.httpRequest",
"position": [450, 300]
}
],
"connections": {
"Manual Trigger": {
"main": [[{"node": "Search Video API"}]]
}
}
}
```
### 2.3 Webhook 動態搜尋
```json
{
"name": "Momentry Dynamic Search",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "search",
"responseMode": "lastNode"
},
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [250, 300]
},
{
"parameters": {
"url": "https://api.momentry.ddns.net/api/v1/n8n/search",
"method": "POST",
"sendBody": true,
"contentType": "json",
"body": {
"query": "={{ JSON.stringify($json.body.query) }}",
"limit": "={{ $json.body.limit || 5 }}"
}
},
"name": "Search API",
"type": "n8n-nodes-base.httpRequest",
"position": [450, 300]
}
],
"connections": {
"Webhook": {
"main": [[{"node": "Search API"}]]
}
}
}
```
### 2.4 測試 Webhook
```bash
# 測試模式(需先在 n8n UI 點擊 Execute
curl -X POST http://localhost:5678/webhook-test/video-rag-mcp \
-H "Content-Type: application/json" \
-d '{"query":"charade","limit":3}'
# 生產環境(需 workflow 為 Active 狀態)
curl -X POST http://localhost:5678/webhook/video-rag-mcp \
-H "Content-Type: application/json" \
-d '{"query":"charade","limit":3}'
```
### 2.5 健康檢查 Workflow
```json
{
"name": "Momentry Health Check",
"nodes": [
{
"parameters": {},
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"position": [250, 300]
},
{
"parameters": {
"url": "https://api.momentry.ddns.net/health",
"method": "GET"
},
"name": "Health Check",
"type": "n8n-nodes-base.httpRequest",
"position": [450, 300]
}
],
"connections": {
"Manual Trigger": {
"main": [[{"node": "Health Check"}]]
}
}
}
```
### 2.6 錯誤處理
| 錯誤 | 原因 | 解決 |
|------|------|------|
| 502 Bad Gateway | API 服務未啟動 | `sudo launchctl load /Library/LaunchDaemons/com.momentry.api.plist` |
| "Your request is invalid" | Body 格式設定錯誤 | 確認 Content Type: JSONBody 為有效 JSON |
| 404 on webhook-test | 未執行 workflow | 在 n8n UI 點擊 "Execute workflow" |
---
## 3. WordPress 範例
### 3.1 PHP 基本用法
```php
<?php
// 搜尋影片
$api_url = 'https://api.momentry.ddns.net/api/v1/n8n/search';
$data = [
'query' => 'charade',
'limit' => 10
];
$response = wp_remote_post($api_url, [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode($data),
'timeout' => 30
]);
if (is_wp_error($response)) {
echo '錯誤: ' . $response->get_error_message();
} else {
$body = json_decode(wp_remote_retrieve_body($response), true);
print_r($body['hits']);
}
?>
```
### 3.2 列出影片
```php
<?php
$api_url = 'https://api.momentry.ddns.net/api/v1/videos';
$response = wp_remote_get($api_url, ['timeout' => 30]);
if (!is_wp_error($response)) {
$body = json_decode(wp_remote_retrieve_body($response), true);
foreach ($body['videos'] as $video) {
echo $video['file_name'] . "\n";
}
}
?>
```
### 3.3 查詢特定影片
```php
<?php
$uuid = 'a1b10138a6bbb0cd';
$api_url = 'https://api.momentry.ddns.net/api/v1/lookup?uuid=' . $uuid;
$response = wp_remote_get($api_url, ['timeout' => 30]);
if (!is_wp_error($response)) {
$video = json_decode(wp_remote_retrieve_body($response), true);
echo '檔案: ' . $video['file_name'] . "\n";
echo '時長: ' . $video['duration'] . ' 秒';
}
?>
```
### 3.4 JavaScript fetch
```javascript
// 搜尋影片
async function searchVideos(query, limit = 10) {
const response = await fetch('https://api.momentry.ddns.net/api/v1/n8n/search', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, limit })
});
if (!response.ok) {
throw new Error('API 請求失敗');
}
return await response.json();
}
// 使用範例
searchVideos('charade', 5)
.then(data => {
data.hits.forEach(hit => {
console.log(`${hit.text} (score: ${hit.score})`);
});
});
```
### 3.5 WordPress Shortcode
`functions.php` 中註冊短碼:
```php
<?php
// 將文件路徑轉換為可訪問的 URL
function convert_file_path_to_url($file_path) {
// 範例: 將 SFTPGo 文件路徑轉換為 web URL
// /Users/accusys/momentry/var/sftpgo/data/demo/video.mp4
// → https://sftpgo.example.com/demo/video.mp4
// 移除基本路徑
$base_path = '/Users/accusys/momentry/var/sftpgo/data/';
if (strpos($file_path, $base_path) === 0) {
$relative_path = substr($file_path, strlen($base_path));
// 替換為實際的 SFTPGo web URL
return 'https://sftpgo.example.com/' . $relative_path;
}
// 如果無法轉換,返回原始路徑
return $file_path;
}
// 註冊短碼
add_shortcode('momentry_search', function($atts) {
$atts = shortcode_atts([
'query' => '',
'limit' => '10'
], $atts);
if (empty($atts['query'])) {
return '<p>請提供搜尋關鍵字</p>';
}
$response = wp_remote_post('https://api.momentry.ddns.net/api/v1/n8n/search', [
'headers' => [
'Content-Type' => 'application/json',
'X-API-Key' => 'YOUR_API_KEY' // 替換為實際的 API Key
],
'body' => json_encode([
'query' => $atts['query'],
'limit' => (int)$atts['limit']
]),
'timeout' => 30
]);
if (is_wp_error($response)) {
return '<p>搜尋服務暫時無法使用</p>';
}
$data = json_decode(wp_remote_retrieve_body($response), true);
if (empty($data['hits'])) {
return '<p>找不到相關結果</p>';
}
$output = '<ul class="momentry-results">';
foreach ($data['hits'] as $hit) {
// 注意: API 現在返回 file_path 而非 media_url
// 需要將文件路徑轉換為可訪問的 URL
$file_path = $hit['file_path'];
$video_url = convert_file_path_to_url($file_path); // 需要實作此函數
$output .= sprintf(
'<li>%s <a href="%s?start=%s">播放</a></li>',
esc_html($hit['text']),
$video_url,
$hit['start']
);
}
$output .= '</ul>';
return $output;
});
?>
```
**使用方式**:
```
[momentry_search query="charade" limit="5"]
```
### 3.6 WordPress REST API Endpoint
在 WordPress REST API 中註冊自定義端點:
```php
<?php
// 註冊 REST API 端點
add_action('rest_api_init', function() {
register_rest_route('momentry/v1', '/search', [
'methods' => 'POST',
'callback' => function($request) {
$response = wp_remote_post(
'https://api.momentry.ddns.net/api/v1/n8n/search',
[
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode([
'query' => $request->get_param('query'),
'limit' => $request->get_param('limit', 10)
])
]
);
if (is_wp_error($response)) {
return new WP_Error('api_error', 'API 請求失敗');
}
return json_decode(wp_remote_retrieve_body($response));
}
]);
});
?>
```
**呼叫方式**:
```
POST /wp-json/momentry/v1/search
Body: {"query": "charade", "limit": 5}
```
---
## 4. 回應格式說明
### 4.1 n8n 格式 (`/api/v1/n8n/search`)
```json
{
"query": "charade",
"count": 10,
"hits": [
{
"id": "sentence_0001",
"vid": "a1b10138a6bbb0cd",
"start": 48.8,
"end": 55.44,
"title": "Chunk sentence_0001",
"text": "fun plot twists...",
"score": 0.92,
"file_path": "/Users/accusys/momentry/var/sftpgo/data/demo/video.mp4"
}
]
}
```
### 4.2 標準格式 (`/api/v1/search`)
```json
{
"results": [
{
"uuid": "a1b10138a6bbb0cd",
"chunk_id": "sentence_0001",
"chunk_type": "sentence",
"start_time": 48.8,
"end_time": 55.44,
"text": "fun plot twists...",
"score": 0.92
}
],
"query": "charade"
}
```
### 4.3 健康檢查
```json
{
"status": "ok",
"version": "0.1.0",
"uptime_ms": 123456
}
```
### 4.4 詳細健康檢查
```json
{
"status": "ok",
"version": "0.1.0",
"uptime_ms": 123456,
"services": {
"postgres": {"status": "ok", "latency_ms": 42, "error": null},
"redis": {"status": "ok", "latency_ms": 0, "error": null},
"qdrant": {"status": "ok", "latency_ms": 15, "error": null},
"mongodb": {"status": "ok", "latency_ms": 0, "error": null}
}
}
```
### 4.5 處理進度
```json
{
"uuid": "a1b10138a6bbb0cd",
"file_name": "video.mp4",
"duration": 120.5,
"overall_progress": 75,
"processors": [
{"name": "asr", "status": "complete", "progress": 100},
{"name": "cut", "status": "complete", "progress": 100},
{"name": "yolo", "status": "progress", "progress": 35}
]
}
```
### 4.6 Probe 回應
```json
{
"uuid": "a1b10138a6bbb0cd",
"file_name": "video.mp4",
"duration": 120.5,
"width": 1920,
"height": 1080,
"fps": 30.0,
"cached": false,
"format": {
"filename": "/path/to/video.mp4",
"format_name": "mov,mp4,m4a,3gp,3g2,mj2",
"duration": "120.5",
"size": "12345678",
"bit_rate": "819200"
},
"streams": [
{
"index": 0,
"codec_name": "h264",
"codec_type": "video",
"width": 1920,
"height": 1080,
"r_frame_rate": "30/1",
"duration": "120.5"
}
]
}
```
---
## 5. HTTP 狀態碼
| 狀態 | 說明 | 解決 |
|------|------|------|
| 200 | 成功 | - |
| 400 | 請求格式錯誤 | 檢查 JSON 格式 |
| 404 | 端點或資源不存在 | 確認 URL 正確 |
| 500 | 伺服器內部錯誤 | 檢查 API 服務日誌 |
| 502 | API 服務未啟動 | 見下方說明 |
### 502 Bad Gateway 解決
```bash
# 檢查服務狀態
launchctl list | grep momentry.api
# 啟動服務
sudo launchctl load /Library/LaunchDaemons/com.momentry.api.plist
# 或使用本地測試
curl http://localhost:3002/health
```
---
## 6. 常見問題
### Q: 為什麼有兩個 URL
| URL | 用途 |
|-----|------|
| `localhost:3002` | 直接訪問,繞過反向代理 |
| `api.momentry.ddns.net` | 通過 Caddy 反向代理 |
### Q: 兩者功能相同嗎?
是的,所有端點和功能完全相同。
### Q: n8n webhook-test 返回 404
需在 n8n UI 中點擊 "Execute workflow" 按鈕後才能使用測試 Webhook。
### Q: 生產環境 webhook 返回 404
需將 workflow 切換為 Active 狀態(右上角開關)。
---
## 相關文件
- [API_INDEX.md](./API_INDEX.md) - 文件總覽
- [API_ENDPOINTS.md](./API_ENDPOINTS.md) - 端點完整說明
- [API_N8N_GUIDE.md](./API_N8N_GUIDE.md) - n8n 詳細指南
- [API_WORDPRESS_GUIDE.md](./API_WORDPRESS_GUIDE.md) - WordPress 詳細指南