文章转语音 (ATS)
将整篇文章转换为语音音频及文本转录内容,并异步发送至您的回调 URL。
“文章转语音”(ATS)接口接收文章文本,并生成 MP3 格式的朗读音频以及同步的字幕文件(.srt)。生成过程异步进行:请求会立即返回202 Accepted状态码,生成的最终文件则会发送至您提供的callbackURL 。该接口正是驱动 ATS WordPress 插件的核心服务。
请勿等待音频生成的 HTTP 响应。该端点会立即返回 202 状态码,并在生成完成后将结果 POST 到您的 callbackURL。
身份验证
将贵公司的 API 密钥作为 Bearer 令牌包含在 Authorization 请求头中。
Authorization: Bearer your_api_key
请求体
发送一个包含文章原始文本以及描述该请求的 postData 对象的 JSON 正文。
| 参数 | 必填 | 类型 | 描述 |
|---|---|---|---|
| text | 必需的 | 字符串 | 要转换为语音的完整文章文本。 |
| postData | 必需的 | 物体 | 请求元数据。请参阅下方字段。 |
postData 对象
| 领域 | 必填 | 类型 | 默认 | 描述 |
|---|---|---|---|---|
| name | 必需的 | 字符串 | — | 文章标题。用作生成的音频请求的标题。 |
| articleId | 必需的 | 字符串 | — | 您为该文章设定的唯一标识符。它既充当幂等性键(参见下文“幂等性”),也会在回调中原样返回。 |
| voiceId | 必需的 | 字符串 | — | 用于旁白的声音。请使用来自……的 ID 语音列表. |
| callbackURL | 必需的 | 字符串 (URL) | — | Moknah 将向其 POST 已完成的音频及转录文本 URL 的 HTTPS URL。系统会为该公司存储该 URL 的最新值。 |
| preprocessType | 可选的 | 字符串 | "0" | 文本预处理模式,以字符串形式发送。使用 ”0” 表示不进行处理(逐字朗读),或使用 ”2” 表示 AI 预处理(朗读效果更整洁;字符计费加倍)。该参数必须是 JSON 字符串——直接传入数字(如 0 或 2)会在文本处理阶段被拒绝。 |
| regenerate | 可选的 | 布尔 | false | 若设为 true,即使该 articleId 之前已生成过,也会强制重新生成。 |
请求示例
curl -X POST "https://api.moknah.io/process-text" \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{
"text": "الذكاء الاصطناعي يتطور بسرعة كبيرة في كل المجالات.",
"postData": {
"name": "AI is evolving fast",
"articleId": "post-123",
"voiceId": "12",
"callbackURL": "https://your-site.com/wp-json/ats/v1/callback",
"preprocessType": "0",
"regenerate": false
}
}'
import requests
response = requests.post(
"https://api.moknah.io/process-text",
headers={
"Authorization": "Bearer your_api_key",
"Content-Type": "application/json"
},
json={
"text": "الذكاء الاصطناعي يتطور بسرعة كبيرة في كل المجالات.",
"postData": {
"name": "AI is evolving fast",
"articleId": "post-123",
"voiceId": "12",
"callbackURL": "https://your-site.com/wp-json/ats/v1/callback",
"preprocessType": "0",
"regenerate": False
}
}
)
# 202 Accepted — the audio is delivered to your callbackURL
print(response.status_code, response.text)
const response = await fetch(
'https://api.moknah.io/process-text',
{
method: 'POST',
headers: {
'Authorization': 'Bearer your_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
text: 'الذكاء الاصطناعي يتطور بسرعة كبيرة في كل المجالات.',
postData: {
name: 'AI is evolving fast',
articleId: 'post-123',
voiceId: '12',
callbackURL: 'https://your-site.com/wp-json/ats/v1/callback',
preprocessType: '0',
regenerate: false
}
})
}
);
// 202 Accepted — result arrives at your callbackURL
立即响应
如果请求被接受,端点会立即响应:
Processing started. Results will be sent to the callback URL.
回调载荷
生成完成后,Moknah 会向您的 callbackURL 发送一个 POST 请求,其中包含以下 JSON 正文:
{
"articleId": "post-123",
"response": {
"audioFile": "https://api-storage.moknah.io/.../******.mp3",
"srtFile": "https://api-storage.moknah.io/.../******.srt",
"signature": "<hmac-sha256-hex>"
}
}
| 领域 | 描述 |
|---|---|
| articleId | 与您在请求中发送的相同的 articleId。 |
| response.audioFile | 生成的 MP3 旁白的公开 URL;若生成失败,则为 null。 |
| response.srtFile | 同步字幕文件(.srt)的公开 URL;若生成失败,则为 null。 |
| response.signature | HMAC-SHA256 签名,可用于验证有效载荷的真实性(见下文)。 |
当生成过程未产生音频时,也会发送回调。此时,response.audioFile 和 response.srtFile 均为 null(签名仍涵盖 articleId|null|null)。请将 audioFile 或 srtFile 为 null 的回调视为失败:不要将文章标记为已完成,而应将 regenerate 参数设为 true 并重新发送请求。
验证签名
该签名是对字符串articleId|audioFile|srtFile进行 HMAC-SHA256(十六进制格式)计算得出的结果,其中使用的密钥是您 API Key 的 SHA-256 十六进制摘要。请在您的端侧重新计算并进行比对,以确认该回调确实来自 Moknah 且未被篡改。
import crypto from 'crypto';
const keyHash = crypto.createHash('sha256').update(API_KEY).digest('hex');
const payload = `${articleId}|${audioFile}|${srtFile}`;
const expected = crypto.createHmac('sha256', keyHash).update(payload).digest('hex');
const isValid = expected === signature;
import hashlib, hmac
key_hash = hashlib.sha256(API_KEY.encode()).hexdigest()
payload = f"{article_id}|{audio_file}|{srt_file}"
expected = hmac.new(key_hash.encode(), payload.encode(), hashlib.sha256).hexdigest()
is_valid = hmac.compare_digest(expected, signature)
幂等性与再生
- 请求按每个公司的 articleId 进行标识。新的 articleId 会启动新一轮的生成过程。
- 如果文章正在生成中,重复请求将被拒绝,并返回 409 ALREADY_PROCESSING 状态。
- 如果文章已生成且 `regenerate` 参数为 `false`,系统会将现有的音频重新发送至您的 `callbackURL`,而不会重新生成(也不会再次收费)。
- 将 regenerate 设置为 true,即可针对现有的 articleId 强制重新生成。
- 如果之前的尝试失败,针对该 `articleId` 存储的结果可能是空的。后续若发起 `regenerate` 设为 `false` 的请求,可能会再次返回该空结果;因此,请将 `regenerate` 设为 `true` 重新发送(或使用新的 `articleId`)以恢复正常。
并发与吞吐量
每篇文章的语音生成过程涉及向“文本转语音”服务提供商并行发送句子请求;该提供商针对您的整个账户实施统一的并发限制。如果同时提交大量文章,可能会超出此限制,导致部分句子(进而导致整篇文章)的处理失败。
- 在处理包含多个部分的页面时,请一次仅进行少量文章(约三篇)的制作,而不要将它们全部同时提交。
- 将 `regenerate` 设为 `true` 以重试任何失败的文章;已生成的文章会被缓存,无需重新发送。
- `/process-text` 接口也针对每个客户端实施了速率限制;超出限制的突发请求将收到“429 Too Many Requests”(请求过多)的响应,因此请分散提交或采用批量提交的方式。
计费
字符消耗量的计算方式为: text字符数乘以预处理系数(默认值为 1;当preprocessType为 2 时,系数为 2)。仅在实际执行生成操作时才会扣除点数。重新发送已生成的文章无需额外付费;若生成或发送失败,系统将自动退还已扣除的点数。
错误
| 状态 | 代码 | 描述 |
|---|---|---|
401 |
AUTH_FAILED | 缺少 Authorization 请求头或 API 密钥无效。 |
422 |
VALIDATION_ERROR | 缺少文本,或 postData 字段无效/缺失。 |
400 |
INVALID_VOICE_ID | 提供的 voiceId 不存在。 |
409 |
ALREADY_PROCESSING | 该文章正在生成中。请在生成完成后重试。 |
422 |
PROCESSING_ERROR | 生成失败。已扣除的积分将退还。 |
422 |
REFUND_FAILED | 处理失败,自动退款未完成。请联系 api@moknah.io。 |
如有关于 API 的问题或疑问,请联系我们: api@moknah.io.