aiconductor-cli 1.2.2 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/aiconductor-cli.js +20 -0
- package/package.json +1 -1
- package/src/api.js +23 -0
- package/src/commands/xhs.js +55 -0
package/bin/aiconductor-cli.js
CHANGED
|
@@ -13,6 +13,7 @@ const {
|
|
|
13
13
|
videoSearchCommand,
|
|
14
14
|
linkToTextCommand,
|
|
15
15
|
} = require("../src/commands/douyin");
|
|
16
|
+
const { notePublishCommand } = require("../src/commands/xhs");
|
|
16
17
|
|
|
17
18
|
const program = new Command();
|
|
18
19
|
|
|
@@ -164,6 +165,25 @@ douyinCmd
|
|
|
164
165
|
.option("-f, --format <format>", "输出格式:json 或 text", "json")
|
|
165
166
|
.action((videoUrl, options) => { linkToTextCommand(videoUrl, options); });
|
|
166
167
|
|
|
168
|
+
// xhs 子命令组
|
|
169
|
+
const xhsCmd = program
|
|
170
|
+
.command("xhs")
|
|
171
|
+
.description("小红书数据工具箱");
|
|
172
|
+
|
|
173
|
+
xhsCmd
|
|
174
|
+
.command("note-publish")
|
|
175
|
+
.description("生成小红书扫码发布页与二维码(图文0.05元/次,含OSS转存0.1元/次)")
|
|
176
|
+
.argument("<type>", "笔记类型:normal(图文)或 video(视频)")
|
|
177
|
+
.option("-k, --api-key <key>", "AIConductor API Key")
|
|
178
|
+
.option("-t, --title <title>", "笔记标题(最多20字符)")
|
|
179
|
+
.option("--content <text>", "笔记正文(最多1000字符)")
|
|
180
|
+
.option("--images <urls>", "图片公网URL列表,逗号分隔(normal类型必填,最多18张)")
|
|
181
|
+
.option("--video <url>", "视频公网URL(video类型必填)")
|
|
182
|
+
.option("--cover <url>", "视频封面图公网URL(仅video类型有效)")
|
|
183
|
+
.option("--transfer-to-oss", "是否将素材转存到云端(更稳定,7天有效)")
|
|
184
|
+
.option("-f, --format <format>", "输出格式:json 或 text", "json")
|
|
185
|
+
.action((type, options) => { notePublishCommand(type, options); });
|
|
186
|
+
|
|
167
187
|
// 未知命令处理
|
|
168
188
|
program.on("command:*", () => {
|
|
169
189
|
console.error(`未知命令: ${program.args.join(" ")}`);
|
package/package.json
CHANGED
package/src/api.js
CHANGED
|
@@ -13,6 +13,7 @@ const DOUYIN_USER_DETAIL_PATH = "/api/douyin_user_detail";
|
|
|
13
13
|
const DOUYIN_USER_SEARCH_PATH = "/api/douyin_user_search";
|
|
14
14
|
const DOUYIN_VIDEO_SEARCH_PATH = "/api/douyin_video_search";
|
|
15
15
|
const DOUYIN_LINK_TO_TEXT_PATH = "/api/douyin_link_to_text_v2";
|
|
16
|
+
const XHS_NOTE_PUBLISH_PATH = "/api/xhs_note_publish";
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* 解析 API Key,三级优先级:命令行参数 > 系统环境变量 > .env 文件
|
|
@@ -300,6 +301,27 @@ async function douyinLinkToText(apiKey, videoUrl) {
|
|
|
300
301
|
return stripBilling(resp);
|
|
301
302
|
}
|
|
302
303
|
|
|
304
|
+
/**
|
|
305
|
+
* 小红书笔记发布 — 生成扫码发布 H5 页面与二维码
|
|
306
|
+
* @param {string} apiKey
|
|
307
|
+
* @param {{ type: string, title?: string, content?: string, images?: string[], video?: string, cover?: string, transferToOss?: boolean }} params
|
|
308
|
+
* @returns {Promise<object>}
|
|
309
|
+
*/
|
|
310
|
+
async function xhsNotePublish(apiKey, params) {
|
|
311
|
+
const body = { type: params.type };
|
|
312
|
+
if (params.title) body.title = params.title;
|
|
313
|
+
if (params.content) body.content = params.content;
|
|
314
|
+
if (params.images && params.images.length > 0) body.images = params.images;
|
|
315
|
+
if (params.video) body.video = params.video;
|
|
316
|
+
if (params.cover) body.cover = params.cover;
|
|
317
|
+
if (params.transferToOss !== undefined) body.transfer_to_oss = params.transferToOss;
|
|
318
|
+
|
|
319
|
+
const resp = await httpPost(API_HOST, XHS_NOTE_PUBLISH_PATH, body, {
|
|
320
|
+
Authorization: `Bearer ${apiKey}`,
|
|
321
|
+
});
|
|
322
|
+
return stripBilling(resp);
|
|
323
|
+
}
|
|
324
|
+
|
|
303
325
|
module.exports = {
|
|
304
326
|
resolveApiKey,
|
|
305
327
|
publishHtml,
|
|
@@ -312,4 +334,5 @@ module.exports = {
|
|
|
312
334
|
douyinUserSearch,
|
|
313
335
|
douyinVideoSearch,
|
|
314
336
|
douyinLinkToText,
|
|
337
|
+
xhsNotePublish,
|
|
315
338
|
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const { xhsNotePublish } = require("../api");
|
|
2
|
+
const { outputResult, resolveKeyOrExit, handleApiError } = require("../lib/cli-utils");
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* text 格式输出:用 ✓ 开头展示关键信息
|
|
6
|
+
*/
|
|
7
|
+
function textFormatter(resp) {
|
|
8
|
+
const d = resp.data || {};
|
|
9
|
+
const lines = [];
|
|
10
|
+
lines.push("✓ 小红书笔记发布页已生成");
|
|
11
|
+
lines.push(` ID: ${d.id}`);
|
|
12
|
+
lines.push(` H5 地址: ${d.url}`);
|
|
13
|
+
if (resp.message) lines.push(` 消息: ${resp.message}`);
|
|
14
|
+
if (d.qrcode) lines.push(` 二维码: ${d.qrcode.substring(0, 50)}...`);
|
|
15
|
+
if (d.transfer_to_oss) lines.push(` OSS转存: 是`);
|
|
16
|
+
if (d.media) {
|
|
17
|
+
if (d.media.images) lines.push(` 图片: ${d.media.images.length} 张`);
|
|
18
|
+
if (d.media.video) lines.push(` 视频: ${d.media.video}`);
|
|
19
|
+
if (d.media.cover) lines.push(` 封面: ${d.media.cover}`);
|
|
20
|
+
}
|
|
21
|
+
return lines.join("\n");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function notePublishCommand(type, options = {}) {
|
|
25
|
+
const format = options.format || "json";
|
|
26
|
+
const apiKey = resolveKeyOrExit(options.apiKey, format);
|
|
27
|
+
|
|
28
|
+
// 解析 --images(逗号分隔的 URL 列表)
|
|
29
|
+
let images;
|
|
30
|
+
if (options.images) {
|
|
31
|
+
images = options.images.split(",").map((s) => s.trim()).filter(Boolean);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 解析 --transfer-to-oss(布尔标志)
|
|
35
|
+
const transferToOss = options.transferToOss !== undefined;
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const result = await xhsNotePublish(apiKey, {
|
|
39
|
+
type,
|
|
40
|
+
title: options.title,
|
|
41
|
+
content: options.content,
|
|
42
|
+
images,
|
|
43
|
+
video: options.video,
|
|
44
|
+
cover: options.cover,
|
|
45
|
+
transferToOss,
|
|
46
|
+
});
|
|
47
|
+
outputResult(result, format, textFormatter);
|
|
48
|
+
process.exit(0);
|
|
49
|
+
} catch (err) {
|
|
50
|
+
handleApiError(err, format);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = { notePublishCommand };
|