siluzan-tso-cli 1.1.48-beta.8 → 1.1.48
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 -2
- package/dist/index.js +909 -647
- package/dist/skill/SKILL.md +4 -4
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/references/accounts/accounts-balance-stats.md +5 -5
- package/dist/skill/references/accounts/accounts-list.md +3 -3
- package/dist/skill/references/accounts/accounts-permissions.md +4 -4
- package/dist/skill/references/accounts/accounts.md +1 -1
- package/dist/skill/references/accounts/finance.md +3 -3
- package/dist/skill/references/accounts/open-account-by-media.md +3 -54
- package/dist/skill/references/accounts/open-account-google-ui.md +1 -1
- package/dist/skill/references/analytics/account-analytics.md +27 -3
- package/dist/skill/references/analytics/rag.md +1 -1
- package/dist/skill/references/analytics/reporting.md +5 -5
- package/dist/skill/references/core/agent-conventions.md +5 -7
- package/dist/skill/references/core/cli-enums.md +1 -9
- package/dist/skill/references/core/setup.md +5 -5
- package/dist/skill/references/core/workflows.md +5 -5
- package/dist/skill/references/misc/tso-home.md +2 -2
- 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/references/report-templates/excel-style-guide.md +1 -3
- package/dist/skill/report-templates/excel-style-guide.md +1 -3
- package/dist/skill/report-templates/excel-style-kit.mjs +1 -2
- package/dist/skill/scripts/install.ps1 +3 -3
- package/dist/skill/scripts/install.sh +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2636,18 +2636,6 @@ function decodeJwtClaims(token) {
|
|
|
2636
2636
|
function decodeJwtSub(token) {
|
|
2637
2637
|
return decodeJwtClaims(token)?.sub ?? null;
|
|
2638
2638
|
}
|
|
2639
|
-
function sleep(ms) {
|
|
2640
|
-
return new Promise((resolve52) => setTimeout(resolve52, ms));
|
|
2641
|
-
}
|
|
2642
|
-
async function pollUntil(fn, intervalMs, timeoutMs) {
|
|
2643
|
-
const deadline = Date.now() + timeoutMs;
|
|
2644
|
-
while (Date.now() < deadline) {
|
|
2645
|
-
const result = await fn();
|
|
2646
|
-
if (result !== null) return result;
|
|
2647
|
-
await sleep(intervalMs);
|
|
2648
|
-
}
|
|
2649
|
-
return null;
|
|
2650
|
-
}
|
|
2651
2639
|
function getCurrentVersion(importMetaUrl) {
|
|
2652
2640
|
try {
|
|
2653
2641
|
const __dirname3 = path2.dirname(fileURLToPath(importMetaUrl));
|
|
@@ -4030,7 +4018,7 @@ var DEFAULT_API_BASE;
|
|
|
4030
4018
|
var init_defaults = __esm({
|
|
4031
4019
|
"src/config/defaults.ts"() {
|
|
4032
4020
|
"use strict";
|
|
4033
|
-
DEFAULT_API_BASE = "https://tso-api
|
|
4021
|
+
DEFAULT_API_BASE = "https://tso-api.siluzan.com";
|
|
4034
4022
|
}
|
|
4035
4023
|
});
|
|
4036
4024
|
|
|
@@ -4835,27 +4823,6 @@ async function fetchBalanceMap(media, accountIds, config, startDate, endDate, ve
|
|
|
4835
4823
|
indexByMediaCustomerId(result, String(item.mediaCustomerId), item);
|
|
4836
4824
|
}
|
|
4837
4825
|
}
|
|
4838
|
-
} else if (media === "Kwai") {
|
|
4839
|
-
const range = defaultDateRange();
|
|
4840
|
-
const params = new URLSearchParams({
|
|
4841
|
-
period: "true",
|
|
4842
|
-
startDate: startDate ?? range.startDate,
|
|
4843
|
-
endDate: endDate ?? range.endDate,
|
|
4844
|
-
mediaCustomerIds: accountIds.join(",")
|
|
4845
|
-
});
|
|
4846
|
-
const url = `${config.apiBaseUrl}/report/media-account/Kwai/accountsoverview?${params}`;
|
|
4847
|
-
const raw = await apiFetch2(url, config, {}, verbose);
|
|
4848
|
-
const items2 = Array.isArray(raw) ? raw : [];
|
|
4849
|
-
for (const item of items2) {
|
|
4850
|
-
if (item.mediaAccountId != null) {
|
|
4851
|
-
result.set(String(item.mediaAccountId), {
|
|
4852
|
-
mediaCustomerId: item.mediaAccountId,
|
|
4853
|
-
remainingAccountBudget: item.remainingAccountBudget,
|
|
4854
|
-
status: item.status,
|
|
4855
|
-
currencyCode: item.currencyCode
|
|
4856
|
-
});
|
|
4857
|
-
}
|
|
4858
|
-
}
|
|
4859
4826
|
}
|
|
4860
4827
|
} catch {
|
|
4861
4828
|
}
|
|
@@ -5040,7 +5007,6 @@ var init_balance = __esm({
|
|
|
5040
5007
|
"Yandex",
|
|
5041
5008
|
"TikTok",
|
|
5042
5009
|
"BingV2",
|
|
5043
|
-
"Kwai",
|
|
5044
5010
|
"MetaAd"
|
|
5045
5011
|
];
|
|
5046
5012
|
CHINA_OFFSET_MS2 = 8 * 36e5;
|
|
@@ -5117,8 +5083,6 @@ function mediaAccountDataBatchSize(media) {
|
|
|
5117
5083
|
case "TikTok":
|
|
5118
5084
|
case "Yandex":
|
|
5119
5085
|
return 10;
|
|
5120
|
-
case "Kwai":
|
|
5121
|
-
return 20;
|
|
5122
5086
|
default:
|
|
5123
5087
|
return 100;
|
|
5124
5088
|
}
|
|
@@ -5245,18 +5209,6 @@ var init_list_fetch = __esm({
|
|
|
5245
5209
|
},
|
|
5246
5210
|
responseType: "mas"
|
|
5247
5211
|
},
|
|
5248
|
-
Kwai: {
|
|
5249
|
-
path: "/query/media-account/SearchMediaAcountByCriteria",
|
|
5250
|
-
pageParam: "pageNum",
|
|
5251
|
-
fixedParams: {
|
|
5252
|
-
MediaTypes: "Kwai",
|
|
5253
|
-
MediaType: "Kwai",
|
|
5254
|
-
advStatus: "",
|
|
5255
|
-
mediaAccountState: "Approved,Linked",
|
|
5256
|
-
isForce: false
|
|
5257
|
-
},
|
|
5258
|
-
responseType: "mas"
|
|
5259
|
-
},
|
|
5260
5212
|
MetaAd: {
|
|
5261
5213
|
path: "/query/media-account/SearchMediaAcountByCriteria",
|
|
5262
5214
|
pageParam: "pageNum",
|
|
@@ -5561,7 +5513,7 @@ function register10(program2) {
|
|
|
5561
5513
|
"\u591A\u8D26\u6237\u6295\u653E\u753B\u50CF\uFF1A\u4E00\u6761\u547D\u4EE4\u62FF\u9F50\u6D88\u8017/\u70B9\u51FB/\u8F6C\u5316/\u4F59\u989D/\u6D3E\u751F\u6307\u6807\uFF08CTR/CPC/CPA\uFF09\uFF0C\u66FF\u4EE3 AI \u9010\u8D26\u6237 `list-accounts` + `stats` \u7684\u7F16\u6392\u3002\u5178\u578B\u573A\u666F\uFF1A\u300C\u8FD9 10 \u4E2A\u8D26\u6237\uFF08\u6216\u67D0\u5A92\u4F53\u5168\u90E8\u8D26\u6237\uFF09\u5E2E\u6211\u6574\u7406\u4E00\u4E0B\u300D\u3001\u8F6C\u5316\u6210\u672C/CPA/\u96F6\u8F6C\u5316\u5DE1\u68C0\u3002\u65E0 --period\uFF1B\u533A\u95F4\u7528 --start/--end\uFF08\u6216 --start-date/--end-date\uFF09\u3002"
|
|
5562
5514
|
).requiredOption(
|
|
5563
5515
|
"-m, --media <type>",
|
|
5564
|
-
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2
|
|
5516
|
+
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2"
|
|
5565
5517
|
).option(
|
|
5566
5518
|
"-a, --accounts <ids>",
|
|
5567
5519
|
"\u6307\u5B9A\u8D26\u6237 mediaCustomerId\uFF0C\u9017\u53F7\u5206\u9694\uFF1B\u7559\u7A7A\u5219\u626B\u63CF\u8BE5\u5A92\u4F53\u4E0B\u5168\u90E8\u8D26\u6237"
|
|
@@ -102375,8 +102327,8 @@ var init_fetch = __esm({
|
|
|
102375
102327
|
});
|
|
102376
102328
|
|
|
102377
102329
|
// src/commands/google-analysis/merge-snapshot.ts
|
|
102378
|
-
import * as
|
|
102379
|
-
import * as
|
|
102330
|
+
import * as fs22 from "fs/promises";
|
|
102331
|
+
import * as path27 from "path";
|
|
102380
102332
|
function asRecord11(value) {
|
|
102381
102333
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
102382
102334
|
return value;
|
|
@@ -102394,7 +102346,7 @@ async function readManifest(snapshotDir, accountId) {
|
|
|
102394
102346
|
const candidates = [];
|
|
102395
102347
|
if (accountId) candidates.push(googleAnalysisManifestFile(accountId));
|
|
102396
102348
|
try {
|
|
102397
|
-
const entries = await
|
|
102349
|
+
const entries = await fs22.readdir(snapshotDir);
|
|
102398
102350
|
const manifestNames = entries.filter((n) => n.startsWith("manifest") && n.endsWith(".json"));
|
|
102399
102351
|
for (const name2 of manifestNames) {
|
|
102400
102352
|
if (!candidates.includes(name2)) candidates.push(name2);
|
|
@@ -102403,7 +102355,7 @@ async function readManifest(snapshotDir, accountId) {
|
|
|
102403
102355
|
}
|
|
102404
102356
|
for (const name2 of candidates) {
|
|
102405
102357
|
try {
|
|
102406
|
-
const raw = await
|
|
102358
|
+
const raw = await fs22.readFile(path27.join(snapshotDir, name2), "utf8");
|
|
102407
102359
|
const parsed = JSON.parse(raw);
|
|
102408
102360
|
if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
|
|
102409
102361
|
} catch {
|
|
@@ -102413,7 +102365,7 @@ async function readManifest(snapshotDir, accountId) {
|
|
|
102413
102365
|
}
|
|
102414
102366
|
async function loadSectionFile(snapshotDir, file) {
|
|
102415
102367
|
try {
|
|
102416
|
-
const raw = await
|
|
102368
|
+
const raw = await fs22.readFile(path27.join(snapshotDir, file), "utf8");
|
|
102417
102369
|
const parsed = JSON.parse(raw);
|
|
102418
102370
|
if (parsed && typeof parsed === "object") return parsed;
|
|
102419
102371
|
return null;
|
|
@@ -102447,7 +102399,7 @@ async function recoverMissingReportSections(sectionMap, absDir, accountId, prefe
|
|
|
102447
102399
|
if (!accountId) return;
|
|
102448
102400
|
let entries;
|
|
102449
102401
|
try {
|
|
102450
|
-
entries = await
|
|
102402
|
+
entries = await fs22.readdir(absDir);
|
|
102451
102403
|
} catch {
|
|
102452
102404
|
return;
|
|
102453
102405
|
}
|
|
@@ -102519,7 +102471,7 @@ function sumCampaignRowsToPeriodKpis(rows) {
|
|
|
102519
102471
|
};
|
|
102520
102472
|
}
|
|
102521
102473
|
async function mergeGoogleAnalysisSnapshotIntoReport(payload, snapshotDir) {
|
|
102522
|
-
const absDir =
|
|
102474
|
+
const absDir = path27.resolve(snapshotDir);
|
|
102523
102475
|
const metaAccountId = typeof asRecord11(payload.meta)?.accountId === "string" ? asRecord11(payload.meta)?.accountId : void 0;
|
|
102524
102476
|
const manifest = await readManifest(snapshotDir, metaAccountId);
|
|
102525
102477
|
if (!manifest) {
|
|
@@ -102798,19 +102750,19 @@ var init_report_content = __esm({
|
|
|
102798
102750
|
});
|
|
102799
102751
|
|
|
102800
102752
|
// src/commands/google-analysis/render-report.ts
|
|
102801
|
-
import
|
|
102753
|
+
import fs23 from "fs";
|
|
102802
102754
|
import fsPromises2 from "fs/promises";
|
|
102803
|
-
import
|
|
102755
|
+
import path28 from "path";
|
|
102804
102756
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
102805
102757
|
function resolveSkillTemplatePath3(basename13) {
|
|
102806
|
-
const dir =
|
|
102758
|
+
const dir = path28.dirname(fileURLToPath6(import.meta.url));
|
|
102807
102759
|
const candidates = [
|
|
102808
|
-
|
|
102809
|
-
|
|
102810
|
-
|
|
102760
|
+
path28.join(dir, "skill", "report-templates", basename13),
|
|
102761
|
+
path28.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
102762
|
+
path28.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
102811
102763
|
];
|
|
102812
102764
|
for (const p of candidates) {
|
|
102813
|
-
if (
|
|
102765
|
+
if (fs23.existsSync(p)) return p;
|
|
102814
102766
|
}
|
|
102815
102767
|
return candidates[0];
|
|
102816
102768
|
}
|
|
@@ -102839,10 +102791,10 @@ function injectReportData2(html, payload) {
|
|
|
102839
102791
|
return html.replace(INJECT_MARKER, `window.__GOOGLE_PERIOD_REPORT__ = ${json};`);
|
|
102840
102792
|
}
|
|
102841
102793
|
async function runGoogleAnalysisRender(opts) {
|
|
102842
|
-
const dataPath =
|
|
102794
|
+
const dataPath = path28.resolve(opts.dataFile);
|
|
102843
102795
|
let data = asRecord13(await readJsonFile2(dataPath));
|
|
102844
102796
|
if (opts.snapshotDir?.trim()) {
|
|
102845
|
-
data = await mergeGoogleAnalysisSnapshotIntoReport(data,
|
|
102797
|
+
data = await mergeGoogleAnalysisSnapshotIntoReport(data, path28.resolve(opts.snapshotDir));
|
|
102846
102798
|
}
|
|
102847
102799
|
const contentCheck = validateGooglePeriodReportContent(data);
|
|
102848
102800
|
if (!contentCheck.ok) {
|
|
@@ -102868,10 +102820,10 @@ async function runGoogleAnalysisRender(opts) {
|
|
|
102868
102820
|
`);
|
|
102869
102821
|
process.exit(1);
|
|
102870
102822
|
}
|
|
102871
|
-
const outPath =
|
|
102872
|
-
opts.out ??
|
|
102823
|
+
const outPath = path28.resolve(
|
|
102824
|
+
opts.out ?? path28.join(path28.dirname(dataPath), "google-period-report.html")
|
|
102873
102825
|
);
|
|
102874
|
-
const outDir =
|
|
102826
|
+
const outDir = path28.dirname(outPath);
|
|
102875
102827
|
await fsPromises2.mkdir(outDir, { recursive: true });
|
|
102876
102828
|
await fsPromises2.writeFile(outPath, injectReportData2(html, data), "utf8");
|
|
102877
102829
|
const { stats } = contentCheck;
|
|
@@ -102898,8 +102850,8 @@ var init_render_report = __esm({
|
|
|
102898
102850
|
});
|
|
102899
102851
|
|
|
102900
102852
|
// src/utils/batch-manifest.ts
|
|
102901
|
-
import * as
|
|
102902
|
-
import * as
|
|
102853
|
+
import * as fs24 from "fs/promises";
|
|
102854
|
+
import * as path29 from "path";
|
|
102903
102855
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
102904
102856
|
function generateRunId(now = /* @__PURE__ */ new Date()) {
|
|
102905
102857
|
const pad = (n) => String(n).padStart(2, "0");
|
|
@@ -102913,26 +102865,26 @@ function isValidRunId(id) {
|
|
|
102913
102865
|
}
|
|
102914
102866
|
function resolveBatchPaths(baseDir, runId) {
|
|
102915
102867
|
if (!isValidRunId(runId)) throw new Error(`\u975E\u6CD5 runId\uFF1A${runId}`);
|
|
102916
|
-
const runDir =
|
|
102917
|
-
const stateDir =
|
|
102868
|
+
const runDir = path29.resolve(baseDir, runId);
|
|
102869
|
+
const stateDir = path29.join(runDir, "state");
|
|
102918
102870
|
return {
|
|
102919
102871
|
runDir,
|
|
102920
|
-
runManifestFile:
|
|
102921
|
-
progressFile:
|
|
102922
|
-
accountsFile:
|
|
102923
|
-
resultsDir:
|
|
102924
|
-
errorsDir:
|
|
102872
|
+
runManifestFile: path29.join(runDir, "run-manifest.json"),
|
|
102873
|
+
progressFile: path29.join(runDir, "progress.json"),
|
|
102874
|
+
accountsFile: path29.join(runDir, "accounts.json"),
|
|
102875
|
+
resultsDir: path29.join(runDir, "results"),
|
|
102876
|
+
errorsDir: path29.join(runDir, "errors"),
|
|
102925
102877
|
stateDir,
|
|
102926
|
-
tasksLogFile:
|
|
102927
|
-
lockFile:
|
|
102878
|
+
tasksLogFile: path29.join(stateDir, "tasks.jsonl"),
|
|
102879
|
+
lockFile: path29.join(stateDir, "tasks.lock")
|
|
102928
102880
|
};
|
|
102929
102881
|
}
|
|
102930
102882
|
async function ensureAccountDirs(paths, accountId) {
|
|
102931
102883
|
const safe = sanitizeAccountSegment(accountId);
|
|
102932
|
-
const results =
|
|
102933
|
-
const errors =
|
|
102934
|
-
await
|
|
102935
|
-
await
|
|
102884
|
+
const results = path29.join(paths.resultsDir, safe);
|
|
102885
|
+
const errors = path29.join(paths.errorsDir, safe);
|
|
102886
|
+
await fs24.mkdir(results, { recursive: true });
|
|
102887
|
+
await fs24.mkdir(errors, { recursive: true });
|
|
102936
102888
|
return { results, errors };
|
|
102937
102889
|
}
|
|
102938
102890
|
function sanitizeAccountSegment(accountId) {
|
|
@@ -102947,20 +102899,20 @@ function sanitizeAccountSegment(accountId) {
|
|
|
102947
102899
|
return slug;
|
|
102948
102900
|
}
|
|
102949
102901
|
async function atomicWriteFile(target, content) {
|
|
102950
|
-
const dir =
|
|
102951
|
-
await
|
|
102952
|
-
const tmp =
|
|
102902
|
+
const dir = path29.dirname(target);
|
|
102903
|
+
await fs24.mkdir(dir, { recursive: true });
|
|
102904
|
+
const tmp = path29.join(dir, `.tmp-${randomUUID2()}-${path29.basename(target)}`);
|
|
102953
102905
|
try {
|
|
102954
|
-
await
|
|
102955
|
-
await
|
|
102906
|
+
await fs24.writeFile(tmp, content, "utf8");
|
|
102907
|
+
await fs24.rename(tmp, target);
|
|
102956
102908
|
} catch (e) {
|
|
102957
|
-
await
|
|
102909
|
+
await fs24.rm(tmp, { force: true }).catch(() => void 0);
|
|
102958
102910
|
throw e;
|
|
102959
102911
|
}
|
|
102960
102912
|
}
|
|
102961
102913
|
async function readJsonIfExists(file) {
|
|
102962
102914
|
try {
|
|
102963
|
-
const raw = await
|
|
102915
|
+
const raw = await fs24.readFile(file, "utf8");
|
|
102964
102916
|
return JSON.parse(raw);
|
|
102965
102917
|
} catch (e) {
|
|
102966
102918
|
if (e.code === "ENOENT") return null;
|
|
@@ -102990,12 +102942,12 @@ function readProgress(paths) {
|
|
|
102990
102942
|
return readJsonIfExists(paths.progressFile);
|
|
102991
102943
|
}
|
|
102992
102944
|
async function appendTaskLog(paths, entry) {
|
|
102993
|
-
await
|
|
102994
|
-
await
|
|
102945
|
+
await fs24.mkdir(paths.stateDir, { recursive: true });
|
|
102946
|
+
await fs24.appendFile(paths.tasksLogFile, JSON.stringify(entry) + "\n", "utf8");
|
|
102995
102947
|
}
|
|
102996
102948
|
async function readTaskLog(paths) {
|
|
102997
102949
|
try {
|
|
102998
|
-
const raw = await
|
|
102950
|
+
const raw = await fs24.readFile(paths.tasksLogFile, "utf8");
|
|
102999
102951
|
return raw.split("\n").filter((s) => s.trim() !== "").map((line) => JSON.parse(line));
|
|
103000
102952
|
} catch (e) {
|
|
103001
102953
|
if (e.code === "ENOENT") return [];
|
|
@@ -103050,9 +103002,9 @@ function emptyProgress(runId, totalTasks, accountConcurrency, sectionConcurrency
|
|
|
103050
103002
|
};
|
|
103051
103003
|
}
|
|
103052
103004
|
async function tryAcquireLock(paths) {
|
|
103053
|
-
await
|
|
103005
|
+
await fs24.mkdir(paths.stateDir, { recursive: true });
|
|
103054
103006
|
try {
|
|
103055
|
-
const handle = await
|
|
103007
|
+
const handle = await fs24.open(paths.lockFile, "wx");
|
|
103056
103008
|
await handle.writeFile(`${process.pid}@${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
103057
103009
|
await handle.close();
|
|
103058
103010
|
return true;
|
|
@@ -103062,7 +103014,7 @@ async function tryAcquireLock(paths) {
|
|
|
103062
103014
|
}
|
|
103063
103015
|
}
|
|
103064
103016
|
async function releaseLock(paths) {
|
|
103065
|
-
await
|
|
103017
|
+
await fs24.rm(paths.lockFile, { force: true }).catch(() => void 0);
|
|
103066
103018
|
}
|
|
103067
103019
|
var BATCH_SCHEMA_VERSION;
|
|
103068
103020
|
var init_batch_manifest = __esm({
|
|
@@ -103074,8 +103026,8 @@ var init_batch_manifest = __esm({
|
|
|
103074
103026
|
|
|
103075
103027
|
// src/utils/batch-runner.ts
|
|
103076
103028
|
import { performance as performance2 } from "perf_hooks";
|
|
103077
|
-
import * as
|
|
103078
|
-
import * as
|
|
103029
|
+
import * as path30 from "path";
|
|
103030
|
+
import * as fs25 from "fs/promises";
|
|
103079
103031
|
async function runPool(items2, concurrencyRef, worker, signal) {
|
|
103080
103032
|
let cursor = 0;
|
|
103081
103033
|
const launch = () => {
|
|
@@ -103214,7 +103166,7 @@ async function runBatch(opts) {
|
|
|
103214
103166
|
}
|
|
103215
103167
|
const inner = {
|
|
103216
103168
|
...emptyProgress(
|
|
103217
|
-
opts.paths.runDir.split(
|
|
103169
|
+
opts.paths.runDir.split(path30.sep).pop() ?? "run",
|
|
103218
103170
|
allTasks.length,
|
|
103219
103171
|
opts.accountConcurrency,
|
|
103220
103172
|
opts.sectionConcurrency
|
|
@@ -103339,7 +103291,7 @@ async function runBatch(opts) {
|
|
|
103339
103291
|
signal: aborterToken.signal
|
|
103340
103292
|
});
|
|
103341
103293
|
await writer({
|
|
103342
|
-
snapshotDir:
|
|
103294
|
+
snapshotDir: path30.join(opts.paths.resultsDir, sanitizeAccountSegment(task.accountId)),
|
|
103343
103295
|
section: task.section,
|
|
103344
103296
|
accountId: task.accountId,
|
|
103345
103297
|
dateRange: result.dateRange,
|
|
@@ -103428,7 +103380,7 @@ async function runBatch(opts) {
|
|
|
103428
103380
|
};
|
|
103429
103381
|
}
|
|
103430
103382
|
async function writeTaskError(paths, errorsDir, task, err, cls) {
|
|
103431
|
-
const file =
|
|
103383
|
+
const file = path30.join(errorsDir, `${sanitizeSection(task.section)}.error.json`);
|
|
103432
103384
|
const payload = {
|
|
103433
103385
|
schemaVersion: 1,
|
|
103434
103386
|
taskId: task.id,
|
|
@@ -103474,10 +103426,10 @@ async function persistRunMetadata(input) {
|
|
|
103474
103426
|
accountsTotal: input.accounts.length,
|
|
103475
103427
|
invocation: input.invocation
|
|
103476
103428
|
};
|
|
103477
|
-
await
|
|
103478
|
-
await
|
|
103479
|
-
await
|
|
103480
|
-
await
|
|
103429
|
+
await fs25.mkdir(paths.runDir, { recursive: true });
|
|
103430
|
+
await fs25.mkdir(paths.stateDir, { recursive: true });
|
|
103431
|
+
await fs25.mkdir(paths.resultsDir, { recursive: true });
|
|
103432
|
+
await fs25.mkdir(paths.errorsDir, { recursive: true });
|
|
103481
103433
|
await writeRunManifest(paths, manifest);
|
|
103482
103434
|
await writeAccounts(paths, input.accounts);
|
|
103483
103435
|
return paths;
|
|
@@ -103520,8 +103472,8 @@ var init_batch_runner = __esm({
|
|
|
103520
103472
|
shouldDowngrade(now = Date.now()) {
|
|
103521
103473
|
if (this.window.length < this.opts.windowSize) return false;
|
|
103522
103474
|
if (now - this.lastDowngradeAt < this.opts.cooldownMs) return false;
|
|
103523
|
-
const
|
|
103524
|
-
const rate =
|
|
103475
|
+
const fail4 = this.window.filter((s) => !s).length;
|
|
103476
|
+
const rate = fail4 / this.window.length;
|
|
103525
103477
|
if (rate >= this.opts.errorRateThreshold) {
|
|
103526
103478
|
this.lastDowngradeAt = now;
|
|
103527
103479
|
this.window.length = 0;
|
|
@@ -103540,7 +103492,7 @@ __export(google_analysis_batch_exports, {
|
|
|
103540
103492
|
parseAccountIds: () => parseAccountIds,
|
|
103541
103493
|
registerGoogleAnalysisBatchCommands: () => registerGoogleAnalysisBatchCommands
|
|
103542
103494
|
});
|
|
103543
|
-
import * as
|
|
103495
|
+
import * as path31 from "path";
|
|
103544
103496
|
import { performance as performance3 } from "perf_hooks";
|
|
103545
103497
|
function parseSections(input) {
|
|
103546
103498
|
if (!input || !input.trim()) return DEFAULT_SECTIONS;
|
|
@@ -104075,7 +104027,7 @@ var init_google_analysis_batch = __esm({
|
|
|
104075
104027
|
});
|
|
104076
104028
|
|
|
104077
104029
|
// src/commands/google-analysis/register-cli.ts
|
|
104078
|
-
import * as
|
|
104030
|
+
import * as path32 from "path";
|
|
104079
104031
|
import { performance as performance4 } from "perf_hooks";
|
|
104080
104032
|
import { Command } from "commander";
|
|
104081
104033
|
function normalizeAnalysisDateOpts(opts) {
|
|
@@ -104201,7 +104153,7 @@ async function runAllSections(opts) {
|
|
|
104201
104153
|
}
|
|
104202
104154
|
const succeeded = results.filter((r) => r.ok).length;
|
|
104203
104155
|
const failed = results.length - succeeded;
|
|
104204
|
-
const absoluteSnapshotDir =
|
|
104156
|
+
const absoluteSnapshotDir = path32.resolve(opts.jsonOut);
|
|
104205
104157
|
const summary = {
|
|
104206
104158
|
kind: "siluzan-tso-google-analysis-snapshot-batch",
|
|
104207
104159
|
absoluteSnapshotDir,
|
|
@@ -104449,8 +104401,8 @@ var init_google_analysis3 = __esm({
|
|
|
104449
104401
|
// src/index.ts
|
|
104450
104402
|
init_dist();
|
|
104451
104403
|
init_dist();
|
|
104452
|
-
import * as
|
|
104453
|
-
import * as
|
|
104404
|
+
import * as fs36 from "fs";
|
|
104405
|
+
import * as path47 from "path";
|
|
104454
104406
|
import { fileURLToPath as fileURLToPath12 } from "url";
|
|
104455
104407
|
import { Command as Command6 } from "commander";
|
|
104456
104408
|
|
|
@@ -104937,8 +104889,8 @@ function deriveWebUrl(apiBaseUrl) {
|
|
|
104937
104889
|
}
|
|
104938
104890
|
var TSO_UMI_ROUTE_PREFIX = "/v3umijs/tso";
|
|
104939
104891
|
function buildTsoPageWebUrl(webUrl, tsoSubRoute, extraQuery) {
|
|
104940
|
-
const
|
|
104941
|
-
const umiPath = `${TSO_UMI_ROUTE_PREFIX}/${
|
|
104892
|
+
const path48 = tsoSubRoute.replace(/^\/+/, "");
|
|
104893
|
+
const umiPath = `${TSO_UMI_ROUTE_PREFIX}/${path48}`;
|
|
104942
104894
|
const q = new URLSearchParams({ tso: umiPath });
|
|
104943
104895
|
if (extraQuery) {
|
|
104944
104896
|
for (const [key, value] of Object.entries(extraQuery)) {
|
|
@@ -104946,7 +104898,7 @@ function buildTsoPageWebUrl(webUrl, tsoSubRoute, extraQuery) {
|
|
|
104946
104898
|
if (v) q.set(key, v);
|
|
104947
104899
|
}
|
|
104948
104900
|
}
|
|
104949
|
-
return `${webUrl.replace(/\/+$/, "")}/v3/foreign_trade/tso/${
|
|
104901
|
+
return `${webUrl.replace(/\/+$/, "")}/v3/foreign_trade/tso/${path48}?${q.toString()}`;
|
|
104950
104902
|
}
|
|
104951
104903
|
function cmdConfigShow() {
|
|
104952
104904
|
const shared = readSharedConfig();
|
|
@@ -105934,8 +105886,7 @@ var VALID_MEDIA_TYPES = [
|
|
|
105934
105886
|
"TikTok",
|
|
105935
105887
|
"Yandex",
|
|
105936
105888
|
"MetaAd",
|
|
105937
|
-
"BingV2"
|
|
105938
|
-
"Kwai"
|
|
105889
|
+
"BingV2"
|
|
105939
105890
|
];
|
|
105940
105891
|
function applyListAccountsSearchKeyword(params, keyword) {
|
|
105941
105892
|
const kw = (keyword ?? "").trim();
|
|
@@ -105994,20 +105945,6 @@ var PLATFORM_CONFIG = {
|
|
|
105994
105945
|
},
|
|
105995
105946
|
responseType: "mas",
|
|
105996
105947
|
idSearchParam: "mediaCustomerIds"
|
|
105997
|
-
},
|
|
105998
|
-
Kwai: {
|
|
105999
|
-
path: "/query/media-account/SearchMediaAcountByCriteria",
|
|
106000
|
-
pageParam: "pageNum",
|
|
106001
|
-
fixedParams: {
|
|
106002
|
-
// 与 Meta 同源接口,后端要求 MediaTypes(否则会 400:mediaTypes is required)
|
|
106003
|
-
MediaTypes: "Kwai",
|
|
106004
|
-
MediaType: "Kwai",
|
|
106005
|
-
advStatus: "",
|
|
106006
|
-
mediaAccountState: "Approved,Linked",
|
|
106007
|
-
isForce: false
|
|
106008
|
-
},
|
|
106009
|
-
responseType: "mas",
|
|
106010
|
-
idSearchParam: "mediaCustomerIds"
|
|
106011
105948
|
}
|
|
106012
105949
|
};
|
|
106013
105950
|
function mergeTikTokAdList(items2, adList) {
|
|
@@ -106554,7 +106491,6 @@ async function runListAccounts(opts) {
|
|
|
106554
106491
|
const isTikTok = opts.media === "TikTok";
|
|
106555
106492
|
const isMetaAd = opts.media === "MetaAd";
|
|
106556
106493
|
const isBingV2 = opts.media === "BingV2";
|
|
106557
|
-
const isKwai = opts.media === "Kwai";
|
|
106558
106494
|
const tableBorderOpts = opts.unicode ? { plain: false } : void 0;
|
|
106559
106495
|
if (isGoogle) {
|
|
106560
106496
|
printGoogleTable(items2, tableBorderOpts, exposeScopeActivated);
|
|
@@ -106564,7 +106500,7 @@ async function runListAccounts(opts) {
|
|
|
106564
106500
|
printTikTokTable(items2, tableBorderOpts);
|
|
106565
106501
|
} else if (isMetaAd) {
|
|
106566
106502
|
printMetaTable(items2, tableBorderOpts);
|
|
106567
|
-
} else if (isBingV2
|
|
106503
|
+
} else if (isBingV2) {
|
|
106568
106504
|
printSpendMetricsAccountTable(items2, tableBorderOpts);
|
|
106569
106505
|
} else {
|
|
106570
106506
|
printDefaultTable(items2, opts.media, tableBorderOpts);
|
|
@@ -106591,10 +106527,10 @@ async function runListAccounts(opts) {
|
|
|
106591
106527
|
// src/commands/list-accounts/register.ts
|
|
106592
106528
|
function register6(program2) {
|
|
106593
106529
|
program2.command("list-accounts").description(
|
|
106594
|
-
"\u67E5\u8BE2\u5E7F\u544A\u8D26\u6237\u5217\u8868\u3002\u5F53\u524D\u8D26\u6237\u5728 TSO \u5E73\u53F0\u5173\u8054\u7684\u5168\u90E8\u5E7F\u544A\u8D26\u6237\uFF08Google/TikTok/Yandex/MetaAd/BingV2
|
|
106530
|
+
"\u67E5\u8BE2\u5E7F\u544A\u8D26\u6237\u5217\u8868\u3002\u5F53\u524D\u8D26\u6237\u5728 TSO \u5E73\u53F0\u5173\u8054\u7684\u5168\u90E8\u5E7F\u544A\u8D26\u6237\uFF08Google/TikTok/Yandex/MetaAd/BingV2 \u7B49\u5A92\u4F53\uFF09"
|
|
106595
106531
|
).option(
|
|
106596
106532
|
"-m, --media <type>",
|
|
106597
|
-
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2
|
|
106533
|
+
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2\uFF08\u7559\u7A7A\u5219\u67E5\u8BE2\u5168\u90E8\u5A92\u4F53\uFF09"
|
|
106598
106534
|
).option("-k, --keyword <text>", "\u5173\u952E\u5B57\uFF08\u516C\u53F8/\u8D26\u6237\u540D/\u8D26\u6237ID \u6A21\u7CCA\u5339\u914D\uFF09").option(
|
|
106599
106535
|
"-s, --status <status>",
|
|
106600
106536
|
"\u8D26\u6237\u72B6\u6001\uFF1Anormal\uFF08\u6B63\u5E38\uFF09| invalid\uFF08\u5931\u6548\uFF09| all\uFF08\u5168\u90E8\uFF0C\u9ED8\u8BA4\uFF09",
|
|
@@ -106629,7 +106565,7 @@ function register6(program2) {
|
|
|
106629
106565
|
init_auth();
|
|
106630
106566
|
init_cli_json_snapshot();
|
|
106631
106567
|
init_cli_table();
|
|
106632
|
-
var VALID_MEDIA = ["Google", "TikTok", "Yandex", "MetaAd", "BingV2"
|
|
106568
|
+
var VALID_MEDIA = ["Google", "TikTok", "Yandex", "MetaAd", "BingV2"];
|
|
106633
106569
|
async function runAccountActiveBills(opts) {
|
|
106634
106570
|
if (!VALID_MEDIA.includes(opts.media)) {
|
|
106635
106571
|
console.error(
|
|
@@ -106717,7 +106653,7 @@ function register7(program2) {
|
|
|
106717
106653
|
"\u67E5\u8BE2\u8D26\u6237\u6FC0\u6D3B/\u5145\u503C\u8D26\u5355\u660E\u7EC6\uFF08GET TSO /AccountActiveBills/{\u5A92\u4F53}/{entityId}\uFF1BentityId \u6765\u81EA list-accounts --json-out ./snap\uFF09"
|
|
106718
106654
|
).requiredOption(
|
|
106719
106655
|
"-m, --media <type>",
|
|
106720
|
-
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2
|
|
106656
|
+
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2"
|
|
106721
106657
|
).requiredOption(
|
|
106722
106658
|
"--id <entityId>",
|
|
106723
106659
|
"\u8D26\u6237 entityId\uFF08list-accounts --json-out ./snap-out \u4E2D\u6BCF\u6761 ma.entityId\uFF0C\u975E mediaCustomerId\uFF09"
|
|
@@ -106745,7 +106681,7 @@ init_cli_table();
|
|
|
106745
106681
|
init_balance();
|
|
106746
106682
|
init_media_account_lookup();
|
|
106747
106683
|
init_media_customer_id();
|
|
106748
|
-
var VALID_MEDIA_TYPES2 = ["Google", "TikTok", "Yandex", "MetaAd", "BingV2"
|
|
106684
|
+
var VALID_MEDIA_TYPES2 = ["Google", "TikTok", "Yandex", "MetaAd", "BingV2"];
|
|
106749
106685
|
async function runBalance(opts) {
|
|
106750
106686
|
const config = loadConfig(opts.token);
|
|
106751
106687
|
if (!VALID_MEDIA_TYPES2.includes(opts.media)) {
|
|
@@ -106869,7 +106805,7 @@ ${media} \u8D26\u6237\u4F59\u989D\uFF08\u7B2C 1 \u9875\uFF0C\u672C\u9875 ${out.l
|
|
|
106869
106805
|
function register8(program2) {
|
|
106870
106806
|
program2.command("balance").description("\u67E5\u8BE2\u5E7F\u544A\u8D26\u6237\u5B9E\u65F6\u4F59\u989D").requiredOption(
|
|
106871
106807
|
"-m, --media <type>",
|
|
106872
|
-
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2
|
|
106808
|
+
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2"
|
|
106873
106809
|
).requiredOption(
|
|
106874
106810
|
"-a, --accounts <ids>",
|
|
106875
106811
|
"\u8D26\u6237 mediaCustomerId\uFF08list-accounts \u7684 ma.mediaCustomerId\uFF1BYandex \u5F62\u5982 porg-\u2026\uFF1B\u7981\u6B62 entityId/UUID\uFF09\uFF0C\u591A\u4E2A\u7528\u9017\u53F7\u5206\u9694"
|
|
@@ -106938,18 +106874,6 @@ var SCAN_PLATFORM_CONFIG = {
|
|
|
106938
106874
|
},
|
|
106939
106875
|
responseType: "mas"
|
|
106940
106876
|
},
|
|
106941
|
-
Kwai: {
|
|
106942
|
-
path: "/query/media-account/SearchMediaAcountByCriteria",
|
|
106943
|
-
pageParam: "pageNum",
|
|
106944
|
-
fixedParams: {
|
|
106945
|
-
MediaTypes: "Kwai",
|
|
106946
|
-
MediaType: "Kwai",
|
|
106947
|
-
advStatus: "",
|
|
106948
|
-
mediaAccountState: "Approved,Linked",
|
|
106949
|
-
isForce: false
|
|
106950
|
-
},
|
|
106951
|
-
responseType: "mas"
|
|
106952
|
-
},
|
|
106953
106877
|
MetaAd: {
|
|
106954
106878
|
path: "/query/media-account/SearchMediaAcountByCriteria",
|
|
106955
106879
|
pageParam: "pageNum",
|
|
@@ -107378,7 +107302,7 @@ function register9(program2) {
|
|
|
107378
107302
|
"\u4E00\u952E\u626B\u63CF\u67D0\u5A92\u4F53\u4E0B\u6709\u6548\u8D26\u6237\u7684\u4F59\u989D\u4E0E\u65E5\u5747\u6D88\u8017\uFF0C\u8FD4\u56DE\u5168\u90E8\u5DF2\u68C0\u67E5\u8D26\u6237\uFF1B\u7528 hitReason \u6807\u8BB0\u7EED\u822A/\u4F59\u989D\u4E0D\u8DB3\u7684\u9884\u8B66\u884C\u3002\u66FF\u4EE3\u5FAA\u73AF\u8C03\u7528 balance \u7684\u4F20\u7EDF\u505A\u6CD5\u3002"
|
|
107379
107303
|
).requiredOption(
|
|
107380
107304
|
"-m, --media <type>",
|
|
107381
|
-
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2
|
|
107305
|
+
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2"
|
|
107382
107306
|
).option(
|
|
107383
107307
|
"-a, --accounts <ids>",
|
|
107384
107308
|
"\u6307\u5B9A mediaCustomerId\uFF08\u9017\u53F7\u5206\u9694\uFF09\uFF1B\u8DF3\u8FC7\u6E05\u5355\u7FFB\u9875\uFF0C\u5BF9\u8FD9\u4E9B ID \u62C9\u4F59\u989D+\u6D88\u8017\u540E\u5168\u90E8\u8F93\u51FA"
|
|
@@ -108080,7 +108004,7 @@ init_balance();
|
|
|
108080
108004
|
init_daily_metrics_range();
|
|
108081
108005
|
init_media_account_lookup();
|
|
108082
108006
|
init_media_customer_id();
|
|
108083
|
-
var VALID_MEDIA_TYPES3 = ["Google", "TikTok", "Yandex", "MetaAd", "BingV2"
|
|
108007
|
+
var VALID_MEDIA_TYPES3 = ["Google", "TikTok", "Yandex", "MetaAd", "BingV2"];
|
|
108084
108008
|
var MAX_BY_DAY_SPAN = 366;
|
|
108085
108009
|
var DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
108086
108010
|
function defaultDateRange2(now = /* @__PURE__ */ new Date()) {
|
|
@@ -108317,7 +108241,7 @@ function register12(program2) {
|
|
|
108317
108241
|
"\u67E5\u8BE2\u5E7F\u544A\u6D88\u8017\u3001\u70B9\u51FB\u3001\u8F6C\u5316\u7B49\u6295\u653E\u6570\u636E\uFF08\u9ED8\u8BA4\u8FD1 7 \u5929\u533A\u95F4\u5408\u8BA1\uFF0C\u4E0D\u542B\u4ECA\u5929\uFF0C\u65E5\u5386\u6309 UTC+8\uFF1B\u8981\u6309\u65E5\u660E\u7EC6\u52A0 --by-day\uFF09"
|
|
108318
108242
|
).requiredOption(
|
|
108319
108243
|
"-m, --media <type>",
|
|
108320
|
-
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2
|
|
108244
|
+
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2"
|
|
108321
108245
|
).option(
|
|
108322
108246
|
"-a, --accounts <ids>",
|
|
108323
108247
|
"\u8D26\u6237 mediaCustomerId\uFF08list-accounts \u7684 ma.mediaCustomerId\uFF1BYandex \u5F62\u5982 porg-\u2026\uFF1B\u7981\u6B62 entityId/UUID\uFF09\uFF0C\u591A\u4E2A\u7528\u9017\u53F7\u5206\u9694\uFF08\u5FC5\u586B\uFF09"
|
|
@@ -108349,7 +108273,7 @@ function register12(program2) {
|
|
|
108349
108273
|
init_auth();
|
|
108350
108274
|
init_cli_json_snapshot();
|
|
108351
108275
|
init_cli_table();
|
|
108352
|
-
var VALID_MEDIA_TYPES4 = ["Google", "TikTok", "Yandex", "MetaAd", "BingV2"
|
|
108276
|
+
var VALID_MEDIA_TYPES4 = ["Google", "TikTok", "Yandex", "MetaAd", "BingV2"];
|
|
108353
108277
|
async function runAccountHistory(opts) {
|
|
108354
108278
|
const config = loadConfig(opts.token);
|
|
108355
108279
|
if (opts.media && !VALID_MEDIA_TYPES4.includes(opts.media)) {
|
|
@@ -108432,7 +108356,7 @@ async function runAccountHistory(opts) {
|
|
|
108432
108356
|
console.log();
|
|
108433
108357
|
}
|
|
108434
108358
|
function register13(program2) {
|
|
108435
|
-
program2.command("account-history").description("\u67E5\u8BE2\u5F00\u6237\u7533\u8BF7\u5386\u53F2\u8BB0\u5F55").option("-m, --media <type>", "\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok |
|
|
108359
|
+
program2.command("account-history").description("\u67E5\u8BE2\u5F00\u6237\u7533\u8BF7\u5386\u53F2\u8BB0\u5F55").option("-m, --media <type>", "\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2").option("-s, --status <status>", "\u7533\u8BF7\u72B6\u6001\u5173\u952E\u5B57").option("-k, --keyword <text>", "\u641C\u7D22\u5173\u952E\u5B57\uFF08\u8D26\u6237\u540D/ID\uFF09").option("--start <date>", "\u5F00\u59CB\u65E5\u671F YYYY-MM-DD").option("--end <date>", "\u7ED3\u675F\u65E5\u671F YYYY-MM-DD").option("-p, --page <n>", "\u9875\u7801", parseInt).option("--page-size <n>", "\u6BCF\u9875\u6570\u91CF\uFF08\u9ED8\u8BA4 20\uFF09", parseInt).option("-t, --token <token>", "Auth Token").option(
|
|
108436
108360
|
"--json-out <path>",
|
|
108437
108361
|
"\u843D\u76D8\uFF08\u76EE\u5F55\u6216 *.json \u6587\u4EF6\u8DEF\u5F84\uFF09\u5E76\u66F4\u65B0 cli-manifest[-<\u67E5\u8BE2id>].json\uFF1B\u76EE\u5F55\u6A21\u5F0F\u6587\u4EF6\u540D\u4E3A `<section>[-<\u67E5\u8BE2id>].json`\uFF1Bstdout \u4E00\u884C\u6458\u8981 JSON\uFF0C\u542B outlineFile\uFF08TS \u5F0F\u7C7B\u578B\u5728 `*.outline.txt`\uFF09",
|
|
108438
108362
|
void 0
|
|
@@ -108460,8 +108384,7 @@ var VALID_MEDIA_TYPES5 = [
|
|
|
108460
108384
|
"TikTok",
|
|
108461
108385
|
"Yandex",
|
|
108462
108386
|
"MetaAd",
|
|
108463
|
-
"BingV2"
|
|
108464
|
-
"Kwai"
|
|
108387
|
+
"BingV2"
|
|
108465
108388
|
];
|
|
108466
108389
|
var REPORT_PUSH_MEDIA = /* @__PURE__ */ new Set(["Google", "TikTok"]);
|
|
108467
108390
|
function assertReportPushMedia(media) {
|
|
@@ -112449,7 +112372,7 @@ function cloneKeywordBlockShell(block) {
|
|
|
112449
112372
|
delete shell["matchTypeV2"];
|
|
112450
112373
|
return shell;
|
|
112451
112374
|
}
|
|
112452
|
-
function splitKeywordsForBatchJobBlockIfMixed(block,
|
|
112375
|
+
function splitKeywordsForBatchJobBlockIfMixed(block, path48, warnings) {
|
|
112453
112376
|
const declaredUi = matchTypeV2ToUi(readBlockMatchTypeRaw(block));
|
|
112454
112377
|
const entries = collectKeywordEntriesFromBlock(block);
|
|
112455
112378
|
if (entries.length === 0) return [block];
|
|
@@ -112468,7 +112391,7 @@ function splitKeywordsForBatchJobBlockIfMixed(block, path49, warnings) {
|
|
|
112468
112391
|
(ui) => matchTypeUiToV2(ui)
|
|
112469
112392
|
);
|
|
112470
112393
|
warnings.push(
|
|
112471
|
-
`${
|
|
112394
|
+
`${path48} \u542B\u591A\u79CD\u5339\u914D\u7C7B\u578B\uFF0C\u5DF2\u81EA\u52A8\u62C6\u5206\u4E3A ${groups.size} \u4E2A KeywordsForBatchJob \u5757\uFF08${labels.join("\u3001")}\uFF09`
|
|
112472
112395
|
);
|
|
112473
112396
|
const shell = cloneKeywordBlockShell(block);
|
|
112474
112397
|
const splitBlocks = [];
|
|
@@ -112488,16 +112411,16 @@ function splitKeywordsForBatchJobBlockIfMixed(block, path49, warnings) {
|
|
|
112488
112411
|
}
|
|
112489
112412
|
return splitBlocks;
|
|
112490
112413
|
}
|
|
112491
|
-
function validateKeywordCore(core,
|
|
112414
|
+
function validateKeywordCore(core, path48, errors, lengthViolations) {
|
|
112492
112415
|
const trimmed = core.trim();
|
|
112493
112416
|
if (!trimmed) {
|
|
112494
|
-
errors.push(`${
|
|
112417
|
+
errors.push(`${path48} \u5173\u952E\u8BCD\u8BCD\u5E72\u4E0D\u80FD\u4E3A\u7A7A`);
|
|
112495
112418
|
return false;
|
|
112496
112419
|
}
|
|
112497
112420
|
if (trimmed.length > GOOGLE_KEYWORD_MAX_CORE_LENGTH) {
|
|
112498
112421
|
if (lengthViolations) {
|
|
112499
112422
|
pushLengthViolation(lengthViolations, {
|
|
112500
|
-
path:
|
|
112423
|
+
path: path48,
|
|
112501
112424
|
field: "KeywordText",
|
|
112502
112425
|
kind: "keyword_core",
|
|
112503
112426
|
limit: GOOGLE_KEYWORD_MAX_CORE_LENGTH,
|
|
@@ -112507,13 +112430,13 @@ function validateKeywordCore(core, path49, errors, lengthViolations) {
|
|
|
112507
112430
|
});
|
|
112508
112431
|
}
|
|
112509
112432
|
errors.push(
|
|
112510
|
-
`${
|
|
112433
|
+
`${path48} \u5173\u952E\u8BCD\u8BCD\u5E72\u8D85\u8FC7 ${GOOGLE_KEYWORD_MAX_CORE_LENGTH} \u5B57\u7B26\uFF08\u5F53\u524D ${trimmed.length}\uFF09\uFF1A"${trimmed}"`
|
|
112511
112434
|
);
|
|
112512
112435
|
return false;
|
|
112513
112436
|
}
|
|
112514
112437
|
if (!VALID_CORE_REGEX.test(trimmed)) {
|
|
112515
112438
|
errors.push(
|
|
112516
|
-
`${
|
|
112439
|
+
`${path48} \u542B Google \u4E0D\u5141\u8BB8\u7684\u5B57\u7B26\uFF08\u8BCD\u5E72\u4EC5\u5141\u8BB8\u5B57\u6BCD/\u6570\u5B57/\u7A7A\u683C/\u8FDE\u5B57\u7B26/\u53E5\u70B9\uFF09\uFF1A"${trimmed.slice(0, 40)}${trimmed.length > 40 ? "\u2026" : ""}"`
|
|
112517
112440
|
);
|
|
112518
112441
|
return false;
|
|
112519
112442
|
}
|
|
@@ -112570,24 +112493,24 @@ function canonicalizeKeywordBatchBlock(block, resolvedMatchV2, normalizedTexts,
|
|
|
112570
112493
|
}
|
|
112571
112494
|
}
|
|
112572
112495
|
}
|
|
112573
|
-
function pushKeywordAutoFixWarning(warnings,
|
|
112496
|
+
function pushKeywordAutoFixWarning(warnings, path48, fieldLabel, trimmedRaw, formatted, declaredUi, beforeUi, matchType, inferredMatchType) {
|
|
112574
112497
|
if (inferredMatchType) {
|
|
112575
112498
|
warnings.push(
|
|
112576
|
-
`${
|
|
112499
|
+
`${path48}.${fieldLabel} \u672A\u6307\u5B9A MatchTypeV2\uFF0C\u5DF2\u6309\u8BCD\u9762\u63A8\u65AD\u4E3A ${matchTypeUiToV2(matchType)}`
|
|
112577
112500
|
);
|
|
112578
112501
|
return;
|
|
112579
112502
|
}
|
|
112580
112503
|
if (declaredUi && beforeUi !== declaredUi) {
|
|
112581
112504
|
warnings.push(
|
|
112582
|
-
`${
|
|
112505
|
+
`${path48}.${fieldLabel} MatchTypeV2=${matchTypeUiToV2(declaredUi)} \u4E0E\u8BCD\u9762\u4E0D\u4E00\u81F4\uFF0C\u5DF2\u81EA\u52A8\u4FEE\u590D\u4E3A\uFF1A${formatted}`
|
|
112583
112506
|
);
|
|
112584
112507
|
return;
|
|
112585
112508
|
}
|
|
112586
112509
|
if (formatted !== trimmedRaw) {
|
|
112587
|
-
warnings.push(`${
|
|
112510
|
+
warnings.push(`${path48}.${fieldLabel} \u5DF2\u81EA\u52A8\u4FEE\u590D\u8BCD\u9762\uFF1A${trimmedRaw} \u2192 ${formatted}`);
|
|
112588
112511
|
}
|
|
112589
112512
|
}
|
|
112590
|
-
function normalizeKeywordTextList(texts, matchTypeRaw,
|
|
112513
|
+
function normalizeKeywordTextList(texts, matchTypeRaw, path48, fieldLabel, errors, warnings, lengthViolations) {
|
|
112591
112514
|
const declaredUi = matchTypeV2ToUi(matchTypeRaw);
|
|
112592
112515
|
const normalized = [];
|
|
112593
112516
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -112595,7 +112518,7 @@ function normalizeKeywordTextList(texts, matchTypeRaw, path49, fieldLabel, error
|
|
|
112595
112518
|
for (let k = 0; k < texts.length; k++) {
|
|
112596
112519
|
const raw = texts[k];
|
|
112597
112520
|
if (typeof raw !== "string" || !raw.trim()) {
|
|
112598
|
-
errors.push(`${
|
|
112521
|
+
errors.push(`${path48}.${fieldLabel}[${k}] \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`);
|
|
112599
112522
|
continue;
|
|
112600
112523
|
}
|
|
112601
112524
|
const trimmedRaw = collapseDuplicateSpacesInKeywordText(raw.trim());
|
|
@@ -112606,7 +112529,7 @@ function normalizeKeywordTextList(texts, matchTypeRaw, path49, fieldLabel, error
|
|
|
112606
112529
|
);
|
|
112607
112530
|
pushKeywordAutoFixWarning(
|
|
112608
112531
|
warnings,
|
|
112609
|
-
|
|
112532
|
+
path48,
|
|
112610
112533
|
fieldLabel,
|
|
112611
112534
|
trimmedRaw,
|
|
112612
112535
|
formatted,
|
|
@@ -112616,11 +112539,11 @@ function normalizeKeywordTextList(texts, matchTypeRaw, path49, fieldLabel, error
|
|
|
112616
112539
|
inferredMatchType
|
|
112617
112540
|
);
|
|
112618
112541
|
const core = unwrapKeywordDisplayTextForEdit(formatted);
|
|
112619
|
-
if (!validateKeywordCore(core, `${
|
|
112542
|
+
if (!validateKeywordCore(core, `${path48}.${fieldLabel}[${k}]`, errors, lengthViolations))
|
|
112620
112543
|
continue;
|
|
112621
112544
|
const dedupeKey = `${matchTypeUiToV2(matchType)}:${core.toLowerCase()}`;
|
|
112622
112545
|
if (seen.has(dedupeKey)) {
|
|
112623
|
-
warnings.push(`${
|
|
112546
|
+
warnings.push(`${path48}.${fieldLabel}[${k}] \u4E0E\u540C\u7EC4\u91CD\u590D\uFF0C\u5DF2\u8DF3\u8FC7\uFF1A${formatted}`);
|
|
112624
112547
|
continue;
|
|
112625
112548
|
}
|
|
112626
112549
|
seen.add(dedupeKey);
|
|
@@ -112629,12 +112552,12 @@ function normalizeKeywordTextList(texts, matchTypeRaw, path49, fieldLabel, error
|
|
|
112629
112552
|
}
|
|
112630
112553
|
return { normalized, resolvedUi };
|
|
112631
112554
|
}
|
|
112632
|
-
function normalizeKeywordsForBatchJobBlock(block,
|
|
112555
|
+
function normalizeKeywordsForBatchJobBlock(block, path48, errors, warnings, lengthViolations) {
|
|
112633
112556
|
const matchTypeRaw = readBlockMatchTypeRaw(block);
|
|
112634
112557
|
const declaredUi = matchTypeV2ToUi(matchTypeRaw);
|
|
112635
112558
|
if (matchTypeRaw !== void 0 && declaredUi === null) {
|
|
112636
112559
|
errors.push(
|
|
112637
|
-
`${
|
|
112560
|
+
`${path48}.MatchTypeV2 \u65E0\u6548\uFF08${String(matchTypeRaw)}\uFF09\uFF0C\u5408\u6CD5\u503C\uFF1ABROAD | PHRASE | EXACT`
|
|
112638
112561
|
);
|
|
112639
112562
|
return;
|
|
112640
112563
|
}
|
|
@@ -112649,7 +112572,7 @@ function normalizeKeywordsForBatchJobBlock(block, path49, errors, warnings, leng
|
|
|
112649
112572
|
const result = normalizeKeywordTextList(
|
|
112650
112573
|
texts,
|
|
112651
112574
|
matchTypeRaw,
|
|
112652
|
-
|
|
112575
|
+
path48,
|
|
112653
112576
|
"KeywordText",
|
|
112654
112577
|
errors,
|
|
112655
112578
|
warnings,
|
|
@@ -112658,7 +112581,7 @@ function normalizeKeywordsForBatchJobBlock(block, path49, errors, warnings, leng
|
|
|
112658
112581
|
normalizedTexts = result.normalized;
|
|
112659
112582
|
if (result.resolvedUi) resolvedUi = result.resolvedUi;
|
|
112660
112583
|
if (normalizedTexts.length === 0 && texts.length > 0) {
|
|
112661
|
-
errors.push(`${
|
|
112584
|
+
errors.push(`${path48}.KeywordText \u7ECF\u6821\u9A8C\u540E\u65E0\u6709\u6548\u5173\u952E\u8BCD\uFF0C\u8BF7\u4FEE\u6B63\u8BCD\u9762\u6216 MatchTypeV2`);
|
|
112662
112585
|
}
|
|
112663
112586
|
}
|
|
112664
112587
|
if (hasItems && items2) {
|
|
@@ -112666,12 +112589,12 @@ function normalizeKeywordsForBatchJobBlock(block, path49, errors, warnings, leng
|
|
|
112666
112589
|
for (let k = 0; k < items2.length; k++) {
|
|
112667
112590
|
const item = items2[k];
|
|
112668
112591
|
if (!item || typeof item !== "object") {
|
|
112669
|
-
errors.push(`${
|
|
112592
|
+
errors.push(`${path48}.Items[${k}] \u5FC5\u987B\u662F\u5BF9\u8C61`);
|
|
112670
112593
|
continue;
|
|
112671
112594
|
}
|
|
112672
112595
|
const raw = readItemText(item);
|
|
112673
112596
|
if (raw === null || !raw.trim()) {
|
|
112674
|
-
errors.push(`${
|
|
112597
|
+
errors.push(`${path48}.Items[${k}].Text \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`);
|
|
112675
112598
|
continue;
|
|
112676
112599
|
}
|
|
112677
112600
|
const trimmedRaw = collapseDuplicateSpacesInKeywordText(raw.trim());
|
|
@@ -112682,7 +112605,7 @@ function normalizeKeywordsForBatchJobBlock(block, path49, errors, warnings, leng
|
|
|
112682
112605
|
);
|
|
112683
112606
|
pushKeywordAutoFixWarning(
|
|
112684
112607
|
warnings,
|
|
112685
|
-
|
|
112608
|
+
path48,
|
|
112686
112609
|
`Items[${k}].Text`,
|
|
112687
112610
|
trimmedRaw,
|
|
112688
112611
|
formatted,
|
|
@@ -112692,11 +112615,11 @@ function normalizeKeywordsForBatchJobBlock(block, path49, errors, warnings, leng
|
|
|
112692
112615
|
inferredMatchType
|
|
112693
112616
|
);
|
|
112694
112617
|
const core = unwrapKeywordDisplayTextForEdit(formatted);
|
|
112695
|
-
if (!validateKeywordCore(core, `${
|
|
112618
|
+
if (!validateKeywordCore(core, `${path48}.Items[${k}].Text`, errors, lengthViolations))
|
|
112696
112619
|
continue;
|
|
112697
112620
|
const dedupeKey = `${matchTypeUiToV2(matchType)}:${core.toLowerCase()}`;
|
|
112698
112621
|
if (seen.has(dedupeKey)) {
|
|
112699
|
-
warnings.push(`${
|
|
112622
|
+
warnings.push(`${path48}.Items[${k}].Text \u4E0E\u540C\u7EC4\u91CD\u590D\uFF0C\u5DF2\u8DF3\u8FC7\uFF1A${formatted}`);
|
|
112700
112623
|
continue;
|
|
112701
112624
|
}
|
|
112702
112625
|
seen.add(dedupeKey);
|
|
@@ -112841,16 +112764,16 @@ function warnIfNegativeKeywordsInPositiveKeywords(campaign, warnings) {
|
|
|
112841
112764
|
const raw = texts[ki];
|
|
112842
112765
|
if (typeof raw !== "string" || !raw.trim()) continue;
|
|
112843
112766
|
const core = normalizeKeywordCoreForNegativeCheck(raw);
|
|
112844
|
-
const
|
|
112767
|
+
const path48 = `campaign.AdGroupsForBatchJob[${gi}].KeywordsForBatchJob[${bi}].KeywordText[${ki}]`;
|
|
112845
112768
|
if (plannedNegCores.has(core)) {
|
|
112846
112769
|
warnings.push(
|
|
112847
|
-
`${
|
|
112770
|
+
`${path48} \u8BCD\u9762\u300C${raw}\u300D\u5DF2\u51FA\u73B0\u5728 campaign.NegativeKeywordsForBatchJob\uFF0C\u4E0D\u5E94\u91CD\u590D\u5199\u5165\u6B63\u5411 KeywordsForBatchJob\uFF1B\u5426\u8BCD\u53EA\u653E NegativeKeywordsForBatchJob`
|
|
112848
112771
|
);
|
|
112849
112772
|
continue;
|
|
112850
112773
|
}
|
|
112851
112774
|
if (looksLikeStandaloneNegativeKeyword(core)) {
|
|
112852
112775
|
warnings.push(
|
|
112853
|
-
`${
|
|
112776
|
+
`${path48} \u8BCD\u9762\u300C${raw}\u300D\u7591\u4F3C\u5426\u5B9A\u5173\u952E\u8BCD\uFF08\u5E38\u89C1\u5426\u8BCD\u8BCD\u6839\uFF09\uFF0C\u5E94\u5199\u5165 campaign.NegativeKeywordsForBatchJob\uFF08MatchTypeV2: BROAD\uFF09\uFF0C\u52FF\u653E\u5165 KeywordsForBatchJob`
|
|
112854
112777
|
);
|
|
112855
112778
|
}
|
|
112856
112779
|
}
|
|
@@ -116478,13 +116401,13 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
116478
116401
|
for (let ki = 0; ki < texts.length; ki++) {
|
|
116479
116402
|
const t = texts[ki];
|
|
116480
116403
|
if (typeof t !== "string" || !t.trim()) continue;
|
|
116481
|
-
const
|
|
116404
|
+
const path48 = `${groupPath}.KeywordsForBatchJob[${bi}].KeywordText[${ki}]`;
|
|
116482
116405
|
const key = keywordKey(t, matchTypeV2);
|
|
116483
116406
|
const plannedContent = `\u8BCD\u9762: ${t} | \u5339\u914D: ${matchTypeV2}`;
|
|
116484
116407
|
if (groupAbsent) {
|
|
116485
116408
|
pushItem(items2, {
|
|
116486
116409
|
layer: "keyword",
|
|
116487
|
-
path:
|
|
116410
|
+
path: path48,
|
|
116488
116411
|
adGroupName: groupName,
|
|
116489
116412
|
plannedContent,
|
|
116490
116413
|
status: "skipped",
|
|
@@ -116496,7 +116419,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
116496
116419
|
if (!liveKwKeys.has(key)) {
|
|
116497
116420
|
pushItem(items2, {
|
|
116498
116421
|
layer: "keyword",
|
|
116499
|
-
path:
|
|
116422
|
+
path: path48,
|
|
116500
116423
|
adGroupName: groupName,
|
|
116501
116424
|
plannedContent,
|
|
116502
116425
|
status: "missing",
|
|
@@ -116506,7 +116429,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
116506
116429
|
} else {
|
|
116507
116430
|
pushItem(items2, {
|
|
116508
116431
|
layer: "keyword",
|
|
116509
|
-
path:
|
|
116432
|
+
path: path48,
|
|
116510
116433
|
adGroupName: groupName,
|
|
116511
116434
|
plannedContent,
|
|
116512
116435
|
status: "ok",
|
|
@@ -116531,14 +116454,14 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
116531
116454
|
for (let ai = 0; ai < ads.length; ai++) {
|
|
116532
116455
|
const ad = asRecord3(ads[ai]);
|
|
116533
116456
|
if (!ad) continue;
|
|
116534
|
-
const
|
|
116457
|
+
const path48 = `${groupPath}.AdsForBatchJob[${ai}]`;
|
|
116535
116458
|
const primary = pickString2(ad["headlinePart1"], ad["AdTitle"]);
|
|
116536
116459
|
const finalUrl = pickString2(ad["Finalurl"], ad["DestinationUrl"], ad["finalUrl"]);
|
|
116537
116460
|
const rsaAssets = listPlannedRsaAssets(ad, groupPath, ai, groupName);
|
|
116538
116461
|
if (groupAbsent) {
|
|
116539
116462
|
pushItem(items2, {
|
|
116540
116463
|
layer: "ad",
|
|
116541
|
-
path:
|
|
116464
|
+
path: path48,
|
|
116542
116465
|
adGroupName: groupName,
|
|
116543
116466
|
plannedContent: primary ? `RSA \u9996\u6807\u9898: ${primary}${finalUrl ? ` | \u843D\u5730\u9875: ${finalUrl}` : ""}` : `AdsForBatchJob[${ai}]\uFF08\u7F3A\u5C11 headlinePart1\uFF09`,
|
|
116544
116467
|
status: "skipped",
|
|
@@ -116562,7 +116485,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
116562
116485
|
if (!primary) {
|
|
116563
116486
|
pushItem(items2, {
|
|
116564
116487
|
layer: "ad",
|
|
116565
|
-
path:
|
|
116488
|
+
path: path48,
|
|
116566
116489
|
adGroupName: groupName,
|
|
116567
116490
|
plannedContent: `AdsForBatchJob[${ai}]\uFF08\u7F3A\u5C11 headlinePart1\uFF0C\u65E0\u6CD5\u6BD4\u5BF9\u6574\u6761 RSA\uFF09`,
|
|
116568
116491
|
status: "missing",
|
|
@@ -116588,7 +116511,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
116588
116511
|
const rsaFound = liveAdsInGroup.some((la) => liveAdHasHeadline(la, primary));
|
|
116589
116512
|
pushItem(items2, {
|
|
116590
116513
|
layer: "ad",
|
|
116591
|
-
path:
|
|
116514
|
+
path: path48,
|
|
116592
116515
|
adGroupName: groupName,
|
|
116593
116516
|
plannedContent: `RSA \u9996\u6807\u9898: ${primary}${finalUrl ? ` | \u843D\u5730\u9875: ${finalUrl}` : ""}`,
|
|
116594
116517
|
status: rsaFound ? "ok" : "missing",
|
|
@@ -116654,11 +116577,11 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
116654
116577
|
for (let ei = 0; ei < extBlocks.length; ei++) {
|
|
116655
116578
|
const ext = asRecord3(extBlocks[ei]);
|
|
116656
116579
|
const plannedContent = formatExtensionPlanned(ext);
|
|
116657
|
-
const
|
|
116580
|
+
const path48 = `campaign.ExtensionsForBatchJob[${ei}]`;
|
|
116658
116581
|
if (campaignMissing) {
|
|
116659
116582
|
pushItem(items2, {
|
|
116660
116583
|
layer: "extension",
|
|
116661
|
-
path:
|
|
116584
|
+
path: path48,
|
|
116662
116585
|
plannedContent,
|
|
116663
116586
|
status: "skipped",
|
|
116664
116587
|
liveNote: "\u7CFB\u5217\u672A\u627E\u5230\uFF0C\u8DF3\u8FC7\u9644\u52A0\u4FE1\u606F\u6BD4\u5BF9",
|
|
@@ -116670,7 +116593,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
116670
116593
|
const remediateCommand = !found && ext && accountId && campaignId ? buildExtensionRemediateCommandLine({ accountId, campaignId, ext }) ?? void 0 : void 0;
|
|
116671
116594
|
pushItem(items2, {
|
|
116672
116595
|
layer: "extension",
|
|
116673
|
-
path:
|
|
116596
|
+
path: path48,
|
|
116674
116597
|
plannedContent,
|
|
116675
116598
|
status: found ? "ok" : "missing",
|
|
116676
116599
|
liveNote: `\u7CFB\u5217\u7EA7\u9644\u52A0\u4FE1\u606F\u8D26\u6237\u5185 ${liveExt}/${plannedExt} \u6761`,
|
|
@@ -116697,11 +116620,11 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
116697
116620
|
if (!id) continue;
|
|
116698
116621
|
const displayName = locationNames[li] || pickString2(loc["locationName"], loc["name"], loc["countryOrRegion"]) || "";
|
|
116699
116622
|
const plannedContent = `locationId: ${id}${displayName ? ` | \u540D\u79F0: ${displayName}` : ""}`;
|
|
116700
|
-
const
|
|
116623
|
+
const path48 = `campaign.targetedLocations[${li}]`;
|
|
116701
116624
|
if (campaignMissing) {
|
|
116702
116625
|
pushItem(items2, {
|
|
116703
116626
|
layer: "location",
|
|
116704
|
-
path:
|
|
116627
|
+
path: path48,
|
|
116705
116628
|
plannedContent,
|
|
116706
116629
|
status: "skipped",
|
|
116707
116630
|
liveNote: "\u7CFB\u5217\u672A\u627E\u5230\uFF0C\u8DF3\u8FC7\u5730\u57DF\u6BD4\u5BF9",
|
|
@@ -116713,7 +116636,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
116713
116636
|
const remediateCommand = !found && accountId && campaignId ? buildGeoRemediateCommandLine({ accountId, campaignId, locationId: id }) : void 0;
|
|
116714
116637
|
pushItem(items2, {
|
|
116715
116638
|
layer: "location",
|
|
116716
|
-
path:
|
|
116639
|
+
path: path48,
|
|
116717
116640
|
plannedContent,
|
|
116718
116641
|
status: found ? "ok" : "missing",
|
|
116719
116642
|
liveNote: `\u7CFB\u5217\u5DF2\u5B9A\u5411 ${liveLocIds.size}/${plannedLocCount} \u4E2A\u5730\u57DF`,
|
|
@@ -118225,8 +118148,8 @@ function pmaxChannelTypesUrl(googleApiUrl) {
|
|
|
118225
118148
|
}
|
|
118226
118149
|
function pmaxCampaignUrl(googleApiUrl, accountId, campaignId) {
|
|
118227
118150
|
const base = googleApiUrl.replace(/\/$/, "");
|
|
118228
|
-
const
|
|
118229
|
-
return campaignId ? `${
|
|
118151
|
+
const path48 = `${base}/accounts/${accountId}/campaign/pmax`;
|
|
118152
|
+
return campaignId ? `${path48}/${campaignId}` : path48;
|
|
118230
118153
|
}
|
|
118231
118154
|
function pmaxBrandAssetsUrl(googleApiUrl, accountId, campaignId) {
|
|
118232
118155
|
return `${pmaxCampaignUrl(googleApiUrl, accountId, campaignId)}/brand-assets`;
|
|
@@ -118236,8 +118159,8 @@ function pmaxBrandGuidelinesEnableUrl(googleApiUrl, accountId, campaignId) {
|
|
|
118236
118159
|
}
|
|
118237
118160
|
function pmaxAssetGroupUrl(googleApiUrl, accountId, assetGroupId, suffix) {
|
|
118238
118161
|
const base = googleApiUrl.replace(/\/$/, "");
|
|
118239
|
-
const
|
|
118240
|
-
return suffix ? `${
|
|
118162
|
+
const path48 = `${base}/accounts/${accountId}/campaign/pmax/asset-group/${assetGroupId}`;
|
|
118163
|
+
return suffix ? `${path48}/${suffix.replace(/^\//, "")}` : path48;
|
|
118241
118164
|
}
|
|
118242
118165
|
function pmaxCampaignAssetGroupUrl(googleApiUrl, accountId, campaignId) {
|
|
118243
118166
|
const base = googleApiUrl.replace(/\/$/, "");
|
|
@@ -120978,8 +120901,8 @@ async function runAdPmaxImageConvert(opts) {
|
|
|
120978
120901
|
}
|
|
120979
120902
|
|
|
120980
120903
|
// src/commands/ad/pmax-brand-mgmt.ts
|
|
120981
|
-
function loadBrandConfig(
|
|
120982
|
-
const cfg = loadPmaxJsonFile(
|
|
120904
|
+
function loadBrandConfig(path48, accountId, campaignId) {
|
|
120905
|
+
const cfg = loadPmaxJsonFile(path48);
|
|
120983
120906
|
return {
|
|
120984
120907
|
...cfg,
|
|
120985
120908
|
account: String(cfg["account"] ?? accountId).trim(),
|
|
@@ -122611,9 +122534,9 @@ function metaAdContext(token) {
|
|
|
122611
122534
|
const config = loadConfig(token);
|
|
122612
122535
|
return { config, facebookApiUrl: requireFacebookApi(config) };
|
|
122613
122536
|
}
|
|
122614
|
-
function adsUrl(facebookApiUrl, account,
|
|
122537
|
+
function adsUrl(facebookApiUrl, account, path48) {
|
|
122615
122538
|
const base = metaAdsBaseUrl(facebookApiUrl, account);
|
|
122616
|
-
const p =
|
|
122539
|
+
const p = path48.startsWith("/") ? path48 : `/${path48}`;
|
|
122617
122540
|
return `${base}${p}`;
|
|
122618
122541
|
}
|
|
122619
122542
|
async function metaAdGet(url, config, verbose, action) {
|
|
@@ -123545,9 +123468,9 @@ async function runMetaAdForms(opts) {
|
|
|
123545
123468
|
if (opts.after) params.set("after", opts.after);
|
|
123546
123469
|
if (opts.before) params.set("before", opts.before);
|
|
123547
123470
|
const qs = params.toString();
|
|
123548
|
-
const
|
|
123471
|
+
const path48 = `/pages/${encodeURIComponent(opts.pageId)}/forms${qs ? `?${qs}` : ""}`;
|
|
123549
123472
|
const raw = await metaAdGet(
|
|
123550
|
-
adsUrl(facebookApiUrl, digits,
|
|
123473
|
+
adsUrl(facebookApiUrl, digits, path48),
|
|
123551
123474
|
config,
|
|
123552
123475
|
opts.verbose,
|
|
123553
123476
|
"\u5217\u8868\u5355\u5931\u8D25"
|
|
@@ -123655,8 +123578,7 @@ var PLATFORM_ACCENTS = {
|
|
|
123655
123578
|
tiktok: "FE2C55",
|
|
123656
123579
|
yandex: "FC3F1D",
|
|
123657
123580
|
bingv2: "0078D4",
|
|
123658
|
-
bing: "0078D4"
|
|
123659
|
-
kwai: "FF8300"
|
|
123581
|
+
bing: "0078D4"
|
|
123660
123582
|
};
|
|
123661
123583
|
var NEUTRAL = {
|
|
123662
123584
|
titleFill: "1F2937",
|
|
@@ -123849,9 +123771,9 @@ function xfXml(x) {
|
|
|
123849
123771
|
function stylesXml(reg) {
|
|
123850
123772
|
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
123773
|
}
|
|
123852
|
-
function cellXml(ref,
|
|
123853
|
-
if (
|
|
123854
|
-
const { value, styleId } =
|
|
123774
|
+
function cellXml(ref, cell3) {
|
|
123775
|
+
if (cell3 == null) return "";
|
|
123776
|
+
const { value, styleId } = cell3;
|
|
123855
123777
|
const sAttr = styleId ? ` s="${styleId}"` : "";
|
|
123856
123778
|
if (value == null || value === "") {
|
|
123857
123779
|
return styleId ? `<c r="${ref}"${sAttr}/>` : "";
|
|
@@ -123866,7 +123788,7 @@ function sheetXml(sheet) {
|
|
|
123866
123788
|
const rowsXml = sheet.rows.map((row, i) => {
|
|
123867
123789
|
const r = i + 1;
|
|
123868
123790
|
const htAttr = row.height ? ` ht="${row.height}" customHeight="1"` : "";
|
|
123869
|
-
const cells = row.cells.map((
|
|
123791
|
+
const cells = row.cells.map((cell3, cIdx) => cellXml(`${colLetter(cIdx)}${r}`, cell3)).join("");
|
|
123870
123792
|
return `<row r="${r}"${htAttr}>${cells}</row>`;
|
|
123871
123793
|
}).join("");
|
|
123872
123794
|
const mergesXml = sheet.merges.length ? `<mergeCells count="${sheet.merges.length}">${sheet.merges.map((m) => `<mergeCell ref="${m}"/>`).join("")}</mergeCells>` : "";
|
|
@@ -127731,7 +127653,7 @@ function register25(program2) {
|
|
|
127731
127653
|
const accountCmd = program2.command("account").description("\u5E7F\u544A\u8D26\u6237\u7BA1\u7406\uFF1AOAuth \u6DFB\u52A0\u6388\u6743\u3001\u89E3\u9664\u5173\u8054\uFF08\u89E3\u7ED1\uFF09\u3001Google MCC \u7ED1\u5B9A/\u89E3\u7ED1\u3001\u8D26\u53F7\u5206\u4EAB");
|
|
127732
127654
|
accountCmd.command("list", { hidden: true }).description("\uFF08\u517C\u5BB9\u522B\u540D\uFF09\u540C list-accounts").option(
|
|
127733
127655
|
"-m, --media <type>",
|
|
127734
|
-
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2
|
|
127656
|
+
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2\uFF08\u7559\u7A7A\u5219\u67E5\u8BE2\u5168\u90E8\u5A92\u4F53\uFF09"
|
|
127735
127657
|
).option("-k, --keyword <text>", "\u5173\u952E\u5B57\uFF08\u516C\u53F8/\u8D26\u6237\u540D/\u8D26\u6237ID \u6A21\u7CCA\u5339\u914D\uFF09").option(
|
|
127736
127658
|
"-s, --status <status>",
|
|
127737
127659
|
"\u8D26\u6237\u72B6\u6001\uFF1Anormal\uFF08\u6B63\u5E38\uFF09| invalid\uFF08\u5931\u6548\uFF09| all\uFF08\u5168\u90E8\uFF0C\u9ED8\u8BA4\uFF09",
|
|
@@ -127846,7 +127768,7 @@ function register25(program2) {
|
|
|
127846
127768
|
"\u6DFB\u52A0\u6388\u6743\uFF1A\u9996\u6B21\u7ED1\u5B9A\u5A92\u4F53\u8D26\u6237 OAuth\uFF08\u7F51\u9875 manageAccounts\u300C\u6DFB\u52A0\u6388\u6743\u300D\uFF09\uFF1BOAuth \u5931\u6548\u8BF7\u7528 reauth"
|
|
127847
127769
|
).requiredOption(
|
|
127848
127770
|
"-m, --media <type>",
|
|
127849
|
-
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Meta | Yandex | BingV2
|
|
127771
|
+
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Meta | Yandex | BingV2"
|
|
127850
127772
|
).option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
|
|
127851
127773
|
await runAccountAuth({ token: opts.token, media: opts.media, verbose: opts.verbose });
|
|
127852
127774
|
});
|
|
@@ -127854,7 +127776,7 @@ function register25(program2) {
|
|
|
127854
127776
|
"\u91CD\u65B0\u6388\u6743\uFF1A\u5148\u89E3\u7ED1\u518D OAuth\uFF08\u7834\u574F\u6027\uFF1B\u987B\u7528\u6237\u786E\u8BA4\u540E\u52A0 --i-confirm + --commit\uFF1BAgent \u73AF\u5883\u7981\u6B62\uFF09"
|
|
127855
127777
|
).requiredOption(
|
|
127856
127778
|
"-m, --media <type>",
|
|
127857
|
-
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Meta | Yandex | BingV2
|
|
127779
|
+
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Meta | Yandex | BingV2"
|
|
127858
127780
|
).option("--id <entityId>", "\u5355\u4E2A\u8D26\u6237 entityId\uFF08\u6765\u81EA list-accounts \u7684 ma.entityId\uFF09").option("--ids <entityIds>", "\u6279\u91CF entityId\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u4E0E --id \u4E8C\u9009\u4E00\uFF0C\u53EF\u540C\u65F6\u4F20\uFF09").option("--i-confirm", "\u786E\u8BA4\u5DF2\u5411\u7528\u6237\u8BF4\u660E\u4F1A\u5148\u89E3\u7ED1\u518D OAuth \u5E76\u83B7\u5F97\u660E\u786E\u540C\u610F", false).option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
|
|
127859
127781
|
async (opts) => {
|
|
127860
127782
|
await runAccountReauth({
|
|
@@ -128709,212 +128631,6 @@ BingV2 \u884C\u4E1A\u5217\u8868\uFF08\u7B2C 1 \u9875\uFF0C\u672C\u9875 ${list.le
|
|
|
128709
128631
|
console.log();
|
|
128710
128632
|
}
|
|
128711
128633
|
|
|
128712
|
-
// src/commands/open-account/kwai.ts
|
|
128713
|
-
init_auth();
|
|
128714
|
-
import * as fs13 from "fs";
|
|
128715
|
-
import * as path18 from "path";
|
|
128716
|
-
|
|
128717
|
-
// src/commands/open-account/kwai-licence-id-type.ts
|
|
128718
|
-
var KWAI_LICENCE_ID_TYPE_LABELS = {
|
|
128719
|
-
"1": "\u7EDF\u4E00\u793E\u4F1A\u4FE1\u7528\u4EE3\u7801 / Business license Uniform social credit code",
|
|
128720
|
-
"2": "DUNS / Data Universal Numbering System",
|
|
128721
|
-
"3": "CNPJ"
|
|
128722
|
-
};
|
|
128723
|
-
var VALID = new Set(Object.keys(KWAI_LICENCE_ID_TYPE_LABELS));
|
|
128724
|
-
var LEGACY_ALIASES = {
|
|
128725
|
-
ENTERPRISE: "1",
|
|
128726
|
-
INDIVIDUAL: "1"
|
|
128727
|
-
};
|
|
128728
|
-
function normalizeKwaiLicenceIdType(raw) {
|
|
128729
|
-
const trimmed = raw.trim();
|
|
128730
|
-
const upper = trimmed.toUpperCase();
|
|
128731
|
-
const legacy = LEGACY_ALIASES[upper];
|
|
128732
|
-
if (legacy) {
|
|
128733
|
-
return { value: legacy, legacyAlias: trimmed };
|
|
128734
|
-
}
|
|
128735
|
-
if (VALID.has(trimmed)) {
|
|
128736
|
-
return { value: trimmed };
|
|
128737
|
-
}
|
|
128738
|
-
const options = Object.entries(KWAI_LICENCE_ID_TYPE_LABELS).map(([k, v]) => `${k}=${v.split(" / ")[0]}`).join("\uFF1B");
|
|
128739
|
-
throw new Error(
|
|
128740
|
-
`\u65E0\u6548\u7684 --licence-id-type\uFF1A${JSON.stringify(raw)}\u3002Kwai \u987B\u4F7F\u7528\u6570\u5B57\u4EE3\u7801\uFF08\u4E0E\u7F51\u9875\u4E00\u81F4\uFF09\uFF1A${options}\u3002\u52FF\u4F7F\u7528 ENTERPRISE / INDIVIDUAL\u3002`
|
|
128741
|
-
);
|
|
128742
|
-
}
|
|
128743
|
-
|
|
128744
|
-
// src/commands/open-account/kwai.ts
|
|
128745
|
-
async function uploadToKwai(filePath, apiBaseUrl, config, verbose) {
|
|
128746
|
-
const ext = path18.extname(filePath).toLowerCase().replace(".", "").replace("jpg", "jpeg");
|
|
128747
|
-
const imageType = ext || "jpeg";
|
|
128748
|
-
const fileBuffer = fs13.readFileSync(filePath);
|
|
128749
|
-
const base64Image = fileBuffer.toString("base64");
|
|
128750
|
-
const res = await apiFetch2(
|
|
128751
|
-
`${apiBaseUrl}/KwaiAccount/Management/Upload`,
|
|
128752
|
-
config,
|
|
128753
|
-
{
|
|
128754
|
-
method: "POST",
|
|
128755
|
-
body: JSON.stringify({ ImageType: imageType, base64Image })
|
|
128756
|
-
},
|
|
128757
|
-
verbose
|
|
128758
|
-
);
|
|
128759
|
-
const blobstoreKey = res?.data?.fileBlobKey;
|
|
128760
|
-
if (!blobstoreKey) {
|
|
128761
|
-
throw new Error("Kwai \u56FE\u7247\u4E0A\u4F20\u5931\u8D25\uFF1A\u54CD\u5E94\u4E2D\u672A\u5305\u542B fileBlobKey");
|
|
128762
|
-
}
|
|
128763
|
-
return blobstoreKey;
|
|
128764
|
-
}
|
|
128765
|
-
async function waitForKwaiAccountInHistory(config, accountName, verbose) {
|
|
128766
|
-
return pollUntil(
|
|
128767
|
-
async () => {
|
|
128768
|
-
const params = new URLSearchParams({
|
|
128769
|
-
MediaType: "Kwai",
|
|
128770
|
-
mediaAccountState: "Created,Approved,Denied",
|
|
128771
|
-
pageNo: "1",
|
|
128772
|
-
pageSize: "5",
|
|
128773
|
-
mediaCustomerName: accountName
|
|
128774
|
-
});
|
|
128775
|
-
const res = await apiFetchWithHeaders2(
|
|
128776
|
-
`${config.apiBaseUrl}/query/media-account/?${params}`,
|
|
128777
|
-
config,
|
|
128778
|
-
{},
|
|
128779
|
-
verbose
|
|
128780
|
-
);
|
|
128781
|
-
const hits = parseInt(res.headers["s-total-hits"] ?? "0", 10);
|
|
128782
|
-
if (hits > 0 && res.data?.length) {
|
|
128783
|
-
return res.data[0] ?? null;
|
|
128784
|
-
}
|
|
128785
|
-
return null;
|
|
128786
|
-
},
|
|
128787
|
-
2e3,
|
|
128788
|
-
3e4
|
|
128789
|
-
);
|
|
128790
|
-
}
|
|
128791
|
-
async function runOpenAccountKwai(opts) {
|
|
128792
|
-
const config = loadConfig(opts.token);
|
|
128793
|
-
let licenceIdType;
|
|
128794
|
-
try {
|
|
128795
|
-
const normalized = normalizeKwaiLicenceIdType(opts.licenceIdType);
|
|
128796
|
-
licenceIdType = normalized.value;
|
|
128797
|
-
if (normalized.legacyAlias) {
|
|
128798
|
-
console.error(
|
|
128799
|
-
`
|
|
128800
|
-
\u26A0\uFE0F --licence-id-type ${normalized.legacyAlias} \u5DF2\u5E9F\u5F03\uFF0C\u5DF2\u81EA\u52A8\u6620\u5C04\u4E3A ${licenceIdType}\uFF08\u7EDF\u4E00\u793E\u4F1A\u4FE1\u7528\u4EE3\u7801\uFF09\u3002\u8BF7\u6539\u7528\u6570\u5B57\u4EE3\u7801\uFF0C\u89C1 open-account-by-media.md \xA7 Kwai\u3002
|
|
128801
|
-
`
|
|
128802
|
-
);
|
|
128803
|
-
}
|
|
128804
|
-
} catch (err) {
|
|
128805
|
-
console.error(`
|
|
128806
|
-
\u274C ${err instanceof Error ? err.message : String(err)}
|
|
128807
|
-
`);
|
|
128808
|
-
process.exit(1);
|
|
128809
|
-
}
|
|
128810
|
-
if (!fs13.existsSync(opts.licenseFile)) {
|
|
128811
|
-
console.error(`
|
|
128812
|
-
\u274C \u8425\u4E1A\u6267\u7167\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${opts.licenseFile}
|
|
128813
|
-
`);
|
|
128814
|
-
process.exit(1);
|
|
128815
|
-
}
|
|
128816
|
-
console.log(" [1/3] \u6B63\u5728\u4E0A\u4F20\u8425\u4E1A\u6267\u7167\u5230 Siluzan \u5B58\u6863...");
|
|
128817
|
-
let imageId;
|
|
128818
|
-
let storageProvider;
|
|
128819
|
-
try {
|
|
128820
|
-
const uploaded = await uploadAttachment(
|
|
128821
|
-
opts.licenseFile,
|
|
128822
|
-
config.apiBaseUrl,
|
|
128823
|
-
config,
|
|
128824
|
-
opts.verbose
|
|
128825
|
-
);
|
|
128826
|
-
imageId = uploaded.id;
|
|
128827
|
-
storageProvider = uploaded.storageProvider;
|
|
128828
|
-
console.log(` Siluzan imageId: ${imageId}`);
|
|
128829
|
-
} catch (err) {
|
|
128830
|
-
console.error(
|
|
128831
|
-
`
|
|
128832
|
-
\u274C Siluzan \u5B58\u6863\u4E0A\u4F20\u5931\u8D25\uFF1A${err instanceof Error ? err.message : String(err)}
|
|
128833
|
-
`
|
|
128834
|
-
);
|
|
128835
|
-
process.exit(1);
|
|
128836
|
-
}
|
|
128837
|
-
console.log(" [2/3] \u6B63\u5728\u4E0A\u4F20\u8425\u4E1A\u6267\u7167\u5230 Kwai...");
|
|
128838
|
-
let blobstoreKey;
|
|
128839
|
-
try {
|
|
128840
|
-
blobstoreKey = await uploadToKwai(opts.licenseFile, config.apiBaseUrl, config, opts.verbose);
|
|
128841
|
-
} catch (err) {
|
|
128842
|
-
console.error(
|
|
128843
|
-
`
|
|
128844
|
-
\u274C Kwai \u8425\u4E1A\u6267\u7167\u4E0A\u4F20\u5931\u8D25\uFF1A${err instanceof Error ? err.message : String(err)}
|
|
128845
|
-
`
|
|
128846
|
-
);
|
|
128847
|
-
process.exit(1);
|
|
128848
|
-
}
|
|
128849
|
-
console.log(` Kwai blobstoreKey: ${blobstoreKey}`);
|
|
128850
|
-
console.log(" [3/3] \u6B63\u5728\u5173\u8054\u5E7F\u544A\u4E3B\u7EC4...");
|
|
128851
|
-
const magKey = await resolveGenericMagKey(
|
|
128852
|
-
config,
|
|
128853
|
-
opts.companyName,
|
|
128854
|
-
{ ImageId: imageId, StorageProvider: storageProvider },
|
|
128855
|
-
opts.verbose,
|
|
128856
|
-
opts.advertiserId
|
|
128857
|
-
);
|
|
128858
|
-
const body = {
|
|
128859
|
-
MediaAccountGroupId: magKey,
|
|
128860
|
-
KwaiAccountInfo: {
|
|
128861
|
-
licenceId: opts.licenceId,
|
|
128862
|
-
licenceRegisterCountryCode: opts.licenceCountry,
|
|
128863
|
-
licenceRegisterLocation: opts.licenceLocation,
|
|
128864
|
-
businessScope: opts.businessScope,
|
|
128865
|
-
product: opts.product,
|
|
128866
|
-
advertisementType: opts.adType,
|
|
128867
|
-
productUrl: opts.productUrl,
|
|
128868
|
-
currencyCode: "USD",
|
|
128869
|
-
licenceIdType,
|
|
128870
|
-
accountName: opts.accountName,
|
|
128871
|
-
legalEntityName: opts.companyName,
|
|
128872
|
-
newIndustryId1: opts.industryId1,
|
|
128873
|
-
newIndustryId2: opts.industryId2,
|
|
128874
|
-
mainCertPhotos: [
|
|
128875
|
-
{
|
|
128876
|
-
blobstoreKey,
|
|
128877
|
-
expireType: opts.expireType,
|
|
128878
|
-
expireAt: opts.expireType === 2 ? 0 : opts.expireAt ?? 0
|
|
128879
|
-
}
|
|
128880
|
-
],
|
|
128881
|
-
targetCountryInfos: [{ targetCountryCode: opts.targetCountry }]
|
|
128882
|
-
}
|
|
128883
|
-
};
|
|
128884
|
-
try {
|
|
128885
|
-
await apiFetch2(
|
|
128886
|
-
`${config.apiBaseUrl}/command/media-account/AddKwaiAccount`,
|
|
128887
|
-
config,
|
|
128888
|
-
{ method: "POST", body: JSON.stringify(body) },
|
|
128889
|
-
opts.verbose
|
|
128890
|
-
);
|
|
128891
|
-
} catch (err) {
|
|
128892
|
-
console.error(`
|
|
128893
|
-
\u274C \u63D0\u4EA4\u5931\u8D25\uFF1A${err instanceof Error ? err.message : String(err)}
|
|
128894
|
-
`);
|
|
128895
|
-
process.exit(1);
|
|
128896
|
-
}
|
|
128897
|
-
console.log("\n \u5DF2\u6536\u5230\u670D\u52A1\u7AEF\u53D7\u7406\uFF08HTTP 202\uFF09\uFF0C\u6B63\u5728\u786E\u8BA4\u5F00\u6237\u8BB0\u5F55\u662F\u5426\u843D\u5E93\u2026");
|
|
128898
|
-
const record2 = await waitForKwaiAccountInHistory(config, opts.accountName, opts.verbose);
|
|
128899
|
-
if (!record2) {
|
|
128900
|
-
console.error(
|
|
128901
|
-
`
|
|
128902
|
-
\u274C \u5F00\u6237\u8BF7\u6C42\u5DF2\u53D7\u7406\uFF0C\u4F46\u5728 30 \u79D2\u5185\u672A\u5728\u300C\u5F00\u6237\u8BB0\u5F55\u300D\u4E2D\u67E5\u5230\u8D26\u6237\u300C${opts.accountName}\u300D\u3002
|
|
128903
|
-
\u5E38\u89C1\u539F\u56E0\uFF1A--licence-id-type \u975E\u6CD5\uFF08\u987B\u4E3A 1/2/3\uFF0C\u4E0E\u7F51\u9875 KwaiOpenAnAccount \u4E00\u81F4\uFF09\u3001\u884C\u4E1A ID \u65E0\u6548\u6216\u8D44\u8D28\u5B57\u6BB5\u88AB Kwai \u5F02\u6B65\u62D2\u7EDD\u3002
|
|
128904
|
-
\u8BF7\u6838\u5BF9\u53C2\u6570\u540E\u91CD\u8BD5\uFF0C\u6216\u6267\u884C\uFF1Asiluzan-tso account-history -m Kwai -k ${opts.accountName}
|
|
128905
|
-
`
|
|
128906
|
-
);
|
|
128907
|
-
process.exit(1);
|
|
128908
|
-
}
|
|
128909
|
-
const state = record2.ma.mediaAccountState ?? "Unknown";
|
|
128910
|
-
console.log(
|
|
128911
|
-
`
|
|
128912
|
-
\u2705 Kwai \u5F00\u6237\u7533\u8BF7\u5DF2\u843D\u5E93\uFF08\u72B6\u6001\uFF1A${state}\uFF0C\u8D26\u6237\u540D\uFF1A${opts.accountName}\uFF09\u3002\u8BF7\u5728\u300C\u5F00\u6237\u8BB0\u5F55\u300D\u67E5\u770B\u5BA1\u6838\u8FDB\u5EA6\u3002
|
|
128913
|
-
`
|
|
128914
|
-
);
|
|
128915
|
-
logAccountOpeningHistoryWebUrl(config.apiBaseUrl, "Kwai");
|
|
128916
|
-
}
|
|
128917
|
-
|
|
128918
128634
|
// src/commands/open-account/google.ts
|
|
128919
128635
|
init_auth();
|
|
128920
128636
|
import * as readline2 from "readline/promises";
|
|
@@ -129282,13 +128998,13 @@ Google \u5F00\u6237\u884C\u4E1A\uFF08\u7B2C 1 \u9875\uFF0C\u672C\u9875 ${rows.le
|
|
|
129282
128998
|
|
|
129283
128999
|
// src/commands/open-account/tiktok.ts
|
|
129284
129000
|
init_auth();
|
|
129285
|
-
import * as
|
|
129286
|
-
import * as
|
|
129001
|
+
import * as fs13 from "fs";
|
|
129002
|
+
import * as path18 from "path";
|
|
129287
129003
|
init_cli_json_snapshot();
|
|
129288
129004
|
init_cli_table();
|
|
129289
129005
|
async function uploadLicenseToTikTok(filePath, businessCentreType, config, verbose) {
|
|
129290
|
-
const fileName =
|
|
129291
|
-
const fileBuffer =
|
|
129006
|
+
const fileName = path18.basename(filePath);
|
|
129007
|
+
const fileBuffer = fs13.readFileSync(filePath);
|
|
129292
129008
|
const base64Image = fileBuffer.toString("base64");
|
|
129293
129009
|
const res = await apiFetch2(
|
|
129294
129010
|
`${config.apiBaseUrl}/command/media-account/tiktok/Upload`,
|
|
@@ -129313,7 +129029,7 @@ async function uploadLicenseToTikTok(filePath, businessCentreType, config, verbo
|
|
|
129313
129029
|
async function runOpenAccountTikTok(opts) {
|
|
129314
129030
|
const config = loadConfig(opts.token);
|
|
129315
129031
|
const bcType = opts.businessCentreType ?? "Shop";
|
|
129316
|
-
if (!
|
|
129032
|
+
if (!fs13.existsSync(opts.licenseFile)) {
|
|
129317
129033
|
console.error(`
|
|
129318
129034
|
\u274C \u8425\u4E1A\u6267\u7167\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${opts.licenseFile}
|
|
129319
129035
|
`);
|
|
@@ -129685,7 +129401,7 @@ async function runOpenAccountMeta(opts) {
|
|
|
129685
129401
|
|
|
129686
129402
|
// src/commands/open-account-register.ts
|
|
129687
129403
|
function register26(program2) {
|
|
129688
|
-
const openAccountCmd = program2.command("open-account").description("\u5F00\u6237\u7533\u8BF7\uFF08Google / TikTok / Yandex / Bing /
|
|
129404
|
+
const openAccountCmd = program2.command("open-account").description("\u5F00\u6237\u7533\u8BF7\uFF08Google / TikTok / Yandex / Bing / Meta \u5F00\u6237\u94FE\u63A5\uFF09");
|
|
129689
129405
|
openAccountCmd.command("meta").description(
|
|
129690
129406
|
"\u83B7\u53D6 Meta/Facebook \u5B98\u65B9\u5F00\u6237\u94FE\u63A5\uFF08GET MetaAccount/Management/GetOpenAccountLink\uFF0C\u4E0E\u7F51\u9875\u300C\u7533\u8BF7\u5F00\u6237\u300D\u4E00\u81F4\uFF09"
|
|
129691
129407
|
).option("-t, --token <token>", "Auth Token").option("--open-browser", "\u5C1D\u8BD5\u7528\u7CFB\u7EDF\u9ED8\u8BA4\u6D4F\u89C8\u5668\u6253\u5F00\u94FE\u63A5").option("--json-out <path>", "\u843D\u76D8 JSON\uFF08\u542B openAccountUrl\uFF09\uFF1Bstdout \u4E00\u884C\u6458\u8981", void 0).option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
|
|
@@ -129901,34 +129617,6 @@ function register26(program2) {
|
|
|
129901
129617
|
});
|
|
129902
129618
|
}
|
|
129903
129619
|
);
|
|
129904
|
-
openAccountCmd.command("kwai").description("\u63D0\u4EA4 Kwai \u5F00\u6237\u7533\u8BF7\uFF08\u9700\u4E0A\u4F20\u8425\u4E1A\u6267\u7167\u56FE\u7247\uFF0C\u6309\u516C\u53F8\u540D\u81EA\u52A8\u521B\u5EFA/\u5173\u8054\u5E7F\u544A\u4E3B\u7EC4\uFF09").requiredOption("--licence-id <id>", "\u8425\u4E1A\u6267\u7167\u53F7\uFF08\u4E3B\u4F53\u4EE3\u7801\uFF09").requiredOption("--licence-country <code>", "\u4E3B\u4F53\u6CE8\u518C\u56FD\u5BB6\u4EE3\u7801\uFF0C\u5982 CN").requiredOption("--licence-location <address>", "\u4E3B\u4F53\u6CE8\u518C\u5730\uFF08\u7701\u5E02\u533A\u8BE6\u7EC6\u5730\u5740\uFF09").requiredOption("--business-scope <scope>", "\u8425\u4E1A\u8303\u56F4").requiredOption("--product <name>", "\u4EA7\u54C1\u6216\u54C1\u724C\u540D\u79F0").requiredOption("--ad-type <n>", "\u8D26\u6237\u7C7B\u578B\uFF1A1=\u6548\u679C\u5E7F\u544A 2=\u54C1\u724C\u5E7F\u544A", parseInt).requiredOption("--product-url <url>", "\u4EA7\u54C1\u6216\u54C1\u724C\u7F51\u5740").requiredOption(
|
|
129905
|
-
"--licence-id-type <code>",
|
|
129906
|
-
"\u6267\u7167/\u8BC1\u4EF6\u7C7B\u578B\uFF1A1=\u7EDF\u4E00\u793E\u4F1A\u4FE1\u7528\u4EE3\u7801 2=DUNS 3=CNPJ\uFF08\u4E0E\u7F51\u9875 KwaiOpenAnAccount \u4E0B\u62C9 value \u4E00\u81F4\uFF09"
|
|
129907
|
-
).requiredOption("--account-name <name>", "\u8D26\u6237\u540D\u79F0").requiredOption("--company-name <name>", "\u516C\u53F8\u4E3B\u4F53\u540D\u79F0").requiredOption("--industry-id1 <id>", "\u4E00\u7EA7\u884C\u4E1A ID").requiredOption("--industry-id2 <id>", "\u4E8C\u7EA7\u884C\u4E1A ID").requiredOption("--expire-type <n>", "\u6709\u6548\u671F\u7C7B\u578B\uFF1A1=\u6709\u9650\u671F 2=\u957F\u671F\u6709\u6548", parseInt).requiredOption("--target-country <code>", "\u6295\u653E\u5730\u533A\u56FD\u5BB6\u4EE3\u7801\uFF0C\u5982 US").requiredOption("--license-file <path>", "\u8425\u4E1A\u6267\u7167\u56FE\u7247\u672C\u5730\u8DEF\u5F84\uFF08JPG/PNG\uFF09").option("--expire-at <ms>", "\u5230\u671F\u65F6\u95F4\u6233\uFF08\u6BEB\u79D2\uFF09\uFF0Cexpire-type=1 \u65F6\u586B\u5199", parseInt).option("--advertiser-id <magKey>", "\u53EF\u9009\uFF1A\u624B\u52A8\u6307\u5B9A\u5E7F\u544A\u4E3B\u7EC4 magKey\uFF08\u4E00\u822C\u65E0\u9700\u586B\u5199\uFF09").option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
|
|
129908
|
-
async (opts) => {
|
|
129909
|
-
await runOpenAccountKwai({
|
|
129910
|
-
token: opts.token,
|
|
129911
|
-
advertiserId: opts.advertiserId,
|
|
129912
|
-
licenceId: opts.licenceId,
|
|
129913
|
-
licenceCountry: opts.licenceCountry,
|
|
129914
|
-
licenceLocation: opts.licenceLocation,
|
|
129915
|
-
businessScope: opts.businessScope,
|
|
129916
|
-
product: opts.product,
|
|
129917
|
-
adType: opts.adType,
|
|
129918
|
-
productUrl: opts.productUrl,
|
|
129919
|
-
licenceIdType: opts.licenceIdType,
|
|
129920
|
-
accountName: opts.accountName,
|
|
129921
|
-
companyName: opts.companyName,
|
|
129922
|
-
industryId1: opts.industryId1,
|
|
129923
|
-
industryId2: opts.industryId2,
|
|
129924
|
-
expireType: opts.expireType,
|
|
129925
|
-
targetCountry: opts.targetCountry,
|
|
129926
|
-
licenseFile: opts.licenseFile,
|
|
129927
|
-
expireAt: opts.expireAt,
|
|
129928
|
-
verbose: opts.verbose
|
|
129929
|
-
});
|
|
129930
|
-
}
|
|
129931
|
-
);
|
|
129932
129620
|
}
|
|
129933
129621
|
|
|
129934
129622
|
// src/commands/diagnostic.ts
|
|
@@ -130577,10 +130265,10 @@ async function runWebsiteDiagnosisCollect(opts) {
|
|
|
130577
130265
|
|
|
130578
130266
|
// src/commands/website-diagnosis/prepare.ts
|
|
130579
130267
|
init_cli_json_snapshot();
|
|
130580
|
-
import
|
|
130581
|
-
import
|
|
130268
|
+
import fs14 from "fs";
|
|
130269
|
+
import path19 from "path";
|
|
130582
130270
|
function readJson(filePath) {
|
|
130583
|
-
const text2 =
|
|
130271
|
+
const text2 = fs14.readFileSync(filePath, "utf8");
|
|
130584
130272
|
try {
|
|
130585
130273
|
const v = JSON.parse(text2);
|
|
130586
130274
|
if (!v || typeof v !== "object" || Array.isArray(v)) {
|
|
@@ -130610,8 +130298,8 @@ function signalsFromCollectPayload(collect) {
|
|
|
130610
130298
|
});
|
|
130611
130299
|
}
|
|
130612
130300
|
async function runWebsiteDiagnosisPrepare(opts) {
|
|
130613
|
-
const collectPath =
|
|
130614
|
-
if (!
|
|
130301
|
+
const collectPath = path19.resolve(opts.collectFile);
|
|
130302
|
+
if (!fs14.existsSync(collectPath)) {
|
|
130615
130303
|
console.error(`
|
|
130616
130304
|
\u274C \u627E\u4E0D\u5230 collect \u6587\u4EF6\uFF1A${collectPath}
|
|
130617
130305
|
`);
|
|
@@ -130620,11 +130308,11 @@ async function runWebsiteDiagnosisPrepare(opts) {
|
|
|
130620
130308
|
const collect = readJson(collectPath);
|
|
130621
130309
|
const signals = signalsFromCollectPayload(collect);
|
|
130622
130310
|
const scaffold = buildDiagnosisScaffold(signals);
|
|
130623
|
-
const outPath =
|
|
130624
|
-
opts.out ??
|
|
130311
|
+
const outPath = path19.resolve(
|
|
130312
|
+
opts.out ?? path19.join(path19.dirname(collectPath), "diagnosis.scaffold.json")
|
|
130625
130313
|
);
|
|
130626
|
-
|
|
130627
|
-
|
|
130314
|
+
fs14.mkdirSync(path19.dirname(outPath), { recursive: true });
|
|
130315
|
+
fs14.writeFileSync(outPath, JSON.stringify(scaffold, null, 2), "utf8");
|
|
130628
130316
|
const summary = {
|
|
130629
130317
|
url: signals.url,
|
|
130630
130318
|
out: outPath,
|
|
@@ -130661,23 +130349,23 @@ async function runWebsiteDiagnosisPrepare(opts) {
|
|
|
130661
130349
|
}
|
|
130662
130350
|
|
|
130663
130351
|
// src/commands/website-diagnosis/render-report.ts
|
|
130664
|
-
import
|
|
130352
|
+
import fs15 from "fs";
|
|
130665
130353
|
import fsPromises from "fs/promises";
|
|
130666
|
-
import
|
|
130354
|
+
import path20 from "path";
|
|
130667
130355
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
130668
130356
|
var TEMPLATE_BASENAMES = {
|
|
130669
130357
|
html: "website-diagnosis-report.html",
|
|
130670
130358
|
runtime: "website-diagnosis-report.runtime.js"
|
|
130671
130359
|
};
|
|
130672
130360
|
function resolveSkillTemplatePath(basename13) {
|
|
130673
|
-
const dir =
|
|
130361
|
+
const dir = path20.dirname(fileURLToPath4(import.meta.url));
|
|
130674
130362
|
const candidates = [
|
|
130675
|
-
|
|
130676
|
-
|
|
130677
|
-
|
|
130363
|
+
path20.join(dir, "skill", "report-templates", basename13),
|
|
130364
|
+
path20.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
130365
|
+
path20.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
130678
130366
|
];
|
|
130679
130367
|
for (const p of candidates) {
|
|
130680
|
-
if (
|
|
130368
|
+
if (fs15.existsSync(p)) return p;
|
|
130681
130369
|
}
|
|
130682
130370
|
return candidates[0];
|
|
130683
130371
|
}
|
|
@@ -130721,11 +130409,11 @@ function injectReportData(html, payload) {
|
|
|
130721
130409
|
return html.replace(marker, `window.__WEBSITE_DIAGNOSIS__ = ${json};`);
|
|
130722
130410
|
}
|
|
130723
130411
|
async function runWebsiteDiagnosisRender(opts) {
|
|
130724
|
-
const dataPath =
|
|
130412
|
+
const dataPath = path20.resolve(opts.dataFile);
|
|
130725
130413
|
const dataRaw = await readJsonFile(dataPath);
|
|
130726
130414
|
let data = asRecord4(dataRaw);
|
|
130727
130415
|
if (opts.collectFile) {
|
|
130728
|
-
const collectRaw = await readJsonFile(
|
|
130416
|
+
const collectRaw = await readJsonFile(path20.resolve(opts.collectFile));
|
|
130729
130417
|
data = mergeCollectLighthouse(data, asRecord4(collectRaw));
|
|
130730
130418
|
}
|
|
130731
130419
|
const templatePath = websiteDiagnosisReportTemplatePath();
|
|
@@ -130739,14 +130427,14 @@ async function runWebsiteDiagnosisRender(opts) {
|
|
|
130739
130427
|
`);
|
|
130740
130428
|
process.exit(1);
|
|
130741
130429
|
}
|
|
130742
|
-
const outPath =
|
|
130743
|
-
opts.out ??
|
|
130430
|
+
const outPath = path20.resolve(
|
|
130431
|
+
opts.out ?? path20.join(path20.dirname(dataPath), "website-diagnosis-report.html")
|
|
130744
130432
|
);
|
|
130745
|
-
const outDir =
|
|
130433
|
+
const outDir = path20.dirname(outPath);
|
|
130746
130434
|
await fsPromises.mkdir(outDir, { recursive: true });
|
|
130747
130435
|
await fsPromises.writeFile(outPath, injectReportData(html, data), "utf8");
|
|
130748
130436
|
const runtimeSrc = websiteDiagnosisRuntimePath();
|
|
130749
|
-
const runtimeOut =
|
|
130437
|
+
const runtimeOut = path20.join(outDir, TEMPLATE_BASENAMES.runtime);
|
|
130750
130438
|
let runtimeCopied = false;
|
|
130751
130439
|
try {
|
|
130752
130440
|
await fsPromises.copyFile(runtimeSrc, runtimeOut);
|
|
@@ -130950,8 +130638,8 @@ async function runMarketAnalysisCollect(opts) {
|
|
|
130950
130638
|
}
|
|
130951
130639
|
|
|
130952
130640
|
// src/commands/market-analysis/render-report.ts
|
|
130953
|
-
import
|
|
130954
|
-
import
|
|
130641
|
+
import fs16 from "fs/promises";
|
|
130642
|
+
import path21 from "path";
|
|
130955
130643
|
|
|
130956
130644
|
// src/commands/market-analysis/report-content.ts
|
|
130957
130645
|
var SILUZAN_ECHARTS_CDN_URL = "https://staticpn.siluzan.com/assets/slz/homeCDN/echarts.min.js";
|
|
@@ -131402,10 +131090,10 @@ function resolveMarketAnalysisHtml(data) {
|
|
|
131402
131090
|
throw new Error("JSON \u4E2D\u7F3A\u5C11 htmlContent \u6216 rawResponse \u5B57\u6BB5");
|
|
131403
131091
|
}
|
|
131404
131092
|
async function runMarketAnalysisRender(opts) {
|
|
131405
|
-
const dataPath =
|
|
131093
|
+
const dataPath = path21.resolve(opts.dataFile);
|
|
131406
131094
|
let dataRaw;
|
|
131407
131095
|
try {
|
|
131408
|
-
dataRaw = JSON.parse(await
|
|
131096
|
+
dataRaw = JSON.parse(await fs16.readFile(dataPath, "utf8"));
|
|
131409
131097
|
} catch {
|
|
131410
131098
|
console.error(`
|
|
131411
131099
|
\u274C \u65E0\u6CD5\u89E3\u6790 JSON\uFF1A${dataPath}
|
|
@@ -131438,11 +131126,11 @@ async function runMarketAnalysisRender(opts) {
|
|
|
131438
131126
|
);
|
|
131439
131127
|
process.exit(1);
|
|
131440
131128
|
}
|
|
131441
|
-
const outPath =
|
|
131442
|
-
opts.out ??
|
|
131129
|
+
const outPath = path21.resolve(
|
|
131130
|
+
opts.out ?? path21.join(path21.dirname(dataPath), "market-analysis-report.html")
|
|
131443
131131
|
);
|
|
131444
|
-
await
|
|
131445
|
-
await
|
|
131132
|
+
await fs16.mkdir(path21.dirname(outPath), { recursive: true });
|
|
131133
|
+
await fs16.writeFile(outPath, html, "utf8");
|
|
131446
131134
|
const { stats } = contentCheck;
|
|
131447
131135
|
console.log(`
|
|
131448
131136
|
\u2705 \u5E02\u573A\u5206\u6790 HTML \u62A5\u544A\u5DF2\u751F\u6210\uFF1A${outPath}
|
|
@@ -131488,12 +131176,12 @@ function registerMarketAnalysisCommands(program2) {
|
|
|
131488
131176
|
|
|
131489
131177
|
// src/commands/google-ads-diagnosis/run-collect.ts
|
|
131490
131178
|
init_auth();
|
|
131491
|
-
import
|
|
131492
|
-
import
|
|
131179
|
+
import fs20 from "fs/promises";
|
|
131180
|
+
import path25 from "path";
|
|
131493
131181
|
|
|
131494
131182
|
// src/commands/google-ads-diagnosis/shared.ts
|
|
131495
|
-
import
|
|
131496
|
-
import
|
|
131183
|
+
import fs17 from "fs";
|
|
131184
|
+
import path22 from "path";
|
|
131497
131185
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
131498
131186
|
var GOOGLE_ADS_DIAGNOSIS_TEMPLATE_BASENAME = "GoogleAdsDiagnosisReport.html";
|
|
131499
131187
|
var GOOGLE_ADS_DIAGNOSIS_DATA_MARKER = "__REPORT_DATA__";
|
|
@@ -131549,14 +131237,14 @@ function buildGoogleAdsDiagnosisNarrativeChecks() {
|
|
|
131549
131237
|
}
|
|
131550
131238
|
var GOOGLE_ADS_DIAGNOSIS_NARRATIVE_CHECKS = buildGoogleAdsDiagnosisNarrativeChecks();
|
|
131551
131239
|
function resolveSkillTemplatePath2(basename13) {
|
|
131552
|
-
const dir =
|
|
131240
|
+
const dir = path22.dirname(fileURLToPath5(import.meta.url));
|
|
131553
131241
|
const candidates = [
|
|
131554
|
-
|
|
131555
|
-
|
|
131556
|
-
|
|
131242
|
+
path22.join(dir, "skill", "report-templates", basename13),
|
|
131243
|
+
path22.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
131244
|
+
path22.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
131557
131245
|
];
|
|
131558
131246
|
for (const p of candidates) {
|
|
131559
|
-
if (
|
|
131247
|
+
if (fs17.existsSync(p)) return p;
|
|
131560
131248
|
}
|
|
131561
131249
|
return candidates[0];
|
|
131562
131250
|
}
|
|
@@ -131583,8 +131271,8 @@ function buildGoogleAdsDiagnosisCollectAgentHint(snapDir) {
|
|
|
131583
131271
|
}
|
|
131584
131272
|
|
|
131585
131273
|
// src/commands/google-ads-diagnosis/build-report-data.ts
|
|
131586
|
-
import
|
|
131587
|
-
import
|
|
131274
|
+
import fs19 from "fs";
|
|
131275
|
+
import path24 from "path";
|
|
131588
131276
|
|
|
131589
131277
|
// src/commands/google-ads-diagnosis/agent-brief.ts
|
|
131590
131278
|
function buildGoogleAdsDiagnosisAgentBrief(input) {
|
|
@@ -131798,8 +131486,8 @@ function emptySummary() {
|
|
|
131798
131486
|
|
|
131799
131487
|
// src/commands/google-ads-diagnosis/snapshot-io.ts
|
|
131800
131488
|
init_google_analysis_snapshot();
|
|
131801
|
-
import
|
|
131802
|
-
import
|
|
131489
|
+
import fs18 from "fs";
|
|
131490
|
+
import path23 from "path";
|
|
131803
131491
|
function dateRangeManifest(start, end) {
|
|
131804
131492
|
if (start && end) return { mode: "range", start, end };
|
|
131805
131493
|
return null;
|
|
@@ -131810,17 +131498,17 @@ function findSectionSnapshotFile(snapDir, section, accountId, start, end) {
|
|
|
131810
131498
|
accountId,
|
|
131811
131499
|
dateRangeManifest(start, end)
|
|
131812
131500
|
);
|
|
131813
|
-
const exactPath =
|
|
131814
|
-
if (
|
|
131501
|
+
const exactPath = path23.join(snapDir, exactName);
|
|
131502
|
+
if (fs18.existsSync(exactPath)) return exactPath;
|
|
131815
131503
|
if (start && end) return void 0;
|
|
131816
|
-
const files =
|
|
131817
|
-
return files.filter((f) => f.startsWith(`${section}-${accountId}`) && f.endsWith(".json")).sort().map((f) =>
|
|
131504
|
+
const files = fs18.readdirSync(snapDir);
|
|
131505
|
+
return files.filter((f) => f.startsWith(`${section}-${accountId}`) && f.endsWith(".json")).sort().map((f) => path23.join(snapDir, f)).at(-1);
|
|
131818
131506
|
}
|
|
131819
131507
|
function loadSectionSnapshot(snapDir, section, accountId, start, end) {
|
|
131820
131508
|
const file = findSectionSnapshotFile(snapDir, section, accountId, start, end);
|
|
131821
|
-
if (!file || !
|
|
131509
|
+
if (!file || !fs18.existsSync(file)) return null;
|
|
131822
131510
|
try {
|
|
131823
|
-
return JSON.parse(
|
|
131511
|
+
return JSON.parse(fs18.readFileSync(file, "utf8"));
|
|
131824
131512
|
} catch {
|
|
131825
131513
|
return null;
|
|
131826
131514
|
}
|
|
@@ -131947,10 +131635,10 @@ function toDailyConversionItem(row) {
|
|
|
131947
131635
|
};
|
|
131948
131636
|
}
|
|
131949
131637
|
function loadCompanyNameFromSnap(snapDir) {
|
|
131950
|
-
const file =
|
|
131951
|
-
if (!
|
|
131638
|
+
const file = path24.join(snapDir, "list-accounts-google.json");
|
|
131639
|
+
if (!fs19.existsSync(file)) return void 0;
|
|
131952
131640
|
try {
|
|
131953
|
-
const parsed = JSON.parse(
|
|
131641
|
+
const parsed = JSON.parse(fs19.readFileSync(file, "utf8"));
|
|
131954
131642
|
const item = parsed.items?.[0];
|
|
131955
131643
|
return item?.ma?.mediaCustomerName?.trim() || item?.mag?.advertiserName?.trim() || void 0;
|
|
131956
131644
|
} catch {
|
|
@@ -132528,8 +132216,8 @@ async function runGoogleAdsDiagnosisCollect(opts) {
|
|
|
132528
132216
|
console.error("\n\u274C collect \u987B\u540C\u65F6\u6307\u5B9A --start \u4E0E --end\u3002\n");
|
|
132529
132217
|
process.exit(1);
|
|
132530
132218
|
}
|
|
132531
|
-
const snapDir =
|
|
132532
|
-
await
|
|
132219
|
+
const snapDir = path25.resolve(opts.jsonOut);
|
|
132220
|
+
await fs20.mkdir(snapDir, { recursive: true });
|
|
132533
132221
|
let degraded = false;
|
|
132534
132222
|
console.error(`
|
|
132535
132223
|
\u{1F4E5} google-analysis \u62C9\u6570\uFF1A\u8D26\u6237 ${accountId}\uFF0C${opts.start} ~ ${opts.end}
|
|
@@ -132622,8 +132310,8 @@ async function runGoogleAdsDiagnosisCollect(opts) {
|
|
|
132622
132310
|
agentBrief,
|
|
132623
132311
|
agentHint: buildGoogleAdsDiagnosisCollectAgentHint(snapDir)
|
|
132624
132312
|
};
|
|
132625
|
-
const collectPath =
|
|
132626
|
-
await
|
|
132313
|
+
const collectPath = path25.join(snapDir, GOOGLE_ADS_DIAGNOSIS_COLLECT_BASENAME);
|
|
132314
|
+
await fs20.writeFile(collectPath, `${JSON.stringify(collectPayload, null, 2)}
|
|
132627
132315
|
`, "utf8");
|
|
132628
132316
|
console.log(
|
|
132629
132317
|
JSON.stringify({
|
|
@@ -132641,15 +132329,15 @@ async function runGoogleAdsDiagnosisCollect(opts) {
|
|
|
132641
132329
|
` Agent\uFF1A\u8BFB agentBrief + reportData\uFF0C\u6309 google-ads-diagnosis.md \u64B0\u5199 narrative\uFF0C\u4FDD\u5B58 ${GOOGLE_ADS_DIAGNOSIS_REPORT_BASENAME}`
|
|
132642
132330
|
);
|
|
132643
132331
|
console.error(
|
|
132644
|
-
` \u7EC8\u7A3F\uFF1Asiluzan-tso google-ads-diagnosis render --data ${
|
|
132332
|
+
` \u7EC8\u7A3F\uFF1Asiluzan-tso google-ads-diagnosis render --data ${path25.join(snapDir, GOOGLE_ADS_DIAGNOSIS_REPORT_BASENAME)}
|
|
132645
132333
|
`
|
|
132646
132334
|
);
|
|
132647
132335
|
if (degraded) process.exit(2);
|
|
132648
132336
|
}
|
|
132649
132337
|
|
|
132650
132338
|
// src/commands/google-ads-diagnosis/render-report.ts
|
|
132651
|
-
import
|
|
132652
|
-
import
|
|
132339
|
+
import fs21 from "fs/promises";
|
|
132340
|
+
import path26 from "path";
|
|
132653
132341
|
|
|
132654
132342
|
// src/commands/google-ads-diagnosis/report-content.ts
|
|
132655
132343
|
function asRecord7(value) {
|
|
@@ -132658,9 +132346,9 @@ function asRecord7(value) {
|
|
|
132658
132346
|
}
|
|
132659
132347
|
return null;
|
|
132660
132348
|
}
|
|
132661
|
-
function getNestedValue(root,
|
|
132349
|
+
function getNestedValue(root, path48) {
|
|
132662
132350
|
let cur = root;
|
|
132663
|
-
for (const key of
|
|
132351
|
+
for (const key of path48) {
|
|
132664
132352
|
const rec = asRecord7(cur);
|
|
132665
132353
|
if (!rec) return void 0;
|
|
132666
132354
|
cur = rec[key];
|
|
@@ -133053,7 +132741,7 @@ function asRecord10(value) {
|
|
|
133053
132741
|
}
|
|
133054
132742
|
async function tryLoadCollectReportData(collectPath) {
|
|
133055
132743
|
try {
|
|
133056
|
-
const raw = JSON.parse(await
|
|
132744
|
+
const raw = JSON.parse(await fs21.readFile(collectPath, "utf8"));
|
|
133057
132745
|
const root = asRecord10(raw);
|
|
133058
132746
|
const reportData = asRecord10(root?.reportData);
|
|
133059
132747
|
return reportData ?? root;
|
|
@@ -133062,10 +132750,10 @@ async function tryLoadCollectReportData(collectPath) {
|
|
|
133062
132750
|
}
|
|
133063
132751
|
}
|
|
133064
132752
|
async function runGoogleAdsDiagnosisRender(opts) {
|
|
133065
|
-
const dataPath =
|
|
132753
|
+
const dataPath = path26.resolve(opts.dataFile);
|
|
133066
132754
|
let dataRaw;
|
|
133067
132755
|
try {
|
|
133068
|
-
dataRaw = JSON.parse(await
|
|
132756
|
+
dataRaw = JSON.parse(await fs21.readFile(dataPath, "utf8"));
|
|
133069
132757
|
} catch {
|
|
133070
132758
|
console.error(`
|
|
133071
132759
|
\u274C \u65E0\u6CD5\u89E3\u6790 JSON\uFF1A${dataPath}
|
|
@@ -133074,8 +132762,8 @@ async function runGoogleAdsDiagnosisRender(opts) {
|
|
|
133074
132762
|
}
|
|
133075
132763
|
let data = asRecord10(dataRaw);
|
|
133076
132764
|
if (!opts.noMergeCollect) {
|
|
133077
|
-
const collectPath =
|
|
133078
|
-
opts.collectFile ??
|
|
132765
|
+
const collectPath = path26.resolve(
|
|
132766
|
+
opts.collectFile ?? path26.join(path26.dirname(dataPath), GOOGLE_ADS_DIAGNOSIS_COLLECT_BASENAME)
|
|
133079
132767
|
);
|
|
133080
132768
|
const collectReportData = await tryLoadCollectReportData(collectPath);
|
|
133081
132769
|
if (collectReportData) {
|
|
@@ -133148,7 +132836,7 @@ async function runGoogleAdsDiagnosisRender(opts) {
|
|
|
133148
132836
|
const templatePath = googleAdsDiagnosisReportTemplatePath();
|
|
133149
132837
|
let html;
|
|
133150
132838
|
try {
|
|
133151
|
-
html = await
|
|
132839
|
+
html = await fs21.readFile(templatePath, "utf8");
|
|
133152
132840
|
} catch {
|
|
133153
132841
|
console.error(`
|
|
133154
132842
|
\u274C \u672A\u627E\u5230\u62A5\u544A\u6A21\u677F\uFF1A${templatePath}
|
|
@@ -133166,11 +132854,11 @@ async function runGoogleAdsDiagnosisRender(opts) {
|
|
|
133166
132854
|
`);
|
|
133167
132855
|
process.exit(1);
|
|
133168
132856
|
}
|
|
133169
|
-
const outPath =
|
|
133170
|
-
opts.out ??
|
|
132857
|
+
const outPath = path26.resolve(
|
|
132858
|
+
opts.out ?? path26.join(path26.dirname(dataPath), "google-ads-diagnosis-report.html")
|
|
133171
132859
|
);
|
|
133172
|
-
await
|
|
133173
|
-
await
|
|
132860
|
+
await fs21.mkdir(path26.dirname(outPath), { recursive: true });
|
|
132861
|
+
await fs21.writeFile(outPath, rendered, "utf8");
|
|
133174
132862
|
console.log(`
|
|
133175
132863
|
\u2705 Google \u5E7F\u544A\u8BCA\u65AD HTML \u62A5\u544A\u5DF2\u751F\u6210\uFF1A${outPath}
|
|
133176
132864
|
`);
|
|
@@ -133314,14 +133002,14 @@ var FACEBOOK_SECTION_ALIASES = {
|
|
|
133314
133002
|
import { Command as Command2 } from "commander";
|
|
133315
133003
|
|
|
133316
133004
|
// src/commands/facebook-analysis/render-report.ts
|
|
133317
|
-
import
|
|
133005
|
+
import fs27 from "fs";
|
|
133318
133006
|
import fsPromises3 from "fs/promises";
|
|
133319
|
-
import
|
|
133007
|
+
import path34 from "path";
|
|
133320
133008
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
133321
133009
|
|
|
133322
133010
|
// src/commands/facebook-analysis/merge-snapshot.ts
|
|
133323
|
-
import * as
|
|
133324
|
-
import * as
|
|
133011
|
+
import * as fs26 from "fs/promises";
|
|
133012
|
+
import * as path33 from "path";
|
|
133325
133013
|
|
|
133326
133014
|
// src/commands/facebook-analysis/report-metrics.ts
|
|
133327
133015
|
function asRecord14(value) {
|
|
@@ -133378,24 +133066,94 @@ function genderLabel(gender) {
|
|
|
133378
133066
|
if (g === "female") return "female";
|
|
133379
133067
|
return str(gender) || "unknown";
|
|
133380
133068
|
}
|
|
133069
|
+
function enumKey(raw) {
|
|
133070
|
+
return raw.toLowerCase().replace(/[\s_\-./]+/g, "");
|
|
133071
|
+
}
|
|
133072
|
+
var RESULT_TYPE_ZH = {
|
|
133073
|
+
linkclick: "\u94FE\u63A5\u70B9\u51FB",
|
|
133074
|
+
landingpageview: "\u843D\u5730\u9875\u6D4F\u89C8",
|
|
133075
|
+
pageengagement: "\u516C\u5171\u4E3B\u9875\u4E92\u52A8",
|
|
133076
|
+
postengagement: "\u5E16\u5B50\u4E92\u52A8",
|
|
133077
|
+
videoview: "\u89C6\u9891\u64AD\u653E",
|
|
133078
|
+
purchase: "\u8D2D\u7269",
|
|
133079
|
+
addtocart: "\u52A0\u5165\u8D2D\u7269\u8F66",
|
|
133080
|
+
initiatecheckout: "\u53D1\u8D77\u7ED3\u8D26",
|
|
133081
|
+
completeregistration: "\u5B8C\u6210\u6CE8\u518C",
|
|
133082
|
+
viewcontent: "\u67E5\u770B\u5185\u5BB9",
|
|
133083
|
+
appinstall: "\u5E94\u7528\u5B89\u88C5",
|
|
133084
|
+
mobileappinstall: "\u5E94\u7528\u5B89\u88C5"
|
|
133085
|
+
};
|
|
133086
|
+
var OBJECTIVE_ZH = {
|
|
133087
|
+
outcomeawareness: "\u77E5\u540D\u5EA6",
|
|
133088
|
+
outcomeengagement: "\u4E92\u52A8",
|
|
133089
|
+
outcomeleads: "\u6F5C\u5728\u5BA2\u6237",
|
|
133090
|
+
outcomesales: "\u9500\u91CF",
|
|
133091
|
+
outcometraffic: "\u6D41\u91CF",
|
|
133092
|
+
outcomeapppromotion: "\u5E94\u7528\u63A8\u5E7F",
|
|
133093
|
+
brandawareness: "\u54C1\u724C\u77E5\u540D\u5EA6",
|
|
133094
|
+
reach: "\u8986\u76D6\u4EBA\u6570",
|
|
133095
|
+
traffic: "\u6D41\u91CF",
|
|
133096
|
+
linkclicks: "\u94FE\u63A5\u70B9\u51FB",
|
|
133097
|
+
engagement: "\u4E92\u52A8",
|
|
133098
|
+
postengagement: "\u5E16\u5B50\u4E92\u52A8",
|
|
133099
|
+
leadgeneration: "\u6F5C\u5728\u5BA2\u6237",
|
|
133100
|
+
conversions: "\u8F6C\u5316",
|
|
133101
|
+
appinstalls: "\u5E94\u7528\u5B89\u88C5",
|
|
133102
|
+
videoviews: "\u89C6\u9891\u64AD\u653E",
|
|
133103
|
+
messages: "\u6D88\u606F",
|
|
133104
|
+
catalogsales: "\u76EE\u5F55\u9500\u552E"
|
|
133105
|
+
};
|
|
133381
133106
|
function displayResultType(raw) {
|
|
133382
133107
|
const v = str(raw);
|
|
133383
133108
|
if (!v) return "";
|
|
133384
|
-
const key = v
|
|
133109
|
+
const key = enumKey(v);
|
|
133385
133110
|
if (key === "lead" || key === "leads" || key.includes("leadgrouped") || key.includes("instantform") || key === "onsiteconversionleadgrouped") {
|
|
133386
133111
|
return "\u6F5C\u5728\u5BA2\u6237\u4FE1\u606F\uFF08\u8868\u5355\uFF09\u91CF";
|
|
133387
133112
|
}
|
|
133388
|
-
return v;
|
|
133113
|
+
return RESULT_TYPE_ZH[key] ?? v;
|
|
133114
|
+
}
|
|
133115
|
+
function displayObjective(raw) {
|
|
133116
|
+
const v = str(raw);
|
|
133117
|
+
if (!v) return "";
|
|
133118
|
+
return OBJECTIVE_ZH[enumKey(v)] ?? v;
|
|
133389
133119
|
}
|
|
133390
133120
|
function displayAttribution(raw) {
|
|
133391
133121
|
const v = str(raw);
|
|
133392
133122
|
if (!v) return "";
|
|
133393
|
-
const key = v
|
|
133123
|
+
const key = enumKey(v);
|
|
133394
133124
|
if (key === "multiple" || key === "7dclick" || key === "7dclick1dview" || key.includes("7dclick") || key.includes("7dayclick")) {
|
|
133395
133125
|
return "\u70B9\u51FB\u540E 7 \u5929\u5185\u6216\u6D4F\u89C8\u540E 1 \u5929\u5185";
|
|
133396
133126
|
}
|
|
133127
|
+
if (key === "1dclick1dview" || key === "1dclickor1dview") {
|
|
133128
|
+
return "\u70B9\u51FB\u540E 1 \u5929\u5185\u6216\u6D4F\u89C8\u540E 1 \u5929\u5185";
|
|
133129
|
+
}
|
|
133130
|
+
if (key === "1dclick") return "\u70B9\u51FB\u540E 1 \u5929\u5185";
|
|
133131
|
+
if (key === "1dview") return "\u6D4F\u89C8\u540E 1 \u5929\u5185";
|
|
133132
|
+
if (key === "7dview") return "\u6D4F\u89C8\u540E 7 \u5929\u5185";
|
|
133133
|
+
if (key === "28dclick") return "\u70B9\u51FB\u540E 28 \u5929\u5185";
|
|
133397
133134
|
return v;
|
|
133398
133135
|
}
|
|
133136
|
+
function localizeMetricLabels(row) {
|
|
133137
|
+
if (!row) return;
|
|
133138
|
+
if (row.resultType != null) row.resultType = displayResultType(row.resultType);
|
|
133139
|
+
if (row.attributionSetting != null) {
|
|
133140
|
+
row.attributionSetting = displayAttribution(row.attributionSetting);
|
|
133141
|
+
}
|
|
133142
|
+
if (row.objective != null) row.objective = displayObjective(row.objective);
|
|
133143
|
+
}
|
|
133144
|
+
function localizeFacebookReportLabels(payload) {
|
|
133145
|
+
localizeMetricLabels(payload.meta);
|
|
133146
|
+
localizeMetricLabels(payload.kpis);
|
|
133147
|
+
const tables = payload.tables;
|
|
133148
|
+
if (!tables) return payload;
|
|
133149
|
+
for (const rows of Object.values(tables)) {
|
|
133150
|
+
if (!Array.isArray(rows)) continue;
|
|
133151
|
+
for (const row of rows) {
|
|
133152
|
+
localizeMetricLabels(asRecord14(row));
|
|
133153
|
+
}
|
|
133154
|
+
}
|
|
133155
|
+
return payload;
|
|
133156
|
+
}
|
|
133399
133157
|
function hasResults(row) {
|
|
133400
133158
|
const n = num3(row.results);
|
|
133401
133159
|
return n != null && n > 0;
|
|
@@ -133403,7 +133161,7 @@ function hasResults(row) {
|
|
|
133403
133161
|
|
|
133404
133162
|
// src/commands/facebook-analysis/merge-snapshot.ts
|
|
133405
133163
|
async function readManifest2(snapshotDir) {
|
|
133406
|
-
const entries = await
|
|
133164
|
+
const entries = await fs26.readdir(snapshotDir);
|
|
133407
133165
|
const manifestNames = entries.filter(
|
|
133408
133166
|
(n) => n.startsWith("report-manifest") && n.endsWith(".json")
|
|
133409
133167
|
);
|
|
@@ -133413,7 +133171,7 @@ async function readManifest2(snapshotDir) {
|
|
|
133413
133171
|
];
|
|
133414
133172
|
for (const name2 of ordered) {
|
|
133415
133173
|
try {
|
|
133416
|
-
const raw = await
|
|
133174
|
+
const raw = await fs26.readFile(path33.join(snapshotDir, name2), "utf8");
|
|
133417
133175
|
const parsed = JSON.parse(raw);
|
|
133418
133176
|
if (parsed?.artifacts?.length) return parsed;
|
|
133419
133177
|
} catch {
|
|
@@ -133423,7 +133181,7 @@ async function readManifest2(snapshotDir) {
|
|
|
133423
133181
|
}
|
|
133424
133182
|
async function loadSectionFile2(snapshotDir, file) {
|
|
133425
133183
|
try {
|
|
133426
|
-
const raw = await
|
|
133184
|
+
const raw = await fs26.readFile(path33.join(snapshotDir, file), "utf8");
|
|
133427
133185
|
return asRecord14(JSON.parse(raw));
|
|
133428
133186
|
} catch {
|
|
133429
133187
|
return null;
|
|
@@ -133467,7 +133225,7 @@ function mapAdSetRows(groups) {
|
|
|
133467
133225
|
})).sort((a, b) => (b.spend ?? 0) - (a.spend ?? 0));
|
|
133468
133226
|
}
|
|
133469
133227
|
async function mergeFacebookSnapshotIntoReport(payload, snapshotDir) {
|
|
133470
|
-
const absDir =
|
|
133228
|
+
const absDir = path33.resolve(snapshotDir);
|
|
133471
133229
|
const manifest = await readManifest2(snapshotDir);
|
|
133472
133230
|
if (!manifest) {
|
|
133473
133231
|
throw new Error(
|
|
@@ -133577,10 +133335,10 @@ function estimateColWidths(rows) {
|
|
|
133577
133335
|
const colCount = rows.reduce((max, row) => Math.max(max, row.length), 0);
|
|
133578
133336
|
const widths = new Array(colCount).fill(MIN_COL_WIDTH);
|
|
133579
133337
|
for (const row of rows) {
|
|
133580
|
-
row.forEach((
|
|
133581
|
-
if (
|
|
133338
|
+
row.forEach((cell3, idx) => {
|
|
133339
|
+
if (cell3 == null) return;
|
|
133582
133340
|
const longestLine = Math.max(
|
|
133583
|
-
...String(
|
|
133341
|
+
...String(cell3).split("\n").map((l) => l.length)
|
|
133584
133342
|
);
|
|
133585
133343
|
const width = Math.min(MAX_COL_WIDTH, Math.max(MIN_COL_WIDTH, Math.ceil(longestLine * 1.3)));
|
|
133586
133344
|
if (width > widths[idx]) widths[idx] = width;
|
|
@@ -134072,14 +133830,14 @@ var TEMPLATE_BASENAMES2 = {
|
|
|
134072
133830
|
};
|
|
134073
133831
|
var INJECT_MARKER2 = "window.__META_PERIOD_REPORT__ = window.__META_PERIOD_REPORT__ || null;";
|
|
134074
133832
|
function resolveSkillTemplatePath4(basename13) {
|
|
134075
|
-
const dir =
|
|
133833
|
+
const dir = path34.dirname(fileURLToPath7(import.meta.url));
|
|
134076
133834
|
const candidates = [
|
|
134077
|
-
|
|
134078
|
-
|
|
134079
|
-
|
|
133835
|
+
path34.join(dir, "skill", "report-templates", basename13),
|
|
133836
|
+
path34.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
133837
|
+
path34.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
134080
133838
|
];
|
|
134081
133839
|
for (const p of candidates) {
|
|
134082
|
-
if (
|
|
133840
|
+
if (fs27.existsSync(p)) return p;
|
|
134083
133841
|
}
|
|
134084
133842
|
return candidates[0];
|
|
134085
133843
|
}
|
|
@@ -134124,7 +133882,7 @@ function injectReportData3(html, payload) {
|
|
|
134124
133882
|
}
|
|
134125
133883
|
function defaultOutPath(dataPath, format, out) {
|
|
134126
133884
|
if (out?.trim()) {
|
|
134127
|
-
const resolved =
|
|
133885
|
+
const resolved = path34.resolve(out);
|
|
134128
133886
|
if (format === "xlsx" && !/\.xlsx$/i.test(resolved)) {
|
|
134129
133887
|
return resolved.replace(/\.(html?)$/i, ".xlsx");
|
|
134130
133888
|
}
|
|
@@ -134133,15 +133891,16 @@ function defaultOutPath(dataPath, format, out) {
|
|
|
134133
133891
|
}
|
|
134134
133892
|
return resolved;
|
|
134135
133893
|
}
|
|
134136
|
-
const dir =
|
|
134137
|
-
return
|
|
133894
|
+
const dir = path34.dirname(dataPath);
|
|
133895
|
+
return path34.join(dir, format === "xlsx" ? "meta-period-report.xlsx" : "meta-period-report.html");
|
|
134138
133896
|
}
|
|
134139
133897
|
async function runFacebookAnalysisRender(opts) {
|
|
134140
|
-
const dataPath =
|
|
133898
|
+
const dataPath = path34.resolve(opts.dataFile);
|
|
134141
133899
|
let data = asRecord17(await readJsonFile3(dataPath));
|
|
134142
133900
|
if (opts.snapshotDir?.trim()) {
|
|
134143
|
-
data = await mergeFacebookSnapshotIntoReport(data,
|
|
133901
|
+
data = await mergeFacebookSnapshotIntoReport(data, path34.resolve(opts.snapshotDir));
|
|
134144
133902
|
}
|
|
133903
|
+
localizeFacebookReportLabels(data);
|
|
134145
133904
|
const contentCheck = validateMetaPeriodReportContent(data);
|
|
134146
133905
|
if (!contentCheck.ok) {
|
|
134147
133906
|
console.error(`
|
|
@@ -134158,7 +133917,7 @@ async function runFacebookAnalysisRender(opts) {
|
|
|
134158
133917
|
const written = [];
|
|
134159
133918
|
for (const format of formats) {
|
|
134160
133919
|
const outPath = defaultOutPath(dataPath, format, opts.out);
|
|
134161
|
-
await fsPromises3.mkdir(
|
|
133920
|
+
await fsPromises3.mkdir(path34.dirname(outPath), { recursive: true });
|
|
134162
133921
|
if (format === "xlsx") {
|
|
134163
133922
|
writeMetaPeriodExcel(outPath, data);
|
|
134164
133923
|
} else {
|
|
@@ -134193,14 +133952,14 @@ async function runFacebookAnalysisRender(opts) {
|
|
|
134193
133952
|
}
|
|
134194
133953
|
|
|
134195
133954
|
// src/commands/facebook-analysis/diagnosis-render-report.ts
|
|
134196
|
-
import
|
|
133955
|
+
import fs29 from "fs";
|
|
134197
133956
|
import fsPromises4 from "fs/promises";
|
|
134198
|
-
import
|
|
133957
|
+
import path36 from "path";
|
|
134199
133958
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
134200
133959
|
|
|
134201
133960
|
// src/commands/facebook-analysis/diagnosis-merge-snapshot.ts
|
|
134202
|
-
import * as
|
|
134203
|
-
import * as
|
|
133961
|
+
import * as fs28 from "fs/promises";
|
|
133962
|
+
import * as path35 from "path";
|
|
134204
133963
|
function asRecord18(value) {
|
|
134205
133964
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
134206
133965
|
return value;
|
|
@@ -134236,7 +133995,7 @@ async function readManifest3(snapshotDir, accountId) {
|
|
|
134236
133995
|
const candidates = [];
|
|
134237
133996
|
if (accountId) candidates.push(reportManifestFile(accountId));
|
|
134238
133997
|
try {
|
|
134239
|
-
const entries = await
|
|
133998
|
+
const entries = await fs28.readdir(snapshotDir);
|
|
134240
133999
|
const manifestNames = entries.filter(
|
|
134241
134000
|
(n) => n.startsWith("report-manifest") && n.endsWith(".json")
|
|
134242
134001
|
);
|
|
@@ -134250,7 +134009,7 @@ async function readManifest3(snapshotDir, accountId) {
|
|
|
134250
134009
|
}
|
|
134251
134010
|
for (const name2 of candidates) {
|
|
134252
134011
|
try {
|
|
134253
|
-
const raw = await
|
|
134012
|
+
const raw = await fs28.readFile(path35.join(snapshotDir, name2), "utf8");
|
|
134254
134013
|
const parsed = JSON.parse(raw);
|
|
134255
134014
|
if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
|
|
134256
134015
|
} catch {
|
|
@@ -134260,14 +134019,14 @@ async function readManifest3(snapshotDir, accountId) {
|
|
|
134260
134019
|
}
|
|
134261
134020
|
async function loadSectionFile3(snapshotDir, file) {
|
|
134262
134021
|
try {
|
|
134263
|
-
const raw = await
|
|
134022
|
+
const raw = await fs28.readFile(path35.join(snapshotDir, file), "utf8");
|
|
134264
134023
|
return asRecord18(JSON.parse(raw));
|
|
134265
134024
|
} catch {
|
|
134266
134025
|
return null;
|
|
134267
134026
|
}
|
|
134268
134027
|
}
|
|
134269
134028
|
async function mergeMetaDiagnosisSnapshotIntoReport(payload, snapshotDir) {
|
|
134270
|
-
const absDir =
|
|
134029
|
+
const absDir = path35.resolve(snapshotDir);
|
|
134271
134030
|
const metaAccountId = typeof asRecord18(payload.meta)?.accountId === "string" ? asRecord18(payload.meta)?.accountId : void 0;
|
|
134272
134031
|
const manifest = await readManifest3(snapshotDir, metaAccountId);
|
|
134273
134032
|
if (!manifest) {
|
|
@@ -134546,14 +134305,14 @@ function formatMetaDiagnosisReportErrors(result) {
|
|
|
134546
134305
|
var TEMPLATE_BASENAME2 = "meta-account-diagnosis-report.html";
|
|
134547
134306
|
var INJECT_MARKER3 = "window.__META_DIAGNOSIS_REPORT__ = window.__META_DIAGNOSIS_REPORT__ || null;";
|
|
134548
134307
|
function resolveSkillTemplatePath5(basename13) {
|
|
134549
|
-
const dir =
|
|
134308
|
+
const dir = path36.dirname(fileURLToPath8(import.meta.url));
|
|
134550
134309
|
const candidates = [
|
|
134551
|
-
|
|
134552
|
-
|
|
134553
|
-
|
|
134310
|
+
path36.join(dir, "skill", "report-templates", basename13),
|
|
134311
|
+
path36.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
134312
|
+
path36.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
134554
134313
|
];
|
|
134555
134314
|
for (const p of candidates) {
|
|
134556
|
-
if (
|
|
134315
|
+
if (fs29.existsSync(p)) return p;
|
|
134557
134316
|
}
|
|
134558
134317
|
return candidates[0];
|
|
134559
134318
|
}
|
|
@@ -134582,10 +134341,10 @@ function injectReportData4(html, payload) {
|
|
|
134582
134341
|
return html.replace(INJECT_MARKER3, `window.__META_DIAGNOSIS_REPORT__ = ${json};`);
|
|
134583
134342
|
}
|
|
134584
134343
|
async function runFacebookAnalysisDiagnosisRender(opts) {
|
|
134585
|
-
const dataPath =
|
|
134344
|
+
const dataPath = path36.resolve(opts.dataFile);
|
|
134586
134345
|
let data = asRecord20(await readJsonFile4(dataPath));
|
|
134587
134346
|
if (opts.snapshotDir?.trim()) {
|
|
134588
|
-
data = await mergeMetaDiagnosisSnapshotIntoReport(data,
|
|
134347
|
+
data = await mergeMetaDiagnosisSnapshotIntoReport(data, path36.resolve(opts.snapshotDir));
|
|
134589
134348
|
}
|
|
134590
134349
|
const contentCheck = validateMetaDiagnosisReportContent(data);
|
|
134591
134350
|
if (!contentCheck.ok) {
|
|
@@ -134611,10 +134370,10 @@ async function runFacebookAnalysisDiagnosisRender(opts) {
|
|
|
134611
134370
|
`);
|
|
134612
134371
|
process.exit(1);
|
|
134613
134372
|
}
|
|
134614
|
-
const outPath =
|
|
134615
|
-
opts.out ??
|
|
134373
|
+
const outPath = path36.resolve(
|
|
134374
|
+
opts.out ?? path36.join(path36.dirname(dataPath), "meta-account-diagnosis-report.html")
|
|
134616
134375
|
);
|
|
134617
|
-
const outDir =
|
|
134376
|
+
const outDir = path36.dirname(outPath);
|
|
134618
134377
|
await fsPromises4.mkdir(outDir, { recursive: true });
|
|
134619
134378
|
await fsPromises4.writeFile(outPath, injectReportData4(html, data), "utf8");
|
|
134620
134379
|
const { stats } = contentCheck;
|
|
@@ -134632,7 +134391,7 @@ async function runFacebookAnalysisDiagnosisRender(opts) {
|
|
|
134632
134391
|
|
|
134633
134392
|
// src/commands/facebook-analysis/run-batch.ts
|
|
134634
134393
|
init_auth();
|
|
134635
|
-
import * as
|
|
134394
|
+
import * as path37 from "path";
|
|
134636
134395
|
import { performance as performance5 } from "perf_hooks";
|
|
134637
134396
|
init_version();
|
|
134638
134397
|
|
|
@@ -134734,7 +134493,7 @@ async function runAllFacebookSections(opts) {
|
|
|
134734
134493
|
const results = await runWithConcurrency3(tasks, concurrency);
|
|
134735
134494
|
const succeeded = results.filter((r) => r.ok).length;
|
|
134736
134495
|
const failed = results.length - succeeded;
|
|
134737
|
-
const absoluteSnapshotDir =
|
|
134496
|
+
const absoluteSnapshotDir = path37.resolve(opts.jsonOut);
|
|
134738
134497
|
const summary = {
|
|
134739
134498
|
kind: "siluzan-tso-facebook-analysis-snapshot-batch",
|
|
134740
134499
|
absoluteSnapshotDir,
|
|
@@ -134858,9 +134617,9 @@ function parseEffectiveStatusFilter(raw) {
|
|
|
134858
134617
|
}
|
|
134859
134618
|
return canonical.length ? canonical.join(",") : void 0;
|
|
134860
134619
|
}
|
|
134861
|
-
function facebookAdsUrl(facebookApiUrl, digits,
|
|
134620
|
+
function facebookAdsUrl(facebookApiUrl, digits, path48) {
|
|
134862
134621
|
const base = facebookApiUrl.replace(/\/$/, "");
|
|
134863
|
-
const p =
|
|
134622
|
+
const p = path48.startsWith("/") ? path48 : `/${path48}`;
|
|
134864
134623
|
return `${base}/api/fb/ads/${digits}${p}`;
|
|
134865
134624
|
}
|
|
134866
134625
|
function facebookInsightsUrl(facebookApiUrl, digits, level) {
|
|
@@ -134897,7 +134656,7 @@ async function fetchFacebookAccount(config, digits, verbose) {
|
|
|
134897
134656
|
verbose
|
|
134898
134657
|
);
|
|
134899
134658
|
}
|
|
134900
|
-
async function fetchFacebookPagedList(config, digits,
|
|
134659
|
+
async function fetchFacebookPagedList(config, digits, path48, opts) {
|
|
134901
134660
|
const base = requireFacebookApi(config);
|
|
134902
134661
|
const items2 = [];
|
|
134903
134662
|
let after;
|
|
@@ -134912,7 +134671,7 @@ async function fetchFacebookPagedList(config, digits, path49, opts) {
|
|
|
134912
134671
|
adsetId: opts.adsetId
|
|
134913
134672
|
});
|
|
134914
134673
|
const raw = await apiFetch2(
|
|
134915
|
-
`${facebookAdsUrl(base, digits,
|
|
134674
|
+
`${facebookAdsUrl(base, digits, path48)}?${query}`,
|
|
134916
134675
|
config,
|
|
134917
134676
|
{},
|
|
134918
134677
|
opts.verbose
|
|
@@ -135047,7 +134806,7 @@ async function runFacebookEntityList(opts, kind) {
|
|
|
135047
134806
|
}
|
|
135048
134807
|
const pageSize = resolveFacebookPageSize(opts.pageSize);
|
|
135049
134808
|
const config = loadConfig(opts.token);
|
|
135050
|
-
const
|
|
134809
|
+
const path48 = `/${kind}`;
|
|
135051
134810
|
const labels = {
|
|
135052
134811
|
campaigns: {
|
|
135053
134812
|
section: "facebook-campaign-entities",
|
|
@@ -135060,7 +134819,7 @@ async function runFacebookEntityList(opts, kind) {
|
|
|
135060
134819
|
const meta = labels[kind];
|
|
135061
134820
|
let result;
|
|
135062
134821
|
try {
|
|
135063
|
-
result = await fetchFacebookPagedList(config, manifestId,
|
|
134822
|
+
result = await fetchFacebookPagedList(config, manifestId, path48, {
|
|
135064
134823
|
pageSize,
|
|
135065
134824
|
verbose: !!opts.verbose,
|
|
135066
134825
|
effectiveStatus,
|
|
@@ -135793,7 +135552,7 @@ function endpointHintForBingSection(def) {
|
|
|
135793
135552
|
|
|
135794
135553
|
// src/commands/bing-analysis/run-batch.ts
|
|
135795
135554
|
init_auth();
|
|
135796
|
-
import * as
|
|
135555
|
+
import * as path38 from "path";
|
|
135797
135556
|
import { performance as performance6 } from "perf_hooks";
|
|
135798
135557
|
init_version();
|
|
135799
135558
|
async function runWithConcurrency4(tasks, concurrency) {
|
|
@@ -135868,7 +135627,7 @@ async function runAllBingSections(opts) {
|
|
|
135868
135627
|
const results = await runWithConcurrency4(tasks, concurrency);
|
|
135869
135628
|
const succeeded = results.filter((r) => r.ok).length;
|
|
135870
135629
|
const failed = results.length - succeeded;
|
|
135871
|
-
const absoluteSnapshotDir =
|
|
135630
|
+
const absoluteSnapshotDir = path38.resolve(opts.jsonOut);
|
|
135872
135631
|
const summary = {
|
|
135873
135632
|
kind: "siluzan-tso-bing-analysis-snapshot-batch",
|
|
135874
135633
|
absoluteSnapshotDir,
|
|
@@ -136212,14 +135971,14 @@ Bing \u5B98\u65B9\u6708\u6D88\u8017\uFF08${id}\uFF09
|
|
|
136212
135971
|
import { Command as Command3 } from "commander";
|
|
136213
135972
|
|
|
136214
135973
|
// src/commands/bing-analysis/render-report.ts
|
|
136215
|
-
import
|
|
135974
|
+
import fs31 from "fs";
|
|
136216
135975
|
import fsPromises5 from "fs/promises";
|
|
136217
|
-
import
|
|
135976
|
+
import path40 from "path";
|
|
136218
135977
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
136219
135978
|
|
|
136220
135979
|
// src/commands/bing-analysis/merge-snapshot.ts
|
|
136221
|
-
import * as
|
|
136222
|
-
import * as
|
|
135980
|
+
import * as fs30 from "fs/promises";
|
|
135981
|
+
import * as path39 from "path";
|
|
136223
135982
|
function asRecord22(value) {
|
|
136224
135983
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
136225
135984
|
return value;
|
|
@@ -136241,7 +136000,7 @@ function asRows2(value) {
|
|
|
136241
136000
|
}
|
|
136242
136001
|
async function loadSectionPayload(snapshotDir, file) {
|
|
136243
136002
|
try {
|
|
136244
|
-
const raw = await
|
|
136003
|
+
const raw = await fs30.readFile(path39.join(snapshotDir, file), "utf8");
|
|
136245
136004
|
return JSON.parse(raw);
|
|
136246
136005
|
} catch {
|
|
136247
136006
|
return null;
|
|
@@ -136251,7 +136010,7 @@ async function readManifest4(snapshotDir, accountId) {
|
|
|
136251
136010
|
const candidates = [];
|
|
136252
136011
|
if (accountId) candidates.push(reportManifestFile(accountId));
|
|
136253
136012
|
try {
|
|
136254
|
-
const entries = await
|
|
136013
|
+
const entries = await fs30.readdir(snapshotDir);
|
|
136255
136014
|
const manifestNames = entries.filter(
|
|
136256
136015
|
(n) => n.startsWith("report-manifest") && n.endsWith(".json")
|
|
136257
136016
|
);
|
|
@@ -136262,7 +136021,7 @@ async function readManifest4(snapshotDir, accountId) {
|
|
|
136262
136021
|
}
|
|
136263
136022
|
for (const name2 of candidates) {
|
|
136264
136023
|
try {
|
|
136265
|
-
const raw = await
|
|
136024
|
+
const raw = await fs30.readFile(path39.join(snapshotDir, name2), "utf8");
|
|
136266
136025
|
const parsed = JSON.parse(raw);
|
|
136267
136026
|
if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
|
|
136268
136027
|
} catch {
|
|
@@ -136411,7 +136170,7 @@ function mapSearchTermRows(payload) {
|
|
|
136411
136170
|
);
|
|
136412
136171
|
}
|
|
136413
136172
|
async function mergeBingAnalysisSnapshotIntoReport(payload, snapshotDir) {
|
|
136414
|
-
const absDir =
|
|
136173
|
+
const absDir = path39.resolve(snapshotDir);
|
|
136415
136174
|
const metaAccountId = typeof asRecord22(payload.meta)?.accountId === "string" ? asRecord22(payload.meta)?.accountId : void 0;
|
|
136416
136175
|
const manifest = await readManifest4(snapshotDir, metaAccountId);
|
|
136417
136176
|
if (!manifest) {
|
|
@@ -136646,14 +136405,14 @@ function formatBingPeriodReportErrors(result) {
|
|
|
136646
136405
|
var TEMPLATE_BASENAME3 = "bing-period-report.html";
|
|
136647
136406
|
var INJECT_MARKER4 = "window.__BING_PERIOD_REPORT__ = window.__BING_PERIOD_REPORT__ || null;";
|
|
136648
136407
|
function resolveSkillTemplatePath6(basename13) {
|
|
136649
|
-
const dir =
|
|
136408
|
+
const dir = path40.dirname(fileURLToPath9(import.meta.url));
|
|
136650
136409
|
const candidates = [
|
|
136651
|
-
|
|
136652
|
-
|
|
136653
|
-
|
|
136410
|
+
path40.join(dir, "skill", "report-templates", basename13),
|
|
136411
|
+
path40.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
136412
|
+
path40.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
136654
136413
|
];
|
|
136655
136414
|
for (const p of candidates) {
|
|
136656
|
-
if (
|
|
136415
|
+
if (fs31.existsSync(p)) return p;
|
|
136657
136416
|
}
|
|
136658
136417
|
return candidates[0];
|
|
136659
136418
|
}
|
|
@@ -136682,10 +136441,10 @@ function injectReportData5(html, payload) {
|
|
|
136682
136441
|
return html.replace(INJECT_MARKER4, `window.__BING_PERIOD_REPORT__ = ${json};`);
|
|
136683
136442
|
}
|
|
136684
136443
|
async function runBingAnalysisRender(opts) {
|
|
136685
|
-
const dataPath =
|
|
136444
|
+
const dataPath = path40.resolve(opts.dataFile);
|
|
136686
136445
|
let data = asRecord24(await readJsonFile5(dataPath));
|
|
136687
136446
|
if (opts.snapshotDir?.trim()) {
|
|
136688
|
-
data = await mergeBingAnalysisSnapshotIntoReport(data,
|
|
136447
|
+
data = await mergeBingAnalysisSnapshotIntoReport(data, path40.resolve(opts.snapshotDir));
|
|
136689
136448
|
}
|
|
136690
136449
|
const contentCheck = validateBingPeriodReportContent(data);
|
|
136691
136450
|
if (!contentCheck.ok) {
|
|
@@ -136711,10 +136470,10 @@ async function runBingAnalysisRender(opts) {
|
|
|
136711
136470
|
`);
|
|
136712
136471
|
process.exit(1);
|
|
136713
136472
|
}
|
|
136714
|
-
const outPath =
|
|
136715
|
-
opts.out ??
|
|
136473
|
+
const outPath = path40.resolve(
|
|
136474
|
+
opts.out ?? path40.join(path40.dirname(dataPath), "bing-period-report.html")
|
|
136716
136475
|
);
|
|
136717
|
-
const outDir =
|
|
136476
|
+
const outDir = path40.dirname(outPath);
|
|
136718
136477
|
await fsPromises5.mkdir(outDir, { recursive: true });
|
|
136719
136478
|
await fsPromises5.writeFile(outPath, injectReportData5(html, data), "utf8");
|
|
136720
136479
|
const { stats } = contentCheck;
|
|
@@ -137050,7 +136809,7 @@ async function fetchTikTokInterestList(config, account, verbose) {
|
|
|
137050
136809
|
|
|
137051
136810
|
// src/commands/tiktok-analysis/run-batch.ts
|
|
137052
136811
|
init_auth();
|
|
137053
|
-
import * as
|
|
136812
|
+
import * as path41 from "path";
|
|
137054
136813
|
import { performance as performance7 } from "perf_hooks";
|
|
137055
136814
|
init_version();
|
|
137056
136815
|
async function runWithConcurrency5(tasks, concurrency) {
|
|
@@ -137125,7 +136884,7 @@ async function runAllTikTokSections(opts) {
|
|
|
137125
136884
|
const results = await runWithConcurrency5(tasks, concurrency);
|
|
137126
136885
|
const succeeded = results.filter((r) => r.ok).length;
|
|
137127
136886
|
const failed = results.length - succeeded;
|
|
137128
|
-
const absoluteSnapshotDir =
|
|
136887
|
+
const absoluteSnapshotDir = path41.resolve(opts.jsonOut);
|
|
137129
136888
|
const summary = {
|
|
137130
136889
|
kind: "siluzan-tso-tiktok-analysis-snapshot-batch",
|
|
137131
136890
|
absoluteSnapshotDir,
|
|
@@ -137148,14 +136907,14 @@ init_auth();
|
|
|
137148
136907
|
import { Command as Command4 } from "commander";
|
|
137149
136908
|
|
|
137150
136909
|
// src/commands/tiktok-analysis/render-report.ts
|
|
137151
|
-
import
|
|
136910
|
+
import fs33 from "fs";
|
|
137152
136911
|
import fsPromises6 from "fs/promises";
|
|
137153
|
-
import
|
|
136912
|
+
import path43 from "path";
|
|
137154
136913
|
import { fileURLToPath as fileURLToPath10 } from "url";
|
|
137155
136914
|
|
|
137156
136915
|
// src/commands/tiktok-analysis/merge-snapshot.ts
|
|
137157
|
-
import * as
|
|
137158
|
-
import * as
|
|
136916
|
+
import * as fs32 from "fs/promises";
|
|
136917
|
+
import * as path42 from "path";
|
|
137159
136918
|
function asRecord25(value) {
|
|
137160
136919
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
137161
136920
|
return value;
|
|
@@ -137171,7 +136930,7 @@ function round24(value) {
|
|
|
137171
136930
|
}
|
|
137172
136931
|
async function loadSectionPayload2(snapshotDir, file) {
|
|
137173
136932
|
try {
|
|
137174
|
-
const raw = await
|
|
136933
|
+
const raw = await fs32.readFile(path42.join(snapshotDir, file), "utf8");
|
|
137175
136934
|
return JSON.parse(raw);
|
|
137176
136935
|
} catch {
|
|
137177
136936
|
return null;
|
|
@@ -137181,7 +136940,7 @@ async function readManifest5(snapshotDir, accountId) {
|
|
|
137181
136940
|
const candidates = [];
|
|
137182
136941
|
if (accountId) candidates.push(reportManifestFile(accountId));
|
|
137183
136942
|
try {
|
|
137184
|
-
const entries = await
|
|
136943
|
+
const entries = await fs32.readdir(snapshotDir);
|
|
137185
136944
|
const manifestNames = entries.filter(
|
|
137186
136945
|
(n) => n.startsWith("report-manifest") && n.endsWith(".json")
|
|
137187
136946
|
);
|
|
@@ -137192,7 +136951,7 @@ async function readManifest5(snapshotDir, accountId) {
|
|
|
137192
136951
|
}
|
|
137193
136952
|
for (const name2 of candidates) {
|
|
137194
136953
|
try {
|
|
137195
|
-
const raw = await
|
|
136954
|
+
const raw = await fs32.readFile(path42.join(snapshotDir, name2), "utf8");
|
|
137196
136955
|
const parsed = JSON.parse(raw);
|
|
137197
136956
|
if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
|
|
137198
136957
|
} catch {
|
|
@@ -137333,7 +137092,7 @@ function mapAudienceMerged(payload) {
|
|
|
137333
137092
|
};
|
|
137334
137093
|
}
|
|
137335
137094
|
async function mergeTikTokAnalysisSnapshotIntoReport(payload, snapshotDir) {
|
|
137336
|
-
const absDir =
|
|
137095
|
+
const absDir = path42.resolve(snapshotDir);
|
|
137337
137096
|
const metaAccountId = typeof asRecord25(payload.meta)?.accountId === "string" ? asRecord25(payload.meta)?.accountId : void 0;
|
|
137338
137097
|
const manifest = await readManifest5(snapshotDir, metaAccountId);
|
|
137339
137098
|
if (!manifest) {
|
|
@@ -137543,14 +137302,14 @@ function formatTikTokPeriodReportErrors(result) {
|
|
|
137543
137302
|
var TEMPLATE_BASENAME4 = "tiktok-period-report.html";
|
|
137544
137303
|
var INJECT_MARKER5 = "window.__TIKTOK_PERIOD_REPORT__ = window.__TIKTOK_PERIOD_REPORT__ || null;";
|
|
137545
137304
|
function resolveSkillTemplatePath7(basename13) {
|
|
137546
|
-
const dir =
|
|
137305
|
+
const dir = path43.dirname(fileURLToPath10(import.meta.url));
|
|
137547
137306
|
const candidates = [
|
|
137548
|
-
|
|
137549
|
-
|
|
137550
|
-
|
|
137307
|
+
path43.join(dir, "skill", "report-templates", basename13),
|
|
137308
|
+
path43.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
137309
|
+
path43.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
137551
137310
|
];
|
|
137552
137311
|
for (const p of candidates) {
|
|
137553
|
-
if (
|
|
137312
|
+
if (fs33.existsSync(p)) return p;
|
|
137554
137313
|
}
|
|
137555
137314
|
return candidates[0];
|
|
137556
137315
|
}
|
|
@@ -137579,10 +137338,10 @@ function injectReportData6(html, payload) {
|
|
|
137579
137338
|
return html.replace(INJECT_MARKER5, `window.__TIKTOK_PERIOD_REPORT__ = ${json};`);
|
|
137580
137339
|
}
|
|
137581
137340
|
async function runTikTokAnalysisRender(opts) {
|
|
137582
|
-
const dataPath =
|
|
137341
|
+
const dataPath = path43.resolve(opts.dataFile);
|
|
137583
137342
|
let data = asRecord27(await readJsonFile6(dataPath));
|
|
137584
137343
|
if (opts.snapshotDir?.trim()) {
|
|
137585
|
-
data = await mergeTikTokAnalysisSnapshotIntoReport(data,
|
|
137344
|
+
data = await mergeTikTokAnalysisSnapshotIntoReport(data, path43.resolve(opts.snapshotDir));
|
|
137586
137345
|
}
|
|
137587
137346
|
const contentCheck = validateTikTokPeriodReportContent(data);
|
|
137588
137347
|
if (!contentCheck.ok) {
|
|
@@ -137608,10 +137367,10 @@ async function runTikTokAnalysisRender(opts) {
|
|
|
137608
137367
|
`);
|
|
137609
137368
|
process.exit(1);
|
|
137610
137369
|
}
|
|
137611
|
-
const outPath =
|
|
137612
|
-
opts.out ??
|
|
137370
|
+
const outPath = path43.resolve(
|
|
137371
|
+
opts.out ?? path43.join(path43.dirname(dataPath), "tiktok-period-report.html")
|
|
137613
137372
|
);
|
|
137614
|
-
const outDir =
|
|
137373
|
+
const outDir = path43.dirname(outPath);
|
|
137615
137374
|
await fsPromises6.mkdir(outDir, { recursive: true });
|
|
137616
137375
|
await fsPromises6.writeFile(outPath, injectReportData6(html, data), "utf8");
|
|
137617
137376
|
const { stats } = contentCheck;
|
|
@@ -138537,7 +138296,7 @@ var YANDEX_SECTION_ALIASES = {
|
|
|
138537
138296
|
|
|
138538
138297
|
// src/commands/yandex-analysis/run-batch.ts
|
|
138539
138298
|
init_auth();
|
|
138540
|
-
import * as
|
|
138299
|
+
import * as path45 from "path";
|
|
138541
138300
|
import { performance as performance8 } from "perf_hooks";
|
|
138542
138301
|
init_version();
|
|
138543
138302
|
|
|
@@ -138677,8 +138436,8 @@ function endpointHintForYandexSection(def) {
|
|
|
138677
138436
|
}
|
|
138678
138437
|
|
|
138679
138438
|
// src/commands/yandex-analysis/merge-snapshot.ts
|
|
138680
|
-
import * as
|
|
138681
|
-
import * as
|
|
138439
|
+
import * as fs34 from "fs/promises";
|
|
138440
|
+
import * as path44 from "path";
|
|
138682
138441
|
function asRecord28(value) {
|
|
138683
138442
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
138684
138443
|
return value;
|
|
@@ -138728,7 +138487,7 @@ function pickMetrics2(row, extras = []) {
|
|
|
138728
138487
|
}
|
|
138729
138488
|
async function loadSectionPayload3(snapshotDir, file) {
|
|
138730
138489
|
try {
|
|
138731
|
-
const raw = await
|
|
138490
|
+
const raw = await fs34.readFile(path44.join(snapshotDir, file), "utf8");
|
|
138732
138491
|
return JSON.parse(raw);
|
|
138733
138492
|
} catch {
|
|
138734
138493
|
return null;
|
|
@@ -138738,7 +138497,7 @@ async function readManifest6(snapshotDir, accountId) {
|
|
|
138738
138497
|
const candidates = [];
|
|
138739
138498
|
if (accountId) candidates.push(reportManifestFile(accountId));
|
|
138740
138499
|
try {
|
|
138741
|
-
const entries = await
|
|
138500
|
+
const entries = await fs34.readdir(snapshotDir);
|
|
138742
138501
|
for (const name2 of entries.filter(
|
|
138743
138502
|
(n) => n.startsWith("report-manifest") && n.endsWith(".json")
|
|
138744
138503
|
)) {
|
|
@@ -138748,7 +138507,7 @@ async function readManifest6(snapshotDir, accountId) {
|
|
|
138748
138507
|
}
|
|
138749
138508
|
for (const name2 of candidates) {
|
|
138750
138509
|
try {
|
|
138751
|
-
const raw = await
|
|
138510
|
+
const raw = await fs34.readFile(path44.join(snapshotDir, name2), "utf8");
|
|
138752
138511
|
const parsed = JSON.parse(raw);
|
|
138753
138512
|
if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
|
|
138754
138513
|
} catch {
|
|
@@ -138907,7 +138666,7 @@ function mapDeviceRows2(payload) {
|
|
|
138907
138666
|
return asItems(payload).map((r) => pickMetrics2(r, ["device", "network"]));
|
|
138908
138667
|
}
|
|
138909
138668
|
async function mergeYandexAnalysisSnapshotIntoReport(payload, snapshotDir) {
|
|
138910
|
-
const absDir =
|
|
138669
|
+
const absDir = path44.resolve(snapshotDir);
|
|
138911
138670
|
const metaAccountId = typeof asRecord28(payload.meta)?.accountId === "string" ? asRecord28(payload.meta)?.accountId : void 0;
|
|
138912
138671
|
const manifest = await readManifest6(snapshotDir, metaAccountId);
|
|
138913
138672
|
if (!manifest) {
|
|
@@ -139093,7 +138852,7 @@ async function runAllYandexSections(opts) {
|
|
|
139093
138852
|
const results = await runWithConcurrency6(tasks, concurrency);
|
|
139094
138853
|
const succeeded = results.filter((r) => r.ok).length;
|
|
139095
138854
|
const failed = results.length - succeeded;
|
|
139096
|
-
const absoluteSnapshotDir =
|
|
138855
|
+
const absoluteSnapshotDir = path45.resolve(opts.jsonOut);
|
|
139097
138856
|
const summary = {
|
|
139098
138857
|
kind: "siluzan-tso-yandex-analysis-snapshot-batch",
|
|
139099
138858
|
absoluteSnapshotDir,
|
|
@@ -139111,9 +138870,9 @@ async function runAllYandexSections(opts) {
|
|
|
139111
138870
|
}
|
|
139112
138871
|
|
|
139113
138872
|
// src/commands/yandex-analysis/render-report.ts
|
|
139114
|
-
import
|
|
138873
|
+
import fs35 from "fs";
|
|
139115
138874
|
import fsPromises7 from "fs/promises";
|
|
139116
|
-
import
|
|
138875
|
+
import path46 from "path";
|
|
139117
138876
|
import { fileURLToPath as fileURLToPath11 } from "url";
|
|
139118
138877
|
|
|
139119
138878
|
// src/commands/yandex-analysis/report-content.ts
|
|
@@ -139317,14 +139076,14 @@ function formatYandexPeriodReportErrors(result) {
|
|
|
139317
139076
|
var TEMPLATE_BASENAME5 = "yandex-period-report.html";
|
|
139318
139077
|
var INJECT_MARKER6 = "window.__YANDEX_PERIOD_REPORT__ = window.__YANDEX_PERIOD_REPORT__ || null;";
|
|
139319
139078
|
function resolveSkillTemplatePath8(basename13) {
|
|
139320
|
-
const dir =
|
|
139079
|
+
const dir = path46.dirname(fileURLToPath11(import.meta.url));
|
|
139321
139080
|
const candidates = [
|
|
139322
|
-
|
|
139323
|
-
|
|
139324
|
-
|
|
139081
|
+
path46.join(dir, "skill", "report-templates", basename13),
|
|
139082
|
+
path46.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
139083
|
+
path46.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
139325
139084
|
];
|
|
139326
139085
|
for (const p of candidates) {
|
|
139327
|
-
if (
|
|
139086
|
+
if (fs35.existsSync(p)) return p;
|
|
139328
139087
|
}
|
|
139329
139088
|
return candidates[0];
|
|
139330
139089
|
}
|
|
@@ -139366,10 +139125,10 @@ function injectReportData7(html, payload) {
|
|
|
139366
139125
|
return html.replace(INJECT_MARKER6, `window.__YANDEX_PERIOD_REPORT__ = ${json};`);
|
|
139367
139126
|
}
|
|
139368
139127
|
async function runYandexAnalysisRender(opts) {
|
|
139369
|
-
const dataPath =
|
|
139128
|
+
const dataPath = path46.resolve(opts.dataFile);
|
|
139370
139129
|
let data = asRecord30(await readJsonFile7(dataPath));
|
|
139371
139130
|
if (opts.snapshotDir?.trim()) {
|
|
139372
|
-
data = await mergeYandexAnalysisSnapshotIntoReport(data,
|
|
139131
|
+
data = await mergeYandexAnalysisSnapshotIntoReport(data, path46.resolve(opts.snapshotDir));
|
|
139373
139132
|
}
|
|
139374
139133
|
data = refreshWeeklyFromDaily(data);
|
|
139375
139134
|
const contentCheck = validateYandexPeriodReportContent(data);
|
|
@@ -139394,10 +139153,10 @@ async function runYandexAnalysisRender(opts) {
|
|
|
139394
139153
|
`);
|
|
139395
139154
|
process.exit(1);
|
|
139396
139155
|
}
|
|
139397
|
-
const outPath =
|
|
139398
|
-
opts.out ??
|
|
139156
|
+
const outPath = path46.resolve(
|
|
139157
|
+
opts.out ?? path46.join(path46.dirname(dataPath), "yandex-period-report.html")
|
|
139399
139158
|
);
|
|
139400
|
-
const outDir =
|
|
139159
|
+
const outDir = path46.dirname(outPath);
|
|
139401
139160
|
await fsPromises7.mkdir(outDir, { recursive: true });
|
|
139402
139161
|
await fsPromises7.writeFile(outPath, injectReportData7(html, data), "utf8");
|
|
139403
139162
|
const { stats } = contentCheck;
|
|
@@ -139411,7 +139170,472 @@ async function runYandexAnalysisRender(opts) {
|
|
|
139411
139170
|
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
139171
|
}
|
|
139413
139172
|
|
|
139173
|
+
// src/commands/yandex-analysis/entities.ts
|
|
139174
|
+
init_auth();
|
|
139175
|
+
init_cli_json_snapshot();
|
|
139176
|
+
init_cli_table();
|
|
139177
|
+
|
|
139178
|
+
// src/commands/yandex-analysis/yandex-api.ts
|
|
139179
|
+
init_auth();
|
|
139180
|
+
var YANDEX_AD_STATUSES = [
|
|
139181
|
+
"DRAFT",
|
|
139182
|
+
"MODERATION",
|
|
139183
|
+
"PREACCEPTED",
|
|
139184
|
+
"ACCEPTED",
|
|
139185
|
+
"REJECTED",
|
|
139186
|
+
"UNKNOWN"
|
|
139187
|
+
];
|
|
139188
|
+
var YANDEX_INSIGHTS_LEVELS = [
|
|
139189
|
+
"daily",
|
|
139190
|
+
"geo",
|
|
139191
|
+
"devices",
|
|
139192
|
+
"keywords",
|
|
139193
|
+
"campaigns",
|
|
139194
|
+
"adgroups",
|
|
139195
|
+
"ads"
|
|
139196
|
+
];
|
|
139197
|
+
var YANDEX_PATH_CAPS = {
|
|
139198
|
+
overview: {},
|
|
139199
|
+
daily: {},
|
|
139200
|
+
campaigns: { limit: true, timeIncrement: true, network: true },
|
|
139201
|
+
adgroups: { limit: true, timeIncrement: true, campaignId: true },
|
|
139202
|
+
ads: { limit: true, timeIncrement: true, status: true, campaignId: true, adGroupId: true },
|
|
139203
|
+
keywords: { limit: true },
|
|
139204
|
+
geo: { limit: true, network: true },
|
|
139205
|
+
devices: { network: true }
|
|
139206
|
+
};
|
|
139207
|
+
function localYmd(d = /* @__PURE__ */ new Date()) {
|
|
139208
|
+
const y = d.getFullYear();
|
|
139209
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
139210
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
139211
|
+
return `${y}-${m}-${day}`;
|
|
139212
|
+
}
|
|
139213
|
+
function parseYandexTimeIncrement(raw) {
|
|
139214
|
+
if (raw == null || String(raw).trim() === "") return void 0;
|
|
139215
|
+
const t = String(raw).trim();
|
|
139216
|
+
if (t !== "1") {
|
|
139217
|
+
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");
|
|
139218
|
+
}
|
|
139219
|
+
return 1;
|
|
139220
|
+
}
|
|
139221
|
+
function parseYandexNetwork(raw) {
|
|
139222
|
+
if (raw == null || String(raw).trim() === "") return void 0;
|
|
139223
|
+
const t = String(raw).trim().toUpperCase();
|
|
139224
|
+
if (t !== "SEARCH" && t !== "ALL") {
|
|
139225
|
+
throw new Error(
|
|
139226
|
+
"--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"
|
|
139227
|
+
);
|
|
139228
|
+
}
|
|
139229
|
+
return t;
|
|
139230
|
+
}
|
|
139231
|
+
function parseYandexAdStatus(raw) {
|
|
139232
|
+
if (raw == null || String(raw).trim() === "") return void 0;
|
|
139233
|
+
const parts = String(raw).split(",").map((x) => x.trim().toUpperCase()).filter(Boolean);
|
|
139234
|
+
if (parts.length === 0) return void 0;
|
|
139235
|
+
const unknown = parts.filter((p) => !YANDEX_AD_STATUSES.includes(p));
|
|
139236
|
+
if (unknown.length > 0) {
|
|
139237
|
+
throw new Error(
|
|
139238
|
+
`--status \u975E\u6CD5\u503C\uFF1A${unknown.join(", ")}\u3002\u5408\u6CD5\uFF1A${YANDEX_AD_STATUSES.join(", ")}\u3002`
|
|
139239
|
+
);
|
|
139240
|
+
}
|
|
139241
|
+
return [...new Set(parts)].join(",");
|
|
139242
|
+
}
|
|
139243
|
+
function parseYandexInsightsLevel(raw) {
|
|
139244
|
+
const t = raw.trim();
|
|
139245
|
+
if (!YANDEX_INSIGHTS_LEVELS.includes(t)) {
|
|
139246
|
+
throw new Error(
|
|
139247
|
+
`--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`
|
|
139248
|
+
);
|
|
139249
|
+
}
|
|
139250
|
+
return t;
|
|
139251
|
+
}
|
|
139252
|
+
function optionalId(raw) {
|
|
139253
|
+
const t = raw?.trim();
|
|
139254
|
+
return t ? t : void 0;
|
|
139255
|
+
}
|
|
139256
|
+
function insightsLevelToPath(level) {
|
|
139257
|
+
return level;
|
|
139258
|
+
}
|
|
139259
|
+
function assertYandexAnalysisQuery(path48, query) {
|
|
139260
|
+
const caps = YANDEX_PATH_CAPS[path48];
|
|
139261
|
+
if (query.timeIncrement != null && !caps.timeIncrement) {
|
|
139262
|
+
throw new Error(`--time-increment \u4E0D\u80FD\u7528\u4E8E /${path48}\uFF08\u4EC5 campaigns / adgroups / ads\uFF09\u3002`);
|
|
139263
|
+
}
|
|
139264
|
+
if (query.network != null && !caps.network) {
|
|
139265
|
+
throw new Error(`--network \u4E0D\u80FD\u7528\u4E8E /${path48}\uFF08\u4EC5 campaigns / geo / devices\uFF09\u3002`);
|
|
139266
|
+
}
|
|
139267
|
+
if (query.status != null && !caps.status) {
|
|
139268
|
+
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`);
|
|
139269
|
+
}
|
|
139270
|
+
if (query.campaignId != null && !caps.campaignId) {
|
|
139271
|
+
throw new Error(`--campaign-id \u4EC5\u7528\u4E8E /adgroups \u4E0E /ads\u3002`);
|
|
139272
|
+
}
|
|
139273
|
+
if (query.adGroupId != null && !caps.adGroupId) {
|
|
139274
|
+
throw new Error(`--adgroup-id \u4EC5\u7528\u4E8E /ads\u3002`);
|
|
139275
|
+
}
|
|
139276
|
+
if (query.status != null && query.timeIncrement != null) {
|
|
139277
|
+
throw new Error(
|
|
139278
|
+
"--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"
|
|
139279
|
+
);
|
|
139280
|
+
}
|
|
139281
|
+
if (query.limit != null && !caps.limit) {
|
|
139282
|
+
throw new Error(`--limit \u4E0D\u80FD\u7528\u4E8E /${path48}\uFF08overview / daily / devices \u65E0\u6B64\u53C2\u6570\uFF09\u3002`);
|
|
139283
|
+
}
|
|
139284
|
+
}
|
|
139285
|
+
function buildYandexAnalysisSearchParams(path48, query) {
|
|
139286
|
+
assertYandexAnalysisQuery(path48, query);
|
|
139287
|
+
const caps = YANDEX_PATH_CAPS[path48];
|
|
139288
|
+
const params = new URLSearchParams({
|
|
139289
|
+
account: query.account,
|
|
139290
|
+
start: query.start,
|
|
139291
|
+
end: query.end
|
|
139292
|
+
});
|
|
139293
|
+
if (caps.limit && query.limit != null) {
|
|
139294
|
+
params.set("limit", String(resolveYandexLimit(query.limit)));
|
|
139295
|
+
}
|
|
139296
|
+
if (caps.timeIncrement && query.timeIncrement === 1) {
|
|
139297
|
+
params.set("timeIncrement", "1");
|
|
139298
|
+
}
|
|
139299
|
+
if (caps.network && query.network) {
|
|
139300
|
+
params.set("network", query.network);
|
|
139301
|
+
}
|
|
139302
|
+
if (caps.status && query.status) {
|
|
139303
|
+
params.set("status", query.status);
|
|
139304
|
+
}
|
|
139305
|
+
if (caps.campaignId && query.campaignId) {
|
|
139306
|
+
params.set("campaignId", query.campaignId);
|
|
139307
|
+
}
|
|
139308
|
+
if (caps.adGroupId && query.adGroupId) {
|
|
139309
|
+
params.set("adGroupId", query.adGroupId);
|
|
139310
|
+
}
|
|
139311
|
+
return params;
|
|
139312
|
+
}
|
|
139313
|
+
async function fetchYandexAnalysisPath(config, path48, query, verbose) {
|
|
139314
|
+
const yandexApiUrl = requireYandexApi(config);
|
|
139315
|
+
const params = buildYandexAnalysisSearchParams(path48, query);
|
|
139316
|
+
const url = analysisUrl(yandexApiUrl, path48, params.toString());
|
|
139317
|
+
return apiFetch2(url, config, {}, verbose);
|
|
139318
|
+
}
|
|
139319
|
+
function unwrapYandexItems(raw) {
|
|
139320
|
+
if (raw && typeof raw === "object" && Array.isArray(raw.items)) {
|
|
139321
|
+
return raw.items;
|
|
139322
|
+
}
|
|
139323
|
+
return [];
|
|
139324
|
+
}
|
|
139325
|
+
function asRecord31(raw) {
|
|
139326
|
+
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
139327
|
+
}
|
|
139328
|
+
|
|
139329
|
+
// src/commands/yandex-analysis/entities.ts
|
|
139330
|
+
function fail3(label, err) {
|
|
139331
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
139332
|
+
console.error(`
|
|
139333
|
+
\u274C ${label}\uFF1A${msg}
|
|
139334
|
+
`);
|
|
139335
|
+
process.exit(1);
|
|
139336
|
+
}
|
|
139337
|
+
function cell2(value) {
|
|
139338
|
+
if (value == null || value === "") return "";
|
|
139339
|
+
if (Array.isArray(value)) return value.map((x) => String(x)).join(" | ");
|
|
139340
|
+
return String(value);
|
|
139341
|
+
}
|
|
139342
|
+
function resolveRange(start, end) {
|
|
139343
|
+
if (!start && !end) {
|
|
139344
|
+
const today = localYmd();
|
|
139345
|
+
return resolveYandexDateRange(today, today);
|
|
139346
|
+
}
|
|
139347
|
+
return resolveYandexDateRange(start, end);
|
|
139348
|
+
}
|
|
139349
|
+
function parseCommonFlags(opts) {
|
|
139350
|
+
return {
|
|
139351
|
+
timeIncrement: parseYandexTimeIncrement(opts.timeIncrement),
|
|
139352
|
+
network: parseYandexNetwork(opts.network),
|
|
139353
|
+
status: parseYandexAdStatus(opts.status),
|
|
139354
|
+
campaignId: optionalId(opts.campaignId),
|
|
139355
|
+
adGroupId: optionalId(opts.adGroupId)
|
|
139356
|
+
};
|
|
139357
|
+
}
|
|
139358
|
+
async function emitOrTable(opts, args) {
|
|
139359
|
+
if (await emitCliJsonOrSnapshot(opts, {
|
|
139360
|
+
section: args.section,
|
|
139361
|
+
commandLabel: args.commandLabel,
|
|
139362
|
+
commandHint: args.accountId,
|
|
139363
|
+
payload: args.payload,
|
|
139364
|
+
idSuffix: args.accountId
|
|
139365
|
+
})) {
|
|
139366
|
+
return;
|
|
139367
|
+
}
|
|
139368
|
+
console.log(`
|
|
139369
|
+
${args.title}
|
|
139370
|
+
`);
|
|
139371
|
+
if (args.rows.length === 0) {
|
|
139372
|
+
console.log(` ${args.empty}
|
|
139373
|
+
`);
|
|
139374
|
+
return;
|
|
139375
|
+
}
|
|
139376
|
+
printCliTable(args.rows, args.columns);
|
|
139377
|
+
console.log(` ${args.footnote}
|
|
139378
|
+
`);
|
|
139379
|
+
}
|
|
139380
|
+
async function fetchPath(opts, path48, extra) {
|
|
139381
|
+
const accountId = assertYandexAccountId(opts.account);
|
|
139382
|
+
const { startDate, endDate } = resolveRange(opts.start, opts.end);
|
|
139383
|
+
const config = loadConfig(opts.token);
|
|
139384
|
+
const raw = await fetchYandexAnalysisPath(
|
|
139385
|
+
config,
|
|
139386
|
+
path48,
|
|
139387
|
+
{
|
|
139388
|
+
account: accountId,
|
|
139389
|
+
start: startDate,
|
|
139390
|
+
end: endDate,
|
|
139391
|
+
...extra
|
|
139392
|
+
},
|
|
139393
|
+
!!opts.verbose
|
|
139394
|
+
);
|
|
139395
|
+
return { accountId, startDate, endDate, raw };
|
|
139396
|
+
}
|
|
139397
|
+
async function runYandexAccountStatus(opts) {
|
|
139398
|
+
let result;
|
|
139399
|
+
try {
|
|
139400
|
+
result = await fetchPath(opts, "overview", {});
|
|
139401
|
+
} catch (err) {
|
|
139402
|
+
fail3("\u67E5\u8BE2 Yandex \u8D26\u6237\u603B\u89C8\u5931\u8D25", err);
|
|
139403
|
+
}
|
|
139404
|
+
const row = asRecord31(result.raw);
|
|
139405
|
+
await emitOrTable(opts, {
|
|
139406
|
+
section: "yandex-account-status",
|
|
139407
|
+
commandLabel: "yandex-analysis account-status",
|
|
139408
|
+
accountId: result.accountId,
|
|
139409
|
+
payload: result.raw,
|
|
139410
|
+
title: `Yandex \u8D26\u6237\u603B\u89C8\uFF08${result.accountId}\uFF0C${result.startDate}~${result.endDate}\uFF09`,
|
|
139411
|
+
empty: "\u65E0\u603B\u89C8\u6570\u636E\u3002",
|
|
139412
|
+
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",
|
|
139413
|
+
rows: [
|
|
139414
|
+
{
|
|
139415
|
+
account: cell2(row.account ?? result.accountId),
|
|
139416
|
+
archived: cell2(row.archived),
|
|
139417
|
+
balance: cell2(row.balance),
|
|
139418
|
+
currency: cell2(row.currency),
|
|
139419
|
+
spend: cell2(row.spend),
|
|
139420
|
+
conversions: cell2(row.conversions)
|
|
139421
|
+
}
|
|
139422
|
+
],
|
|
139423
|
+
columns: [
|
|
139424
|
+
{ key: "account", header: "\u8D26\u6237" },
|
|
139425
|
+
{ key: "archived", header: "archived" },
|
|
139426
|
+
{ key: "balance", header: "\u4F59\u989D" },
|
|
139427
|
+
{ key: "currency", header: "\u5E01\u79CD" },
|
|
139428
|
+
{ key: "spend", header: "\u533A\u95F4\u82B1\u8D39" },
|
|
139429
|
+
{ key: "conversions", header: "\u8F6C\u5316" }
|
|
139430
|
+
]
|
|
139431
|
+
});
|
|
139432
|
+
}
|
|
139433
|
+
async function runYandexCampaignEntities(opts) {
|
|
139434
|
+
let flags;
|
|
139435
|
+
let result;
|
|
139436
|
+
try {
|
|
139437
|
+
flags = parseCommonFlags(opts);
|
|
139438
|
+
result = await fetchPath(opts, "campaigns", {
|
|
139439
|
+
limit: opts.limit,
|
|
139440
|
+
timeIncrement: flags.timeIncrement,
|
|
139441
|
+
network: flags.network
|
|
139442
|
+
});
|
|
139443
|
+
} catch (err) {
|
|
139444
|
+
fail3("\u67E5\u8BE2 Yandex \u7CFB\u5217\u5931\u8D25", err);
|
|
139445
|
+
}
|
|
139446
|
+
const items2 = unwrapYandexItems(result.raw);
|
|
139447
|
+
await emitOrTable(opts, {
|
|
139448
|
+
section: "yandex-campaign-entities",
|
|
139449
|
+
commandLabel: "yandex-analysis campaign-entities",
|
|
139450
|
+
accountId: result.accountId,
|
|
139451
|
+
payload: result.raw,
|
|
139452
|
+
title: `Yandex \u5E7F\u544A\u7CFB\u5217\uFF08${result.accountId}\uFF0C${result.startDate}~${result.endDate}\uFF0C\u5171 ${items2.length} \u884C\uFF09`,
|
|
139453
|
+
empty: "\u5F53\u524D\u8FC7\u6EE4\u4E0B\u65E0\u7CFB\u5217\u884C\uFF08\u9ED8\u8BA4\u53EA\u51FA\u73B0\u6709\u6D88\u8017\u7684\u5BF9\u8C61\uFF09\u3002",
|
|
139454
|
+
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",
|
|
139455
|
+
rows: items2.map((r) => ({
|
|
139456
|
+
campaignId: cell2(r.campaignId),
|
|
139457
|
+
name: cell2(r.campaignName),
|
|
139458
|
+
spend: cell2(r.spend),
|
|
139459
|
+
budget: cell2(r.budget),
|
|
139460
|
+
weeklyBudget: cell2(r.weeklyBudget),
|
|
139461
|
+
strategy: cell2(r.strategy),
|
|
139462
|
+
targetCpa: cell2(r.targetCpa),
|
|
139463
|
+
status: cell2(r.status),
|
|
139464
|
+
date: cell2(r.date)
|
|
139465
|
+
})),
|
|
139466
|
+
columns: [
|
|
139467
|
+
{ key: "campaignId", header: "\u7CFB\u5217ID" },
|
|
139468
|
+
{ key: "name", header: "\u540D\u79F0" },
|
|
139469
|
+
{ key: "spend", header: "spend" },
|
|
139470
|
+
{ key: "budget", header: "\u65E5\u9884\u7B97" },
|
|
139471
|
+
{ key: "weeklyBudget", header: "\u5468\u9884\u7B97" },
|
|
139472
|
+
{ key: "strategy", header: "\u7B56\u7565" },
|
|
139473
|
+
{ key: "targetCpa", header: "\u76EE\u6807CPA" },
|
|
139474
|
+
{ key: "status", header: "\u72B6\u6001" },
|
|
139475
|
+
{ key: "date", header: "date" }
|
|
139476
|
+
]
|
|
139477
|
+
});
|
|
139478
|
+
}
|
|
139479
|
+
async function runYandexAdGroupEntities(opts) {
|
|
139480
|
+
let flags;
|
|
139481
|
+
let result;
|
|
139482
|
+
try {
|
|
139483
|
+
flags = parseCommonFlags(opts);
|
|
139484
|
+
result = await fetchPath(opts, "adgroups", {
|
|
139485
|
+
limit: opts.limit,
|
|
139486
|
+
timeIncrement: flags.timeIncrement,
|
|
139487
|
+
campaignId: flags.campaignId
|
|
139488
|
+
});
|
|
139489
|
+
} catch (err) {
|
|
139490
|
+
fail3("\u67E5\u8BE2 Yandex \u5E7F\u544A\u7EC4\u5931\u8D25", err);
|
|
139491
|
+
}
|
|
139492
|
+
const items2 = unwrapYandexItems(result.raw);
|
|
139493
|
+
await emitOrTable(opts, {
|
|
139494
|
+
section: "yandex-adgroup-entities",
|
|
139495
|
+
commandLabel: "yandex-analysis adgroup-entities",
|
|
139496
|
+
accountId: result.accountId,
|
|
139497
|
+
payload: result.raw,
|
|
139498
|
+
title: `Yandex \u5E7F\u544A\u7EC4\uFF08${result.accountId}\uFF0C${result.startDate}~${result.endDate}\uFF0C\u5171 ${items2.length} \u884C\uFF09`,
|
|
139499
|
+
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",
|
|
139500
|
+
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",
|
|
139501
|
+
rows: items2.map((r) => ({
|
|
139502
|
+
adGroupId: cell2(r.adGroupId),
|
|
139503
|
+
name: cell2(r.adGroupName),
|
|
139504
|
+
campaignId: cell2(r.campaignId),
|
|
139505
|
+
spend: cell2(r.spend),
|
|
139506
|
+
conversions: cell2(r.conversions),
|
|
139507
|
+
cpa: cell2(r.costPerConversion),
|
|
139508
|
+
targetCpa: cell2(r.campaignTargetCpa),
|
|
139509
|
+
weeklyBudget: cell2(r.campaignWeeklyBudget),
|
|
139510
|
+
strategy: cell2(r.campaignStrategy),
|
|
139511
|
+
date: cell2(r.date)
|
|
139512
|
+
})),
|
|
139513
|
+
columns: [
|
|
139514
|
+
{ key: "adGroupId", header: "\u7EC4ID" },
|
|
139515
|
+
{ key: "name", header: "\u540D\u79F0" },
|
|
139516
|
+
{ key: "campaignId", header: "\u7CFB\u5217ID" },
|
|
139517
|
+
{ key: "spend", header: "spend" },
|
|
139518
|
+
{ key: "conversions", header: "\u8F6C\u5316" },
|
|
139519
|
+
{ key: "cpa", header: "\u5B9E\u9645CPA" },
|
|
139520
|
+
{ key: "targetCpa", header: "\u7CFB\u5217\u76EE\u6807CPA" },
|
|
139521
|
+
{ key: "weeklyBudget", header: "\u7CFB\u5217\u5468\u9884\u7B97" },
|
|
139522
|
+
{ key: "strategy", header: "\u7B56\u7565" },
|
|
139523
|
+
{ key: "date", header: "date" }
|
|
139524
|
+
]
|
|
139525
|
+
});
|
|
139526
|
+
}
|
|
139527
|
+
async function runYandexAdEntities(opts) {
|
|
139528
|
+
let flags;
|
|
139529
|
+
let result;
|
|
139530
|
+
try {
|
|
139531
|
+
flags = parseCommonFlags(opts);
|
|
139532
|
+
result = await fetchPath(opts, "ads", {
|
|
139533
|
+
limit: opts.limit,
|
|
139534
|
+
timeIncrement: flags.timeIncrement,
|
|
139535
|
+
status: flags.status,
|
|
139536
|
+
campaignId: flags.campaignId,
|
|
139537
|
+
adGroupId: flags.adGroupId
|
|
139538
|
+
});
|
|
139539
|
+
} catch (err) {
|
|
139540
|
+
fail3("\u67E5\u8BE2 Yandex \u5E7F\u544A\u5931\u8D25", err);
|
|
139541
|
+
}
|
|
139542
|
+
const items2 = unwrapYandexItems(result.raw);
|
|
139543
|
+
const filtered = flags.status != null;
|
|
139544
|
+
await emitOrTable(opts, {
|
|
139545
|
+
section: "yandex-ad-entities",
|
|
139546
|
+
commandLabel: "yandex-analysis ad-entities",
|
|
139547
|
+
accountId: result.accountId,
|
|
139548
|
+
payload: result.raw,
|
|
139549
|
+
title: `Yandex \u5E7F\u544A\uFF08${result.accountId}\uFF0C${result.startDate}~${result.endDate}\uFF0C\u5171 ${items2.length} \u884C\uFF09`,
|
|
139550
|
+
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",
|
|
139551
|
+
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",
|
|
139552
|
+
rows: items2.map((r) => ({
|
|
139553
|
+
adId: cell2(r.adId),
|
|
139554
|
+
campaignId: cell2(r.campaignId),
|
|
139555
|
+
adGroupId: cell2(r.adGroupId),
|
|
139556
|
+
spend: cell2(r.spend),
|
|
139557
|
+
conversions: cell2(r.conversions),
|
|
139558
|
+
ctr: cell2(r.ctr),
|
|
139559
|
+
roi: cell2(r.roi),
|
|
139560
|
+
status: cell2(r.status),
|
|
139561
|
+
landing: cell2(r.landingUrls)
|
|
139562
|
+
})),
|
|
139563
|
+
columns: [
|
|
139564
|
+
{ key: "adId", header: "\u5E7F\u544AID" },
|
|
139565
|
+
{ key: "campaignId", header: "\u7CFB\u5217ID" },
|
|
139566
|
+
{ key: "adGroupId", header: "\u7EC4ID" },
|
|
139567
|
+
{ key: "spend", header: "spend" },
|
|
139568
|
+
{ key: "conversions", header: "\u8F6C\u5316" },
|
|
139569
|
+
{ key: "ctr", header: "ctr" },
|
|
139570
|
+
{ key: "roi", header: "roi" },
|
|
139571
|
+
{ key: "status", header: "\u5BA1\u6838\u6001" },
|
|
139572
|
+
{ key: "landing", header: "\u843D\u5730\u9875" }
|
|
139573
|
+
]
|
|
139574
|
+
});
|
|
139575
|
+
}
|
|
139576
|
+
async function runYandexInsights(opts) {
|
|
139577
|
+
let level;
|
|
139578
|
+
let flags;
|
|
139579
|
+
let result;
|
|
139580
|
+
try {
|
|
139581
|
+
level = parseYandexInsightsLevel(opts.level);
|
|
139582
|
+
flags = parseCommonFlags(opts);
|
|
139583
|
+
result = await fetchPath(opts, insightsLevelToPath(level), {
|
|
139584
|
+
limit: opts.limit,
|
|
139585
|
+
timeIncrement: flags.timeIncrement,
|
|
139586
|
+
network: flags.network,
|
|
139587
|
+
status: flags.status,
|
|
139588
|
+
campaignId: flags.campaignId,
|
|
139589
|
+
adGroupId: flags.adGroupId
|
|
139590
|
+
});
|
|
139591
|
+
} catch (err) {
|
|
139592
|
+
fail3("\u67E5\u8BE2 Yandex insights \u5931\u8D25", err);
|
|
139593
|
+
}
|
|
139594
|
+
const items2 = unwrapYandexItems(result.raw);
|
|
139595
|
+
await emitOrTable(opts, {
|
|
139596
|
+
section: "yandex-insights",
|
|
139597
|
+
commandLabel: "yandex-analysis insights",
|
|
139598
|
+
accountId: result.accountId,
|
|
139599
|
+
payload: result.raw,
|
|
139600
|
+
title: `Yandex insights ${level}\uFF08${result.accountId}\uFF0C${result.startDate}~${result.endDate}\uFF0C\u5171 ${items2.length} \u884C\uFF09`,
|
|
139601
|
+
empty: "\u65E0\u62A5\u8868\u884C\uFF08\u9ED8\u8BA4\u53EA\u51FA\u73B0\u533A\u95F4\u5185\u6709\u6D88\u8017\u7684\u5BF9\u8C61\uFF09\u3002",
|
|
139602
|
+
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",
|
|
139603
|
+
rows: items2.map((r) => ({
|
|
139604
|
+
id: cell2(
|
|
139605
|
+
r.adId ?? r.adGroupId ?? r.campaignId ?? r.keywordId ?? r.regionName ?? r.device ?? r.date
|
|
139606
|
+
),
|
|
139607
|
+
name: cell2(
|
|
139608
|
+
r.adName ?? r.adGroupName ?? r.campaignName ?? r.keyword ?? r.regionName ?? r.device
|
|
139609
|
+
),
|
|
139610
|
+
spend: cell2(r.spend),
|
|
139611
|
+
conversions: cell2(r.conversions),
|
|
139612
|
+
ctr: cell2(r.ctr),
|
|
139613
|
+
roi: cell2(r.roi),
|
|
139614
|
+
date: cell2(r.date)
|
|
139615
|
+
})),
|
|
139616
|
+
columns: [
|
|
139617
|
+
{ key: "id", header: "\u5BF9\u8C61" },
|
|
139618
|
+
{ key: "name", header: "\u540D\u79F0" },
|
|
139619
|
+
{ key: "spend", header: "spend" },
|
|
139620
|
+
{ key: "conversions", header: "\u8F6C\u5316" },
|
|
139621
|
+
{ key: "ctr", header: "ctr" },
|
|
139622
|
+
{ key: "roi", header: "roi" },
|
|
139623
|
+
{ key: "date", header: "date" }
|
|
139624
|
+
]
|
|
139625
|
+
});
|
|
139626
|
+
}
|
|
139627
|
+
|
|
139414
139628
|
// src/commands/yandex-analysis/register-cli.ts
|
|
139629
|
+
var ACCOUNT_OPTION4 = [
|
|
139630
|
+
"-a, --account <id>",
|
|
139631
|
+
"Yandex Client-Login / mediaCustomerId\uFF08\u5982 porg-xxx\uFF0C\u4E0E list-accounts -m Yandex \u4E00\u81F4\uFF09"
|
|
139632
|
+
];
|
|
139633
|
+
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";
|
|
139634
|
+
var START_OPTION = [
|
|
139635
|
+
"--start <date>",
|
|
139636
|
+
"\u5F00\u59CB\u65E5\u671F YYYY-MM-DD\uFF08\u4E0E --end \u540C\u4F20\u6216\u540C\u7701\u7565\uFF1B\u7701\u7565=\u5F53\u5929\uFF09"
|
|
139637
|
+
];
|
|
139638
|
+
var END_OPTION = ["--end <date>", "\u7ED3\u675F\u65E5\u671F YYYY-MM-DD"];
|
|
139415
139639
|
function registerBatchCommand4(sectionHelp, aliasHelp) {
|
|
139416
139640
|
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
139641
|
"-a, --account <id>",
|
|
@@ -139437,7 +139661,7 @@ function registerYandexAnalysisCommands(program2) {
|
|
|
139437
139661
|
const sectionHelp = YANDEX_SECTION_NAMES.join(", ");
|
|
139438
139662
|
const aliasHelp = Object.keys(YANDEX_SECTION_ALIASES).join(", ");
|
|
139439
139663
|
const root = program2.command("yandex-analysis").description(
|
|
139440
|
-
"Yandex \u8D26\u6237\u5206\u6790\uFF1A\u6279\u91CF\u62C9\u53D6 /yandex-analysis \
|
|
139664
|
+
"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
139665
|
);
|
|
139442
139666
|
root.addCommand(registerBatchCommand4(sectionHelp, aliasHelp), { isDefault: true });
|
|
139443
139667
|
root.command("render").description(
|
|
@@ -139452,6 +139676,44 @@ function registerYandexAnalysisCommands(program2) {
|
|
|
139452
139676
|
out: opts.out
|
|
139453
139677
|
});
|
|
139454
139678
|
});
|
|
139679
|
+
root.command("account-status").description(
|
|
139680
|
+
"\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"
|
|
139681
|
+
).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(
|
|
139682
|
+
async (opts) => {
|
|
139683
|
+
await runYandexAccountStatus(opts);
|
|
139684
|
+
}
|
|
139685
|
+
);
|
|
139686
|
+
root.command("campaign-entities").description(
|
|
139687
|
+
"\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"
|
|
139688
|
+
).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(
|
|
139689
|
+
async (opts) => {
|
|
139690
|
+
await runYandexCampaignEntities(opts);
|
|
139691
|
+
}
|
|
139692
|
+
);
|
|
139693
|
+
root.command("adgroup-entities").description(
|
|
139694
|
+
"\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"
|
|
139695
|
+
).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(
|
|
139696
|
+
async (opts) => {
|
|
139697
|
+
await runYandexAdGroupEntities(opts);
|
|
139698
|
+
}
|
|
139699
|
+
);
|
|
139700
|
+
root.command("ad-entities").description(
|
|
139701
|
+
`\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`
|
|
139702
|
+
).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(
|
|
139703
|
+
"--status <list>",
|
|
139704
|
+
"\u5BA1\u6838\u6001\u9017\u53F7\u5206\u9694\uFF0C\u5982 REJECTED \u6216 MODERATION,REJECTED\uFF1B\u5E26 status \u65F6\u4E0D\u62C9\u7EE9\u6548\uFF08spend=0\uFF09"
|
|
139705
|
+
).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(
|
|
139706
|
+
async (opts) => {
|
|
139707
|
+
await runYandexAdEntities(opts);
|
|
139708
|
+
}
|
|
139709
|
+
);
|
|
139710
|
+
root.command("insights").description(
|
|
139711
|
+
"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"
|
|
139712
|
+
).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(
|
|
139713
|
+
async (opts) => {
|
|
139714
|
+
await runYandexInsights(opts);
|
|
139715
|
+
}
|
|
139716
|
+
);
|
|
139455
139717
|
}
|
|
139456
139718
|
|
|
139457
139719
|
// src/index.ts
|
|
@@ -139528,9 +139790,9 @@ function interceptAgentCompatArgv(argv) {
|
|
|
139528
139790
|
installProcessHandlers();
|
|
139529
139791
|
function getVersion() {
|
|
139530
139792
|
try {
|
|
139531
|
-
const __dirname3 =
|
|
139532
|
-
const pkgPath =
|
|
139533
|
-
const pkg = JSON.parse(
|
|
139793
|
+
const __dirname3 = path47.dirname(fileURLToPath12(import.meta.url));
|
|
139794
|
+
const pkgPath = path47.join(__dirname3, "..", "package.json");
|
|
139795
|
+
const pkg = JSON.parse(fs36.readFileSync(pkgPath, "utf8"));
|
|
139534
139796
|
return pkg.version ?? "0.0.0";
|
|
139535
139797
|
} catch {
|
|
139536
139798
|
return "0.0.0";
|
|
@@ -139551,7 +139813,7 @@ configureCliJsonSnapshot({
|
|
|
139551
139813
|
configureSiluzanClientIdentity({ client: "tso-cli", resolveVersion: getVersion });
|
|
139552
139814
|
var program = new Command6();
|
|
139553
139815
|
program.name("siluzan-tso").description(
|
|
139554
|
-
"Siluzan \u5E7F\u544A\u8D26\u6237\u7BA1\u7406\uFF1A\u8D26\u6237\u67E5\u8BE2\u3001\u4F59\u989D\u3001\u6295\u653E\u6570\u636E\u3001\u5F00\u6237\u7533\u8BF7\uFF08Google/TikTok/Yandex/Bing
|
|
139816
|
+
"Siluzan \u5E7F\u544A\u8D26\u6237\u7BA1\u7406\uFF1A\u8D26\u6237\u67E5\u8BE2\u3001\u4F59\u989D\u3001\u6295\u653E\u6570\u636E\u3001\u5F00\u6237\u7533\u8BF7\uFF08Google/TikTok/Yandex/Bing\uFF09\u3001\n\u8D26\u53F7\u5206\u4EAB/\u89E3\u7ED1\u3001\u4F18\u5316\u62A5\u544A\u3001Google/Meta/TikTok/Bing/Yandex \u8D26\u6237\u5206\u6790\u3001Google \u5E7F\u544A\u8BCA\u65AD\u62A5\u544A\uFF08google-ads-diagnosis render\uFF09\u3001\u7F51\u7AD9\u8BCA\u65AD\uFF08website-diagnosis\uFF09\u3001\u6218\u7565\u5E02\u573A\u5206\u6790\uFF08market-analysis\uFF0CAgent \u751F\u6210\u62A5\u544A\uFF09\u3001\u5145\u503C\u8F6C\u8D26\u3001\u5F00\u7968\u3001\u667A\u80FD\u9884\u8B66\u3001Google \u5E7F\u544A\u7BA1\u7406\uFF08\u542B\u5F02\u6B65\u6279\u91CF\uFF09\u3002"
|
|
139555
139817
|
).version(getVersion());
|
|
139556
139818
|
program.option("--commit <text>", "\u5199\u64CD\u4F5C\u8BF4\u660E\uFF1B\u8BB0\u5165\u672C\u673A\u5199\u5BA1\u8BA1 JSONL");
|
|
139557
139819
|
program.hook("preAction", async () => {
|