siluzan-tso-cli 1.1.48-beta.8 → 1.1.48-beta.9
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/README.md +1 -1
- package/dist/index.js +513 -10
- package/dist/skill/SKILL.md +1 -1
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/references/analytics/account-analytics.md +25 -1
- package/dist/skill/references/core/workflows.md +1 -1
- package/dist/skill/references/operations/hosted-automation-scenarios.md +1 -1
- package/dist/skill/references/operations/hosted-automation-user-catalog.md +9 -7
- package/dist/skill/references/operations/hosted-automation-yandex.md +104 -34
- package/dist/skill/scripts/install.ps1 +1 -1
- package/dist/skill/scripts/install.sh +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ siluzan-tso init -d /path/to/skills # 写入自定义目录
|
|
|
51
51
|
siluzan-tso init --force # 强制覆盖已存在文件
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
> **注意**:当前为测试版(1.1.48-beta.
|
|
54
|
+
> **注意**:当前为测试版(1.1.48-beta.9),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
|
|
55
55
|
|
|
56
56
|
| 助手 | 建议 `--ai` |
|
|
57
57
|
| ----------------------- | ------------------------------------ |
|
package/dist/index.js
CHANGED
|
@@ -103520,8 +103520,8 @@ var init_batch_runner = __esm({
|
|
|
103520
103520
|
shouldDowngrade(now = Date.now()) {
|
|
103521
103521
|
if (this.window.length < this.opts.windowSize) return false;
|
|
103522
103522
|
if (now - this.lastDowngradeAt < this.opts.cooldownMs) return false;
|
|
103523
|
-
const
|
|
103524
|
-
const rate =
|
|
103523
|
+
const fail4 = this.window.filter((s) => !s).length;
|
|
103524
|
+
const rate = fail4 / this.window.length;
|
|
103525
103525
|
if (rate >= this.opts.errorRateThreshold) {
|
|
103526
103526
|
this.lastDowngradeAt = now;
|
|
103527
103527
|
this.window.length = 0;
|
|
@@ -123849,9 +123849,9 @@ function xfXml(x) {
|
|
|
123849
123849
|
function stylesXml(reg) {
|
|
123850
123850
|
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><fonts count="${reg.fonts.length}">${reg.fonts.map(fontXml).join("")}</fonts><fills count="${reg.fills.length}">${reg.fills.map(fillXml).join("")}</fills><borders count="${reg.borders.length}">${reg.borders.map(borderXml).join("")}</borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="${reg.xfs.length}">${reg.xfs.map(xfXml).join("")}</cellXfs><cellStyles count="1"><cellStyle name="\u5E38\u89C4" xfId="0" builtinId="0"/></cellStyles></styleSheet>`;
|
|
123851
123851
|
}
|
|
123852
|
-
function cellXml(ref,
|
|
123853
|
-
if (
|
|
123854
|
-
const { value, styleId } =
|
|
123852
|
+
function cellXml(ref, cell3) {
|
|
123853
|
+
if (cell3 == null) return "";
|
|
123854
|
+
const { value, styleId } = cell3;
|
|
123855
123855
|
const sAttr = styleId ? ` s="${styleId}"` : "";
|
|
123856
123856
|
if (value == null || value === "") {
|
|
123857
123857
|
return styleId ? `<c r="${ref}"${sAttr}/>` : "";
|
|
@@ -123866,7 +123866,7 @@ function sheetXml(sheet) {
|
|
|
123866
123866
|
const rowsXml = sheet.rows.map((row, i) => {
|
|
123867
123867
|
const r = i + 1;
|
|
123868
123868
|
const htAttr = row.height ? ` ht="${row.height}" customHeight="1"` : "";
|
|
123869
|
-
const cells = row.cells.map((
|
|
123869
|
+
const cells = row.cells.map((cell3, cIdx) => cellXml(`${colLetter(cIdx)}${r}`, cell3)).join("");
|
|
123870
123870
|
return `<row r="${r}"${htAttr}>${cells}</row>`;
|
|
123871
123871
|
}).join("");
|
|
123872
123872
|
const mergesXml = sheet.merges.length ? `<mergeCells count="${sheet.merges.length}">${sheet.merges.map((m) => `<mergeCell ref="${m}"/>`).join("")}</mergeCells>` : "";
|
|
@@ -133577,10 +133577,10 @@ function estimateColWidths(rows) {
|
|
|
133577
133577
|
const colCount = rows.reduce((max, row) => Math.max(max, row.length), 0);
|
|
133578
133578
|
const widths = new Array(colCount).fill(MIN_COL_WIDTH);
|
|
133579
133579
|
for (const row of rows) {
|
|
133580
|
-
row.forEach((
|
|
133581
|
-
if (
|
|
133580
|
+
row.forEach((cell3, idx) => {
|
|
133581
|
+
if (cell3 == null) return;
|
|
133582
133582
|
const longestLine = Math.max(
|
|
133583
|
-
...String(
|
|
133583
|
+
...String(cell3).split("\n").map((l) => l.length)
|
|
133584
133584
|
);
|
|
133585
133585
|
const width = Math.min(MAX_COL_WIDTH, Math.max(MIN_COL_WIDTH, Math.ceil(longestLine * 1.3)));
|
|
133586
133586
|
if (width > widths[idx]) widths[idx] = width;
|
|
@@ -139411,7 +139411,472 @@ async function runYandexAnalysisRender(opts) {
|
|
|
139411
139411
|
console.log("\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00 HTML \u6587\u4EF6\u5373\u53EF\u67E5\u770B\u5B8C\u6574\u7AE0\u8282\uFF08\u6837\u5F0F\u5BF9\u9F50\u5F00\u53D1\u6837\u4F8B\uFF09\u3002\n");
|
|
139412
139412
|
}
|
|
139413
139413
|
|
|
139414
|
+
// src/commands/yandex-analysis/entities.ts
|
|
139415
|
+
init_auth();
|
|
139416
|
+
init_cli_json_snapshot();
|
|
139417
|
+
init_cli_table();
|
|
139418
|
+
|
|
139419
|
+
// src/commands/yandex-analysis/yandex-api.ts
|
|
139420
|
+
init_auth();
|
|
139421
|
+
var YANDEX_AD_STATUSES = [
|
|
139422
|
+
"DRAFT",
|
|
139423
|
+
"MODERATION",
|
|
139424
|
+
"PREACCEPTED",
|
|
139425
|
+
"ACCEPTED",
|
|
139426
|
+
"REJECTED",
|
|
139427
|
+
"UNKNOWN"
|
|
139428
|
+
];
|
|
139429
|
+
var YANDEX_INSIGHTS_LEVELS = [
|
|
139430
|
+
"daily",
|
|
139431
|
+
"geo",
|
|
139432
|
+
"devices",
|
|
139433
|
+
"keywords",
|
|
139434
|
+
"campaigns",
|
|
139435
|
+
"adgroups",
|
|
139436
|
+
"ads"
|
|
139437
|
+
];
|
|
139438
|
+
var YANDEX_PATH_CAPS = {
|
|
139439
|
+
overview: {},
|
|
139440
|
+
daily: {},
|
|
139441
|
+
campaigns: { limit: true, timeIncrement: true, network: true },
|
|
139442
|
+
adgroups: { limit: true, timeIncrement: true, campaignId: true },
|
|
139443
|
+
ads: { limit: true, timeIncrement: true, status: true, campaignId: true, adGroupId: true },
|
|
139444
|
+
keywords: { limit: true },
|
|
139445
|
+
geo: { limit: true, network: true },
|
|
139446
|
+
devices: { network: true }
|
|
139447
|
+
};
|
|
139448
|
+
function localYmd(d = /* @__PURE__ */ new Date()) {
|
|
139449
|
+
const y = d.getFullYear();
|
|
139450
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
139451
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
139452
|
+
return `${y}-${m}-${day}`;
|
|
139453
|
+
}
|
|
139454
|
+
function parseYandexTimeIncrement(raw) {
|
|
139455
|
+
if (raw == null || String(raw).trim() === "") return void 0;
|
|
139456
|
+
const t = String(raw).trim();
|
|
139457
|
+
if (t !== "1") {
|
|
139458
|
+
throw new Error("--time-increment \u53EA\u5141\u8BB8 1\uFF08\u6309\u65E5\uFF09\uFF1B\u4E0D\u4F20=\u533A\u95F4\u6C47\u603B\u3002Direct \u6CA1\u6709\u5C0F\u65F6\u7EF4\u5EA6\u3002");
|
|
139459
|
+
}
|
|
139460
|
+
return 1;
|
|
139461
|
+
}
|
|
139462
|
+
function parseYandexNetwork(raw) {
|
|
139463
|
+
if (raw == null || String(raw).trim() === "") return void 0;
|
|
139464
|
+
const t = String(raw).trim().toUpperCase();
|
|
139465
|
+
if (t !== "SEARCH" && t !== "ALL") {
|
|
139466
|
+
throw new Error(
|
|
139467
|
+
"--network \u53EA\u5141\u8BB8 SEARCH \u6216 ALL\uFF08\u9ED8\u8BA4 SEARCH\uFF1BALL=\u5168\u7F51\u4E00\u884C\u5408\u8BA1\uFF0C\u884C\u5185 network \u4E3A null\uFF09\u3002"
|
|
139468
|
+
);
|
|
139469
|
+
}
|
|
139470
|
+
return t;
|
|
139471
|
+
}
|
|
139472
|
+
function parseYandexAdStatus(raw) {
|
|
139473
|
+
if (raw == null || String(raw).trim() === "") return void 0;
|
|
139474
|
+
const parts = String(raw).split(",").map((x) => x.trim().toUpperCase()).filter(Boolean);
|
|
139475
|
+
if (parts.length === 0) return void 0;
|
|
139476
|
+
const unknown = parts.filter((p) => !YANDEX_AD_STATUSES.includes(p));
|
|
139477
|
+
if (unknown.length > 0) {
|
|
139478
|
+
throw new Error(
|
|
139479
|
+
`--status \u975E\u6CD5\u503C\uFF1A${unknown.join(", ")}\u3002\u5408\u6CD5\uFF1A${YANDEX_AD_STATUSES.join(", ")}\u3002`
|
|
139480
|
+
);
|
|
139481
|
+
}
|
|
139482
|
+
return [...new Set(parts)].join(",");
|
|
139483
|
+
}
|
|
139484
|
+
function parseYandexInsightsLevel(raw) {
|
|
139485
|
+
const t = raw.trim();
|
|
139486
|
+
if (!YANDEX_INSIGHTS_LEVELS.includes(t)) {
|
|
139487
|
+
throw new Error(
|
|
139488
|
+
`--level \u53EA\u5141\u8BB8 ${YANDEX_INSIGHTS_LEVELS.join(" / ")}\uFF08daily/geo/devices/keywords \u6216\u4E0E\u5B9E\u4F53\u5B50\u547D\u4EE4\u540C\u53E3\u5F84\u7684 campaigns/adgroups/ads\uFF09\u3002`
|
|
139489
|
+
);
|
|
139490
|
+
}
|
|
139491
|
+
return t;
|
|
139492
|
+
}
|
|
139493
|
+
function optionalId(raw) {
|
|
139494
|
+
const t = raw?.trim();
|
|
139495
|
+
return t ? t : void 0;
|
|
139496
|
+
}
|
|
139497
|
+
function insightsLevelToPath(level) {
|
|
139498
|
+
return level;
|
|
139499
|
+
}
|
|
139500
|
+
function assertYandexAnalysisQuery(path49, query) {
|
|
139501
|
+
const caps = YANDEX_PATH_CAPS[path49];
|
|
139502
|
+
if (query.timeIncrement != null && !caps.timeIncrement) {
|
|
139503
|
+
throw new Error(`--time-increment \u4E0D\u80FD\u7528\u4E8E /${path49}\uFF08\u4EC5 campaigns / adgroups / ads\uFF09\u3002`);
|
|
139504
|
+
}
|
|
139505
|
+
if (query.network != null && !caps.network) {
|
|
139506
|
+
throw new Error(`--network \u4E0D\u80FD\u7528\u4E8E /${path49}\uFF08\u4EC5 campaigns / geo / devices\uFF09\u3002`);
|
|
139507
|
+
}
|
|
139508
|
+
if (query.status != null && !caps.status) {
|
|
139509
|
+
throw new Error(`--status \u4EC5\u7528\u4E8E /ads\uFF08\u62D2\u5BA1/\u5BA1\u6838\u6001\u8D70\u7ED3\u6784\u67E5\u8BE2\uFF0C\u884C\u5185 spend \u4E3A 0\uFF09\u3002`);
|
|
139510
|
+
}
|
|
139511
|
+
if (query.campaignId != null && !caps.campaignId) {
|
|
139512
|
+
throw new Error(`--campaign-id \u4EC5\u7528\u4E8E /adgroups \u4E0E /ads\u3002`);
|
|
139513
|
+
}
|
|
139514
|
+
if (query.adGroupId != null && !caps.adGroupId) {
|
|
139515
|
+
throw new Error(`--adgroup-id \u4EC5\u7528\u4E8E /ads\u3002`);
|
|
139516
|
+
}
|
|
139517
|
+
if (query.status != null && query.timeIncrement != null) {
|
|
139518
|
+
throw new Error(
|
|
139519
|
+
"--status \u4E0E --time-increment \u4E0D\u80FD\u540C\u65F6\u4F20\uFF08\u7F51\u5173 400\uFF09\u3002\u62D2\u5BA1\u7528\u533A\u95F4\u6C47\u603B\uFF0C\u4E0D\u8981\u52A0\u6309\u65E5\u3002"
|
|
139520
|
+
);
|
|
139521
|
+
}
|
|
139522
|
+
if (query.limit != null && !caps.limit) {
|
|
139523
|
+
throw new Error(`--limit \u4E0D\u80FD\u7528\u4E8E /${path49}\uFF08overview / daily / devices \u65E0\u6B64\u53C2\u6570\uFF09\u3002`);
|
|
139524
|
+
}
|
|
139525
|
+
}
|
|
139526
|
+
function buildYandexAnalysisSearchParams(path49, query) {
|
|
139527
|
+
assertYandexAnalysisQuery(path49, query);
|
|
139528
|
+
const caps = YANDEX_PATH_CAPS[path49];
|
|
139529
|
+
const params = new URLSearchParams({
|
|
139530
|
+
account: query.account,
|
|
139531
|
+
start: query.start,
|
|
139532
|
+
end: query.end
|
|
139533
|
+
});
|
|
139534
|
+
if (caps.limit && query.limit != null) {
|
|
139535
|
+
params.set("limit", String(resolveYandexLimit(query.limit)));
|
|
139536
|
+
}
|
|
139537
|
+
if (caps.timeIncrement && query.timeIncrement === 1) {
|
|
139538
|
+
params.set("timeIncrement", "1");
|
|
139539
|
+
}
|
|
139540
|
+
if (caps.network && query.network) {
|
|
139541
|
+
params.set("network", query.network);
|
|
139542
|
+
}
|
|
139543
|
+
if (caps.status && query.status) {
|
|
139544
|
+
params.set("status", query.status);
|
|
139545
|
+
}
|
|
139546
|
+
if (caps.campaignId && query.campaignId) {
|
|
139547
|
+
params.set("campaignId", query.campaignId);
|
|
139548
|
+
}
|
|
139549
|
+
if (caps.adGroupId && query.adGroupId) {
|
|
139550
|
+
params.set("adGroupId", query.adGroupId);
|
|
139551
|
+
}
|
|
139552
|
+
return params;
|
|
139553
|
+
}
|
|
139554
|
+
async function fetchYandexAnalysisPath(config, path49, query, verbose) {
|
|
139555
|
+
const yandexApiUrl = requireYandexApi(config);
|
|
139556
|
+
const params = buildYandexAnalysisSearchParams(path49, query);
|
|
139557
|
+
const url = analysisUrl(yandexApiUrl, path49, params.toString());
|
|
139558
|
+
return apiFetch2(url, config, {}, verbose);
|
|
139559
|
+
}
|
|
139560
|
+
function unwrapYandexItems(raw) {
|
|
139561
|
+
if (raw && typeof raw === "object" && Array.isArray(raw.items)) {
|
|
139562
|
+
return raw.items;
|
|
139563
|
+
}
|
|
139564
|
+
return [];
|
|
139565
|
+
}
|
|
139566
|
+
function asRecord31(raw) {
|
|
139567
|
+
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
139568
|
+
}
|
|
139569
|
+
|
|
139570
|
+
// src/commands/yandex-analysis/entities.ts
|
|
139571
|
+
function fail3(label, err) {
|
|
139572
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
139573
|
+
console.error(`
|
|
139574
|
+
\u274C ${label}\uFF1A${msg}
|
|
139575
|
+
`);
|
|
139576
|
+
process.exit(1);
|
|
139577
|
+
}
|
|
139578
|
+
function cell2(value) {
|
|
139579
|
+
if (value == null || value === "") return "";
|
|
139580
|
+
if (Array.isArray(value)) return value.map((x) => String(x)).join(" | ");
|
|
139581
|
+
return String(value);
|
|
139582
|
+
}
|
|
139583
|
+
function resolveRange(start, end) {
|
|
139584
|
+
if (!start && !end) {
|
|
139585
|
+
const today = localYmd();
|
|
139586
|
+
return resolveYandexDateRange(today, today);
|
|
139587
|
+
}
|
|
139588
|
+
return resolveYandexDateRange(start, end);
|
|
139589
|
+
}
|
|
139590
|
+
function parseCommonFlags(opts) {
|
|
139591
|
+
return {
|
|
139592
|
+
timeIncrement: parseYandexTimeIncrement(opts.timeIncrement),
|
|
139593
|
+
network: parseYandexNetwork(opts.network),
|
|
139594
|
+
status: parseYandexAdStatus(opts.status),
|
|
139595
|
+
campaignId: optionalId(opts.campaignId),
|
|
139596
|
+
adGroupId: optionalId(opts.adGroupId)
|
|
139597
|
+
};
|
|
139598
|
+
}
|
|
139599
|
+
async function emitOrTable(opts, args) {
|
|
139600
|
+
if (await emitCliJsonOrSnapshot(opts, {
|
|
139601
|
+
section: args.section,
|
|
139602
|
+
commandLabel: args.commandLabel,
|
|
139603
|
+
commandHint: args.accountId,
|
|
139604
|
+
payload: args.payload,
|
|
139605
|
+
idSuffix: args.accountId
|
|
139606
|
+
})) {
|
|
139607
|
+
return;
|
|
139608
|
+
}
|
|
139609
|
+
console.log(`
|
|
139610
|
+
${args.title}
|
|
139611
|
+
`);
|
|
139612
|
+
if (args.rows.length === 0) {
|
|
139613
|
+
console.log(` ${args.empty}
|
|
139614
|
+
`);
|
|
139615
|
+
return;
|
|
139616
|
+
}
|
|
139617
|
+
printCliTable(args.rows, args.columns);
|
|
139618
|
+
console.log(` ${args.footnote}
|
|
139619
|
+
`);
|
|
139620
|
+
}
|
|
139621
|
+
async function fetchPath(opts, path49, extra) {
|
|
139622
|
+
const accountId = assertYandexAccountId(opts.account);
|
|
139623
|
+
const { startDate, endDate } = resolveRange(opts.start, opts.end);
|
|
139624
|
+
const config = loadConfig(opts.token);
|
|
139625
|
+
const raw = await fetchYandexAnalysisPath(
|
|
139626
|
+
config,
|
|
139627
|
+
path49,
|
|
139628
|
+
{
|
|
139629
|
+
account: accountId,
|
|
139630
|
+
start: startDate,
|
|
139631
|
+
end: endDate,
|
|
139632
|
+
...extra
|
|
139633
|
+
},
|
|
139634
|
+
!!opts.verbose
|
|
139635
|
+
);
|
|
139636
|
+
return { accountId, startDate, endDate, raw };
|
|
139637
|
+
}
|
|
139638
|
+
async function runYandexAccountStatus(opts) {
|
|
139639
|
+
let result;
|
|
139640
|
+
try {
|
|
139641
|
+
result = await fetchPath(opts, "overview", {});
|
|
139642
|
+
} catch (err) {
|
|
139643
|
+
fail3("\u67E5\u8BE2 Yandex \u8D26\u6237\u603B\u89C8\u5931\u8D25", err);
|
|
139644
|
+
}
|
|
139645
|
+
const row = asRecord31(result.raw);
|
|
139646
|
+
await emitOrTable(opts, {
|
|
139647
|
+
section: "yandex-account-status",
|
|
139648
|
+
commandLabel: "yandex-analysis account-status",
|
|
139649
|
+
accountId: result.accountId,
|
|
139650
|
+
payload: result.raw,
|
|
139651
|
+
title: `Yandex \u8D26\u6237\u603B\u89C8\uFF08${result.accountId}\uFF0C${result.startDate}~${result.endDate}\uFF09`,
|
|
139652
|
+
empty: "\u65E0\u603B\u89C8\u6570\u636E\u3002",
|
|
139653
|
+
footnote: "archived=true \u8868\u793A\u5E7F\u544A\u4E3B\u5DF2\u5F52\u6863\uFF08inactive\uFF09\u3002\u5B98\u65B9\u65E0\u5C01\u6237\u72B6\u6001\u4E0E\u539F\u56E0\u3002\u4F59\u989D\u770B balance / currency\uFF1B\u5B98\u65B9\u65E0\u72EC\u7ACB\u989D\u5EA6\u3002",
|
|
139654
|
+
rows: [
|
|
139655
|
+
{
|
|
139656
|
+
account: cell2(row.account ?? result.accountId),
|
|
139657
|
+
archived: cell2(row.archived),
|
|
139658
|
+
balance: cell2(row.balance),
|
|
139659
|
+
currency: cell2(row.currency),
|
|
139660
|
+
spend: cell2(row.spend),
|
|
139661
|
+
conversions: cell2(row.conversions)
|
|
139662
|
+
}
|
|
139663
|
+
],
|
|
139664
|
+
columns: [
|
|
139665
|
+
{ key: "account", header: "\u8D26\u6237" },
|
|
139666
|
+
{ key: "archived", header: "archived" },
|
|
139667
|
+
{ key: "balance", header: "\u4F59\u989D" },
|
|
139668
|
+
{ key: "currency", header: "\u5E01\u79CD" },
|
|
139669
|
+
{ key: "spend", header: "\u533A\u95F4\u82B1\u8D39" },
|
|
139670
|
+
{ key: "conversions", header: "\u8F6C\u5316" }
|
|
139671
|
+
]
|
|
139672
|
+
});
|
|
139673
|
+
}
|
|
139674
|
+
async function runYandexCampaignEntities(opts) {
|
|
139675
|
+
let flags;
|
|
139676
|
+
let result;
|
|
139677
|
+
try {
|
|
139678
|
+
flags = parseCommonFlags(opts);
|
|
139679
|
+
result = await fetchPath(opts, "campaigns", {
|
|
139680
|
+
limit: opts.limit,
|
|
139681
|
+
timeIncrement: flags.timeIncrement,
|
|
139682
|
+
network: flags.network
|
|
139683
|
+
});
|
|
139684
|
+
} catch (err) {
|
|
139685
|
+
fail3("\u67E5\u8BE2 Yandex \u7CFB\u5217\u5931\u8D25", err);
|
|
139686
|
+
}
|
|
139687
|
+
const items2 = unwrapYandexItems(result.raw);
|
|
139688
|
+
await emitOrTable(opts, {
|
|
139689
|
+
section: "yandex-campaign-entities",
|
|
139690
|
+
commandLabel: "yandex-analysis campaign-entities",
|
|
139691
|
+
accountId: result.accountId,
|
|
139692
|
+
payload: result.raw,
|
|
139693
|
+
title: `Yandex \u5E7F\u544A\u7CFB\u5217\uFF08${result.accountId}\uFF0C${result.startDate}~${result.endDate}\uFF0C\u5171 ${items2.length} \u884C\uFF09`,
|
|
139694
|
+
empty: "\u5F53\u524D\u8FC7\u6EE4\u4E0B\u65E0\u7CFB\u5217\u884C\uFF08\u9ED8\u8BA4\u53EA\u51FA\u73B0\u6709\u6D88\u8017\u7684\u5BF9\u8C61\uFF09\u3002",
|
|
139695
|
+
footnote: "\u9ED8\u8BA4 SEARCH\u3002\u5168\u6E20\u9053\u82B1\u8D39\u987B --network ALL\uFF08\u884C\u5185 network \u4E3A null\uFF09\u3002budget \u662F\u7CFB\u5217\u65E5\u9884\u7B97\uFF0C\u81EA\u52A8\u7B56\u7565\u5E38\u4E3A\u7A7A\uFF1B\u5BF9\u7167 weeklyBudget\u3002\u81EA\u52A8\u51FA\u4EF7\u4E0D\u8981\u5F53\u624B\u52A8 CPC \u6539\u4EF7\u3002",
|
|
139696
|
+
rows: items2.map((r) => ({
|
|
139697
|
+
campaignId: cell2(r.campaignId),
|
|
139698
|
+
name: cell2(r.campaignName),
|
|
139699
|
+
spend: cell2(r.spend),
|
|
139700
|
+
budget: cell2(r.budget),
|
|
139701
|
+
weeklyBudget: cell2(r.weeklyBudget),
|
|
139702
|
+
strategy: cell2(r.strategy),
|
|
139703
|
+
targetCpa: cell2(r.targetCpa),
|
|
139704
|
+
status: cell2(r.status),
|
|
139705
|
+
date: cell2(r.date)
|
|
139706
|
+
})),
|
|
139707
|
+
columns: [
|
|
139708
|
+
{ key: "campaignId", header: "\u7CFB\u5217ID" },
|
|
139709
|
+
{ key: "name", header: "\u540D\u79F0" },
|
|
139710
|
+
{ key: "spend", header: "spend" },
|
|
139711
|
+
{ key: "budget", header: "\u65E5\u9884\u7B97" },
|
|
139712
|
+
{ key: "weeklyBudget", header: "\u5468\u9884\u7B97" },
|
|
139713
|
+
{ key: "strategy", header: "\u7B56\u7565" },
|
|
139714
|
+
{ key: "targetCpa", header: "\u76EE\u6807CPA" },
|
|
139715
|
+
{ key: "status", header: "\u72B6\u6001" },
|
|
139716
|
+
{ key: "date", header: "date" }
|
|
139717
|
+
]
|
|
139718
|
+
});
|
|
139719
|
+
}
|
|
139720
|
+
async function runYandexAdGroupEntities(opts) {
|
|
139721
|
+
let flags;
|
|
139722
|
+
let result;
|
|
139723
|
+
try {
|
|
139724
|
+
flags = parseCommonFlags(opts);
|
|
139725
|
+
result = await fetchPath(opts, "adgroups", {
|
|
139726
|
+
limit: opts.limit,
|
|
139727
|
+
timeIncrement: flags.timeIncrement,
|
|
139728
|
+
campaignId: flags.campaignId
|
|
139729
|
+
});
|
|
139730
|
+
} catch (err) {
|
|
139731
|
+
fail3("\u67E5\u8BE2 Yandex \u5E7F\u544A\u7EC4\u5931\u8D25", err);
|
|
139732
|
+
}
|
|
139733
|
+
const items2 = unwrapYandexItems(result.raw);
|
|
139734
|
+
await emitOrTable(opts, {
|
|
139735
|
+
section: "yandex-adgroup-entities",
|
|
139736
|
+
commandLabel: "yandex-analysis adgroup-entities",
|
|
139737
|
+
accountId: result.accountId,
|
|
139738
|
+
payload: result.raw,
|
|
139739
|
+
title: `Yandex \u5E7F\u544A\u7EC4\uFF08${result.accountId}\uFF0C${result.startDate}~${result.endDate}\uFF0C\u5171 ${items2.length} \u884C\uFF09`,
|
|
139740
|
+
empty: "\u5F53\u524D\u8FC7\u6EE4\u4E0B\u65E0\u5E7F\u544A\u7EC4\u884C\uFF08\u9ED8\u8BA4\u53EA\u51FA\u73B0\u6709\u6D88\u8017\u7684\u5BF9\u8C61\uFF09\u3002",
|
|
139741
|
+
footnote: "campaignTargetCpa \u662F\u7CFB\u5217\u76EE\u6807\uFF08\u53EA\u53D6 Search\uFF09\uFF0C\u4E0D\u662F\u7EC4\u7EA7\u76EE\u6807\u4EF7\u3002conversions<=0 \u65F6\u4E0D\u8981\u5224 CPA\u3002\u672C\u6279\u6CA1\u6709\u6539\u4EF7\u63A5\u53E3\u3002",
|
|
139742
|
+
rows: items2.map((r) => ({
|
|
139743
|
+
adGroupId: cell2(r.adGroupId),
|
|
139744
|
+
name: cell2(r.adGroupName),
|
|
139745
|
+
campaignId: cell2(r.campaignId),
|
|
139746
|
+
spend: cell2(r.spend),
|
|
139747
|
+
conversions: cell2(r.conversions),
|
|
139748
|
+
cpa: cell2(r.costPerConversion),
|
|
139749
|
+
targetCpa: cell2(r.campaignTargetCpa),
|
|
139750
|
+
weeklyBudget: cell2(r.campaignWeeklyBudget),
|
|
139751
|
+
strategy: cell2(r.campaignStrategy),
|
|
139752
|
+
date: cell2(r.date)
|
|
139753
|
+
})),
|
|
139754
|
+
columns: [
|
|
139755
|
+
{ key: "adGroupId", header: "\u7EC4ID" },
|
|
139756
|
+
{ key: "name", header: "\u540D\u79F0" },
|
|
139757
|
+
{ key: "campaignId", header: "\u7CFB\u5217ID" },
|
|
139758
|
+
{ key: "spend", header: "spend" },
|
|
139759
|
+
{ key: "conversions", header: "\u8F6C\u5316" },
|
|
139760
|
+
{ key: "cpa", header: "\u5B9E\u9645CPA" },
|
|
139761
|
+
{ key: "targetCpa", header: "\u7CFB\u5217\u76EE\u6807CPA" },
|
|
139762
|
+
{ key: "weeklyBudget", header: "\u7CFB\u5217\u5468\u9884\u7B97" },
|
|
139763
|
+
{ key: "strategy", header: "\u7B56\u7565" },
|
|
139764
|
+
{ key: "date", header: "date" }
|
|
139765
|
+
]
|
|
139766
|
+
});
|
|
139767
|
+
}
|
|
139768
|
+
async function runYandexAdEntities(opts) {
|
|
139769
|
+
let flags;
|
|
139770
|
+
let result;
|
|
139771
|
+
try {
|
|
139772
|
+
flags = parseCommonFlags(opts);
|
|
139773
|
+
result = await fetchPath(opts, "ads", {
|
|
139774
|
+
limit: opts.limit,
|
|
139775
|
+
timeIncrement: flags.timeIncrement,
|
|
139776
|
+
status: flags.status,
|
|
139777
|
+
campaignId: flags.campaignId,
|
|
139778
|
+
adGroupId: flags.adGroupId
|
|
139779
|
+
});
|
|
139780
|
+
} catch (err) {
|
|
139781
|
+
fail3("\u67E5\u8BE2 Yandex \u5E7F\u544A\u5931\u8D25", err);
|
|
139782
|
+
}
|
|
139783
|
+
const items2 = unwrapYandexItems(result.raw);
|
|
139784
|
+
const filtered = flags.status != null;
|
|
139785
|
+
await emitOrTable(opts, {
|
|
139786
|
+
section: "yandex-ad-entities",
|
|
139787
|
+
commandLabel: "yandex-analysis ad-entities",
|
|
139788
|
+
accountId: result.accountId,
|
|
139789
|
+
payload: result.raw,
|
|
139790
|
+
title: `Yandex \u5E7F\u544A\uFF08${result.accountId}\uFF0C${result.startDate}~${result.endDate}\uFF0C\u5171 ${items2.length} \u884C\uFF09`,
|
|
139791
|
+
empty: filtered ? "\u5F53\u524D\u5BA1\u6838\u8FC7\u6EE4\u4E0B\u65E0\u8BB0\u5F55\uFF08\u7A7A\u5217\u8868=\u6210\u529F\u4E14\u6CA1\u6709\u672A\u5F52\u6863\u5339\u914D\u9879\uFF09\u3002" : "\u5F53\u524D\u8FC7\u6EE4\u4E0B\u65E0\u5E7F\u544A\u884C\uFF08\u9ED8\u8BA4\u53EA\u51FA\u73B0\u533A\u95F4\u5185\u6709\u6D88\u8017\u7684\u5E7F\u544A\uFF09\u3002",
|
|
139792
|
+
footnote: "landingUrls \u7A7A\u6570\u7EC4\u4E0D\u662F\u6B7B\u94FE\uFF08Dynamic/Smart/Shopping \u6216\u4EC5 TurboPage \u5E38\u4E3A []\uFF09\u3002CLI \u4E0D\u63A2\u6D3B HTTP\u3002\u62D2\u5BA1\u7528 --status REJECTED\uFF08\u4E0E --time-increment \u4E92\u65A5\uFF1B\u5DF2\u5F52\u6863\u4E0D\u4F1A\u51FA\u73B0\uFF09\u3002",
|
|
139793
|
+
rows: items2.map((r) => ({
|
|
139794
|
+
adId: cell2(r.adId),
|
|
139795
|
+
campaignId: cell2(r.campaignId),
|
|
139796
|
+
adGroupId: cell2(r.adGroupId),
|
|
139797
|
+
spend: cell2(r.spend),
|
|
139798
|
+
conversions: cell2(r.conversions),
|
|
139799
|
+
ctr: cell2(r.ctr),
|
|
139800
|
+
roi: cell2(r.roi),
|
|
139801
|
+
status: cell2(r.status),
|
|
139802
|
+
landing: cell2(r.landingUrls)
|
|
139803
|
+
})),
|
|
139804
|
+
columns: [
|
|
139805
|
+
{ key: "adId", header: "\u5E7F\u544AID" },
|
|
139806
|
+
{ key: "campaignId", header: "\u7CFB\u5217ID" },
|
|
139807
|
+
{ key: "adGroupId", header: "\u7EC4ID" },
|
|
139808
|
+
{ key: "spend", header: "spend" },
|
|
139809
|
+
{ key: "conversions", header: "\u8F6C\u5316" },
|
|
139810
|
+
{ key: "ctr", header: "ctr" },
|
|
139811
|
+
{ key: "roi", header: "roi" },
|
|
139812
|
+
{ key: "status", header: "\u5BA1\u6838\u6001" },
|
|
139813
|
+
{ key: "landing", header: "\u843D\u5730\u9875" }
|
|
139814
|
+
]
|
|
139815
|
+
});
|
|
139816
|
+
}
|
|
139817
|
+
async function runYandexInsights(opts) {
|
|
139818
|
+
let level;
|
|
139819
|
+
let flags;
|
|
139820
|
+
let result;
|
|
139821
|
+
try {
|
|
139822
|
+
level = parseYandexInsightsLevel(opts.level);
|
|
139823
|
+
flags = parseCommonFlags(opts);
|
|
139824
|
+
result = await fetchPath(opts, insightsLevelToPath(level), {
|
|
139825
|
+
limit: opts.limit,
|
|
139826
|
+
timeIncrement: flags.timeIncrement,
|
|
139827
|
+
network: flags.network,
|
|
139828
|
+
status: flags.status,
|
|
139829
|
+
campaignId: flags.campaignId,
|
|
139830
|
+
adGroupId: flags.adGroupId
|
|
139831
|
+
});
|
|
139832
|
+
} catch (err) {
|
|
139833
|
+
fail3("\u67E5\u8BE2 Yandex insights \u5931\u8D25", err);
|
|
139834
|
+
}
|
|
139835
|
+
const items2 = unwrapYandexItems(result.raw);
|
|
139836
|
+
await emitOrTable(opts, {
|
|
139837
|
+
section: "yandex-insights",
|
|
139838
|
+
commandLabel: "yandex-analysis insights",
|
|
139839
|
+
accountId: result.accountId,
|
|
139840
|
+
payload: result.raw,
|
|
139841
|
+
title: `Yandex insights ${level}\uFF08${result.accountId}\uFF0C${result.startDate}~${result.endDate}\uFF0C\u5171 ${items2.length} \u884C\uFF09`,
|
|
139842
|
+
empty: "\u65E0\u62A5\u8868\u884C\uFF08\u9ED8\u8BA4\u53EA\u51FA\u73B0\u533A\u95F4\u5185\u6709\u6D88\u8017\u7684\u5BF9\u8C61\uFF09\u3002",
|
|
139843
|
+
footnote: "revenue \u662F\u6210\u4EA4\u989D PurchaseRevenue\uFF0C\u4E0D\u662F\u76EE\u6807\u8D4B\u503C\u3002roi=(\u6210\u4EA4\u989D\u2212\u82B1\u8D39)/\u82B1\u8D39\u3002geo/devices \u9ED8\u8BA4 SEARCH\uFF0C\u5168\u7F51\u987B --network ALL\u3002\u65E0\u5C0F\u65F6\u7EF4\u5EA6\u3002",
|
|
139844
|
+
rows: items2.map((r) => ({
|
|
139845
|
+
id: cell2(
|
|
139846
|
+
r.adId ?? r.adGroupId ?? r.campaignId ?? r.keywordId ?? r.regionName ?? r.device ?? r.date
|
|
139847
|
+
),
|
|
139848
|
+
name: cell2(
|
|
139849
|
+
r.adName ?? r.adGroupName ?? r.campaignName ?? r.keyword ?? r.regionName ?? r.device
|
|
139850
|
+
),
|
|
139851
|
+
spend: cell2(r.spend),
|
|
139852
|
+
conversions: cell2(r.conversions),
|
|
139853
|
+
ctr: cell2(r.ctr),
|
|
139854
|
+
roi: cell2(r.roi),
|
|
139855
|
+
date: cell2(r.date)
|
|
139856
|
+
})),
|
|
139857
|
+
columns: [
|
|
139858
|
+
{ key: "id", header: "\u5BF9\u8C61" },
|
|
139859
|
+
{ key: "name", header: "\u540D\u79F0" },
|
|
139860
|
+
{ key: "spend", header: "spend" },
|
|
139861
|
+
{ key: "conversions", header: "\u8F6C\u5316" },
|
|
139862
|
+
{ key: "ctr", header: "ctr" },
|
|
139863
|
+
{ key: "roi", header: "roi" },
|
|
139864
|
+
{ key: "date", header: "date" }
|
|
139865
|
+
]
|
|
139866
|
+
});
|
|
139867
|
+
}
|
|
139868
|
+
|
|
139414
139869
|
// src/commands/yandex-analysis/register-cli.ts
|
|
139870
|
+
var ACCOUNT_OPTION4 = [
|
|
139871
|
+
"-a, --account <id>",
|
|
139872
|
+
"Yandex Client-Login / mediaCustomerId\uFF08\u5982 porg-xxx\uFF0C\u4E0E list-accounts -m Yandex \u4E00\u81F4\uFF09"
|
|
139873
|
+
];
|
|
139874
|
+
var JSON_OUT_OPTION_DESC4 = "\u843D\u76D8\uFF08\u76EE\u5F55\u6216 *.json \u6587\u4EF6\u8DEF\u5F84\uFF09\u5E76\u66F4\u65B0 cli-manifest[-<\u67E5\u8BE2id>].json\uFF1Bstdout \u4E00\u884C\u6458\u8981 JSON";
|
|
139875
|
+
var START_OPTION = [
|
|
139876
|
+
"--start <date>",
|
|
139877
|
+
"\u5F00\u59CB\u65E5\u671F YYYY-MM-DD\uFF08\u4E0E --end \u540C\u4F20\u6216\u540C\u7701\u7565\uFF1B\u7701\u7565=\u5F53\u5929\uFF09"
|
|
139878
|
+
];
|
|
139879
|
+
var END_OPTION = ["--end <date>", "\u7ED3\u675F\u65E5\u671F YYYY-MM-DD"];
|
|
139415
139880
|
function registerBatchCommand4(sectionHelp, aliasHelp) {
|
|
139416
139881
|
return new Command5("run").description("\u6279\u91CF\u62C9\u53D6 YandexAPI /yandex-analysis \u5404\u7EF4\u5EA6\uFF08\u7701\u7565\u5B50\u547D\u4EE4\u540D\u65F6\u9ED8\u8BA4\u6267\u884C\u672C\u547D\u4EE4\uFF09").requiredOption(
|
|
139417
139882
|
"-a, --account <id>",
|
|
@@ -139437,7 +139902,7 @@ function registerYandexAnalysisCommands(program2) {
|
|
|
139437
139902
|
const sectionHelp = YANDEX_SECTION_NAMES.join(", ");
|
|
139438
139903
|
const aliasHelp = Object.keys(YANDEX_SECTION_ALIASES).join(", ");
|
|
139439
139904
|
const root = program2.command("yandex-analysis").description(
|
|
139440
|
-
"Yandex \u8D26\u6237\u5206\u6790\uFF1A\u6279\u91CF\u62C9\u53D6 /yandex-analysis \
|
|
139905
|
+
"Yandex \u8D26\u6237\u5206\u6790\uFF1A\u6279\u91CF\u62C9\u53D6 /yandex-analysis \u5468\u671F\u62A5\u8868\uFF08\u9ED8\u8BA4 run\uFF09\u3001render HTML\uFF0C\u6216\u67E5\u8BE2\u8D26\u6237\u5F52\u6863/\u7CFB\u5217/\u7EC4/\u5E7F\u544A/insights\uFF08\u53EA\u8BFB\u8FD0\u8425\uFF1B\u672C\u6279\u4E0D\u80FD\u6682\u505C/\u6539\u4EF7/\u6539\u9884\u7B97\uFF09"
|
|
139441
139906
|
);
|
|
139442
139907
|
root.addCommand(registerBatchCommand4(sectionHelp, aliasHelp), { isDefault: true });
|
|
139443
139908
|
root.command("render").description(
|
|
@@ -139452,6 +139917,44 @@ function registerYandexAnalysisCommands(program2) {
|
|
|
139452
139917
|
out: opts.out
|
|
139453
139918
|
});
|
|
139454
139919
|
});
|
|
139920
|
+
root.command("account-status").description(
|
|
139921
|
+
"\u8D26\u6237\u5F52\u6863/\u4F59\u989D/\u533A\u95F4 KPI\uFF08GET /overview\uFF1Barchived=true \u4E3A\u5DF2\u5F52\u6863\uFF1B\u5B98\u65B9\u65E0\u5C01\u6237\u539F\u56E0\uFF1B\u7701\u7565\u65E5\u671F=\u5F53\u5929\uFF09"
|
|
139922
|
+
).requiredOption(...ACCOUNT_OPTION4).option(...START_OPTION).option(...END_OPTION).option("-t, --token <token>", "Auth Token").option("--json-out <path>", JSON_OUT_OPTION_DESC4).option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
|
|
139923
|
+
async (opts) => {
|
|
139924
|
+
await runYandexAccountStatus(opts);
|
|
139925
|
+
}
|
|
139926
|
+
);
|
|
139927
|
+
root.command("campaign-entities").description(
|
|
139928
|
+
"\u7CFB\u5217\u7EE9\u6548+\u9884\u7B97/\u7B56\u7565\uFF08GET /campaigns\uFF1Aspend/weeklyBudget/budget/strategy/targetCpa\uFF1B\u5168\u6E20\u9053\u82B1\u8D39\u987B --network ALL\uFF1B\u53EF --time-increment 1 \u6309\u65E5\uFF09"
|
|
139929
|
+
).requiredOption(...ACCOUNT_OPTION4).option(...START_OPTION).option(...END_OPTION).option("--time-increment <n>", "\u4F20 1 \u6309\u65E5\u5207\u5206\uFF1B\u4E0D\u4F20=\u533A\u95F4\u6C47\u603B\u3002Direct \u65E0\u5C0F\u65F6\u7EF4\u5EA6").option("--network <value>", "SEARCH\uFF08\u9ED8\u8BA4\uFF09\u6216 ALL\uFF08\u5168\u7F51\u4E00\u884C\u5408\u8BA1\uFF0C\u884C\u5185 network \u4E3A null\uFF09").option("--limit <n>", "\u6761\u6570\u4E0A\u9650\uFF08\u9ED8\u8BA4\u7F51\u5173 100\uFF0C\u6700\u5927 10000\uFF09", (v) => parseInt(v, 10)).option("-t, --token <token>", "Auth Token").option("--json-out <path>", JSON_OUT_OPTION_DESC4).option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
|
|
139930
|
+
async (opts) => {
|
|
139931
|
+
await runYandexCampaignEntities(opts);
|
|
139932
|
+
}
|
|
139933
|
+
);
|
|
139934
|
+
root.command("adgroup-entities").description(
|
|
139935
|
+
"\u5E7F\u544A\u7EC4\u7EE9\u6548+\u7CFB\u5217\u76EE\u6807 CPA/\u5468\u9884\u7B97\uFF08GET /adgroups\uFF1B\u9ED8\u8BA4\u5168\u7F51\uFF1BCPA \u98D9\u5347\u770B\u8FD1 3 \u65E5\u533A\u95F4\u6C47\u603B\uFF0C\u4E0D\u8981\u4F20 timeIncrement\uFF09"
|
|
139936
|
+
).requiredOption(...ACCOUNT_OPTION4).option(...START_OPTION).option(...END_OPTION).option("--time-increment <n>", "\u4F20 1 \u6309\u65E5\u5207\u5206\uFF1B\u4E0D\u4F20=\u533A\u95F4\u6C47\u603B").option("--campaign-id <id>", "\u53EA\u62C9\u8BE5\u7CFB\u5217\u4E0B\u7684\u7EC4").option("--limit <n>", "\u6761\u6570\u4E0A\u9650\uFF08\u9ED8\u8BA4\u7F51\u5173 100\uFF0C\u6700\u5927 10000\uFF09", (v) => parseInt(v, 10)).option("-t, --token <token>", "Auth Token").option("--json-out <path>", JSON_OUT_OPTION_DESC4).option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
|
|
139937
|
+
async (opts) => {
|
|
139938
|
+
await runYandexAdGroupEntities(opts);
|
|
139939
|
+
}
|
|
139940
|
+
);
|
|
139941
|
+
root.command("ad-entities").description(
|
|
139942
|
+
`\u5E7F\u544A\u7EE9\u6548+\u843D\u5730\u9875/\u62D2\u5BA1\uFF08GET /ads\uFF1B\u62D2\u5BA1\u4F20 --status REJECTED\uFF1B\u5408\u6CD5\uFF1A${YANDEX_AD_STATUSES.join(",")}\uFF1B\u4E0E --time-increment \u4E92\u65A5\uFF09`
|
|
139943
|
+
).requiredOption(...ACCOUNT_OPTION4).option(...START_OPTION).option(...END_OPTION).option("--time-increment <n>", "\u4F20 1 \u6309\u65E5\u5207\u5206\uFF1B\u4E0D\u4F20=\u533A\u95F4\u6C47\u603B\u3002\u4E0D\u8981\u548C --status \u540C\u65F6\u4F20").option(
|
|
139944
|
+
"--status <list>",
|
|
139945
|
+
"\u5BA1\u6838\u6001\u9017\u53F7\u5206\u9694\uFF0C\u5982 REJECTED \u6216 MODERATION,REJECTED\uFF1B\u5E26 status \u65F6\u4E0D\u62C9\u7EE9\u6548\uFF08spend=0\uFF09"
|
|
139946
|
+
).option("--campaign-id <id>", "\u53EA\u62C9\u8BE5\u7CFB\u5217\u4E0B\u7684\u5E7F\u544A").option("--adgroup-id <id>", "\u53EA\u62C9\u8BE5\u7EC4\u4E0B\u7684\u5E7F\u544A").option("--limit <n>", "\u6761\u6570\u4E0A\u9650\uFF08\u9ED8\u8BA4\u7F51\u5173 100\uFF0C\u6700\u5927 10000\uFF09", (v) => parseInt(v, 10)).option("-t, --token <token>", "Auth Token").option("--json-out <path>", JSON_OUT_OPTION_DESC4).option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
|
|
139947
|
+
async (opts) => {
|
|
139948
|
+
await runYandexAdEntities(opts);
|
|
139949
|
+
}
|
|
139950
|
+
);
|
|
139951
|
+
root.command("insights").description(
|
|
139952
|
+
"YandexAPI \u62A5\u8868\u5207\u7247\uFF08GET /daily|/geo|/devices|/keywords \u6216 campaigns/adgroups/ads\uFF1B\u53EF\u542B\u4ECA\u5929\uFF1B\u65E0\u5C0F\u65F6\u7EF4\u5EA6\u3002geo/devices \u5168\u7F51\u987B --network ALL\uFF09"
|
|
139953
|
+
).requiredOption(...ACCOUNT_OPTION4).requiredOption("--level <level>", YANDEX_INSIGHTS_LEVELS.join(" / ")).option(...START_OPTION).option(...END_OPTION).option("--time-increment <n>", "\u4EC5 campaigns/adgroups/ads\uFF1A\u4F20 1 \u6309\u65E5\uFF1B\u4E0D\u8981\u548C --status \u540C\u65F6\u4F20").option("--network <value>", "\u4EC5 campaigns/geo/devices\uFF1ASEARCH \u6216 ALL").option("--status <list>", "\u4EC5 --level ads\uFF1A\u5BA1\u6838\u6001\u8FC7\u6EE4").option("--campaign-id <id>", "\u4EC5 adgroups/ads").option("--adgroup-id <id>", "\u4EC5 ads").option("--limit <n>", "\u6709 limit \u7684 path\uFF1A\u9ED8\u8BA4\u7F51\u5173 100\uFF0C\u6700\u5927 10000", (v) => parseInt(v, 10)).option("-t, --token <token>", "Auth Token").option("--json-out <path>", JSON_OUT_OPTION_DESC4).option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
|
|
139954
|
+
async (opts) => {
|
|
139955
|
+
await runYandexInsights(opts);
|
|
139956
|
+
}
|
|
139957
|
+
);
|
|
139455
139958
|
}
|
|
139456
139959
|
|
|
139457
139960
|
// src/index.ts
|
package/dist/skill/SKILL.md
CHANGED
|
@@ -125,7 +125,7 @@ siluzan-tso -h
|
|
|
125
125
|
| 日/周巡检 | W12 | `references/core/workflows.md`(W12)+ `references/accounts/accounts-balance-stats.md` |
|
|
126
126
|
| 超预算熔断 / 空耗熔断(全户 Google) | — | `references/operations/guard.md`(`guard budget-circuit` / `guard zero-conv`;禁止逐户 for-loop) |
|
|
127
127
|
| Bing 自动化巡检(封禁/拒审/超预算/空耗预警) | — | `references/operations/hosted-automation-bing.md`(只读告警,不能自动暂停/改价) |
|
|
128
|
-
| Yandex
|
|
128
|
+
| Yandex 自动化巡检(归档/拒审/超预算/空耗预警) | — | `references/operations/hosted-automation-yandex.md`(只读告警,不能自动暂停/改价) |
|
|
129
129
|
| TikTok 自动化巡检(封禁/拒审/超预算/空耗预警) | — | `references/operations/hosted-automation-tiktok.md`(只读告警,不能自动暂停/改价) |
|
|
130
130
|
| Facebook / MetaAd 自动化巡检(封禁/拒审/超预算/空耗预警) | — | `references/operations/hosted-automation-facebook.md`(只读告警,不能自动暂停/改价) |
|
|
131
131
|
| 宿主编排 / 投放自控 / 异常监控 / 自动优化 | — | `references/operations/hosted-automation-user-catalog.md`(**仅当用户问自动化/巡检/熔断**;表内每行只 Read **一个** SOP;Google 熔断优先 guard.md;Bing/Yandex/TikTok/Facebook 走上四行) |
|
package/dist/skill/_meta.json
CHANGED
|
@@ -460,7 +460,7 @@ siluzan-tso bing-analysis run -a <mediaCustomerId> --json-out ./snap --sections
|
|
|
460
460
|
|
|
461
461
|
## Yandex 账户分析
|
|
462
462
|
|
|
463
|
-
>
|
|
463
|
+
> **自动化巡检步骤**(归档 / 拒审 / 落地页 / 当日超预算 / 空耗预警,只读告警):`references/operations/hosted-automation-yandex.md`。
|
|
464
464
|
>
|
|
465
465
|
> **网关**:直打 YandexAPI `{yandexApiUrl}/yandex-analysis/*`(从 TSO `apiBaseUrl` 推导:`tso-api-ci` → `yandexapi-ci.mysiluzan.com`;可用 `SILUZAN_YANDEX_API` 覆盖)。
|
|
466
466
|
>
|
|
@@ -498,6 +498,30 @@ siluzan-tso yandex-analysis render \
|
|
|
498
498
|
|
|
499
499
|
`search` / `campaigns` / `keywords` / `geo` / `devices` 在 Direct 侧过滤 `AdNetworkType=SEARCH`。无 Metrica / 写操作。报告模板:`report-templates/yandex-period-report.md`(8 个分析章节必写总结+建议;周趋势读落盘 `daily.weekly[]`,**禁止**自行按 `date` 聚周)。
|
|
500
500
|
|
|
501
|
+
### Yandex 只读运营(`yandex-analysis` 子命令,YandexAPI)
|
|
502
|
+
|
|
503
|
+
> 与上面 `run` 的周期报表不同。归档/余额、当日全网花费、组级 CPA、拒审、落地页、按日环比走以下子命令。省略 `--start/--end` 默认当天。金额已是账户币种小数。本批**不能**暂停 / 改价 / 改预算。
|
|
504
|
+
|
|
505
|
+
| 子命令 | 说明 |
|
|
506
|
+
| --- | --- |
|
|
507
|
+
| `account-status` | `GET /overview`:`archived` / `balance` / `currency`;官方无封户原因 |
|
|
508
|
+
| `campaign-entities` | `GET /campaigns`:`spend` / `weeklyBudget` / `budget` / `strategy` / `targetCpa`;全网加 `--network ALL`;按日加 `--time-increment 1` |
|
|
509
|
+
| `adgroup-entities` | `GET /adgroups`:组绩效 + `campaignTargetCpa` / `campaignWeeklyBudget`;默认全网 |
|
|
510
|
+
| `ad-entities` | `GET /ads`:落地页 `landingUrls`;拒审 `--status REJECTED`(与 `--time-increment` 互斥) |
|
|
511
|
+
| `insights` | `--level daily\|geo\|devices\|keywords\|campaigns\|adgroups\|ads`;geo/devices 全网须 `--network ALL` |
|
|
512
|
+
|
|
513
|
+
```bash
|
|
514
|
+
siluzan-tso yandex-analysis account-status -a <porg-xxx> --json-out ./snap-yandex
|
|
515
|
+
siluzan-tso yandex-analysis campaign-entities -a <porg-xxx> --json-out ./snap-yandex \
|
|
516
|
+
--start 2026-08-27 --end 2026-08-27 --time-increment 1 --network ALL
|
|
517
|
+
siluzan-tso yandex-analysis ad-entities -a <porg-xxx> --json-out ./snap-yandex \
|
|
518
|
+
--status REJECTED --start 2026-08-27 --end 2026-08-27
|
|
519
|
+
siluzan-tso yandex-analysis insights -a <porg-xxx> --json-out ./snap-yandex \
|
|
520
|
+
--level daily --start 2026-08-25 --end 2026-08-27
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
**要点**:Direct 无小时维度。默认报表只出现有消耗对象。`budget` 是系列日预算(自动策略常空),对照 `weeklyBudget`。`campaignTargetCpa` 只取 Search。`roi` 按成交额算。
|
|
524
|
+
|
|
501
525
|
---
|
|
502
526
|
|
|
503
527
|
## 报告模板
|
|
@@ -215,7 +215,7 @@
|
|
|
215
215
|
2. 消耗:`stats -m <媒体> -a <id> --start <昨天/上周一> --end <昨天/上周日>`(多户汇总走 **P3**;Bing/Yandex **今天**不要用 `stats`)。
|
|
216
216
|
3. Google 当日超预算/空耗熔断(若用户要求):`guard budget-circuit` / `guard zero-conv -m Google --json-out`(**禁止**逐户 for-loop)。
|
|
217
217
|
4. Bing 巡检(若用户要求):按 `hosted-automation-bing.md` 跑封禁/拒审/当日超预算或空耗预警(只告警,不暂停)。
|
|
218
|
-
5. Yandex 巡检(若用户要求):按 `hosted-automation-yandex.md`
|
|
218
|
+
5. Yandex 巡检(若用户要求):按 `hosted-automation-yandex.md` 跑归档/拒审/当日超预算或空耗预警(只告警,不暂停)。
|
|
219
219
|
6. TikTok 巡检(若用户要求):按 `hosted-automation-tiktok.md` 跑封禁/拒审/当日超预算或空耗预警(只告警,不暂停)。
|
|
220
220
|
7. Facebook / MetaAd 巡检(若用户要求):按 `hosted-automation-facebook.md` 跑封禁/拒审/当日超预算或空耗预警(只告警,不暂停)。
|
|
221
221
|
8. 预警触发:`forewarning records -m <媒体> --start <S>`(见 **W10**)。
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
| [`references/operations/hosted-automation-monitoring-json.md`](references/operations/hosted-automation-monitoring-json.md) | **Google 异常监控**落盘与读数 |
|
|
13
13
|
| [`references/operations/hosted-automation-optimize-index.md`](references/operations/hosted-automation-optimize-index.md) | **Google 自动优化**:差素材降价/关停、高转化扩量、A/B 停输家 |
|
|
14
14
|
| [`references/operations/hosted-automation-bing.md`](references/operations/hosted-automation-bing.md) | **Bing 只读巡检**:余额/IO、封禁、拒审、落地页、当日超预算预警、CPA/空耗预警;**不能**自动暂停/改价 |
|
|
15
|
-
| [`references/operations/hosted-automation-yandex.md`](references/operations/hosted-automation-yandex.md) | **Yandex
|
|
15
|
+
| [`references/operations/hosted-automation-yandex.md`](references/operations/hosted-automation-yandex.md) | **Yandex 只读巡检**:归档/余额、拒审、落地页、当日超预算、CPA/空耗、按日异动;**不能**自动暂停/改价 |
|
|
16
16
|
| [`references/operations/hosted-automation-tiktok.md`](references/operations/hosted-automation-tiktok.md) | **TikTok 只读巡检**:封禁/余额、拒审、落地页、当日超预算、CPA/空耗、小时异动;**不能**自动暂停/改价 |
|
|
17
17
|
| [`references/operations/hosted-automation-facebook.md`](references/operations/hosted-automation-facebook.md) | **Facebook / MetaAd 只读巡检**:封禁/余额、拒审、落地页、当日超预算、CPA/空耗、小时异动;**不能**自动暂停/改价 |
|
|
18
18
|
|
|
@@ -70,13 +70,15 @@
|
|
|
70
70
|
|
|
71
71
|
## Yandex:只读巡检
|
|
72
72
|
|
|
73
|
-
全部步骤只读一份:`references/operations/hosted-automation-yandex.md
|
|
74
|
-
|
|
75
|
-
| 场景
|
|
76
|
-
|
|
|
77
|
-
|
|
|
78
|
-
|
|
|
79
|
-
|
|
|
73
|
+
全部步骤只读一份:`references/operations/hosted-automation-yandex.md`。**不能**自动暂停/改价/改预算。无小时维度。
|
|
74
|
+
|
|
75
|
+
| 场景 | 做什么 | SOP |
|
|
76
|
+
| ------------ | ---------------------------------------------------------------------- | -------------------------------------------------- |
|
|
77
|
+
| 余额 / 归档 | `yandex-analysis account-status`;`archived=true` 告警 | `references/operations/hosted-automation-yandex.md` |
|
|
78
|
+
| 素材拒审 | `ad-entities --status REJECTED` | 同上 |
|
|
79
|
+
| 落地页死链 | `ad-entities` 拉 `landingUrls`,宿主 HTTP 探活 | 同上 |
|
|
80
|
+
| 当日超预算 | `campaign-entities --time-increment 1 --network ALL`;只告警 | 同上 |
|
|
81
|
+
| CPA / 空耗 | `adgroup-entities` 近 3 日 + 当日 `--time-increment 1`;只告警 | 同上 |
|
|
80
82
|
|
|
81
83
|
## Facebook / MetaAd:只读巡检
|
|
82
84
|
|
|
@@ -1,83 +1,153 @@
|
|
|
1
1
|
# 宿主编排:Yandex 只读巡检
|
|
2
2
|
|
|
3
|
-
> **何时 Read**:用户要 Yandex /
|
|
4
|
-
>
|
|
5
|
-
>
|
|
3
|
+
> **何时 Read**:用户要 Yandex / 直通广告自动化、巡检、熔断、封禁、拒审、落地页、超预算或空耗。Google 熔断走 `references/operations/guard.md`;Bing 走 `hosted-automation-bing.md`。
|
|
4
|
+
> **能做什么**:拉数、对比阈值、宿主告警。
|
|
5
|
+
> **不能做什么**:暂停系列/组/广告、改价、改预算。本批只读,**禁止**假装已执行熔断。
|
|
6
6
|
|
|
7
7
|
**前置**:已 `siluzan-tso login`,并用 `list-accounts -m Yandex --json-out ./snap` 确认 `mediaCustomerId`(形如 `porg-…`,**不是**纯数字,也不是 `entityId`)。
|
|
8
8
|
|
|
9
9
|
**硬约束**:
|
|
10
10
|
|
|
11
11
|
- `guard` **只支持 Google**。禁止 `guard … -m Yandex`。
|
|
12
|
-
-
|
|
13
|
-
- `
|
|
14
|
-
-
|
|
12
|
+
- `yandex-analysis run` 是**周期报表**(默认 8 维、SEARCH、区间汇总)。当天花费、拒审、落地页、组级 CPA、全网花费走下面的**只读运营子命令**。
|
|
13
|
+
- 省略 `--start/--end` 时运营子命令默认**当天**(本机日历日)。`run` 省略则仍是近 7 天含今天。
|
|
14
|
+
- Direct **没有小时报表**。不要传 hourly,也不要编造近两小时 CPA。
|
|
15
|
+
- `revenue` 是成交额 PurchaseRevenue;`roi = (成交额 − 花费) / 花费`。不要用目标赋值反推。
|
|
16
|
+
- 默认报表路径只出现**有消耗**的对象。拒审须带 `--status`(结构查询,行内 `spend` 为 0)。
|
|
17
|
+
- `--status` 与 `--time-increment` **不能同时传**(400)。
|
|
18
|
+
- `/campaigns` `/geo` `/devices` 默认 SEARCH。全渠道花费须 `--network ALL`(行内 `network` 为 null,不拆行)。
|
|
19
|
+
- 自动策略与共享账户通常只有**周预算**,`budget`(日预算)常为 null。不要把周预算写进日预算字段。
|
|
15
20
|
|
|
16
21
|
---
|
|
17
22
|
|
|
18
|
-
## 1.
|
|
23
|
+
## 1. 余额 / 账户状态
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
siluzan-tso yandex-analysis account-status -a <porg-xxx> --json-out ./snap-yandex
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
读 `archived`、`balance`、`currency`、`balanceAsOf`。`archived=true` → 宿主告警「已归档」。官方**无**封户状态与原因,不要把 `archived` 写成「因违规被封」。官方无独立额度;续航用余额 ÷ 近几日日均花费(日均走 `insights --level daily`)。CLI **不能**自动充值。
|
|
30
|
+
|
|
31
|
+
多户续航也可先扫 TSO 余额(截至昨天的日均):
|
|
19
32
|
|
|
20
33
|
```bash
|
|
21
34
|
siluzan-tso balance-scan -m Yandex --threshold-days 7 --json-out ./snap-yandex
|
|
22
35
|
```
|
|
23
36
|
|
|
24
|
-
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 2. 素材拒审
|
|
25
40
|
|
|
26
41
|
```bash
|
|
27
|
-
siluzan-tso
|
|
42
|
+
siluzan-tso yandex-analysis ad-entities -a <porg-xxx> \
|
|
43
|
+
--start <当天> --end <当天> --status REJECTED --json-out ./snap-yandex
|
|
28
44
|
```
|
|
29
45
|
|
|
46
|
+
也可 `MODERATION` / `PREACCEPTED`。合法值:`DRAFT,MODERATION,PREACCEPTED,ACCEPTED,REJECTED,UNKNOWN`。空列表 = 成功且没有未归档拒审,不是失败。已归档素材不会出现。命中 → 告警 `adId` / `campaignId` / `status` / `statusClarification`。
|
|
47
|
+
|
|
30
48
|
---
|
|
31
49
|
|
|
32
|
-
##
|
|
50
|
+
## 3. 落地页死链
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
siluzan-tso yandex-analysis ad-entities -a <porg-xxx> \
|
|
54
|
+
--start <当天> --end <当天> --json-out ./snap-yandex
|
|
55
|
+
```
|
|
33
56
|
|
|
34
|
-
|
|
57
|
+
读每条广告的 `landingUrls`(数组)。空数组 **不要**当死链(Dynamic / Smart / Shopping 或仅 `TurboPageId` 常为 `[]`)。CLI **不**发 HTTP。宿主对非空 URL 做 HEAD/GET,4xx/5xx 或超时 → 告警。扫在投、含 0 消耗素材用 `--status ACCEPTED`(该路径不带花费)。
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 4. 当日超预算(只预警,不暂停)
|
|
62
|
+
|
|
63
|
+
全渠道当日花费 + 周预算(官方常无系列日预算):
|
|
35
64
|
|
|
36
65
|
```bash
|
|
37
|
-
siluzan-tso
|
|
38
|
-
|
|
39
|
-
siluzan-tso accounts-digest -m Yandex --start <S> --end <D> --max-cpa <目标CPA> --json-out ./snap-yandex
|
|
66
|
+
siluzan-tso yandex-analysis campaign-entities -a <porg-xxx> --json-out ./snap-yandex \
|
|
67
|
+
--start <当天> --end <当天> --time-increment 1 --network ALL
|
|
40
68
|
```
|
|
41
69
|
|
|
42
|
-
|
|
70
|
+
用同一 `campaignId` 看 `spend` 对 `weeklyBudget`(点击策略、投放天数 ≥ 3 时,单日大约最多花到周预算的 35%)。`budget` 仍是系列日预算,自动策略下通常为 null。命中 → **告警P1**,不要写「已暂停」。
|
|
43
71
|
|
|
44
72
|
---
|
|
45
73
|
|
|
46
|
-
##
|
|
74
|
+
## 5. CPA / 空耗(只预警,不降价、不暂停)
|
|
75
|
+
|
|
76
|
+
近 3 日组级转化成本(无小时维度,不要编造近两小时):
|
|
47
77
|
|
|
48
78
|
```bash
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
--start <当日或近几日> --end <当日> --sections overview,daily,campaigns
|
|
79
|
+
siluzan-tso yandex-analysis adgroup-entities -a <porg-xxx> --json-out ./snap-yandex \
|
|
80
|
+
--start <今天-2> --end <今天>
|
|
52
81
|
```
|
|
53
82
|
|
|
54
|
-
|
|
83
|
+
对照 `conversions`、`costPerConversion`、`campaignTargetCpa`。`conversions <= 0` 时通常不判 CPA。有目标价时可用 `costPerConversion > campaignTargetCpa × 1.5` 作为飙升参考。没有目标价不算读取失败。`campaignStrategy` 只说明策略类型。
|
|
55
84
|
|
|
56
|
-
|
|
57
|
-
- **系列花费 / 预算**:同一窗口读 `campaigns`,用落盘里的花费对照 `budget`;缺字段就不要猜,改用日环比。
|
|
58
|
-
- **CPA**:`花费 / 转化`(转化为 0 不算 CPA,改走空耗判断)。超过约定目标倍数 → 告警。
|
|
59
|
-
- **空耗**:当日(或约定日)花费已达「目标 CPA × N」且转化为 0 → 告警「空耗预警」,文案不要写成「已熔断」。目标 CPA 用落盘 `targetCpa` 或账户约定。
|
|
85
|
+
当日空耗(组 / 广告):
|
|
60
86
|
|
|
61
|
-
|
|
87
|
+
```bash
|
|
88
|
+
siluzan-tso yandex-analysis adgroup-entities -a <porg-xxx> --json-out ./snap-yandex \
|
|
89
|
+
--start <当天> --end <当天> --time-increment 1
|
|
90
|
+
siluzan-tso yandex-analysis ad-entities -a <porg-xxx> --json-out ./snap-yandex \
|
|
91
|
+
--start <当天> --end <当天> --time-increment 1
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
有花费、无转化 → 告警「空耗预警」,文案不要写成「已熔断」。连续天数由宿主按日统计。
|
|
62
95
|
|
|
63
96
|
---
|
|
64
97
|
|
|
65
|
-
##
|
|
98
|
+
## 6. 花费异动 / 广告效果 / A/B / 根因
|
|
99
|
+
|
|
100
|
+
按日花费环比(前天~今天):
|
|
66
101
|
|
|
67
102
|
```bash
|
|
103
|
+
siluzan-tso yandex-analysis insights -a <porg-xxx> --json-out ./snap-yandex \
|
|
104
|
+
--level daily --start <前天> --end <今天>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
差广告 / A/B(同一份广告列表,按 `adId` 比 `spend` / `ctr` / `conversions` / `roi` / `costPerConversion`):
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
siluzan-tso yandex-analysis ad-entities -a <porg-xxx> --json-out ./snap-yandex \
|
|
111
|
+
--start <区间起> --end <区间止>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
高转化扩量(组绩效 + 关键词搜索出价;自动策略下看系列周预算,不要按手动 CPC 改价):
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
siluzan-tso yandex-analysis adgroup-entities -a <porg-xxx> --json-out ./snap-yandex \
|
|
118
|
+
--start <区间起> --end <区间止>
|
|
119
|
+
siluzan-tso yandex-analysis insights -a <porg-xxx> --json-out ./snap-yandex \
|
|
120
|
+
--level keywords --start <区间起> --end <区间止>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
异动根因(地域与设备须分别请求;全网加 `--network ALL`):
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
siluzan-tso yandex-analysis insights -a <porg-xxx> --json-out ./snap-yandex \
|
|
127
|
+
--level geo --start <S> --end <D> --network ALL
|
|
128
|
+
siluzan-tso yandex-analysis insights -a <porg-xxx> --json-out ./snap-yandex \
|
|
129
|
+
--level devices --start <S> --end <D> --network ALL
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`/geo` 有 `limit`(默认 100)。截断后的地域 `spend` 合计通常低于全网,不宜直接拿去对 `/devices`。
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 7. 周期报告与多账户(给人看,不代替巡检告警)
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
siluzan-tso accounts-digest -m Yandex --start <S> --end <D> --json-out ./snap-yandex
|
|
68
140
|
siluzan-tso yandex-analysis -a <porg-xxx> --start <S> --end <D> --json-out ./snap-yandex
|
|
69
141
|
```
|
|
70
142
|
|
|
71
|
-
|
|
143
|
+
`accounts-digest` / `balance-scan` 的消耗截至**昨天**。出 HTML 按 `report-templates/yandex-period-report.md` 写 narrative 后再 `yandex-analysis render`。阈值告警仍走上面 1–6 步。
|
|
72
144
|
|
|
73
145
|
---
|
|
74
146
|
|
|
75
147
|
## 做不到(勿编造命令)
|
|
76
148
|
|
|
77
|
-
| 场景
|
|
78
|
-
|
|
|
79
|
-
|
|
|
80
|
-
|
|
|
81
|
-
|
|
|
82
|
-
| 小时花费 | 无 |
|
|
83
|
-
| 自动暂停 / 改价 | 无写接口;告警后人工在 Yandex 后台处理 |
|
|
149
|
+
| 场景 | 现状 |
|
|
150
|
+
| --------------- | ----------------------------------------- |
|
|
151
|
+
| 账户封禁原因 | 无;只能读 `archived` |
|
|
152
|
+
| 小时花费 / 小时 CPA | 无;改用按日或近 3 日区间 |
|
|
153
|
+
| 自动暂停 / 改价 / 改预算 | 无写接口;告警后人工在 Yandex 后台处理 |
|
|
@@ -9,7 +9,7 @@ $ErrorActionPreference = 'Stop'
|
|
|
9
9
|
# -- Package info (injected at build time) ------------------------------------
|
|
10
10
|
$PKG_NAME = 'siluzan-tso-cli'
|
|
11
11
|
# PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
|
|
12
|
-
$PKG_VERSION = '1.1.48-beta.
|
|
12
|
+
$PKG_VERSION = '1.1.48-beta.9'
|
|
13
13
|
$CLI_BIN = 'siluzan-tso'
|
|
14
14
|
$SKILL_LABEL = 'Siluzan TSO'
|
|
15
15
|
$INSTALL_CMD = 'npm install -g siluzan-tso-cli@beta'
|
|
@@ -9,7 +9,7 @@ set -euo pipefail
|
|
|
9
9
|
# -- Package info (injected at build time) ------------------------------------
|
|
10
10
|
readonly PKG_NAME="siluzan-tso-cli"
|
|
11
11
|
# PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
|
|
12
|
-
readonly PKG_VERSION="1.1.48-beta.
|
|
12
|
+
readonly PKG_VERSION="1.1.48-beta.9"
|
|
13
13
|
readonly CLI_BIN="siluzan-tso"
|
|
14
14
|
readonly SKILL_LABEL="Siluzan TSO"
|
|
15
15
|
readonly INSTALL_CMD="npm install -g siluzan-tso-cli@beta"
|