OmniDocOmniDoc 开发者文档
OMNIDOC / QUICKSTART

翻译第一份文件。

下面每个示例都是独立的完整流程:上传、确认文档、创建任务、等待完成、下载结果。选择一种语言,从头运行即可。

开始之前

  1. 在 API 控制台创建 Key,并设置环境变量 OMNIDOC_API_KEY。
  2. 准备一份 report.docx,放在脚本所在目录;也可修改示例中的文件路径。
  3. 先用 余额查询验证凭据。翻译会产生用量,确认账号积分及 Key 预算。
示例不自动重试创建请求。遇到网络超时,保留任务 ID、幂等键和请求体,先查询状态。已经创建的任务不会因为脚本退出而自动取消。
Bash + curl + jq + uuidgen · 保存为 translate.sh,运行 bash translate.sh
#!/usr/bin/env bash
set -euo pipefail
: "${OMNIDOC_API_KEY:?请设置 OMNIDOC_API_KEY}"
BASE='https://omnidoc.top/api/v1'
FILE='report.docx'
TARGET='en'
SIZE=$(wc -c < "$FILE" | tr -d ' ')

# 1. 申请直传;上传地址和凭据不要写入日志。
TICKET=$(curl --fail-with-body -sS --max-time 30 "$BASE/upload/presign" \
  -H "X-API-Key: $OMNIDOC_API_KEY" -H 'Content-Type: application/json' \
  -d "$(jq -n --arg name "$(basename "$FILE")" --argjson size "$SIZE" \
    '{filename:$name,file_size:$size}')")
UPLOAD_URL=$(jq -er '.upload_url' <<< "$TICKET")
FINALIZE_TOKEN=$(jq -er '.finalize_token' <<< "$TICKET")
UPLOAD_HEADERS=()
while IFS= read -r header; do UPLOAD_HEADERS+=(-H "$header"); done \
  < <(jq -r '.upload_headers | to_entries[] | "\(.key): \(.value)"' <<< "$TICKET")

# 2. 只发返回的上传头;不带 API Key。
curl --fail-with-body -sS --max-time 300 -X PUT "$UPLOAD_URL" \
  "${UPLOAD_HEADERS[@]}" --upload-file "$FILE"

# 3. 确认上传,取得 document.id。
DOCUMENT=$(curl --fail-with-body -sS --max-time 30 "$BASE/upload/finalize" \
  -H "X-API-Key: $OMNIDOC_API_KEY" -H 'Content-Type: application/json' \
  -d "$(jq -n --arg token "$FINALIZE_TOKEN" '{finalize_token:$token}')")
DOCUMENT_ID=$(jq -er '.document.id' <<< "$DOCUMENT")

# 4. 每个新任务生成一个键;重试本次创建时保留此键和请求体。
IDEMPOTENCY_KEY=$(uuidgen)
JOB=$(curl --fail-with-body -sS --max-time 30 "$BASE/jobs" \
  -H "X-API-Key: $OMNIDOC_API_KEY" -H 'Content-Type: application/json' \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -d "$(jq -n --arg doc "$DOCUMENT_ID" --arg lang "$TARGET" \
    '{document_id:$doc,target_lang:$lang}')")
JOB_ID=$(jq -er '.id' <<< "$JOB")
printf 'job_id: %s\n' "$JOB_ID"

# 5. 有界轮询;超时不取消任务,也不要因此重复创建。
STATUS=''
for ((attempt=0; attempt<240; attempt++)); do
  JOB=$(curl --fail-with-body -sS --max-time 20 "$BASE/jobs/$JOB_ID" \
    -H "X-API-Key: $OMNIDOC_API_KEY")
  STATUS=$(jq -er '.status' <<< "$JOB")
  if [[ "$STATUS" == 'completed' ]]; then break; fi
  if [[ "$STATUS" == 'failed' ]]; then
    jq -r '.error_msg // "translation failed"' <<< "$JOB" >&2; exit 1
  fi
  sleep 3
done
if [[ "$STATUS" != 'completed' ]]; then
  printf '等待超时,请继续查询任务 %s\n' "$JOB_ID" >&2; exit 1
fi

# 6. 逐项下载到新建目录,不使用服务端文件名作为路径。
ARTIFACTS=$(curl --fail-with-body -sS --max-time 30 \
  "$BASE/artifacts?job_id=$JOB_ID" -H "X-API-Key: $OMNIDOC_API_KEY")
OUTPUT=$(mktemp -d './omnidoc-output.XXXXXX')
INDEX=0
while IFS=$'\t' read -r id format; do
  INDEX=$((INDEX + 1))
  [[ "$format" =~ ^[a-zA-Z0-9]+$ ]] || format='bin'
  curl --fail-with-body -sS --max-time 300 \
    "$BASE/artifacts/$id/download" -H "X-API-Key: $OMNIDOC_API_KEY" \
    -o "$OUTPUT/$INDEX.$format"
done < <(jq -r '.[] | [.id,.format] | @tsv' <<< "$ARTIFACTS")
printf '结果目录:%s\n' "$OUTPUT"

cURL 示例适用于 Bash,不要直接粘贴到 PowerShell。Python 与 Node.js 示例可在 Windows 使用;下载时若目标文件已存在会报错,以避免覆盖旧结果。

运行后你会得到什么

控制台先输出 job_id。成功后,文件写入当前目录的 omnidoc-output(cURL 会创建带随机后缀的新目录)。轮询结束条件为 completed 或 failed。

文件规模和排队情况可能影响时长。示例设置了等待上限,生产环境可以改用 Webhook 或 SSE,不要无限轮询。

遇到错误

  • 401:检查环境变量是否设置、Key 是否有效。
  • 402 或任务中的 quota_exceeded:检查积分。
  • 403:检查 Key 预算、配置权限与资源归属。
  • 429:读取业务错误码,区分频率、排队与预算限制。
  • 直传地址过期或上传失败:重新申请上传地址。

记录 X-Request-Id 与请求路径;日志不要包含完整密钥和上传凭据。完整错误与重试参考 →