查询发布状态
同步查询一次 发布翻译任务 的执行状态。专为轮询场景设计 —— 服务端不写调用日志,可以放心高频调用(建议间隔 ≥ 3s)。
为什么需要这个接口
发布是异步的:/tasks/publish 立刻返回 job_id,真正把译文写入项目级聚合表的是后台 GCP Workflow。而 /export/ini 读的正是这些聚合表 —— 发布还没写完就导出,会拿到旧数据。
在本接口出现之前,发布完成只能靠 task.publish.completed 回调获知;无法接收回调的环境(本地脚本、Agent 沙箱、命令行)只能"发布后盲等一段保险时间再导出"。本接口把盲等换成确定性轮询:等到 completed 再导出即可。
请求地址
GET {BASE_URL}/api/open/v1/tasks/publish-status也支持 POST(job_id 放在 body 里,JSON 格式)。
鉴权 Header
和 查询任务状态 完全一样:
| Header | 值 |
|---|---|
X-Loxily-AppKey | 项目 App Key |
X-Loxily-Timestamp | Unix 秒(5 分钟有效) |
X-Loxily-Sign | MD5(timestamp + "" + appSecret) —— GET 无 body,body 以空字符串参与签名 |
查询参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
job_id | string | 是 | 发布翻译任务 返回的 publish_open_... job ID |
响应字段
成功(HTTP 200):
{
"success": true,
"code": 0,
"msg": "ok",
"trace_id": "8a3f12ab-4d2a-9f51-7e2c6d8a9101",
"data": {
"job_id": "publish_open_...",
"task_id": "68a12cb7e1f9a88b4ea23c77",
"status": "running",
"is_completed": false,
"is_failed": false,
"error": null,
"accepted_at": "2026-04-23T09:15:22.117Z",
"updated_at": "2026-04-23T09:15:40.552Z"
}
}status 的 4 种取值
| status | 含义 |
|---|---|
pending | 发布已受理,工作流尚未上报进度 |
running | PUBLISH_TASK 工作流执行中 |
completed | 发布完成,项目级聚合表已写完,可以安全调用 /export/ini |
failed | 发布失败,error 携带原因 |
终态判定与 task.publish.completed / task.publish.failed 回调完全一致,两者数据来源相同。
错误码
| code | 说明 |
|---|---|
| 400 | job_id 缺失 |
| 401 | 签名无效 / 时间戳过期 |
| 404 | job_id 不存在、不是发布任务、或不属于当前 App Key |
| 500 | 系统错误 |
归属校验统一回 404
job_id 存在但属于其它 App Key 时也返回 404(而非 403),不泄漏 job 的存在性。
示例
cURL(GET)
APP_KEY="5685414646a54423c891d87194d87f3f"
APP_SECRET="<你的 App Secret>"
BASE_URL="https://api.loxily.com"
JOB_ID="publish_open_68a12cb7_1745399722"
TIMESTAMP=$(date +%s)
# GET 无 body,body 以空字符串参与签名
SIGN=$(printf '%s' "${TIMESTAMP}${APP_SECRET}" | md5)
curl -s "${BASE_URL}/api/open/v1/tasks/publish-status?job_id=${JOB_ID}" \
-H "X-Loxily-AppKey: ${APP_KEY}" \
-H "X-Loxily-Timestamp: ${TIMESTAMP}" \
-H "X-Loxily-Sign: ${SIGN}"Node.js 轮询直到发布完成再导出
import crypto from 'crypto';
async function waitForPublish(jobId, { timeoutMs = 15 * 60 * 1000, intervalMs = 3000 } = {}) {
const start = Date.now();
while (Date.now() - start < timeoutMs) {
const timestamp = Math.floor(Date.now() / 1000).toString();
const sign = crypto.createHash('md5')
.update(`${timestamp}${process.env.LOXILY_APP_SECRET}`, 'utf8')
.digest('hex');
const resp = await fetch(
`${process.env.LOXILY_BASE_URL}/api/open/v1/tasks/publish-status?job_id=${jobId}`,
{
headers: {
'X-Loxily-AppKey': process.env.LOXILY_APP_KEY,
'X-Loxily-Timestamp': timestamp,
'X-Loxily-Sign': sign,
},
},
);
const { data } = await resp.json();
if (data.is_completed) return data;
if (data.is_failed) throw new Error(`Publish failed: ${data.error}`);
await new Promise((r) => setTimeout(r, intervalMs));
}
throw new Error(`Polling timeout (${timeoutMs}ms)`);
}
// publish → 等发布写完 → 再导出
const { data } = await publishTask('68a12cb7e1f9a88b4ea23c77');
await waitForPublish(data.job_id);
// 此时聚合表已写完,可以安全 /export/iniMCP 对应工具
MCP 集成方不需要手写轮询:
loxily_query_publish_status—— 单次查询(对应本接口一次调用)loxily_wait_for_publish—— 聚合轮询,阻塞到终态才返回(默认 15 分钟上限、3s 间隔)
FAQ
Q:和 task.publish.completed 回调有什么区别? 回调是推送,本接口是拉取。回调及时但需要公网入口;本接口需要轮询但对任何环境通用。两者终态判定完全一致。
Q:为什么 /tasks/status 查不到发布进度?/tasks/status 反映的是翻译链路(导入 → 扫描 → 翻译 → 智能优化)的状态;发布是翻译完成后独立触发的另一条工作流,其 job 不挂在任务的 jobs 摘要里。发布进度只能用本接口(或回调)获取。
Q:调用频率有限制吗? 本接口不写调用日志,无单独限流。建议轮询间隔 ≥ 3s。