Files
momentry_core/docs/DEMO_MANUAL.md
accusys 383201cacd feat: Initial v0.9 release with API Key authentication
## v0.9.20260325_144654

### Features
- API Key Authentication System
- Job Worker System
- V2 Backup Versioning

### Bug Fixes
- get_processor_results_by_job column mapping

Co-authored-by: OpenCode
2026-03-25 14:53:41 +08:00

675 lines
16 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 示範手冊
| 項目 | 內容 |
|------|------|
| 版本 | V1.0 |
| 日期 | 2026-03-25 |
| 狀態 | 完成 |
---
## 快速開始
### Demo API Key
```
API Key: muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69
Key ID: muser_68600856036340bcafc01930eb4bd839
過期日: 2027-03-25
```
### 測試連線
```bash
curl http://localhost:3002/health
```
```json
{"status":"ok","version":"0.1.0","uptime_ms":456464}
```
### 測試認證
```bash
curl -H "X-API-Key: muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69" \
http://localhost:3002/api/v1/videos | jq '.videos | length'
```
```json
13
```
---
## 環境 URL
| 環境 | URL | 用途 |
|------|-----|------|
| **本地開發** | `http://localhost:3002` | 本機開發測試 |
| **外部訪問** | `https://api.momentry.ddns.net` | n8n/WordPress/curl 生產環境 |
---
## 端點總覽
| 方法 | 端點 | 說明 | 認證 |
|------|------|------|------|
| GET | `/health` | 健康檢查 | 公開 |
| GET | `/health/detailed` | 詳細健康檢查 | 公開 |
| POST | `/api/v1/register` | 註冊影片 | 需要 |
| POST | `/api/v1/probe` | 探測影片資訊 | 需要 |
| POST | `/api/v1/search` | 語意搜尋 | 需要 |
| POST | `/api/v1/n8n/search` | n8n 格式搜尋 | 需要 |
| POST | `/api/v1/search/hybrid` | 混合搜尋 | 需要 |
| GET | `/api/v1/videos` | 列出所有影片 | 需要 |
| GET | `/api/v1/lookup` | 查詢影片 UUID | 需要 |
| GET | `/api/v1/progress/:uuid` | 處理進度 | 需要 |
| GET | `/api/v1/jobs` | 任務列表 | 需要 |
| GET | `/api/v1/jobs/:uuid` | 任務詳情 | 需要 |
---
## 1. curl 範例
### 基本格式
```bash
curl -H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
URL
```
### 1.1 健康檢查(公開)
```bash
# 基本健康檢查
curl http://localhost:3002/health
# 詳細健康檢查(含服務狀態)
curl http://localhost:3002/health/detailed
```
### 1.2 列出影片
```bash
curl -H "X-API-Key: muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69" \
http://localhost:3002/api/v1/videos | jq '.'
```
```json
{
"videos": [
{
"uuid": "952f5854b9febad1",
"file_name": "ExaSAN PCIe series - Director Ou Yu-Zhi Shares His Experience.mp4",
"duration": 159.637188,
"width": 640,
"height": 360
},
...
]
}
```
### 1.3 搜尋影片
```bash
curl -X POST \
-H "X-API-Key: muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69" \
-H "Content-Type: application/json" \
-d '{"query": "ExaSAN", "limit": 5}' \
http://localhost:3002/api/v1/search | jq '.'
```
```json
{
"results": [
{
"uuid": "952f5854b9febad1",
"chunk_id": "...",
"text": "...",
"score": 0.85,
"start_time": 0.0,
"end_time": 5.0
}
],
"total": 1,
"query": "ExaSAN",
"took_ms": 123
}
```
### 1.4 查詢進度
```bash
curl -H "X-API-Key: muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69" \
http://localhost:3002/api/v1/progress/952f5854b9febad1 | jq '.'
```
```json
{
"uuid": "952f5854b9febad1",
"overall_progress": 67,
"current_processor": "yolo",
"processors": [
{"name": "asr", "status": "completed"},
{"name": "cut", "status": "completed"},
{"name": "yolo", "status": "running"}
]
}
```
---
## 2. n8n 範例
### 2.1 HTTP Request 節點設定
```
Method: POST
URL: https://api.momentry.ddns.net/api/v1/search
Authentication: None (使用 Header)
Headers:
┌─────────────────────┬──────────────────────────────────────────────────┐
│ Name │ Value │
├─────────────────────┼──────────────────────────────────────────────────┤
│ X-API-Key │ muser_68600856036340bcafc01930eb4bd839_... │
│ Content-Type │ application/json │
└─────────────────────┴──────────────────────────────────────────────────┘
Body Content (JSON):
{
"query": "{{ $json.search_term }}",
"limit": 5
}
```
### 2.2 n8n 搜尋 Workflow
```json
{
"nodes": [
{
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"position": [250, 300]
},
{
"name": "Set Search Term",
"type": "n8n-nodes-base.set",
"parameters": {
"values": {
"json": {
"search_term": "ExaSAN"
}
}
},
"position": [450, 300]
},
{
"name": "Search Videos",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://api.momentry.ddns.net/api/v1/search",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-API-Key",
"value": "muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69"
}
]
},
"sendBody": true,
"bodyContentType": "json",
"specifyBody": "json",
"jsonBody": "={{ { \"query\": $json.search_term, \"limit\": 5 } }}"
},
"position": [650, 300]
},
{
"name": "Process Results",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "// Extract video results\nconst results = $input.first().json.results;\nreturn results.map(r => ({\n uuid: r.uuid,\n text: r.text,\n score: r.score,\n time: `${r.start_time}s - ${r.end_time}s`\n}));"
},
"position": [850, 300]
}
],
"connections": {
"Manual Trigger": {
"main": [[{"node": "Set Search Term"}]]
},
"Set Search Term": {
"main": [[{"node": "Search Videos"}]]
},
"Search Videos": {
"main": [[{"node": "Process Results"}]]
}
}
}
```
### 2.3 n8n 列出影片 Workflow
```json
{
"nodes": [
{
"name": "Get Videos",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "GET",
"url": "https://api.momentry.ddns.net/api/v1/videos",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-API-Key",
"value": "muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69"
}
]
}
},
"position": [450, 300]
},
{
"name": "Extract Video List",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "const videos = $input.first().json.videos;\nreturn videos.map(v => ({\n json: {\n uuid: v.uuid,\n name: v.file_name,\n duration: Math.round(v.duration) + 's',\n resolution: `${v.width}x${v.height}`\n }\n}));"
},
"position": [650, 300]
},
{
"name": "Slack Notification",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "#momentry",
"text": "=Found {{ $json.length }} videos:\n{{ $json.map(v => `• ${v.name} (${v.duration})`).join(`\n`) }}"
},
"position": [850, 300]
}
]
}
```
### 2.4 n8n 定時同步 Workflow
```json
{
"nodes": [
{
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"parameters": {
"rule": {
"interval": [{"field": "hours", "hours": 1}]
}
},
"position": [250, 300]
},
{
"name": "Get Pending Videos",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "GET",
"url": "https://api.momentry.ddns.net/api/v1/videos"
},
"position": [450, 300]
},
{
"name": "Filter Processing",
"type": "n8n-nodes-base.filter",
"parameters": {
"conditions": {
"options": {"caseSensitive": true},
"conditions": [
{"id": "status", "leftValue": "{{ $json.status }}", "rightValue": "processing"}
]
}
},
"position": [650, 300]
}
]
}
```
---
## 3. WordPress 範例
### 3.1 PHP 函數庫
```php
<?php
/**
* Momentry API Client
*/
class Momentry_API {
private const API_URL = 'https://api.momentry.ddns.net';
private const API_KEY = 'muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69';
/**
* 發送 API 請求
*/
private function request(string $endpoint, array $data = [], string $method = 'GET'): array {
$url = self::API_URL . $endpoint;
$args = [
'headers' => [
'X-API-Key' => self::API_KEY,
'Content-Type' => 'application/json',
],
'timeout' => 30,
];
if ($method === 'POST') {
$args['method'] = 'POST';
$args['body'] = json_encode($data);
}
$response = wp_remote_request($url, $args);
if (is_wp_error($response)) {
throw new Exception($response->get_error_message());
}
return json_decode(wp_remote_retrieve_body($response), true);
}
/**
* 列出所有影片
*/
public function list_videos(): array {
return $this->request('/api/v1/videos');
}
/**
* 搜尋影片內容
*/
public function search(string $query, int $limit = 10): array {
return $this->request('/api/v1/search', [
'query' => $query,
'limit' => $limit,
], 'POST');
}
/**
* 取得影片進度
*/
public function get_progress(string $uuid): array {
return $this->request("/api/v1/progress/{$uuid}");
}
/**
* 檢查健康狀態
*/
public function health_check(): array {
return $this->request('/health');
}
}
```
### 3.2 短代碼 (Shortcode)
```php
<?php
/**
* WordPress 短代碼範例
*/
// 註冊短代碼
add_shortcode('momentry_videos', function($atts) {
$atts = shortcode_atts([
'limit' => 10,
], $atts);
$api = new Momentry_API();
try {
$result = $api->list_videos();
$videos = array_slice($result['videos'], 0, $atts['limit']);
ob_start();
?>
<div class="momentry-videos">
<h3>影片列表</h3>
<ul>
<?php foreach ($videos as $video): ?>
<li>
<strong><?= esc_html($video['file_name']) ?></strong>
<br>
<small>
UUID: <?= esc_html($video['uuid']) ?>
| 時長: <?= gmdate("H:i:s", $video['duration']) ?>
</small>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php
return ob_get_clean();
} catch (Exception $e) {
return '<p class="error">載入失敗: ' . esc_html($e->getMessage()) . '</p>';
}
});
// 搜尋短代碼
add_shortcode('momentry_search', function($atts, $content = '') {
$query = sanitize_text_field($content);
if (empty($query)) {
return '<p>請提供搜尋關鍵字</p>';
}
$api = new Momentry_API();
try {
$result = $api->search($query);
ob_start();
?>
<div class="momentry-search-results">
<h3>「<?= esc_html($query) ?>」搜尋結果</h3>
<?php if (empty($result['results'])): ?>
<p>沒有找到相關結果</p>
<?php else: ?>
<ul>
<?php foreach ($result['results'] as $item): ?>
<li>
<a href="/video/<?= esc_attr($item['uuid']) ?>?t=<?= (int)$item['start_time'] ?>">
<?= esc_html($item['text']) ?>
</a>
<br>
<small>相似度: <?= round($item['score'] * 100) ?>%</small>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
<?php
return ob_get_clean();
} catch (Exception $e) {
return '<p class="error">搜尋失敗: ' . esc_html($e->getMessage()) . '</p>';
}
});
```
### 3.3 使用方式
在 WordPress 頁面或文章中:
```
[momentry_videos limit="5"]
[momentry_search]ExaSAN[/momentry_search]
```
### 3.4 REST API 整合
```php
<?php
/**
* 註冊 WordPress REST API 端點
*/
add_action('rest_api_init', function() {
register_rest_route('momentry/v1', '/search', [
'methods' => 'GET',
'callback' => function(WP_REST_Request $request) {
$query = sanitize_text_field($request->get_param('q'));
if (empty($query)) {
return new WP_Error('missing_query', '需要搜尋關鍵字', ['status' => 400]);
}
$api = new Momentry_API();
$result = $api->search($query);
return new WP_REST_Response($result, 200);
},
'permission_callback' => '__return_true',
]);
});
// 使用方式: GET /wp-json/momentry/v1/search?q=ExaSAN
```
---
## 4. 疑難排解
### 4.1 常見錯誤
| 錯誤 | 原因 | 解決方案 |
|------|------|----------|
| `401 Unauthorized` | API Key 無效或過期 | 檢查 API Key 是否正確 |
| `500 Internal Server Error` | 伺服器錯誤 | 檢查 `/health/detailed` 服務狀態 |
| `Connection Timeout` | 網路問題 | 確認 `api.momentry.ddns.net` 可達 |
### 4.2 測試腳本
```bash
#!/bin/bash
# test_api.sh - Momentry API 測試腳本
API_KEY="muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69"
BASE_URL="http://localhost:3002"
echo "=== 1. 健康檢查 ==="
curl -s "$BASE_URL/health" | jq .
echo ""
echo "=== 2. 列出影片 ==="
curl -s -H "X-API-Key: $API_KEY" "$BASE_URL/api/v1/videos" | jq '.videos | length'
echo ""
echo "=== 3. 搜尋測試 ==="
curl -s -X POST -H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "test", "limit": 3}' \
"$BASE_URL/api/v1/search" | jq '.results | length'
echo ""
echo "=== 完成 ==="
```
### 4.3 驗證腳本
```bash
#!/bin/bash
# verify_auth.sh - 驗證 API Key
API_KEY="muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69"
BASE_URL="http://localhost:3002"
# 測試 1: 無 API Key
echo "測試 1: 無 API Key"
RESULT=$(curl -s -o /dev/null -w "%{http_code}" "$BASE_URL/api/v1/videos")
[ "$RESULT" = "401" ] && echo "✅ 正確拒絕 (401)" || echo "❌ 預期 401實際 $RESULT"
# 測試 2: 有 API Key
echo "測試 2: 有 API Key"
RESULT=$(curl -s -H "X-API-Key: $API_KEY" "$BASE_URL/api/v1/videos")
echo "$RESULT" | jq -e '.videos' > /dev/null && echo "✅ 成功取得資料" || echo "❌ 取得資料失敗"
# 測試 3: 無效 API Key
echo "測試 3: 無效 API Key"
RESULT=$(curl -s -o /dev/null -w "%{http_code}" -H "X-API-Key: invalid_key" "$BASE_URL/api/v1/videos")
[ "$RESULT" = "401" ] && echo "✅ 正確拒絕 (401)" || echo "❌ 預期 401實際 $RESULT"
```
---
## 5. API Key 管理
### 5.1 建立新 API Key
```bash
# 本地建立
./target/release/momentry api-key create "My App" --key-type user --ttl 90
```
### 5.2 列出 API Keys
```bash
./target/release/momentry api-key list
```
### 5.3 驗證 API Key
```bash
./target/release/momentry api-key validate --key "YOUR_API_KEY"
```
### 5.4 撤銷 API Key
```bash
./target/release/momentry api-key revoke --key "YOUR_API_KEY"
```
---
## 附錄
### A. 影片 UUID 說明
UUID 是基於檔案路徑的 SHA256 哈希前 16 位:
```
/Users/accusys/momentry/var/sftpgo/data/demo/video.mp4
SHA256 Hash
9760d0820f0cf9a7
```
### B. 處理器狀態
| 狀態 | 說明 |
|------|------|
| `pending` | 等待處理 |
| `running` | 處理中 |
| `completed` | 已完成 |
| `failed` | 失敗 |
### C. 支援的處理器
- **ASR**: 語音識別
- **CUT**: 場景剪切
- **YOLO**: 物件偵測
### D. 聯絡支援
- Email: support@momentry.ddns.net
- 文件: https://docs.momentry.ddns.net
- GitHub: https://github.com/anomalyco/momentry