Files
momentry_core/docs_v1.0/IMPLEMENTATION/DEMO_MANUAL.md

17 KiB
Raw Blame History

document_type, service, title, date, version, status, owner, created_by, tags, ai_query_hints
document_type service title date version status owner created_by tags ai_query_hints
implementation_guide MOMENTRY_CORE Momentry Core API 示範手冊 2026-03-25 V1.0 active Warren OpenCode
momentry
core
示範手冊
查詢 Momentry Core API 示範手冊 的內容
Momentry Core API 示範手冊 的主要目的是什麼?
如何操作或實施 Momentry Core API 示範手冊?

Momentry Core API 示範手冊

項目 內容
建立者 OpenCode
建立時間 2026-03-25
文件版本 V1.0

版本歷史

版本 日期 目的 操作人 工具/模型
V1.0 2026-03-25 創建示範手冊,包含 Demo API Key 與完整範例 OpenCode deepseek-reasoner

狀態: 完成


快速開始

Demo API Key

API Key:  muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69
Key ID:   muser_68600856036340bcafc01930eb4bd839
過期日:   2027-03-25

測試連線

curl http://localhost:3002/health
{"status":"ok","version":"0.1.0","uptime_ms":456464}

測試認證

curl -H "X-API-Key: muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69" \
  http://localhost:3002/api/v1/videos | jq '.videos | length'
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 範例

基本格式

curl -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  URL

1.1 健康檢查(公開)

# 基本健康檢查
curl http://localhost:3002/health

# 詳細健康檢查(含服務狀態)
curl http://localhost:3002/health/detailed

1.2 列出影片

curl -H "X-API-Key: muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69" \
  http://localhost:3002/api/v1/videos | jq '.'
{
  "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 搜尋影片

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 '.'
{
  "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 查詢進度

curl -H "X-API-Key: muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69" \
  http://localhost:3002/api/v1/progress/952f5854b9febad1 | jq '.'
{
  "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

{
  "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

{
  "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

{
  "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
/**
 * 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
/**
 * 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
/**
 * 註冊 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 測試腳本

#!/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 驗證腳本

#!/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

# 本地建立
./target/release/momentry api-key create "My App" --key-type user --ttl 90

5.2 列出 API Keys

./target/release/momentry api-key list

5.3 驗證 API Key

./target/release/momentry api-key validate --key "YOUR_API_KEY"

5.4 撤銷 API Key

./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. 聯絡支援