ingest-text 文本数据摄取接口文档
用于将外部文本数据安全推送到 Supabase text_records 表,并在后台系统进行统一存储、检索与分页展示。
1. 接口信息
- 请求方法:
POST
- 接口地址:
/functions/v1/ingest-text
- 完整 URL:
https://<project-ref>.supabase.co/functions/v1/ingest-text
- 鉴权机制: HMAC-SHA256 签名(
verify_jwt = false,与 ingest-jobs 接口鉴权规则完全一致)
- 时间窗口容忍: 5 分钟(
Math.abs(Date.now() - timestamp) <= 300000 ms)
2. 请求头规范
| Header | 必填 | 格式 / 示例 | 说明 |
|---|
content-type | 是 | application/json | 内容类型(亦兼容 text/plain) |
x-timestamp | 是 | 1787544626850 | Unix 毫秒时间戳(字符串) |
x-signature | 是 | base64url(...) | base64url(HMAC_SHA256(secret, "${x-timestamp}.${rawBody}")) |
3. 请求体格式
支持以下三种方式:
方式 1:标准 JSON 对象(推荐)
{
"text": "这是一段需要保存和展示的文本内容...",
"metadata": {
"source": "crawler-news",
"category": "notice",
"author": "system",
"external_id": "item-20260824-001"
}
}
方式 2:使用 content 字段
{
"content": "这是一段需要保存和展示的文本内容...",
"metadata": {
"source": "manual-push"
}
}
方式 3:直接传递纯文本字符串
直接传递一段纯文本
4. 字段说明
| 字段名 | 类型 | 必填 | 默认值 | 说明 |
|---|
text 或 content | string | 是 | 无 | 待保存的文本参数内容(不可为空) |
metadata | object | 否 | {} | 任意附加的 JSON 元数据(如来源、分类、外部 ID、请求标签等) |
5. 响应格式
成功响应(HTTP 200)
{
"ok": true,
"id": 1,
"created_at": "2026-08-24T04:10:29.382547+00:00",
"message": "Text recorded successfully"
}
| 字段 | 类型 | 说明 |
|---|
ok | boolean | 操作是否成功(固定 true) |
id | number | 写入数据库 text_records 表的自增 ID |
created_at | string | 数据库记录创建时间(ISO 8601 UTC 时间戳) |
message | string | 状态提示信息 |
错误响应状态码
| HTTP 状态码 | 触发场景 | 返回体示例 |
|---|
400 | 缺少文本参数或文本内容为空 | {"error": "Missing or empty text parameter (expected \"text\" or \"content\" field)"} |
401 | 缺少签名头、时间戳过期(>5分钟)或 HMAC 签名不匹配 | {"error": "Missing x-signature or x-timestamp"}<br/>{"error": "Signature expired"}<br/>{"error": "Invalid signature"} |
405 | 使用非 POST / OPTIONS 方法请求 | {"error": "Method not allowed"} |
500 | 数据库写入失败或服务端异常 | {"error": "Database insert failed: ..."} |
6. 代码示例
Node.js (TypeScript / JavaScript)
import crypto from 'node:crypto'
const url = 'https://ocfohbkrcdgtrnljrhfj.supabase.co/functions/v1/ingest-text'
const secret = process.env.INGEST_TEXT_SECRET || process.env.INGEST_JOBS_SECRET || 'your-secret'
const timestamp = Date.now().toString()
const payload = {
text: '京畿道华城汽车配件厂招聘质检员,提供食宿与通勤车。',
metadata: {
source: 'crawler-api',
batch_id: 'batch-2026-08'
}
}
const body = JSON.stringify(payload)
// 计算 HMAC-SHA256 签名 (base64url 格式)
const signature = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${body}`)
.digest('base64url')
const res = await fetch(url, {
method: 'POST',
headers: {
'content-type': 'application/json',
'x-timestamp': timestamp,
'x-signature': signature,
},
body,
})
const data = await res.json()
console.log('Response:', data)
Python (requests)
import time
import json
import hmac
import hashlib
import base64
import requests
url = "https://ocfohbkrcdgtrnljrhfj.supabase.co/functions/v1/ingest-text"
secret = "your-secret"
timestamp = str(int(time.time() * 1000))
payload = {
"text": "京畿道华城汽车配件厂招聘质检员,提供食宿与通勤车。",
"metadata": {
"source": "python-script"
}
}
body = json.dumps(payload, ensure_ascii=False)
# HMAC-SHA256 Base64URL 签名
sign_data = f"{timestamp}.{body}".encode("utf-8")
raw_sig = hmac.new(secret.encode("utf-8"), sign_data, hashlib.sha256).digest()
signature = base64.urlsafe_b64encode(raw_sig).decode("utf-8").rstrip("=")
headers = {
"content-type": "application/json",
"x-timestamp": timestamp,
"x-signature": signature
}
response = requests.post(url, data=body.encode("utf-8"), headers=headers)
print("Status:", response.status_code)
print("Response:", response.json())
7. 后台管理页面查看
推送成功的文本数据可直接在管理后台实时查看与检索:
- 管理端访问路径:
/dashboard/texts(侧边栏点击 “文本记录”)
- 功能特性: 支持精确创建时间展示、相对时间展示、快捷时间过滤、分页浏览、关键词模糊检索、一键复制全文及详情查看。