docs: file_uuid generation rules for M4
This commit is contained in:
127
docs_v1.0/INTEGRATIONS/Momentry_Core_API.postman_collection.json
Normal file
127
docs_v1.0/INTEGRATIONS/Momentry_Core_API.postman_collection.json
Normal file
@@ -0,0 +1,127 @@
|
||||
{
|
||||
"info": {
|
||||
"name": "Momentry Core API",
|
||||
"description": "Video RAG API for Momentry Core - Video search and management",
|
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
||||
},
|
||||
"variable": [
|
||||
{
|
||||
"key": "baseUrl",
|
||||
"value": "http://localhost:3002/api/v1"
|
||||
}
|
||||
],
|
||||
"item": [
|
||||
{
|
||||
"name": "Search",
|
||||
"item": [
|
||||
{
|
||||
"name": "Semantic Search",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"query\": \"charade\",\n \"limit\": 5\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/search",
|
||||
"host": ["{{baseUrl}}"],
|
||||
"path": ["search"]
|
||||
},
|
||||
"description": "Semantic search across video chunks using vector embeddings"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Search with UUID Filter",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"query\": \"charade\",\n \"limit\": 5,\n \"uuid\": \"a1b10138a6bbb0cd\"\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/search",
|
||||
"host": ["{{baseUrl}}"],
|
||||
"path": ["search"]
|
||||
},
|
||||
"description": "Search within a specific video by UUID"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "n8n Integration Search",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"query\": \"charade\",\n \"limit\": 5\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/n8n/search",
|
||||
"host": ["{{baseUrl}}"],
|
||||
"path": ["n8n", "search"]
|
||||
},
|
||||
"description": "Search formatted for n8n workflow integration"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Videos",
|
||||
"item": [
|
||||
{
|
||||
"name": "List All Videos",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/videos",
|
||||
"host": ["{{baseUrl}}"],
|
||||
"path": ["videos"]
|
||||
},
|
||||
"description": "Get list of all registered videos"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Get Video by UUID",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/videos/a1b10138a6bbb0cd",
|
||||
"host": ["{{baseUrl}}"],
|
||||
"path": ["videos", "a1b10138a6bbb0cd"]
|
||||
},
|
||||
"description": "Get details for a specific video"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Get Video Chunks",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/videos/a1b10138a6bbb0cd/chunks",
|
||||
"host": ["{{baseUrl}}"],
|
||||
"path": ["videos", "a1b10138a6bbb0cd", "chunks"]
|
||||
},
|
||||
"description": "Get all chunks for a video"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
106
docs_v1.0/INTEGRATIONS/N8N_API_FIX_SUMMARY.md
Normal file
106
docs_v1.0/INTEGRATIONS/N8N_API_FIX_SUMMARY.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# n8n REST API Fix Summary
|
||||
|
||||
## Issue
|
||||
n8n REST API was returning 404 errors for all endpoints (`/api/v1/workflows`, `/rest/workflows`, etc.)
|
||||
|
||||
## Root Cause
|
||||
Port 5678 was occupied by the **n8n worker** process, preventing the main n8n instance from starting properly.
|
||||
|
||||
## Solution
|
||||
|
||||
### 1. Identified Port Conflict
|
||||
- Worker process was listening on port 5678 (same as main instance)
|
||||
- Main n8n couldn't start because port was in use
|
||||
|
||||
### 2. Fixed Worker Configuration
|
||||
Updated `/Library/LaunchDaemons/com.momentry.n8n.worker.plist`:
|
||||
- Added `N8N_PORT=5680` to worker environment variables
|
||||
- Workers shouldn't need HTTP ports, but this prevents port conflict
|
||||
|
||||
### 3. Restarted Services
|
||||
```bash
|
||||
# Kill all n8n processes
|
||||
sudo pkill -9 -f n8n
|
||||
|
||||
# Start main n8n (now successfully binds to port 5678)
|
||||
sudo launchctl enable system/com.momentry.n8n.main
|
||||
sudo launchctl bootstrap system /Library/LaunchDaemons/com.momentry.n8n.main.plist
|
||||
```
|
||||
|
||||
## Current Status
|
||||
|
||||
### n8n Instance
|
||||
- **URL**: http://localhost:5678
|
||||
- **Version**: 2.3.5
|
||||
- **Status**: Running ✅
|
||||
- **API Enabled**: Yes ✅
|
||||
|
||||
### API Key
|
||||
```
|
||||
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJlNjdiY2UzOS1iY2RkLTRjMjEtYmMwYy0yODNhYmI3ZjVjMjMiLCJpc3MiOiJuOG4iLCJhdWQiOiJwdWJsaWMtYXBpIiwiaWF0IjoxNzc0MTk4NzgwfQ.zke_Qc-saILl_tcwXm2K3J4slCmaXnzCfxVbdVPPvCE
|
||||
```
|
||||
|
||||
### MCP Configuration
|
||||
File: `~/.config/opencode/opencode.json`
|
||||
```json
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"mcp": {
|
||||
"gitea": {
|
||||
"type": "local",
|
||||
"enabled": true,
|
||||
"command": [
|
||||
"/opt/homebrew/bin/gitea-mcp-server",
|
||||
"-token", "<GITEA_TOKEN>",
|
||||
"-host", "http://localhost:3000"
|
||||
]
|
||||
},
|
||||
"n8n": {
|
||||
"type": "local",
|
||||
"enabled": true,
|
||||
"command": ["/opt/homebrew/bin/mcp-n8n"],
|
||||
"environment": {
|
||||
"N8N_BASE_URL": "http://localhost:5678",
|
||||
"N8N_API_KEY": "<N8N_API_KEY>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Verified Endpoints
|
||||
|
||||
### List Workflows
|
||||
```bash
|
||||
curl -H "X-N8N-API-KEY: <API_KEY>" http://localhost:5678/api/v1/workflows
|
||||
```
|
||||
**Result**: ✅ 30 workflows returned
|
||||
|
||||
### List Executions
|
||||
```bash
|
||||
curl -H "X-N8N-API-KEY: <API_KEY>" http://localhost:5678/api/v1/executions
|
||||
```
|
||||
**Result**: ✅ 100 executions returned
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Start n8n Worker** (optional for MCP):
|
||||
Workers handle job processing but aren't required for API access.
|
||||
|
||||
2. **Test MCP Integration**:
|
||||
Restart OpenCode to load the MCP configuration and test n8n integration.
|
||||
|
||||
3. **Verify Workflow Management**:
|
||||
- Create workflow via API
|
||||
- Execute workflow
|
||||
- Monitor execution status
|
||||
|
||||
## Files Modified
|
||||
- `/Library/LaunchDaemons/com.momentry.n8n.worker.plist` - Added N8N_PORT=5680
|
||||
|
||||
## API Documentation
|
||||
- Base URL: `http://localhost:5678/api/v1`
|
||||
- Authentication: Header `X-N8N-API-KEY: <token>`
|
||||
- Available endpoints: workflows, executions, credentials, users, etc.
|
||||
|
||||
See full API reference: https://docs.n8n.io/api/
|
||||
321
docs_v1.0/INTEGRATIONS/N8N_VIDEO_SEARCH_SUCCESS.md
Normal file
321
docs_v1.0/INTEGRATIONS/N8N_VIDEO_SEARCH_SUCCESS.md
Normal file
@@ -0,0 +1,321 @@
|
||||
---
|
||||
document_type: "reference_doc"
|
||||
service: "N8N"
|
||||
title: "n8n Video Search 工作流程 - 成功設定指南"
|
||||
date: "2026-03-22"
|
||||
version: "V1.0"
|
||||
status: "active"
|
||||
owner: "Warren"
|
||||
created_by: "OpenCode"
|
||||
tags:
|
||||
- "成功設定指南"
|
||||
- "video"
|
||||
- "工作流程"
|
||||
- "search"
|
||||
ai_query_hints:
|
||||
- "查詢 n8n Video Search 工作流程 - 成功設定指南 的內容"
|
||||
- "n8n Video Search 工作流程 - 成功設定指南 的主要目的是什麼?"
|
||||
- "如何操作或實施 n8n Video Search 工作流程 - 成功設定指南?"
|
||||
---
|
||||
|
||||
# n8n Video Search 工作流程 - 成功設定指南
|
||||
|
||||
| 項目 | 內容 |
|
||||
|------|------|
|
||||
| 建立者 | Warren |
|
||||
| 建立時間 | 2026-03-22 |
|
||||
| 文件版本 | V1.1 |
|
||||
| 適用版本 | n8n 2.3.5 |
|
||||
|
||||
---
|
||||
|
||||
## 版本歷史
|
||||
|
||||
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|
||||
|------|------|------|--------|-----------|
|
||||
| V1.0 | 2026-03-22 | 創建文件 | Warren | OpenCode |
|
||||
| V1.1 | 2026-03-26 | 更新 API 範例,新增 X-API-Key 驗證標頭 | OpenCode | deepseek-reasoner |
|
||||
|
||||
---
|
||||
|
||||
## ✅ 成功案例
|
||||
|
||||
| 項目 | 內容 |
|
||||
|------|------|
|
||||
| **工作流程名稱** | Video Search - Working v3 |
|
||||
| **ID** | 4vQo8I4SXEaR5E1A |
|
||||
| **狀態** | ✅ 成功運作 |
|
||||
| **測試結果** | 成功搜尋 "charade",返回 3 個結果 |
|
||||
|
||||
---
|
||||
|
||||
## 正確的 HTTP Request Node 設定
|
||||
|
||||
### 成功的設定方式
|
||||
|
||||
```json
|
||||
{
|
||||
"url": "https://api.momentry.ddns.net/api/v1/n8n/search",
|
||||
"method": "POST",
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "{\"query\":\"charade\",\"limit\":3}",
|
||||
"options": {
|
||||
"headers": {
|
||||
"X-API-Key": "muser_68600856036340bcafc01930eb4bd839"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 關鍵設定說明
|
||||
|
||||
| 設定項目 | 正確值 | 錯誤值 | 說明 |
|
||||
|---------|--------|--------|------|
|
||||
| **specifyBody** | `"json"` | `"body"` | 必須選擇 `"json"` |
|
||||
| **jsonBody** | 字串 `"{...}"` | 物件 `{}` | 必須是 JSON 字串格式 |
|
||||
| **轉義** | `\"query\"` | `"query"` | 引號需要轉義 |
|
||||
|
||||
---
|
||||
|
||||
## 工作流程架構
|
||||
|
||||
```
|
||||
┌─────────────────────────┐
|
||||
│ Manual Trigger │ ← 點擊 "Execute Workflow"
|
||||
└───────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ HTTP Request Node │ ← 呼叫 Momentry API
|
||||
│ - specifyBody: "json" │
|
||||
│ - jsonBody: "{...}" │
|
||||
└───────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ Code Node │ ← 格式化輸出
|
||||
│ - console.log() │
|
||||
│ - return json │
|
||||
└─────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 完整的 Workflow JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Video Search - Working v3",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [250, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "https://api.momentry.ddns.net/api/v1/n8n/search",
|
||||
"method": "POST",
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "{\"query\":\"charade\",\"limit\":3}",
|
||||
"options": {
|
||||
"headers": {
|
||||
"X-API-Key": "muser_68600856036340bcafc01930eb4bd839"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Search API",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.1,
|
||||
"position": [450, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const data = $input.first().json;\nconsole.log('Response:', JSON.stringify(data, null, 2));\nreturn [{ json: data }];"
|
||||
},
|
||||
"name": "Show Result",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [650, 300]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [[{"node": "Search API", "type": "main", "index": 0}]]
|
||||
},
|
||||
"Search API": {
|
||||
"main": [[{"node": "Show Result", "type": "main", "index": 0}]]
|
||||
}
|
||||
},
|
||||
"settings": {"executionOrder": "v1"},
|
||||
"staticData": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用步驟
|
||||
|
||||
### 步驟 1: 導入工作流程
|
||||
1. 開啟 n8n UI: `https://n8n.momentry.ddns.net`
|
||||
2. 點擊 **Add Workflow** (+)
|
||||
3. 點擊 **Import from File**
|
||||
4. 選擇上面的 JSON 檔案
|
||||
|
||||
### 步驟 2: 執行測試
|
||||
1. 點擊 **"Execute Workflow"** 按鈕 (▶️)
|
||||
2. 等待執行完成
|
||||
3. 點擊 **"Show Result"** 節點
|
||||
4. 查看右側 **JSON** 面板
|
||||
|
||||
### 步驟 3: 修改搜尋關鍵字
|
||||
1. 點擊 **"Search API"** 節點
|
||||
2. 修改 `jsonBody`:
|
||||
```json
|
||||
"{\"query\":\"您的關鍵字\",\"limit\":5}"
|
||||
```
|
||||
3. 點擊 **Save** (Ctrl+S)
|
||||
4. 重新執行
|
||||
|
||||
---
|
||||
|
||||
## 成功的回應範例
|
||||
|
||||
```json
|
||||
{
|
||||
"query": "charade",
|
||||
"count": 3,
|
||||
"hits": [
|
||||
{
|
||||
"id": "sentence_0006",
|
||||
"vid": "a1b10138a6bbb0cd",
|
||||
"start": 48.8,
|
||||
"end": 55.44,
|
||||
"title": "Chunk sentence_0006",
|
||||
"text": "fun plot twists, Woody Dialog and charming performances...",
|
||||
"score": 0.526,
|
||||
"file_path": "/Users/accusys/momentry/var/sftpgo/data/demo/Old_Time_Movie_Show_-_Charade_1963.HD.mov"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 常見錯誤與解決
|
||||
|
||||
### ❌ 錯誤 1: "Your request is invalid"
|
||||
|
||||
**原因**: `specifyBody` 設為 `"body"` 而不是 `"json"`
|
||||
|
||||
**解決**:
|
||||
```json
|
||||
✅ "specifyBody": "json"
|
||||
❌ "specifyBody": "body"
|
||||
```
|
||||
|
||||
### ❌ 錯誤 2: "$httpRequest is not defined"
|
||||
|
||||
**原因**: Code Node 中使用 `$httpRequest`,但您的 n8n 版本不支援
|
||||
|
||||
**解決**: 使用 **HTTP Request Node** 代替 Code Node
|
||||
|
||||
### ❌ 錯誤 3: Body 格式錯誤
|
||||
|
||||
**原因**: `body` 使用物件格式 `{query: "..."}`
|
||||
|
||||
**解決**: 使用 `jsonBody` 字串格式 `{"query":"..."}`
|
||||
|
||||
### ❌ 錯誤 4: JSON 引號未轉義
|
||||
|
||||
**原因**: `"{query: "charade"}"` - 引號衝突
|
||||
|
||||
**解決**: `\"` 轉義 `"{\"query\":\"charade\"}"`
|
||||
|
||||
---
|
||||
|
||||
## 測試指令
|
||||
|
||||
### 直接測試 API
|
||||
```bash
|
||||
curl -X POST https://api.momentry.ddns.net/api/v1/n8n/search \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-API-Key: muser_68600856036340bcafc01930eb4bd839" \
|
||||
-d '{"query":"charade","limit":3}'
|
||||
```
|
||||
|
||||
### 驗證服務狀態
|
||||
```bash
|
||||
# 檢查 Momentry Core
|
||||
curl -H "X-API-Key: muser_68600856036340bcafc01930eb4bd839" https://api.momentry.ddns.net/api/v1/videos
|
||||
|
||||
# 檢查 n8n
|
||||
curl http://localhost:5678/api/v1/workflows \
|
||||
-H "X-N8N-API-KEY: <your_api_key>"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 服務資訊
|
||||
|
||||
| 服務 | URL | 說明 |
|
||||
|------|-----|------|
|
||||
| **n8n UI** | https://n8n.momentry.ddns.net | 工作流程管理 |
|
||||
| **Momentry API** | https://api.momentry.ddns.net | 影片搜尋 API |
|
||||
| **工作流程** | https://n8n.momentry.ddns.net/workflow/4vQo8I4SXEaR5E1A | 成功案例 |
|
||||
|
||||
---
|
||||
|
||||
## 進階使用
|
||||
|
||||
### 添加 Webhook 觸發器
|
||||
|
||||
如果你想從外部呼叫這個工作流程:
|
||||
|
||||
1. 在第一個節點前添加 **Webhook** Node
|
||||
2. 設定:
|
||||
```
|
||||
Method: POST
|
||||
Path: video-search
|
||||
Response Mode: Last Node
|
||||
```
|
||||
3. 將 Webhook 連接到 Search API
|
||||
4. 儲存並執行
|
||||
5. 使用生成的 Webhook URL 呼叫:
|
||||
```bash
|
||||
curl -X POST <webhook_url> \
|
||||
-d '{"query":"charade","limit":3}'
|
||||
```
|
||||
|
||||
### 使用動態變數
|
||||
|
||||
修改 jsonBody 使用表達式:
|
||||
```json
|
||||
"{\"query\":\"={{ $json.query }}\",\"limit\":{{ $json.limit }}}"
|
||||
```
|
||||
|
||||
然後在前面添加 Set Node 設定變數。
|
||||
|
||||
---
|
||||
|
||||
## 相關文件
|
||||
|
||||
- `docs_v1.0/IMPLEMENTATION/N8N_SETUP_COMPLETE.md` - 完整設定總結
|
||||
- `docs_v1.0/IMPLEMENTATION/N8N_HTTP_REQUEST_GUIDE.md` - HTTP Request 詳細指南
|
||||
- `docs/API_URL_EXAMPLES.md` - API URL 範例
|
||||
|
||||
---
|
||||
|
||||
## 完成!🎉
|
||||
|
||||
您現在擁有一個可以成功搜尋影片的 n8n 工作流程!
|
||||
|
||||
**關鍵成功要素**:
|
||||
1. ✅ 使用 `specifyBody: "json"`
|
||||
2. ✅ 使用 `jsonBody` 字串格式
|
||||
3. ✅ 正確轉義 JSON 引號
|
||||
4. ✅ 使用外部 API URL (`https://api.momentry.ddns.net`)
|
||||
818
docs_v1.0/INTEGRATIONS/n8n_workflow_core_v1.2.json
Normal file
818
docs_v1.0/INTEGRATIONS/n8n_workflow_core_v1.2.json
Normal file
@@ -0,0 +1,818 @@
|
||||
{
|
||||
"id": "o9MZ3XaJ5Vyf4kJ9",
|
||||
"name": "Momentry Search API - Core v1.2",
|
||||
"active": true,
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "search",
|
||||
"responseMode": "responseNode",
|
||||
"options": {}
|
||||
},
|
||||
"id": "b5f92603-1071-42e0-85b1-6c1655f9c992",
|
||||
"name": "Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
-384,
|
||||
1408
|
||||
],
|
||||
"webhookId": "79d6584e-c37c-49c4-9e83-c72896cef416"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"name": "query",
|
||||
"value": "={{$json.body.query || $json.query}}",
|
||||
"type": "string",
|
||||
"id": "f9a4b19c-b478-4fd3-9969-cd78298d2138"
|
||||
},
|
||||
{
|
||||
"name": "mode",
|
||||
"value": "={{ $json.body?.mode || $json.mode || \"mock\" }}",
|
||||
"type": "string",
|
||||
"id": "59066dec-1e8e-4339-ab5e-ce538c0dc216"
|
||||
},
|
||||
{
|
||||
"name": "request_source",
|
||||
"value": "portal",
|
||||
"type": "string",
|
||||
"id": "1ff615c2-23b2-45af-a580-9d27a6a8d4bc"
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
"value": 10,
|
||||
"type": "number",
|
||||
"id": "16adb464-079b-4a91-bbb9-bd9b44db83ed"
|
||||
},
|
||||
{
|
||||
"id": "d298ad4d-4fab-41f0-a11a-7d089cf78ae3",
|
||||
"name": "query_normalized",
|
||||
"value": "={{ ($json.body.query || $json.query || \"\").toLowerCase().trim() }}",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "fadff1c5-038b-4aa7-ad18-957440d0942c",
|
||||
"name": "Build Search Request",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.4,
|
||||
"position": [
|
||||
-160,
|
||||
1408
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"rules": {
|
||||
"values": [
|
||||
{
|
||||
"conditions": {
|
||||
"options": {
|
||||
"caseSensitive": true,
|
||||
"leftValue": "",
|
||||
"typeValidation": "strict",
|
||||
"version": 1
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"leftValue": "={{$json.query_normalized}}",
|
||||
"rightValue": "sun",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "contains"
|
||||
},
|
||||
"id": "54556e33-0dff-4e3d-ada0-81ea89f422c2"
|
||||
}
|
||||
],
|
||||
"combinator": "and"
|
||||
}
|
||||
},
|
||||
{
|
||||
"conditions": {
|
||||
"options": {
|
||||
"caseSensitive": true,
|
||||
"leftValue": "",
|
||||
"typeValidation": "strict",
|
||||
"version": 1
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"leftValue": "={{$json.query_normalized}}",
|
||||
"rightValue": "morning",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "contains"
|
||||
},
|
||||
"id": "cca4c190-d840-486c-937f-221d62fcf05f"
|
||||
}
|
||||
],
|
||||
"combinator": "and"
|
||||
}
|
||||
},
|
||||
{
|
||||
"conditions": {
|
||||
"options": {
|
||||
"caseSensitive": true,
|
||||
"leftValue": "",
|
||||
"typeValidation": "strict",
|
||||
"version": 1
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"id": "88239dfd-773c-4337-9f2e-521e6368305b",
|
||||
"leftValue": "={{$json.query_normalized}}",
|
||||
"rightValue": "error",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "equals",
|
||||
"name": "filter.operator.equals"
|
||||
}
|
||||
}
|
||||
],
|
||||
"combinator": "and"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"fallbackOutput": "extra"
|
||||
}
|
||||
},
|
||||
"id": "613caa5d-d3f7-4099-a5f3-5c642264d32c",
|
||||
"name": "Search Adapter (Mock Router)",
|
||||
"type": "n8n-nodes-base.switch",
|
||||
"typeVersion": 3,
|
||||
"position": [
|
||||
512,
|
||||
1664
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"name": "query",
|
||||
"value": "={{$json.query}}",
|
||||
"type": "string",
|
||||
"id": "7af70495-2dbb-4e7b-aed3-79cd7e970183"
|
||||
},
|
||||
{
|
||||
"name": "search_results",
|
||||
"value": "={{[\n {\n \"moment_id\": \"m001\",\n \"video_id\": \"v001\",\n \"t_start\": 3,\n \"t_end\": 8,\n \"title\": \"Sunset moment\",\n \"snippet\": \"The sun slowly sets over the sea\",\n \"score\": 0.92,\n \"video_url\": \"https://wp.momentry.ddns.net/wp-content/uploads/2026/03/H_moment3.mp4\"\n },\n {\n \"moment_id\": \"m002\",\n \"video_id\": \"v002\",\n \"t_start\": 3,\n \"t_end\": 7,\n \"title\": \"Morning sunlight\",\n \"snippet\": \"Sunlight enters the room\",\n \"score\": 0.88,\n \"video_url\": \"https://wp.momentry.ddns.net/wp-content/uploads/2026/03/O_moment3.mp4\"\n }\n]}}",
|
||||
"type": "array",
|
||||
"id": "e504493f-0dec-4a80-b434-7586059159f0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "38b6c814-3e60-45e1-a31f-b93fcf9b2fd5",
|
||||
"name": "Mock Sun Results",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.4,
|
||||
"position": [
|
||||
736,
|
||||
1456
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"name": "query",
|
||||
"value": "={{$json.query}}",
|
||||
"type": "string",
|
||||
"id": "137b4cd7-5ef8-41f2-94bc-921c9040e0e5"
|
||||
},
|
||||
{
|
||||
"name": "search_results",
|
||||
"value": "={{[\n {\n \"moment_id\": \"m002\",\n \"video_id\": \"v002\",\n \"t_start\": 3,\n \"t_end\": 7,\n \"title\": \"Morning sunlight\",\n \"snippet\": \"Sunlight enters the room\",\n \"score\": 0.88,\n \"video_url\": \"https://wp.momentry.ddns.net/wp-content/uploads/2026/03/H_moment3.mp4\"\n }\n]}}",
|
||||
"type": "array",
|
||||
"id": "181df2c1-9469-4d3d-9f23-2ca839091583"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "e0bc4873-b4a7-4cdc-a4e8-01aef82a79b8",
|
||||
"name": "Mock Morning Results",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.4,
|
||||
"position": [
|
||||
736,
|
||||
1648
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"name": "query",
|
||||
"value": "={{$json.query}}",
|
||||
"type": "string",
|
||||
"id": "be01ea1f-f92f-41c7-8dab-f998e7c07bec"
|
||||
},
|
||||
{
|
||||
"name": "search_results",
|
||||
"value": "={{ [] }}",
|
||||
"type": "array",
|
||||
"id": "21e46d9d-0a35-4641-b936-806713ff021c"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "e7c3a7b0-6cee-4832-b6ad-9cdc30f59131",
|
||||
"name": "Mock Empty Results",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.4,
|
||||
"position": [
|
||||
736,
|
||||
2032
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"name": "query",
|
||||
"value": "={{$json.query}}",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "total",
|
||||
"value": "={{$json.search_results.length}}",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"name": "results",
|
||||
"value": "={{$json.search_results}}",
|
||||
"type": "array"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "e746705c-ddfc-4c6b-904b-a5a8ed5d7420",
|
||||
"name": "Format Search Response",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.4,
|
||||
"position": [
|
||||
960,
|
||||
1648
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ { \"query\": $json.query, \"total\": $json.total, \"results\": $json.results } }}",
|
||||
"options": {}
|
||||
},
|
||||
"id": "d7f9806c-ad9f-4e56-bbdc-a943f1d416fd",
|
||||
"name": "Respond Search",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
1184,
|
||||
1168
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"rules": {
|
||||
"values": [
|
||||
{
|
||||
"conditions": {
|
||||
"options": {
|
||||
"caseSensitive": true,
|
||||
"leftValue": "",
|
||||
"typeValidation": "strict",
|
||||
"version": 3
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"id": "99d7d111-05ae-42aa-8b86-a5de7a7fdb52",
|
||||
"leftValue": "={{ $json.mode }}",
|
||||
"rightValue": "mock",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "equals",
|
||||
"name": "filter.operator.equals"
|
||||
}
|
||||
}
|
||||
],
|
||||
"combinator": "and"
|
||||
},
|
||||
"renameOutput": true,
|
||||
"outputKey": "mock"
|
||||
},
|
||||
{
|
||||
"conditions": {
|
||||
"options": {
|
||||
"caseSensitive": true,
|
||||
"leftValue": "",
|
||||
"typeValidation": "strict",
|
||||
"version": 3
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"id": "d24d518d-bd6b-4b99-a4c9-cc98c49027ca",
|
||||
"leftValue": "={{ $json.mode }}",
|
||||
"rightValue": "core_stub",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "equals",
|
||||
"name": "filter.operator.equals"
|
||||
}
|
||||
}
|
||||
],
|
||||
"combinator": "and"
|
||||
},
|
||||
"renameOutput": true,
|
||||
"outputKey": "core_stub"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"fallbackOutput": "none"
|
||||
}
|
||||
},
|
||||
"type": "n8n-nodes-base.switch",
|
||||
"typeVersion": 3.4,
|
||||
"position": [
|
||||
64,
|
||||
1408
|
||||
],
|
||||
"id": "550273ba-8d33-4653-a26b-2b83218ce993",
|
||||
"name": "Mode Router"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "c2c253a2-689c-4d8f-92d1-017dacbf1eca",
|
||||
"name": "error",
|
||||
"value": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"id": "523b04a9-9843-4542-846d-d027f697ceff",
|
||||
"name": "message",
|
||||
"value": "mock backend error",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "ef30be3a-cdf7-4461-90b9-6d3ee6a88ba3",
|
||||
"name": "query",
|
||||
"value": "={{$json.query}}",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.4,
|
||||
"position": [
|
||||
736,
|
||||
1840
|
||||
],
|
||||
"id": "be069c6a-da6b-4a1b-a930-b535818b9ae2",
|
||||
"name": "Mock Error Response"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ { \"error\": true, \"message\": $json.message, \"query\": $json.query } }}",
|
||||
"options": {
|
||||
"responseCode": 500
|
||||
}
|
||||
},
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1.5,
|
||||
"position": [
|
||||
960,
|
||||
1888
|
||||
],
|
||||
"id": "6777eded-6c8e-426d-82b2-550580f74591",
|
||||
"name": "Respond Search Error"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const query = $json.query ?? \"\";\nconst hits = Array.isArray($json.hits) ? $json.hits : [];\n\nreturn [\n {\n json: {\n query,\n total: typeof $json.count === \"number\" ? $json.count : hits.length,\n results: hits.map(hit => ({\n moment_id: hit.id ?? \"\",\n video_id: hit.vid ?? \"\",\n t_start: Number(hit.start ?? 0),\n t_end: Number(hit.end ?? 0),\n title: hit.title ?? \"\",\n snippet: hit.text ?? \"\",\n score: Number(hit.score ?? 0),\n video_url: hit.media_url ?? \"\"\n }))\n }\n }\n];"
|
||||
},
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
960,
|
||||
1120
|
||||
],
|
||||
"id": "34662909-6e7a-4cf4-967b-1f474748777a",
|
||||
"name": "Normalize Core Response"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"options": {
|
||||
"caseSensitive": true,
|
||||
"leftValue": "",
|
||||
"typeValidation": "strict",
|
||||
"version": 3
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"id": "c51bf73f-e1e0-4811-985c-4de5ec70b9d8",
|
||||
"leftValue": "={{ $json.error ? \"yes\" : \"no\" }}",
|
||||
"rightValue": "=yes",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "equals"
|
||||
}
|
||||
}
|
||||
],
|
||||
"combinator": "and"
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2.3,
|
||||
"position": [
|
||||
736,
|
||||
1168
|
||||
],
|
||||
"id": "cb6a5372-05a5-4f1b-ae5e-3b33bf009d4c",
|
||||
"name": "Check Core Error"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "fad95504-6182-4d4c-bc95-8927c25c7f31",
|
||||
"name": "ok",
|
||||
"value": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"id": "d267371c-90d8-401e-8180-a753e807441b",
|
||||
"name": "error_code",
|
||||
"value": "={{ $json.error?.code === \"ECONNABORTED\" ? \"SEARCH_TIMEOUT\" : \"SEARCH_BACKEND_ERROR\" }}",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "4992c4d9-e61d-453a-a826-8895374f56b8",
|
||||
"name": "message",
|
||||
"value": "={{ $json.error?.code === \"ECONNABORTED\" ? \"Search service timeout\" : \"Search service unavailable\" }}",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "56b9fbfa-4c98-4265-b992-498e3edf733b",
|
||||
"name": "query",
|
||||
"value": "={{ $node[\"Build Search Request\"].json.query || \"unknown\" }}",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "c50010c1-a0c8-47b9-a763-e7212a8db93c",
|
||||
"name": "results",
|
||||
"value": "={{ [] }}",
|
||||
"type": "array"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.4,
|
||||
"position": [
|
||||
960,
|
||||
1312
|
||||
],
|
||||
"id": "1c811ef9-91da-465c-9121-6247549d16fc",
|
||||
"name": "Map Search Error"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ {\n \"ok\": $json.ok,\n \"error_code\": $json.error_code,\n \"message\": $json.message,\n \"query\": $json.query,\n \"results\": $json.results\n} }}",
|
||||
"options": {
|
||||
"responseCode": 500
|
||||
}
|
||||
},
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1.5,
|
||||
"position": [
|
||||
1184,
|
||||
1360
|
||||
],
|
||||
"id": "797824a7-85ac-40d9-bd2b-42ea11dfd1a1",
|
||||
"name": "Respond Search Error1"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "c08206fb-5d74-40f0-a682-f2116c290af1",
|
||||
"name": "query",
|
||||
"value": "={{ $json.query }}",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"id": "85e83fbc-b4f0-4b22-8d37-516609387918",
|
||||
"name": "limit",
|
||||
"value": "={{ Number($json.limit || 10) }}",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"id": "823706fe-288a-4a71-a498-0ad3daad5081",
|
||||
"name": "mode",
|
||||
"value": "={{ $json.mode }}",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.4,
|
||||
"position": [
|
||||
288,
|
||||
1168
|
||||
],
|
||||
"id": "89366f65-c36a-4b19-9970-706a5d729594",
|
||||
"name": "Prepare Core Request Context"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "https://api.momentry.ddns.net/api/v1/n8n/search",
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={{ {\n \"query\": $json.query,\n \"limit\": $json.limit,\n \"request_query\": $json.query\n} }}",
|
||||
"options": {
|
||||
"timeout": 3000
|
||||
}
|
||||
},
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.3,
|
||||
"position": [
|
||||
512,
|
||||
1168
|
||||
],
|
||||
"id": "d5ea8f1b-5bd7-4c88-9c38-70e5b14ca1d8",
|
||||
"name": "Call Momentry Core API",
|
||||
"onError": "continueRegularOutput"
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Build Search Request",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Build Search Request": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Mode Router",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Search Adapter (Mock Router)": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Mock Sun Results",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Mock Morning Results",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Mock Error Response",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Mock Empty Results",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Mock Sun Results": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Format Search Response",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Mock Morning Results": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Format Search Response",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Mock Empty Results": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Format Search Response",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Format Search Response": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Respond Search",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Mode Router": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Search Adapter (Mock Router)",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Prepare Core Request Context",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Mock Error Response": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Respond Search Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Normalize Core Response": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Respond Search",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Check Core Error": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Map Search Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Normalize Core Response",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Map Search Error": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Respond Search Error1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Prepare Core Request Context": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Call Momentry Core API",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Call Momentry Core API": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Check Core Error",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"executionOrder": "v1",
|
||||
"availableInMCP": false,
|
||||
"binaryMode": "separate"
|
||||
},
|
||||
"staticData": null,
|
||||
"pinData": {
|
||||
"Webhook": [
|
||||
{
|
||||
"json": {
|
||||
"headers": {
|
||||
"host": "n8n.momentry.ddns.net",
|
||||
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36 Edg/145.0.0.0",
|
||||
"content-length": "15",
|
||||
"accept": "*/*",
|
||||
"accept-encoding": "gzip, deflate, br, zstd",
|
||||
"accept-language": "zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6,zh-HK;q=0.5",
|
||||
"content-type": "application/json",
|
||||
"origin": "https://wp.momentry.ddns.net",
|
||||
"priority": "u=1, i",
|
||||
"referer": "https://wp.momentry.ddns.net/",
|
||||
"sec-ch-ua": "\"Not:A-Brand\";v=\"99\", \"Microsoft Edge\";v=\"145\", \"Chromium\";v=\"145\"",
|
||||
"sec-ch-ua-mobile": "?0",
|
||||
"sec-ch-ua-platform": "\"macOS\"",
|
||||
"sec-fetch-dest": "empty",
|
||||
"sec-fetch-mode": "cors",
|
||||
"sec-fetch-site": "same-site",
|
||||
"via": "3.0 Caddy",
|
||||
"x-forwarded-for": "111.243.8.96",
|
||||
"x-forwarded-host": "n8n.momentry.ddns.net",
|
||||
"x-forwarded-proto": "https"
|
||||
},
|
||||
"params": {},
|
||||
"query": {},
|
||||
"body": {
|
||||
"query": "sun"
|
||||
},
|
||||
"webhookUrl": "https://n8n.momentry.ddns.net/webhook/search",
|
||||
"executionMode": "production"
|
||||
},
|
||||
"pairedItem": {
|
||||
"item": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"triggerCount": 1,
|
||||
"createdAt": "2026-03-23T19:06:43.592+08:00",
|
||||
"updatedAt": "2026-03-23T20:06:51.588+08:00"
|
||||
}
|
||||
123
docs_v1.0/INTEGRATIONS/n8n_workflow_simple.json
Normal file
123
docs_v1.0/INTEGRATIONS/n8n_workflow_simple.json
Normal file
@@ -0,0 +1,123 @@
|
||||
{
|
||||
"name": "Momentry Video Search - Simple",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "video-search-simple",
|
||||
"responseMode": "lastNode",
|
||||
"options": {}
|
||||
},
|
||||
"id": "webhook-simple",
|
||||
"name": "Webhook (Simple)",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
250,
|
||||
300
|
||||
],
|
||||
"webhookId": "video-search-simple"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "http://localhost:3002/api/v1/n8n/search",
|
||||
"method": "POST",
|
||||
"sendBody": true,
|
||||
"bodyParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "query",
|
||||
"value": "={{ $json.body }}"
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
"value": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"headers": {
|
||||
"Content-Type": "application/json",
|
||||
"X-API-Key": "demo_api_key_12345"
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "http-search",
|
||||
"name": "搜尋 Momentry",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 3,
|
||||
"position": [
|
||||
500,
|
||||
300
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "// 處理 Momentry 搜尋結果\nconst data = $input.first().json;\nconst hits = data.hits;\n\nif (!hits || hits.length === 0) {\n return {\n json: {\n success: false,\n message: '找不到相關結果',\n query: data.query\n }\n };\n}\n\n// 格式化結果\nconst formattedResults = hits.map((hit, idx) => {\n return {\n index: idx + 1,\n id: hit.id,\n title: hit.title,\n text: hit.text,\n startTime: hit.start,\n endTime: hit.end,\n relevance: Math.round(hit.score * 100) + '%',\n file_path: hit.file_path\n };\n});\n\nreturn {\n json: {\n success: true,\n query: data.query,\n totalFound: data.count,\n results: formattedResults\n }\n};"
|
||||
},
|
||||
"id": "code-process-simple",
|
||||
"name": "處理結果",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
750,
|
||||
300
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ $json }}"
|
||||
},
|
||||
"id": "respond-webhook",
|
||||
"name": "回傳結果",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
1000,
|
||||
300
|
||||
]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook (Simple)": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "搜尋 Momentry",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"搜尋 Momentry": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "處理結果",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"處理結果": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "回傳結果",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {},
|
||||
"id": "momentry-video-search-simple",
|
||||
"versionId": "1",
|
||||
"createdAt": "2026-03-23T00:00:00.000Z",
|
||||
"updatedAt": "2026-03-23T00:00:00.000Z"
|
||||
}
|
||||
89
docs_v1.0/INTEGRATIONS/n8n_workflow_simple_test.json
Normal file
89
docs_v1.0/INTEGRATIONS/n8n_workflow_simple_test.json
Normal file
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"name": "Momentry Video Search Test",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "video-search-test",
|
||||
"responseMode": "lastNode",
|
||||
"options": {}
|
||||
},
|
||||
"name": "Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [250, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "http://localhost:3002/api/v1/n8n/search",
|
||||
"method": "POST",
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={{ JSON.stringify({ query: $json.body.query || \"test\", limit: $json.body.limit || 5 }) }}",
|
||||
"options": {}
|
||||
},
|
||||
"name": "HTTP Request",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.1,
|
||||
"position": [500, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "return $input.first().json;"
|
||||
},
|
||||
"name": "Code",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [750, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ JSON.stringify($json) }}"
|
||||
},
|
||||
"name": "Respond to Webhook",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1.5,
|
||||
"position": [1000, 300]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "HTTP Request",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"HTTP Request": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Code",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Respond to Webhook",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"staticData": null
|
||||
}
|
||||
109
docs_v1.0/INTEGRATIONS/n8n_workflow_video_rag_mcp.json
Normal file
109
docs_v1.0/INTEGRATIONS/n8n_workflow_video_rag_mcp.json
Normal file
@@ -0,0 +1,109 @@
|
||||
{
|
||||
"name": "Momentry Video RAG MCP",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "video-rag-mcp",
|
||||
"responseMode": "lastNode",
|
||||
"options": {}
|
||||
},
|
||||
"name": "Webhook Trigger",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
250,
|
||||
300
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "http://localhost:3002/api/v1/n8n/search",
|
||||
"method": "POST",
|
||||
"sendBody": true,
|
||||
"contentType": "json",
|
||||
"body": "={{ JSON.stringify({query: $json.body.query || $json.body, limit: $json.body.limit || 5, uuid: $json.body.uuid}) }}",
|
||||
"options": {
|
||||
"timeout": 30000,
|
||||
"headers": {
|
||||
"X-API-Key": "demo_api_key_12345"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Search Momentry Core",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.1,
|
||||
"position": [
|
||||
500,
|
||||
300
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "// Process Momentry Core search results\nconst data = $input.first().json;\nconst hits = data.hits || [];\n\nif (hits.length === 0) {\n return {\n json: {\n success: false,\n message: 'No relevant results found',\n query: data.query,\n results: []\n }\n };\n}\n\n// Format results for RAG\nconst formattedResults = hits.map((hit, idx) => {\n return {\n index: idx + 1,\n id: hit.id || hit.chunk_id,\n title: hit.title || 'Unknown Video',\n text: hit.text || hit.content || '',\n startTime: hit.start_time || hit.start || 0,\n endTime: hit.end_time || hit.end || 0,\n relevance: Math.round((hit.score || 0) * 100) + '%',\n videoUuid: hit.video_uuid || hit.uuid,\n file_path: hit.file_path || ''\n };\n});\n\n// Build context for RAG\nconst context = formattedResults\n .map(r => \\`[\\${r.index}] \\${r.text} (Video: \\${r.title}, Time: \\${r.startTime}s-\\${r.endTime}s)\\`)\n .join('\\n\\n');\n\nreturn {\n json: {\n success: true,\n query: data.query,\n totalFound: data.count || hits.length,\n context: context,\n results: formattedResults\n }\n};"
|
||||
},
|
||||
"name": "Process RAG Results",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
750,
|
||||
300
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ JSON.stringify($json) }}",
|
||||
"options": {
|
||||
"statusCode": 200
|
||||
}
|
||||
},
|
||||
"name": "Respond to Webhook",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1.5,
|
||||
"position": [
|
||||
1000,
|
||||
300
|
||||
]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Search Momentry Core",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Search Momentry Core": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Process RAG Results",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Process RAG Results": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Respond to Webhook",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"staticData": null
|
||||
}
|
||||
138
docs_v1.0/INTEGRATIONS/n8n_workflow_video_search.json
Normal file
138
docs_v1.0/INTEGRATIONS/n8n_workflow_video_search.json
Normal file
@@ -0,0 +1,138 @@
|
||||
{
|
||||
"name": "Momentry Video Search",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "video-search",
|
||||
"responseMode": "lastNode",
|
||||
"options": {}
|
||||
},
|
||||
"id": "webhook-trigger",
|
||||
"name": "Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
250,
|
||||
300
|
||||
],
|
||||
"webhookId": "video-search"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"url": "http://localhost:3002/api/v1/n8n/search",
|
||||
"method": "POST",
|
||||
"sendBody": true,
|
||||
"bodyParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "query",
|
||||
"value": "={{ $json.body }}"
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
"value": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"headers": {
|
||||
"Content-Type": "application/json",
|
||||
"X-API-Key": "demo_api_key_12345"
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "http-request-search",
|
||||
"name": "搜尋 Momentry",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 3,
|
||||
"position": [
|
||||
500,
|
||||
300
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const hits = $input.first().json.hits;\n\nif (!hits || hits.length === 0) {\n return {\n json: {\n message: '找不到相關結果',\n query: $input.first().json.query\n }\n };\n}\n\nconst results = hits.map((hit, index) => {\n return {\n number: index + 1,\n text: hit.text,\n start: hit.start,\n end: hit.end,\n score: Math.round(hit.score * 100) + '%',\n video_title: hit.title,\n file_path: hit.file_path\n };\n});\n\nreturn {\n json: {\n query: $input.first().json.query,\n count: $input.first().json.count,\n results: results\n }\n};"
|
||||
},
|
||||
"id": "code-process",
|
||||
"name": "處理結果",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
750,
|
||||
300
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/sendMessage",
|
||||
"sendBody": true,
|
||||
"bodyParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "chat_id",
|
||||
"value": "={{ $json.chat_id }}"
|
||||
},
|
||||
{
|
||||
"name": "text",
|
||||
"value": "=🎬 搜尋結果: \"{{ $json.query }}\"\n\n{{ $json.results.map(r => r.number + '️⃣ \"' + r.text.substring(0, 50) + '...\"\n⏱ ' + r.start + 's - ' + r.end + 's\n📊 相關度: ' + r.score).join('\n\n') }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "telegram-send",
|
||||
"name": "Telegram 通知",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 3,
|
||||
"position": [
|
||||
1000,
|
||||
300
|
||||
],
|
||||
"continueOnFail": true
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "搜尋 Momentry",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"搜尋 Momentry": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "處理結果",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"處理結果": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Telegram 通知",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {},
|
||||
"id": "momentry-video-search",
|
||||
"versionId": "1",
|
||||
"createdAt": "2026-03-23T00:00:00.000Z",
|
||||
"updatedAt": "2026-03-23T00:00:00.000Z"
|
||||
}
|
||||
100
docs_v1.0/INTEGRATIONS/test_all.sh
Executable file
100
docs_v1.0/INTEGRATIONS/test_all.sh
Executable file
@@ -0,0 +1,100 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "=========================================="
|
||||
echo "Momentry Core API 測試腳本"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# 顏色定義
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 測試 1: Momentry Core 搜尋
|
||||
echo -e "${YELLOW}測試 1: Momentry Core 搜尋 API${NC}"
|
||||
echo "URL: http://localhost:3002/api/v1/n8n/search"
|
||||
echo ""
|
||||
RESPONSE=$(curl -s -X POST http://localhost:3002/api/v1/n8n/search \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"query":"charade","limit":2}')
|
||||
|
||||
if echo "$RESPONSE" | grep -q '"hits"'; then
|
||||
echo -e "${GREEN}✅ 成功!${NC}"
|
||||
echo "$RESPONSE" | python3 -m json.tool | grep -E '"query"|"count"' | head -3
|
||||
echo ""
|
||||
echo "前 2 個結果:"
|
||||
echo "$RESPONSE" | python3 -c "
|
||||
import sys, json
|
||||
data = json.load(sys.stdin)
|
||||
for i, hit in enumerate(data.get('hits', [])[:2]):
|
||||
print(f\" [{i+1}] {hit.get('text', '')[:50]}...\")
|
||||
print(f\" 時間: {hit.get('start')}s - {hit.get('end')}s\")
|
||||
print(f\" 影片: {hit.get('title')}\")
|
||||
"
|
||||
else
|
||||
echo -e "${RED}❌ 失敗${NC}"
|
||||
echo "$RESPONSE"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 測試 2: 列出影片
|
||||
echo -e "${YELLOW}測試 2: 列出所有影片${NC}"
|
||||
echo "URL: http://localhost:3002/api/v1/videos"
|
||||
echo ""
|
||||
RESPONSE=$(curl -s http://localhost:3002/api/v1/videos)
|
||||
|
||||
if echo "$RESPONSE" | grep -q '"videos"'; then
|
||||
echo -e "${GREEN}✅ 成功!${NC}"
|
||||
echo "$RESPONSE" | python3 -c "
|
||||
import sys, json
|
||||
data = json.load(sys.stdin)
|
||||
print(f\"找到 {len(data.get('videos', []))} 個影片:\")
|
||||
for v in data.get('videos', []):
|
||||
print(f\" - {v.get('file_name')} (UUID: {v.get('uuid')[:8]}...)\")
|
||||
"
|
||||
else
|
||||
echo -e "${RED}❌ 失敗${NC}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 測試 3: n8n Webhook (Test Mode)
|
||||
echo -e "${YELLOW}測試 3: n8n Webhook (Test Mode)${NC}"
|
||||
echo "URL: http://localhost:5678/webhook-test/video-rag-mcp"
|
||||
echo ""
|
||||
echo "⚠️ 注意: 請先在 n8n UI 中點擊 'Execute workflow' 按鈕"
|
||||
echo ""
|
||||
|
||||
RESPONSE=$(curl -s -X POST http://localhost:5678/webhook-test/video-rag-mcp \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"query":"charade","limit":2}')
|
||||
|
||||
if echo "$RESPONSE" | grep -q '"success": true'; then
|
||||
echo -e "${GREEN}✅ Webhook 測試成功!${NC}"
|
||||
echo "$RESPONSE" | python3 -c "
|
||||
import sys, json
|
||||
data = json.load(sys.stdin)
|
||||
print(f\"查詢: {data.get('query')}\")
|
||||
print(f\"找到: {data.get('totalFound')} 個結果\")
|
||||
print(f\"Context 長度: {len(data.get('context', ''))} 字元\")
|
||||
"
|
||||
elif echo "$RESPONSE" | grep -q '404'; then
|
||||
echo -e "${RED}❌ Webhook 未找到${NC}"
|
||||
echo "請在 n8n UI 中:"
|
||||
echo " 1. 開啟 'Momentry Video RAG MCP' 工作流程"
|
||||
echo " 2. 點擊 'Execute workflow' 按鈕"
|
||||
echo " 3. 30 秒內再次執行此腳本"
|
||||
else
|
||||
echo -e "${RED}❌ 錯誤${NC}"
|
||||
echo "$RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$RESPONSE"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "測試完成!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "快速參考:"
|
||||
echo " Momentry API: http://localhost:3002/api/v1"
|
||||
echo " n8n UI: https://n8n.momentry.ddns.net"
|
||||
echo " Webhook Test: http://localhost:5678/webhook-test/video-rag-mcp"
|
||||
33
docs_v1.0/INTEGRATIONS/test_momentry_api.sh
Executable file
33
docs_v1.0/INTEGRATIONS/test_momentry_api.sh
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test Momentry Core API directly
|
||||
# This bypasses n8n and tests the API directly
|
||||
|
||||
echo "=========================================="
|
||||
echo "Testing Momentry Core API Directly"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Test 1: Health check
|
||||
echo "Test 1: Health Check"
|
||||
curl -s http://localhost:3002/api/v1/health 2>&1 | head -5
|
||||
echo ""
|
||||
|
||||
# Test 2: Search API
|
||||
echo "Test 2: Search API"
|
||||
echo "Query: 'charade'"
|
||||
curl -s -X POST http://localhost:3002/api/v1/n8n/search \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"query":"charade","limit":3}' | python3 -m json.tool
|
||||
echo ""
|
||||
|
||||
# Test 3: List videos
|
||||
echo "Test 3: List Videos"
|
||||
curl -s http://localhost:3002/api/v1/videos | python3 -m json.tool 2>/dev/null || echo "No videos or endpoint error"
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "If all tests show JSON responses, API is working!"
|
||||
echo ""
|
||||
echo "Next step: Use the API in n8n workflows"
|
||||
echo "=========================================="
|
||||
104
docs_v1.0/INTEGRATIONS/test_workflow.sh
Executable file
104
docs_v1.0/INTEGRATIONS/test_workflow.sh
Executable file
@@ -0,0 +1,104 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test Momentry Video RAG MCP Workflow
|
||||
# Usage: ./test_workflow.sh [query] [limit] [uuid]
|
||||
|
||||
N8N_URL="http://localhost:5678"
|
||||
WEBHOOK_PATH="webhook-test/video-rag-mcp"
|
||||
|
||||
echo "⚠️ 注意:使用 Test Webhook URL"
|
||||
echo "(生產環境 Webhook 需要工作流程手動激活後才能使用)"
|
||||
echo ""
|
||||
|
||||
# Default values
|
||||
QUERY="${1:-charade}"
|
||||
LIMIT="${2:-3}"
|
||||
UUID="${3:-}"
|
||||
|
||||
echo "=========================================="
|
||||
echo "Testing Video RAG Workflow"
|
||||
echo "=========================================="
|
||||
echo "Query: $QUERY"
|
||||
echo "Limit: $LIMIT"
|
||||
if [ -n "$UUID" ]; then
|
||||
echo "UUID: $UUID"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Build JSON payload
|
||||
if [ -n "$UUID" ]; then
|
||||
PAYLOAD=$(cat <<JSON
|
||||
{
|
||||
"query": "$QUERY",
|
||||
"limit": $LIMIT,
|
||||
"uuid": "$UUID"
|
||||
}
|
||||
JSON
|
||||
)
|
||||
else
|
||||
PAYLOAD=$(cat <<JSON
|
||||
{
|
||||
"query": "$QUERY",
|
||||
"limit": $LIMIT
|
||||
}
|
||||
JSON
|
||||
)
|
||||
fi
|
||||
|
||||
echo "Request:"
|
||||
echo "$PAYLOAD" | python3 -m json.tool 2>/dev/null || echo "$PAYLOAD"
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Response:"
|
||||
echo "=========================================="
|
||||
echo "URL: ${N8N_URL}/${WEBHOOK_PATH}"
|
||||
echo ""
|
||||
|
||||
# Make the request
|
||||
RESPONSE=$(curl -s -X POST "${N8N_URL}/${WEBHOOK_PATH}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$PAYLOAD")
|
||||
|
||||
# Format and display response
|
||||
echo "$RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$RESPONSE"
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
|
||||
# Check if successful
|
||||
if echo "$RESPONSE" | grep -q '"success": true'; then
|
||||
echo "✅ Test PASSED"
|
||||
|
||||
# Extract and display summary
|
||||
echo ""
|
||||
echo "Summary:"
|
||||
echo "$RESPONSE" | python3 -c "
|
||||
import sys, json
|
||||
data = json.load(sys.stdin)
|
||||
if data.get('success'):
|
||||
print(f\" Query: {data.get('query', 'N/A')}\")
|
||||
print(f\" Total Found: {data.get('totalFound', 0)}\")
|
||||
results = data.get('results', [])
|
||||
print(f\" Results Count: {len(results)}\")
|
||||
print()
|
||||
print(' Top Results:')
|
||||
for r in results[:3]:
|
||||
print(f\" [{r.get('index')}] {r.get('title', 'Unknown')}\")
|
||||
text = r.get('text', '')[:50]
|
||||
print(f\" Text: {text}...\")
|
||||
print(f\" Time: {r.get('startTime')}s - {r.get('endTime')}s\")
|
||||
print(f\" Relevance: {r.get('relevance')}\")
|
||||
print()
|
||||
" 2>/dev/null || true
|
||||
elif echo "$RESPONSE" | grep -q '"code": 404'; then
|
||||
echo "❌ Webhook not found"
|
||||
echo ""
|
||||
echo "可能的解決方案:"
|
||||
echo " 1. 在 n8n UI 中開啟工作流程: https://n8n.momentry.ddns.net"
|
||||
echo " 2. 點擊右上角的 'Active' 開關"
|
||||
echo " 3. 或者使用 test webhook: webhook-test/video-rag-mcp"
|
||||
else
|
||||
echo "❌ Test FAILED or no results found"
|
||||
fi
|
||||
|
||||
echo "=========================================="
|
||||
Reference in New Issue
Block a user