772 lines
17 KiB
Markdown
772 lines
17 KiB
Markdown
# 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: JSON,Body 為有效 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 詳細指南
|