@optima-chat/browser-cli 0.16.0 → 0.17.0
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/dist/index.js +1 -137
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -291,33 +291,6 @@ var BrowserAPI = class {
|
|
|
291
291
|
async getScreenshot(sessionId) {
|
|
292
292
|
return requestBinary(`/api/sessions/${sessionId}/screenshot`);
|
|
293
293
|
}
|
|
294
|
-
async runRecipeScript(name, params, pollMs = 2e3, timeoutMs = 36e4, timeoutHint) {
|
|
295
|
-
const started = await request(`/api/scripts/${name}/run`, {
|
|
296
|
-
method: "POST",
|
|
297
|
-
body: JSON.stringify({ params })
|
|
298
|
-
});
|
|
299
|
-
const deadline = Date.now() + timeoutMs;
|
|
300
|
-
for (; ; ) {
|
|
301
|
-
const task = await request(`/api/script-tasks/${started.id}`);
|
|
302
|
-
if (task.status === "completed") {
|
|
303
|
-
if (!task.output) {
|
|
304
|
-
throw new Error(
|
|
305
|
-
`recipe ${name} reported completed but returned no output (task ${started.id})`
|
|
306
|
-
);
|
|
307
|
-
}
|
|
308
|
-
return task.output;
|
|
309
|
-
}
|
|
310
|
-
if (task.status === "failed" || task.status === "needs_fallback") {
|
|
311
|
-
throw new Error(task.error || task.output?.error || `recipe ${task.status}`);
|
|
312
|
-
}
|
|
313
|
-
if (Date.now() >= deadline) {
|
|
314
|
-
throw new Error(
|
|
315
|
-
`recipe ${name} did not finish within ${Math.round(timeoutMs / 1e3)}s (task ${started.id})` + (timeoutHint ? ` \u2014\u2014 ${timeoutHint}` : "")
|
|
316
|
-
);
|
|
317
|
-
}
|
|
318
|
-
await new Promise((r) => setTimeout(r, pollMs));
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
294
|
async fetchArtifact(artifactPath) {
|
|
322
295
|
return requestBinary(artifactPath);
|
|
323
296
|
}
|
|
@@ -1033,7 +1006,7 @@ Each artifact can be fetched once; if runscript printed "Saved ->", the file is
|
|
|
1033
1006
|
});
|
|
1034
1007
|
}
|
|
1035
1008
|
function sleep(ms) {
|
|
1036
|
-
return new Promise((
|
|
1009
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
1037
1010
|
}
|
|
1038
1011
|
|
|
1039
1012
|
// src/ziniao-doctor.ts
|
|
@@ -1247,114 +1220,6 @@ function registerChromeCommands(program2) {
|
|
|
1247
1220
|
});
|
|
1248
1221
|
}
|
|
1249
1222
|
|
|
1250
|
-
// src/commands/recipes.ts
|
|
1251
|
-
import { writeFileSync as writeFileSync4 } from "fs";
|
|
1252
|
-
import { resolve as resolve2 } from "path";
|
|
1253
|
-
var PUBLISH_TIMEOUT_MS = 18e5;
|
|
1254
|
-
var AD_REPORT_TIMEOUT_MS = 132e4;
|
|
1255
|
-
var PUBLISH_TIMEOUT_HINT = "\u4EFB\u52A1\u4ECD\u5728\u540E\u7AEF\u8FD0\u884C,\u89C6\u9891\u53EF\u80FD\u5DF2\u7ECF\u53D1\u51FA\u53BB\u4E86\u3002\u53D1\u5E03\u72B6\u6001\u672A\u77E5 \u2014\u2014 \u8BF7\u5230\u5356\u5BB6\u540E\u53F0\u786E\u8BA4,\u4E0D\u8981\u91CD\u8DD1\u672C\u547D\u4EE4(\u4F1A\u53D1\u51FA\u91CD\u590D\u89C6\u9891)\u3002";
|
|
1256
|
-
async function runExport(script, params, out, timeoutMs) {
|
|
1257
|
-
const outPath = resolve2(out);
|
|
1258
|
-
const result = await api.runRecipeScript(script, { ...params, out_path: outPath }, 2e3, timeoutMs);
|
|
1259
|
-
if (!result.path) {
|
|
1260
|
-
if (!result.artifact_path) {
|
|
1261
|
-
throw new Error(
|
|
1262
|
-
`Script ${script} finished but delivered no file \u2014 no workspace path and no staged artifact. Nothing was written to ${outPath}.`
|
|
1263
|
-
);
|
|
1264
|
-
}
|
|
1265
|
-
writeFileSync4(outPath, await api.fetchArtifact(result.artifact_path));
|
|
1266
|
-
}
|
|
1267
|
-
console.log(`Saved ${result.filename} -> ${outPath} (${result.size} bytes)`);
|
|
1268
|
-
}
|
|
1269
|
-
function registerRecipeCommands(program2) {
|
|
1270
|
-
program2.command("export-ad-report").description("Export TikTok Shop ad data (per-creative by default) into the session workspace").requiredOption("--ziniao-profile <id>", "ZiNiao browser profile ID").option("--report-url <url>", "Ad dashboard URL (default: TikTok Shop MY local site)").option("--days <n>", "Date range: 7 / 30 / 90 / 180 / 365 (default: 7)").option(
|
|
1271
|
-
"--scope <scope>",
|
|
1272
|
-
"creative = per-creative rows (default) | daily = account-level daily totals"
|
|
1273
|
-
).option("--out <path>", "Output CSV path", "./tt_ad_report.csv").action(
|
|
1274
|
-
async (opts) => {
|
|
1275
|
-
try {
|
|
1276
|
-
const params = { ziniao_profile_id: opts.ziniaoProfile };
|
|
1277
|
-
if (opts.reportUrl) params.report_url = opts.reportUrl;
|
|
1278
|
-
if (opts.days) params.days = opts.days;
|
|
1279
|
-
if (opts.scope) params.scope = opts.scope;
|
|
1280
|
-
await runExport("tiktok_video_ad_export", params, opts.out, AD_REPORT_TIMEOUT_MS);
|
|
1281
|
-
} catch (err) {
|
|
1282
|
-
console.error(formatError(err));
|
|
1283
|
-
process.exit(1);
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
);
|
|
1287
|
-
program2.command("export-order-report").description("Export TikTok Shop order data into the session workspace").requiredOption("--ziniao-profile <id>", "ZiNiao browser profile ID").option("--report-url <url>", "Order list URL (default: TikTok Shop MY local site)").option("--days <n>", "Export the last N days (default: 7, max 365)").option("--out <path>", "Output CSV path", "./tt_orders.csv").action(async (opts) => {
|
|
1288
|
-
try {
|
|
1289
|
-
const params = { ziniao_profile_id: opts.ziniaoProfile };
|
|
1290
|
-
if (opts.reportUrl) params.report_url = opts.reportUrl;
|
|
1291
|
-
if (opts.days) params.days = opts.days;
|
|
1292
|
-
await runExport("tiktok_order_export", params, opts.out, 54e4);
|
|
1293
|
-
} catch (err) {
|
|
1294
|
-
console.error(formatError(err));
|
|
1295
|
-
process.exit(1);
|
|
1296
|
-
}
|
|
1297
|
-
});
|
|
1298
|
-
program2.command("publish-video-global").description("Publish one shoppable video to a TikTok Shop CROSS-BORDER store (one region per run)").requiredOption("--ziniao-profile <id>", "ZiNiao browser profile ID").requiredOption("--video <name>", "Video file name (from list-videos)").requiredOption("--account <username>", "Publishing account username; it also picks the region (one region per run)").requiredOption("--product-query <keyword>", "Product search keyword or product ID, narrow enough to hit exactly one product (ask the user)").requiredOption(
|
|
1299
|
-
"--product-name <text>",
|
|
1300
|
-
"Display name on the video: max 30 chars, letters/digits/spaces only (ask the user)"
|
|
1301
|
-
).requiredOption("--caption <text>", "Video caption").option("--dry-run", "Fill everything, run the pre-publish checks, then STOP before clicking publish (nothing is published; the browser window stays open for you to inspect)").option("--hashtags <text>", "Comma-separated hashtags, bare words (the page adds the # itself)").option("--publish-url <url>", "Video publish page URL (include the right ?shop_region=)").action(async (opts) => {
|
|
1302
|
-
try {
|
|
1303
|
-
const params = {
|
|
1304
|
-
ziniao_profile_id: opts.ziniaoProfile,
|
|
1305
|
-
video: opts.video,
|
|
1306
|
-
account: opts.account,
|
|
1307
|
-
product_query: opts.productQuery,
|
|
1308
|
-
product_name: opts.productName,
|
|
1309
|
-
caption: opts.caption
|
|
1310
|
-
};
|
|
1311
|
-
if (opts.dryRun) params.dry_run = "1";
|
|
1312
|
-
if (opts.hashtags) params.hashtags = opts.hashtags;
|
|
1313
|
-
if (opts.publishUrl) params.publish_url = opts.publishUrl;
|
|
1314
|
-
const result = await api.runRecipeScript(
|
|
1315
|
-
"tiktok_video_publish_global",
|
|
1316
|
-
params,
|
|
1317
|
-
2e3,
|
|
1318
|
-
PUBLISH_TIMEOUT_MS,
|
|
1319
|
-
PUBLISH_TIMEOUT_HINT
|
|
1320
|
-
);
|
|
1321
|
-
console.log(result.detail);
|
|
1322
|
-
} catch (err) {
|
|
1323
|
-
console.error(formatError(err));
|
|
1324
|
-
process.exit(1);
|
|
1325
|
-
}
|
|
1326
|
-
});
|
|
1327
|
-
program2.command("publish-video").description("Publish one shoppable video to TikTok Shop").requiredOption("--ziniao-profile <id>", "ZiNiao browser profile ID").requiredOption("--video <name>", "Video file name (from list-videos)").requiredOption("--product-query <keyword>", "Product search keyword, narrow enough to hit exactly one product (ask the user)").requiredOption(
|
|
1328
|
-
"--product-name <text>",
|
|
1329
|
-
"Display name on the video: max 30 chars, letters/digits/spaces only (ask the user)"
|
|
1330
|
-
).requiredOption("--caption <text>", "Video caption").option("--account <username>", "Publishing account username (default: the shop's official account; pass a marketing sub-account to post as it)").option("--dry-run", "Fill everything, run the pre-publish checks, then STOP before clicking publish (nothing is published; the browser window stays open for you to inspect)").option("--hashtags <text>", "Comma-separated hashtags, bare words (the page adds the # itself)").option("--publish-url <url>", "Video publish page URL").action(async (opts) => {
|
|
1331
|
-
try {
|
|
1332
|
-
const params = {
|
|
1333
|
-
ziniao_profile_id: opts.ziniaoProfile,
|
|
1334
|
-
video: opts.video,
|
|
1335
|
-
product_query: opts.productQuery,
|
|
1336
|
-
product_name: opts.productName,
|
|
1337
|
-
caption: opts.caption
|
|
1338
|
-
};
|
|
1339
|
-
if (opts.account) params.account = opts.account;
|
|
1340
|
-
if (opts.dryRun) params.dry_run = "1";
|
|
1341
|
-
if (opts.hashtags) params.hashtags = opts.hashtags;
|
|
1342
|
-
if (opts.publishUrl) params.publish_url = opts.publishUrl;
|
|
1343
|
-
const result = await api.runRecipeScript(
|
|
1344
|
-
"tiktok_video_publish",
|
|
1345
|
-
params,
|
|
1346
|
-
2e3,
|
|
1347
|
-
PUBLISH_TIMEOUT_MS,
|
|
1348
|
-
PUBLISH_TIMEOUT_HINT
|
|
1349
|
-
);
|
|
1350
|
-
console.log(result.detail);
|
|
1351
|
-
} catch (err) {
|
|
1352
|
-
console.error(formatError(err));
|
|
1353
|
-
process.exit(1);
|
|
1354
|
-
}
|
|
1355
|
-
});
|
|
1356
|
-
}
|
|
1357
|
-
|
|
1358
1223
|
// src/commands/bitbrowser.ts
|
|
1359
1224
|
function registerBitBrowserCommands(program2) {
|
|
1360
1225
|
const bitbrowser = program2.command("bitbrowser").description("Manage BitBrowser (\u6BD4\u7279\u6D4F\u89C8\u5668) anti-detect browser");
|
|
@@ -1471,7 +1336,6 @@ registerTabCommands(program);
|
|
|
1471
1336
|
registerScriptCommands(program);
|
|
1472
1337
|
registerZiNiaoCommands(program);
|
|
1473
1338
|
registerChromeCommands(program);
|
|
1474
|
-
registerRecipeCommands(program);
|
|
1475
1339
|
registerBitBrowserCommands(program);
|
|
1476
1340
|
registerFeikuaCommands(program);
|
|
1477
1341
|
registerFileCommands(program);
|