siluzan-tso-cli 1.1.19-beta.2 → 1.1.19-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.js +89 -8
- package/dist/skill/SKILL.md +4 -4
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/references/account-analytics.md +13 -8
- package/dist/skill/references/google-analysis-batch.md +1 -0
- package/dist/skill/report-templates/README.md +1 -1
- package/dist/skill/report-templates/REPORT-WORKFLOW.md +1 -1
- package/dist/skill/report-templates/okki-weekly-google-client.md +124 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ siluzan-tso init -d /path/to/skills # 写入自定义目录
|
|
|
51
51
|
siluzan-tso init --force # 强制覆盖已存在文件
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
> **注意**:当前为测试版(1.1.19-beta.
|
|
54
|
+
> **注意**:当前为测试版(1.1.19-beta.4),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
|
|
55
55
|
|
|
56
56
|
| 助手 | 建议 `--ai` |
|
|
57
57
|
| ----------------------- | ------------------------------------ |
|
package/dist/index.js
CHANGED
|
@@ -4738,10 +4738,23 @@ var init_sections = __esm({
|
|
|
4738
4738
|
},
|
|
4739
4739
|
{
|
|
4740
4740
|
name: "geographic",
|
|
4741
|
-
description: "\u56FD\u5BB6/\u5730\u533A\u5206\u6BB5 GeographicSectionData",
|
|
4741
|
+
description: "\u56FD\u5BB6/\u5730\u533A\u5206\u6BB5 GeographicSectionData\uFF08\u8D26\u6237\u7EA7\u805A\u5408\uFF09",
|
|
4742
4742
|
dateMode: "range",
|
|
4743
4743
|
path: (id) => `/reporting/media-account/${id}/GeographicSectionData`
|
|
4744
4744
|
},
|
|
4745
|
+
{
|
|
4746
|
+
name: "campaign-geo",
|
|
4747
|
+
description: "\u5E7F\u544A\u7CFB\u5217\u7EF4\u5EA6\u5730\u7406 GET \u2026/campaigns/reports/geo\uFF08GetCampaignGeoReport\uFF1B\u884C\u53EF\u542B campaign/adGroup\uFF09",
|
|
4748
|
+
dateMode: "range",
|
|
4749
|
+
path: (id) => `/reporting/media-account/${id}/campaigns/reports/geo`,
|
|
4750
|
+
campaignGeoFilterOption: true
|
|
4751
|
+
},
|
|
4752
|
+
{
|
|
4753
|
+
name: "campaign-device",
|
|
4754
|
+
description: "\u5E7F\u544A\u7CFB\u5217\u7EF4\u5EA6\u8BBE\u5907 GET \u2026/campaigns/reports/device\uFF08GetCampaignDeviceReport\uFF1B\u884C\u53EF\u542B campaign/adGroup\uFF09",
|
|
4755
|
+
dateMode: "range",
|
|
4756
|
+
path: (id) => `/reporting/media-account/${id}/campaigns/reports/device`
|
|
4757
|
+
},
|
|
4745
4758
|
{
|
|
4746
4759
|
name: "audience",
|
|
4747
4760
|
description: "\u53D7\u4F17\u5206\u6BB5 AdGroupAudienceData",
|
|
@@ -4885,6 +4898,10 @@ async function fetchGoogleAnalysisSectionJson(config, fullPath, verbose, name) {
|
|
|
4885
4898
|
return fetchJson(config, fullPath, verbose);
|
|
4886
4899
|
case "geographic":
|
|
4887
4900
|
return fetchJson(config, fullPath, verbose);
|
|
4901
|
+
case "campaign-geo":
|
|
4902
|
+
return fetchJson(config, fullPath, verbose);
|
|
4903
|
+
case "campaign-device":
|
|
4904
|
+
return fetchJson(config, fullPath, verbose);
|
|
4888
4905
|
case "audience":
|
|
4889
4906
|
return fetchJson(config, fullPath, verbose);
|
|
4890
4907
|
case "asset-images":
|
|
@@ -4935,6 +4952,12 @@ async function fetchSectionPayload(def, opts, config, id) {
|
|
|
4935
4952
|
if (def.audienceFilterOption && opts.audienceType) {
|
|
4936
4953
|
extras.audienceTypeFilter = opts.audienceType;
|
|
4937
4954
|
}
|
|
4955
|
+
if (def.campaignGeoFilterOption) {
|
|
4956
|
+
const n = (x) => typeof x === "number" && Number.isFinite(x);
|
|
4957
|
+
if (n(opts.costGreater)) extras.costGreater = opts.costGreater;
|
|
4958
|
+
if (n(opts.clickGreater)) extras.clickGreater = opts.clickGreater;
|
|
4959
|
+
if (n(opts.conversionsGreater)) extras.conversionsGreater = opts.conversionsGreater;
|
|
4960
|
+
}
|
|
4938
4961
|
if (def.name === "materials") {
|
|
4939
4962
|
const { startDate, endDate } = resolveDateRange2(opts.start, opts.end);
|
|
4940
4963
|
const q = `?${new URLSearchParams({ startDate, endDate }).toString()}`;
|
|
@@ -4986,7 +5009,10 @@ async function fetchOneGoogleSection(opts) {
|
|
|
4986
5009
|
limit: opts.limit,
|
|
4987
5010
|
noOrderByCost: opts.noOrderByCost,
|
|
4988
5011
|
level: opts.level,
|
|
4989
|
-
audienceType: opts.audienceType
|
|
5012
|
+
audienceType: opts.audienceType,
|
|
5013
|
+
costGreater: opts.costGreater,
|
|
5014
|
+
clickGreater: opts.clickGreater,
|
|
5015
|
+
conversionsGreater: opts.conversionsGreater
|
|
4990
5016
|
},
|
|
4991
5017
|
opts.config,
|
|
4992
5018
|
opts.accountId
|
|
@@ -5594,7 +5620,10 @@ async function runBatch(opts) {
|
|
|
5594
5620
|
section: task.section,
|
|
5595
5621
|
start: opts.start,
|
|
5596
5622
|
end: opts.end,
|
|
5597
|
-
limit: opts.keywordLimit
|
|
5623
|
+
limit: opts.keywordLimit,
|
|
5624
|
+
costGreater: opts.campaignGeoCostGreater,
|
|
5625
|
+
clickGreater: opts.campaignGeoClickGreater,
|
|
5626
|
+
conversionsGreater: opts.campaignGeoConversionsGreater
|
|
5598
5627
|
}),
|
|
5599
5628
|
{
|
|
5600
5629
|
label: `${task.section}/${task.accountId}`,
|
|
@@ -5715,6 +5744,9 @@ async function persistRunMetadata(input) {
|
|
|
5715
5744
|
},
|
|
5716
5745
|
minSpend: input.minSpend,
|
|
5717
5746
|
keywordLimit: input.keywordLimit,
|
|
5747
|
+
campaignGeoCostGreater: input.campaignGeoCostGreater,
|
|
5748
|
+
campaignGeoClickGreater: input.campaignGeoClickGreater,
|
|
5749
|
+
campaignGeoConversionsGreater: input.campaignGeoConversionsGreater,
|
|
5718
5750
|
deadlineMs: input.deadlineMs,
|
|
5719
5751
|
accountsTotal: input.accounts.length,
|
|
5720
5752
|
invocation: input.invocation
|
|
@@ -5868,6 +5900,9 @@ function decideExitCode(state, tokenInvalidated) {
|
|
|
5868
5900
|
if (state === "paused") return EXIT_PARTIAL;
|
|
5869
5901
|
return EXIT_FAILED;
|
|
5870
5902
|
}
|
|
5903
|
+
function finiteBatchOpt(n) {
|
|
5904
|
+
return typeof n === "number" && Number.isFinite(n) ? n : void 0;
|
|
5905
|
+
}
|
|
5871
5906
|
async function resolveBatchAccounts(config, opts) {
|
|
5872
5907
|
if (opts.explicitAccountIds && opts.explicitAccountIds.length > 0) {
|
|
5873
5908
|
const accounts2 = opts.explicitAccountIds.map((id) => ({
|
|
@@ -5963,6 +5998,9 @@ async function executeBatchRun(input) {
|
|
|
5963
5998
|
start: input.start,
|
|
5964
5999
|
end: input.end,
|
|
5965
6000
|
keywordLimit: input.keywordLimit,
|
|
6001
|
+
campaignGeoCostGreater: input.campaignGeoCostGreater,
|
|
6002
|
+
campaignGeoClickGreater: input.campaignGeoClickGreater,
|
|
6003
|
+
campaignGeoConversionsGreater: input.campaignGeoConversionsGreater,
|
|
5966
6004
|
minSpend: input.minSpend,
|
|
5967
6005
|
accountConcurrency: input.accountConcurrency,
|
|
5968
6006
|
sectionConcurrency: input.sectionConcurrency,
|
|
@@ -6015,6 +6053,9 @@ async function executeBatchRun(input) {
|
|
|
6015
6053
|
start: input.start,
|
|
6016
6054
|
end: input.end,
|
|
6017
6055
|
keywordLimit: input.keywordLimit,
|
|
6056
|
+
campaignGeoCostGreater: input.campaignGeoCostGreater,
|
|
6057
|
+
campaignGeoClickGreater: input.campaignGeoClickGreater,
|
|
6058
|
+
campaignGeoConversionsGreater: input.campaignGeoConversionsGreater,
|
|
6018
6059
|
accountConcurrency: input.accountConcurrency,
|
|
6019
6060
|
sectionConcurrency: input.sectionConcurrency,
|
|
6020
6061
|
retry: input.retry,
|
|
@@ -6089,6 +6130,9 @@ async function cmdRun(opts) {
|
|
|
6089
6130
|
accountConcurrency,
|
|
6090
6131
|
sectionConcurrency,
|
|
6091
6132
|
keywordLimit: opts.keywordLimit,
|
|
6133
|
+
campaignGeoCostGreater: finiteBatchOpt(opts.campaignGeoCostGreater),
|
|
6134
|
+
campaignGeoClickGreater: finiteBatchOpt(opts.campaignGeoClickGreater),
|
|
6135
|
+
campaignGeoConversionsGreater: finiteBatchOpt(opts.campaignGeoConversionsGreater),
|
|
6092
6136
|
minSpend,
|
|
6093
6137
|
deadlineMs,
|
|
6094
6138
|
retry,
|
|
@@ -6161,6 +6205,9 @@ async function cmdResume(opts) {
|
|
|
6161
6205
|
start: manifest.dateRange.start,
|
|
6162
6206
|
end: manifest.dateRange.end,
|
|
6163
6207
|
keywordLimit: manifest.keywordLimit,
|
|
6208
|
+
campaignGeoCostGreater: finiteBatchOpt(manifest.campaignGeoCostGreater),
|
|
6209
|
+
campaignGeoClickGreater: finiteBatchOpt(manifest.campaignGeoClickGreater),
|
|
6210
|
+
campaignGeoConversionsGreater: finiteBatchOpt(manifest.campaignGeoConversionsGreater),
|
|
6164
6211
|
accountConcurrency: manifest.concurrency.account,
|
|
6165
6212
|
sectionConcurrency: manifest.concurrency.section,
|
|
6166
6213
|
retry: { ...DEFAULT_RETRY_POLICY, ...manifest.retry },
|
|
@@ -6264,6 +6311,18 @@ function registerGoogleAnalysisBatchCommands(program2) {
|
|
|
6264
6311
|
"--keyword-limit <n>",
|
|
6265
6312
|
"\u900F\u4F20\u7ED9 keywords / search-terms \u7684\u6761\u6570\u4E0A\u9650\uFF08\u63A7\u5236\u5927\u8D26\u6237\u54CD\u5E94\u4F53\u79EF\uFF09",
|
|
6266
6313
|
(v) => parseInt(v, 10)
|
|
6314
|
+
).option(
|
|
6315
|
+
"--campaign-geo-cost-greater <n>",
|
|
6316
|
+
"\u4EC5 campaign-geo\uFF1A\u7F51\u5173 costGreater \u8FC7\u6EE4\uFF08\u6574\u6570\uFF09",
|
|
6317
|
+
(v) => parseInt(v, 10)
|
|
6318
|
+
).option(
|
|
6319
|
+
"--campaign-geo-click-greater <n>",
|
|
6320
|
+
"\u4EC5 campaign-geo\uFF1A\u7F51\u5173 clickGreater \u8FC7\u6EE4\uFF08\u6574\u6570\uFF09",
|
|
6321
|
+
(v) => parseInt(v, 10)
|
|
6322
|
+
).option(
|
|
6323
|
+
"--campaign-geo-conversions-greater <n>",
|
|
6324
|
+
"\u4EC5 campaign-geo\uFF1A\u7F51\u5173 conversionsGreater \u8FC7\u6EE4\uFF08\u6574\u6570\uFF09",
|
|
6325
|
+
(v) => parseInt(v, 10)
|
|
6267
6326
|
).option(
|
|
6268
6327
|
"--min-spend <n>",
|
|
6269
6328
|
"\u533A\u95F4\u5185\u6D88\u8017 \u2264 \u6B64\u503C\u7684\u8D26\u6237\u8DF3\u8FC7\uFF1B0=\u4E0D\u8FC7\u6EE4\uFF08\u4E0E --accounts \u540C\u4F20\u65F6\u65E0\u6548\uFF09",
|
|
@@ -6349,7 +6408,7 @@ async function runAllSections(opts) {
|
|
|
6349
6408
|
}
|
|
6350
6409
|
if (!opts.jsonOut || !opts.jsonOut.trim()) {
|
|
6351
6410
|
console.error(
|
|
6352
|
-
"\n\u274C all \u6A21\u5F0F\u5FC5\u987B\u4F20 --json-out <\u76EE\u5F55>\
|
|
6411
|
+
"\n\u274C all \u6A21\u5F0F\u5FC5\u987B\u4F20 --json-out <\u76EE\u5F55>\uFF0823 \u4E2A\u7EF4\u5EA6\u7ED3\u679C\u843D\u76D8\u540E\u7531 manifest \u7D22\u5F15\uFF09\u3002\n"
|
|
6353
6412
|
);
|
|
6354
6413
|
process.exit(1);
|
|
6355
6414
|
}
|
|
@@ -6411,6 +6470,9 @@ async function runAllSections(opts) {
|
|
|
6411
6470
|
console.log(JSON.stringify(summary));
|
|
6412
6471
|
if (failed > 0) process.exit(2);
|
|
6413
6472
|
}
|
|
6473
|
+
function finiteOpt(n) {
|
|
6474
|
+
return typeof n === "number" && Number.isFinite(n) ? n : void 0;
|
|
6475
|
+
}
|
|
6414
6476
|
function parseAccountIdsForAnalysis(input) {
|
|
6415
6477
|
const out = [];
|
|
6416
6478
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -6451,6 +6513,9 @@ async function runMultiAccountViaBatch(accountIds, opts) {
|
|
|
6451
6513
|
accountConcurrency,
|
|
6452
6514
|
sectionConcurrency: concurrency,
|
|
6453
6515
|
keywordLimit: opts.limit,
|
|
6516
|
+
campaignGeoCostGreater: finiteOpt(opts.costGreater),
|
|
6517
|
+
campaignGeoClickGreater: finiteOpt(opts.clickGreater),
|
|
6518
|
+
campaignGeoConversionsGreater: finiteOpt(opts.conversionsGreater),
|
|
6454
6519
|
minSpend: 0,
|
|
6455
6520
|
retry: DEFAULT_RETRY_POLICY,
|
|
6456
6521
|
token: opts.token,
|
|
@@ -6500,7 +6565,7 @@ function registerGoogleAnalysisCommands(program2) {
|
|
|
6500
6565
|
"\u5F00\u59CB\u65E5\u671F YYYY-MM-DD\uFF08range \u7C7B\u7EF4\u5EA6\u751F\u6548\uFF1B\u7701\u7565=\u8FD1 7 \u5929\u622A\u81F3\u6628\u5929\uFF1B\u4E0E --end \u540C\u4F20\u6216\u540C\u7701\uFF09"
|
|
6501
6566
|
).option("--end <date>", "\u7ED3\u675F\u65E5\u671F YYYY-MM-DD").option(
|
|
6502
6567
|
"--sections <list>",
|
|
6503
|
-
"\u4EC5\u6267\u884C\u6307\u5B9A\u7EF4\u5EA6\uFF08\u9017\u53F7\u5206\u9694\uFF09\uFF0C\u5982 overview,keywords,ads\uFF1B\u7701\u7565=\u5168\u90E8
|
|
6568
|
+
"\u4EC5\u6267\u884C\u6307\u5B9A\u7EF4\u5EA6\uFF08\u9017\u53F7\u5206\u9694\uFF09\uFF0C\u5982 overview,keywords,ads\uFF1B\u7701\u7565=\u5168\u90E8 23 \u4E2A"
|
|
6504
6569
|
).option(
|
|
6505
6570
|
"--exclude <list>",
|
|
6506
6571
|
"\u6392\u9664\u6307\u5B9A\u7EF4\u5EA6\uFF08\u9017\u53F7\u5206\u9694\uFF09\uFF0C\u5982 materials,gold-account\uFF1B\u4E0E --sections \u53EF\u53E0\u52A0"
|
|
@@ -6511,15 +6576,27 @@ function registerGoogleAnalysisCommands(program2) {
|
|
|
6511
6576
|
).option("--limit <n>", "\u900F\u4F20\u7ED9 keywords / search-terms \u7EF4\u5EA6\u7684\u6761\u6570\u4E0A\u9650", (v) => parseInt(v, 10)).option("--no-order-by-cost", "\u900F\u4F20\uFF1Akeywords / search-terms \u4E0D\u6309\u6D88\u8017\u6392\u5E8F", false).option("--level <level>", "\u900F\u4F20\u7ED9 extensions \u7EF4\u5EA6\u7684 level \u8FC7\u6EE4\uFF1AAccount | Campaign | Ad Group").option(
|
|
6512
6577
|
"--audience-type <type>",
|
|
6513
6578
|
"\u900F\u4F20\u7ED9 audience \u7EF4\u5EA6\u7684 audienceTypeFilter\uFF1ASystemDefined | UserDefined"
|
|
6579
|
+
).option(
|
|
6580
|
+
"--cost-greater <n>",
|
|
6581
|
+
"\u4EC5 campaign-geo\uFF1A\u7F51\u5173\u53EF\u9009\u8FC7\u6EE4 costGreater\uFF08\u6574\u6570\uFF0C\u5355\u4F4D\u4EE5\u540E\u7AEF\u4E3A\u51C6\uFF09",
|
|
6582
|
+
(v) => parseInt(v, 10)
|
|
6583
|
+
).option(
|
|
6584
|
+
"--click-greater <n>",
|
|
6585
|
+
"\u4EC5 campaign-geo\uFF1A\u7F51\u5173\u53EF\u9009\u8FC7\u6EE4 clickGreater\uFF08\u6574\u6570\uFF09",
|
|
6586
|
+
(v) => parseInt(v, 10)
|
|
6587
|
+
).option(
|
|
6588
|
+
"--conversions-greater <n>",
|
|
6589
|
+
"\u4EC5 campaign-geo\uFF1A\u7F51\u5173\u53EF\u9009\u8FC7\u6EE4 conversionsGreater\uFF08\u6574\u6570\uFF09",
|
|
6590
|
+
(v) => parseInt(v, 10)
|
|
6514
6591
|
).option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).addHelpText(
|
|
6515
6592
|
"after",
|
|
6516
6593
|
[
|
|
6517
6594
|
"",
|
|
6518
|
-
"\u53EF\u7528\u7EF4\u5EA6\
|
|
6595
|
+
"\u53EF\u7528\u7EF4\u5EA6\uFF0823 \u4E2A\uFF0C\u4E0E --sections / --exclude \u53D6\u503C\u4E00\u81F4\uFF09\uFF1A",
|
|
6519
6596
|
...SECTIONS.map((s) => ` ${s.name.padEnd(20)} ${s.description}`),
|
|
6520
6597
|
"",
|
|
6521
6598
|
"\u793A\u4F8B\uFF1A",
|
|
6522
|
-
" # \u5355\u8D26\u6237\uFF1A\u62C9\u5168\u90E8
|
|
6599
|
+
" # \u5355\u8D26\u6237\uFF1A\u62C9\u5168\u90E8 23 \u4E2A\u7EF4\u5EA6",
|
|
6523
6600
|
" siluzan-tso google-analysis -a <mediaCustomerId> --json-out ./snap",
|
|
6524
6601
|
"",
|
|
6525
6602
|
" # \u5355\u8D26\u6237\uFF1A\u4EC5\u62C9\u5355\u4E2A\u7EF4\u5EA6\uFF08\u66FF\u4EE3\u5386\u53F2\u7684 google-analysis overview ...\uFF09",
|
|
@@ -6533,7 +6610,11 @@ function registerGoogleAnalysisCommands(program2) {
|
|
|
6533
6610
|
" siluzan-tso google-analysis -a id1,id2,id3 --start 2026-04-01 --end 2026-04-30 \\",
|
|
6534
6611
|
" --sections campaigns,geographic,keywords --json-out ./snap",
|
|
6535
6612
|
"",
|
|
6536
|
-
" # \u591A\u8D26\u6237\u573A\u666F\u5982\u9700 resume / \u81EA\u9002\u5E94\u9650\u6D41 / deadline\uFF0C\u8BF7\u76F4\u63A5\u7528 google-analysis-batch run -a ..."
|
|
6613
|
+
" # \u591A\u8D26\u6237\u573A\u666F\u5982\u9700 resume / \u81EA\u9002\u5E94\u9650\u6D41 / deadline\uFF0C\u8BF7\u76F4\u63A5\u7528 google-analysis-batch run -a ...",
|
|
6614
|
+
"",
|
|
6615
|
+
" # campaign-geo \u53EF\u9009\u9608\u503C\uFF08\u4E0E\u7F51\u5173 GetCampaignsGeoReport \u4E00\u81F4\uFF09",
|
|
6616
|
+
" siluzan-tso google-analysis -a <id> --sections campaign-geo --start <s> --end <e> \\",
|
|
6617
|
+
" --cost-greater 1000000 --json-out ./snap"
|
|
6537
6618
|
].join("\n")
|
|
6538
6619
|
).action(async (legacySection, opts) => {
|
|
6539
6620
|
if (legacySection) {
|
package/dist/skill/SKILL.md
CHANGED
|
@@ -5,7 +5,7 @@ description: >-
|
|
|
5
5
|
写 Google 搜索方案/计划/待确认结构表时先读 references/google-ads.md。
|
|
6
6
|
关键字规划师/拓词/竞品网址拓词/词包清洗/否词/建户关键词编排:先读 references/keyword-planner-workflows.md。
|
|
7
7
|
①竞品URL+种子拓词→JSON筛排TopN ②多种子长尾 ③月搜阈值与词根/意图洗词 ④google-analysis keywords 叠分批 keyword 市场指标 ⑤search-terms 与拓词对照否词线索 ⑥CPC/竞争度/搜索量筛高意图 ⑦否词表+ad keyword-negative-create ⑧Campaign→AdGroup→匹配表+ad 落地 ⑨keyword --json-out 供脚本复用。无 Forecast、无 Planner 官方按月 12 个月趋势接口。
|
|
8
|
-
运营「OKKI 周报」固定话术(如「使用okki周报模板生成…」)→ `report-templates/okki-weekly-google-client.md
|
|
8
|
+
运营「OKKI 周报」固定话术(如「使用okki周报模板生成…」)→ `report-templates/okki-weekly-google-client.md`:拉数仅用现有 `stats`/`balance`/`google-analysis`(不新增拉数子命令);**多 Sheet Excel 由 Agent 落盘后写脚本生成**,CLI **不**提供内置「写 Excel」子命令。
|
|
9
9
|
license: MIT
|
|
10
10
|
metadata:
|
|
11
11
|
requires: nodejs,siluzan-tso-cli
|
|
@@ -56,7 +56,7 @@ Windows 注意:部分 Agent 客户端通过 PowerShell / cmd 代执行命令
|
|
|
56
56
|
| `references/finance.md` | 转账、开票、发票抬头、充值网页引导 |
|
|
57
57
|
| `references/write-audit-restore.md` | 本机写审计、`--commit`、补偿写 `audit restore-plan` / `restore-apply` |
|
|
58
58
|
| `report-templates/report-template.html` | 默认 HTML 报告样式参考 |
|
|
59
|
-
| `report-templates/okki-weekly-google-client.md` | **OKKI
|
|
59
|
+
| `report-templates/okki-weekly-google-client.md` | **OKKI 周报**:固定话术 + 精简维度 CLI 拉数;**Excel 由 Agent 脚本写**(见 P6),无 CLI 内置写表命令 |
|
|
60
60
|
|
|
61
61
|
---
|
|
62
62
|
|
|
@@ -219,8 +219,8 @@ siluzan-tso accounts-digest -m Google -a id1,id2,... --start <S> --end <D> --jso
|
|
|
219
219
|
|
|
220
220
|
1. **不要**按 `google-period-report.md` 展开默认 8 维并追问追加;改读 **`report-templates/okki-weekly-google-client.md`** 全文并按其结构交付。
|
|
221
221
|
2. 确认 `mediaCustomerId` 与 `--start` / `--end`(未给齐则按上文「时间范围强制反问」)。
|
|
222
|
-
3. 同一 `--json-out` 目录执行模板中的命令组合:`list-accounts`(可选但推荐)、`stats`、`balance`、`google-analysis --sections overview,campaigns,keywords,search-terms,
|
|
223
|
-
4. **先 outline 后脚本**:读各 `*.outline.txt
|
|
222
|
+
3. 同一 `--json-out` 目录执行模板中的命令组合:`list-accounts`(可选但推荐)、`stats`、`balance`、`google-analysis --sections overview,campaigns,keywords,search-terms,campaign-device,campaign-geo`。
|
|
223
|
+
4. **先 outline 后脚本**:读各 `*.outline.txt`,再编写并执行代码从 JSON 计算并写出:① 客户话术(Markdown/纯文本均可);② 若需 **Excel**:**必须**产出多 Sheet `.xlsx`(版式与 Sheet 名见模板「必选交付」节),**只能**由 Agent 在当前环境执行脚本生成,**禁止**假设存在 `siluzan-tso … excel` 类 CLI 子命令。WorkBuddy 等编排器须在流程中显式包含「写 `.xlsx` 脚本并执行」一步,否则易缺产物。
|
|
224
224
|
5. 遵守 SKILL 硬规范:金额 `*Display`、禁止手填业务数、禁止编造 ID。
|
|
225
225
|
|
|
226
226
|
### P5 · 多账户多维度报告
|
package/dist/skill/_meta.json
CHANGED
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
|
|
90
90
|
## Google 账户分析:`google-analysis` 命令
|
|
91
91
|
|
|
92
|
-
> **重要**:`google-analysis` 是统一入口,所有
|
|
92
|
+
> **重要**:`google-analysis` 是统一入口,所有 23 个维度都通过 `--sections` 选取。关键词维度用 `--sections keywords`,**不要**用 `ad keywords` 代替。涉及「今天/当天」消耗的口径见本文顶部「数据时效性」表。
|
|
93
93
|
|
|
94
94
|
```bash
|
|
95
95
|
# 单维度
|
|
@@ -99,7 +99,7 @@ siluzan-tso google-analysis -a <id> --sections overview --json-out <dir>
|
|
|
99
99
|
siluzan-tso google-analysis -a <id> --start YYYY-MM-DD --end YYYY-MM-DD \
|
|
100
100
|
--sections overview,campaigns,devices,geographic,keywords,daily-metrics --json-out <dir>
|
|
101
101
|
|
|
102
|
-
# 全量
|
|
102
|
+
# 全量 23 个(省略 --sections)
|
|
103
103
|
siluzan-tso google-analysis -a <id> --json-out <dir>
|
|
104
104
|
|
|
105
105
|
# 排除慢/不需要的维度
|
|
@@ -112,7 +112,7 @@ siluzan-tso google-analysis -a <id> --exclude materials,gold-account --json-out
|
|
|
112
112
|
| ------------------------ | ------------------------------------------------------------------------------------ |
|
|
113
113
|
| `-a, --account <id>` | Google `mediaCustomerId`(必填) |
|
|
114
114
|
| `--json-out <dir>` | 必填;每维一个 `<section>-<accountId>.json` + `manifest-<accountId>.json` |
|
|
115
|
-
| `--sections <list>` | 仅执行指定维度(逗号分隔);省略=全部
|
|
115
|
+
| `--sections <list>` | 仅执行指定维度(逗号分隔);省略=全部 23 个 |
|
|
116
116
|
| `--exclude <list>` | 排除指定维度;与 `--sections` 可叠加 |
|
|
117
117
|
| `--start` / `--end` | 统计区间(YYYY-MM-DD);省略=近 7 天截至昨天;`final-urls`/`campaign-types` 自动忽略 |
|
|
118
118
|
| `--concurrency <n>` | 并发数,默认 5,上限 16 |
|
|
@@ -120,9 +120,12 @@ siluzan-tso google-analysis -a <id> --exclude materials,gold-account --json-out
|
|
|
120
120
|
| `--level <lvl>` | 透传给 `extensions`(Account/Campaign/Ad Group) |
|
|
121
121
|
| `--audience-type <type>` | 透传给 `audience`(SystemDefined/UserDefined) |
|
|
122
122
|
| `--no-order-by-cost` | 透传给 `keywords`/`search-terms` |
|
|
123
|
+
| `--cost-greater <n>` | 仅 **`campaign-geo`**:网关 `costGreater`(整数,单位以后端为准) |
|
|
124
|
+
| `--click-greater <n>` | 仅 **`campaign-geo`**:网关 `clickGreater` |
|
|
125
|
+
| `--conversions-greater <n>` | 仅 **`campaign-geo`**:网关 `conversionsGreater` |
|
|
123
126
|
| `--verbose` | 打印详细错误 |
|
|
124
127
|
|
|
125
|
-
### 维度列表(
|
|
128
|
+
### 维度列表(23 个)
|
|
126
129
|
|
|
127
130
|
| 维度 | 说明 |
|
|
128
131
|
| -------------------- | --------------------------------------------------------------------------------------------------- |
|
|
@@ -133,8 +136,10 @@ siluzan-tso google-analysis -a <id> --exclude materials,gold-account --json-out
|
|
|
133
136
|
| `campaign-hour` | 系列按小时(根为 JSON 数组) |
|
|
134
137
|
| `ads` | 广告;与 `ad list` 同源 |
|
|
135
138
|
| `extensions` | 附加信息;可选 `--level` |
|
|
136
|
-
| `devices` |
|
|
137
|
-
| `geographic` |
|
|
139
|
+
| `devices` | 设备分布(账户级 `DeviceSectionData`) |
|
|
140
|
+
| `geographic` | 地域分布(账户级 `GeographicSectionData`,网关侧常按国家聚合) |
|
|
141
|
+
| `campaign-geo` | 广告系列维度地理 (可选 `--cost-greater` / `--click-greater` / `--conversions-greater` 与网关一致) |
|
|
142
|
+
| `campaign-device` | 广告系列维度设备 (行可含系列/组) |
|
|
138
143
|
| `audience` | 受众;可选 `--audience-type` |
|
|
139
144
|
| `asset-images` | 图片素材 |
|
|
140
145
|
| `videos` | 视频 |
|
|
@@ -156,8 +161,8 @@ siluzan-tso google-analysis -a <id> --exclude materials,gold-account --json-out
|
|
|
156
161
|
"absoluteSnapshotDir": "/abs/path/to/snap-google",
|
|
157
162
|
"manifestFile": "manifest-9526903813.json",
|
|
158
163
|
"accountId": "9526903813",
|
|
159
|
-
"totalSections":
|
|
160
|
-
"succeeded":
|
|
164
|
+
"totalSections": 23,
|
|
165
|
+
"succeeded": 23,
|
|
161
166
|
"failed": 0,
|
|
162
167
|
"concurrency": 5,
|
|
163
168
|
"elapsedMs": 18712,
|
|
@@ -73,6 +73,7 @@ siluzan-tso google-analysis-batch status --json-out ./snap-batch --run-id <runId
|
|
|
73
73
|
| `--account-concurrency <n>` | 账户级并发(1~16) | 4 |
|
|
74
74
|
| `--section-concurrency <n>` | 单账户内维度并发(1~16) | 6 |
|
|
75
75
|
| `--keyword-limit <n>` | keywords / search-terms 条数上限 | google-analysis 默认 |
|
|
76
|
+
| `--campaign-geo-cost-greater <n>` 等 | 仅 **`campaign-geo`**:与网关 `GetCampaignsGeoReport` 可选 query 一致;写入 `run-manifest.json`,`resume` 沿用 | 不设 |
|
|
76
77
|
| `--min-spend <n>` | 区间消耗 ≤ 此值跳过(与 `-a` 同传无效) | 0 |
|
|
77
78
|
| `--deadline <dur>` | 整任务硬截止(如 `30m` / `2h`),到期标记 paused | 不设 |
|
|
78
79
|
| `--task-timeout-ms <n>` | 单 task 硬超时 | 60000 |
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
| `meta-period-report.md` | Meta(Facebook)账户周期报告 |
|
|
22
22
|
| `tiktok-period-report.md` | TikTok 广告主周期报告 |
|
|
23
23
|
| `bing-period-report.md` | Bing(BingV2)分析报告 |
|
|
24
|
-
| `okki-weekly-google-client.md` | **OKKI 周报**:Google 发客户固定话术 +
|
|
24
|
+
| `okki-weekly-google-client.md` | **OKKI 周报**:Google 发客户固定话术 + 精简维度 CLI;**Excel 仅 Agent 脚本**(无 CLI 写表子命令),见 SKILL P6 |
|
|
25
25
|
|
|
26
26
|
---
|
|
27
27
|
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
| 用户措辞 | 映射 |
|
|
75
75
|
| ------------------------------ | ----------------------------------------------------------------- |
|
|
76
76
|
| 月报、周报、投放总结、效果回顾 | 周期分析 → 对应媒体 `*-period-report.md` |
|
|
77
|
-
| **使用 okki 周报模板 / OKKI 周报 / okki 周报**(Google + 区间) | **固定话术 +
|
|
77
|
+
| **使用 okki 周报模板 / OKKI 周报 / okki 周报**(Google + 区间) | **固定话术 + 精简表 +(按需)Excel** → `okki-weekly-google-client.md`(见 SKILL **P6**);Excel **仅**由 Agent 脚本生成,**无** CLI 内置写表子命令 |
|
|
78
78
|
| 健康检查、诊断、账户分析 | 诊断 → `google-account-diagnosis-report.md`(Google)或周期型降级 |
|
|
79
79
|
| 对比、汇报、给客户看 | 以周期型为骨架,简化版本 |
|
|
80
80
|
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
> **触发话术(等价即可)**
|
|
4
4
|
> `使用okki周报模板生成<账户名或ID>,<YYYY-MM-DD>--<YYYY-MM-DD>的投放报告`
|
|
5
5
|
> 同义:`OKKI 周报`、`okki 周报模板`、`运营 OKKI 周报`。
|
|
6
|
-
> **媒体**:当前模板仅规范 **Google**(`mediaCustomerId`)。其他媒体用各自 `*-period-report.md`。
|
|
6
|
+
> **媒体**:当前模板仅规范 **Google**(`mediaCustomerId`)。其他媒体用各自 `*-period-report.md`。
|
|
7
|
+
> **Excel 版式基准**:与运营样表《**数据复盘分析**》类 xlsx 对齐(如 `2025.12数据复盘分析.xlsx`):**工作簿 5 个 Sheet、顺序与表头**以本文「最终 xlsx 版式规范」为准;Agent 生成产物须可与之逐 Sheet 对照验收。
|
|
7
8
|
|
|
8
9
|
识别到上述意图时:**不要**再走 `google-period-report.md` 的「默认 8 维 + 追问追加」流程;按本文**固定维度 + 固定客户话术**交付即可(数据仍全部来自 CLI 落盘 JSON,见 `references/account-analytics.md`)。
|
|
9
10
|
|
|
@@ -14,6 +15,15 @@
|
|
|
14
15
|
1. **账户**:`mediaCustomerId` 来自 `list-accounts -m Google -k <id>`,禁止猜 ID。
|
|
15
16
|
2. **统计区间**:`--start` / `--end`(用户未给齐时按 SKILL 反问;授权默认时可用「上一完整自然周」白名单并写明)。
|
|
16
17
|
3. **询盘口径**:模板正文第 7 条默认使用 **区间内 `conversions`(转化次数)**(来自 `stats` 或 `overview` 汇总)。若运营将「询盘」定义为某一类转化,须在报告首段脚注说明数据来源(必要时补拉 `google-analysis --sections conversion-actions` 仅作说明,不替代统计口径 unless 用户确认)。
|
|
18
|
+
4. **日期写法**:用户可能写 `2026.4.1`、`2026/4/1` 等,Agent 须先规范为 CLI 要求的 **`YYYY-MM-DD`**(如 `2026-04-01`)再传 `--start` / `--end`。
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 架构约定(Excel 谁来做)
|
|
23
|
+
|
|
24
|
+
- **`siluzan-tso` 不提供**「一键生成 OKKI Excel」的内置子命令,也**不要**在 CLI 里新增此类能力。
|
|
25
|
+
- **需要交付 Excel 时**:由 **Agent(含 WorkBuddy 编排)** 在下列 CLI **`--json-out` 落盘完成后**,自行编写并执行 **Node.js / Python** 脚本(可选用 `exceljs`、`xlsx`、`openpyxl` 等)读取目录内 JSON → 按本文「多 Sheet 版式」写出 `.xlsx`。
|
|
26
|
+
- 脚本与依赖可在当前工作区临时添加(如 `package.json` + `npm install` 或 `pip install`),或由宿主环境预装;**数值一律来自落盘 JSON**,禁止在脚本源码里写死业务数字。
|
|
17
27
|
|
|
18
28
|
---
|
|
19
29
|
|
|
@@ -31,18 +41,121 @@ siluzan-tso stats -m Google -a <mediaCustomerId> --start <S> --end <E> --json-ou
|
|
|
31
41
|
siluzan-tso balance -m Google -a <mediaCustomerId> --json-out ./snap-okki
|
|
32
42
|
|
|
33
43
|
siluzan-tso google-analysis -a <mediaCustomerId> --start <S> --end <E> --json-out ./snap-okki \
|
|
34
|
-
--sections overview,campaigns,keywords,search-terms,
|
|
44
|
+
--sections overview,campaigns,keywords,search-terms,campaign-device,campaign-geo
|
|
35
45
|
```
|
|
36
46
|
|
|
37
47
|
**说明**:
|
|
38
48
|
|
|
39
49
|
- `stats`:区间消耗、曝光、点击、转化、CTR、CPC 等与**账户级周报摘要**对齐;金额用 `*Display` 或文档规定的展示字段。
|
|
40
50
|
- `balance`:**当前**账户余额(非历史快照);话术里写清「截至查询时点」。
|
|
41
|
-
- `google-analysis`:系列 / 词 /
|
|
51
|
+
- `google-analysis`:系列 / 词 / 搜索词;**设备与国家两 Sheet 的数据源**须用 **`campaign-device` / `campaign-geo`**(网关 `…/campaigns/reports/device` 与 `…/campaigns/reports/geo`,**按广告系列(及常见广告组)拆行**),**不要**再用账户级 `devices` / `geographic`。JSON 根结构仍为 `devices[]` / `countries[]`,落盘文件名分别为 `campaign-device-<id>.json`、`campaign-geo-<id>.json`。若运营需对「国家」「设备」做跨系列汇总,在脚本中聚合,**禁止**改回账户级维度冒充系列口径。
|
|
52
|
+
- 可选:`campaign-geo` 支持网关阈值过滤,与 CLI 一致时追加 `--cost-greater` / `--click-greater` / `--conversions-greater`(见 `references/account-analytics.md`)。
|
|
53
|
+
- TopN、排序、跨系列汇总均在脚本内对 JSON 完成,禁止心算。
|
|
42
54
|
- **写脚本前**先读各 `<section>-<id>.outline.txt`(及 stats/balance 的 outline,若有),再读对应 `.json`。
|
|
43
55
|
|
|
44
56
|
---
|
|
45
57
|
|
|
58
|
+
## 最终 xlsx 版式规范(与运营样表对齐)
|
|
59
|
+
|
|
60
|
+
以下按 **工作簿 → Sheet 名(须完全一致)→ 版式** 约定,便于 WorkBuddy / 人工用样表对照验收。**不**再单独建名为「广告系列」的 Sheet(系列表在 **`账户报告`** 内)。
|
|
61
|
+
|
|
62
|
+
### 工作簿级
|
|
63
|
+
|
|
64
|
+
| 顺序 | Sheet 名 | 数据来源(CLI 落盘) |
|
|
65
|
+
| ---: | ---------- | -------------------- |
|
|
66
|
+
| 1 | `账户报告` | `campaigns` + 复盘文案(stats/overview 汇总后由 Agent 撰写) |
|
|
67
|
+
| 2 | `关键词` | `keywords` |
|
|
68
|
+
| 3 | `搜索词` | `search-terms` |
|
|
69
|
+
| 4 | `设备` | **`campaign-device`**(`campaign-device-*.json`;按系列/组拆行,非账户级 `devices`) |
|
|
70
|
+
| 5 | `国家` | **`campaign-geo`**(`campaign-geo-*.json`;按系列/地域拆行,非账户级 `geographic`) |
|
|
71
|
+
|
|
72
|
+
### 各 Sheet 共同版式
|
|
73
|
+
|
|
74
|
+
- **第 1 行(A1)**:该 Sheet 的**报告标题**(见下表「R1 标题」)。建议合并单元格横跨数据区(样表约 A1:K1 / A1:N1)。
|
|
75
|
+
- **第 2 行(A2)**:统计区间,**中文可读**:`YYYY年M月D日 - YYYY年M月D日`(由 `--start` / `--end` 转换,与样表一致)。
|
|
76
|
+
- **第 3 行**:**表头**(列名、顺序须与下表一致)。
|
|
77
|
+
- **第 4 行起**:数据行;列宽与自动筛选、首行冻结为可选(样表含 `autoFilter`、部分 Sheet 对数据区设默认**按费用/转化相关列降序**排序,Agent 可复现或省略,**不得**因此改数)。
|
|
78
|
+
|
|
79
|
+
### 百分比与金额(与样表一致)
|
|
80
|
+
|
|
81
|
+
- **点击率、转化率、互动率**等列:样表为 **0~1 小数**(例如 7.95% 存 `0.0795`);若写百分比数字列须与运营约定二选一,**禁止**同一文件混用。
|
|
82
|
+
- **费用、CPC、每次转化费用、预算**等:与 `references/account-analytics.md` 一致;`campaigns` 中 **`budgetAmount` 为分**,展示为「元」须 **÷100**;同条 `spend`、`averageCpc` 等已为**元**。
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
### Sheet `账户报告`
|
|
87
|
+
|
|
88
|
+
| 行 | 内容 |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| R1 标题 | `广告系列报告`(与样表一致;若运营统一改名,可改文案但须保持 Sheet 名仍为 `账户报告`) |
|
|
91
|
+
| R2 | 统计区间(中文日期,见上) |
|
|
92
|
+
| R3 表头(A→K,共 11 列) | `广告系列` \| `预算` \| `费用` \| `展示次数` \| `点击次数` \| `点击率` \| `平均每次点击费用` \| `所有转化次数` \| `转化次数` \| `每次转化费用` \| `转化率` |
|
|
93
|
+
| R4… | 每行一条广告系列:来自 `campaigns-*.json` 的 `campaignName`、`budgetAmount`(÷100 为元)、`spend`、`impressions`、`clicks`、`ctr`(或 `clicks/impressions`)、`averageCpc`、**所有转化**与 **转化**字段以 JSON 及 outline 为准映射(若网关仅提供 `conversions`,缺列填 `0` 或留空并在脚注说明) |
|
|
94
|
+
| 末行「合计」 | **广告系列**列填 `总计`;**预算**列填 `--`;其余列按列语义对上方数据行做**求和或可加和指标**;**点击率 / 转化率**须用合计展示、点击、转化等**重算**,禁止对各行比率取算术平均 |
|
|
95
|
+
|
|
96
|
+
表下**留白若干行**后写 **「数据复盘」**(与样表一致):
|
|
97
|
+
|
|
98
|
+
- 首行标题:`{结束日所在月份}月份数据复盘:`(例:`12月份数据复盘:`)。
|
|
99
|
+
- 接续 **5 条结构化要点**(每条一行或自动换行,对应样表逻辑):
|
|
100
|
+
**1. 账户层级**(整体消耗、展示、点击、点击率与 3% 基准对比、询盘/转化数、平均询盘成本等,数来自 stats/overview 与上表合计);
|
|
101
|
+
**2. 关键词层级**(高转化词、高消耗低转化词及出价/竞争力建议);
|
|
102
|
+
**3. 搜索字词层级**(标红/高意向词、否词与加词建议);
|
|
103
|
+
**4. 设备层级**(基于 **`campaign-device`**:各设备在系列上的消耗/转化分布;复盘可汇总或点出高消耗系列×设备组合);
|
|
104
|
+
**5. 国家层级**(基于 **`campaign-geo`**:各国家/地区在系列上的消耗/转化;高消耗/低转化地域与降权/调价建议)。
|
|
105
|
+
文案由 Agent 据 JSON 撰写,**不得编造**表中不存在的数字。
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
### Sheet `关键词`
|
|
110
|
+
|
|
111
|
+
| 行 | 内容 |
|
|
112
|
+
| --- | --- |
|
|
113
|
+
| R1 标题 | `搜索关键字报告` |
|
|
114
|
+
| R2 | 统计区间(同 `账户报告`) |
|
|
115
|
+
| R3 表头(A→L,共 12 列) | `关键字` \| `匹配类型` \| `广告系列` \| `广告组` \| `费用` \| `展示次数` \| `点击次数` \| `点击率` \| `平均每次点击费用` \| `转化次数` \| `每次转化费用` \| `转化率` |
|
|
116
|
+
| R4… | `keywords-*.json` 行映射;`keywordMatchType` → 匹配类型;`campaignName` / `adGroupName` 等按 outline |
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
### Sheet `搜索词`
|
|
121
|
+
|
|
122
|
+
| 行 | 内容 |
|
|
123
|
+
| --- | --- |
|
|
124
|
+
| R1 标题 | `搜索字词报告` |
|
|
125
|
+
| R2 | 统计区间 |
|
|
126
|
+
| R3 表头(A→N,共 14 列) | `搜索字词` \| `匹配类型` \| `已添加/已排除` \| `广告系列` \| `广告组` \| `关键字` \| `展示次数` \| `点击次数` \| `点击率` \| `平均每次点击费用` \| `费用` \| `转化次数` \| `每次转化费用` \| `转化率` |
|
|
127
|
+
| R4… | `search-terms-*.json`;`已添加/已排除` 若 JSON 无此枚举则留空或填「—」,禁止臆造状态 |
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
### Sheet `设备`
|
|
132
|
+
|
|
133
|
+
| 行 | 内容 |
|
|
134
|
+
| --- | --- |
|
|
135
|
+
| R1 标题 | `设备报告` |
|
|
136
|
+
| R2 | 统计区间 |
|
|
137
|
+
| R3 表头(A→M,共 13 列) | `设备` \| `级别` \| `出价调整` \| `广告系列` \| `广告组` \| `展示次数` \| `点击次数` \| `点击率` \| `平均每次点击费用` \| `费用` \| `转化次数` \| `每次转化费用` \| `转化率` |
|
|
138
|
+
| R4… | **`campaign-device-*.json`**(根字段仍为 `devices[]`):`deviceType` → 设备;`campaignName` / `adGroupName` 等映射「广告系列」「广告组」列;**级别 / 出价调整** 若 JSON 无字段则留空或「—」 |
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
### Sheet `国家`
|
|
143
|
+
|
|
144
|
+
| 行 | 内容 |
|
|
145
|
+
| --- | --- |
|
|
146
|
+
| R1 标题 | `地理位置报告` |
|
|
147
|
+
| R2 | 统计区间 |
|
|
148
|
+
| R3 表头(A→L,共 12 列) | `地理位置` \| `广告系列` \| `展示次数` \| `互动次数` \| `互动率` \| `费用` \| `平均费用` \| `点击次数` \| `点击率` \| `转化次数` \| `每次转化费用` \| `转化率` |
|
|
149
|
+
| R4… | **`campaign-geo-*.json`**(根字段仍为 `countries[]`):`countryOrRegion` → 地理位置;`campaignName` 映射「广告系列」列;**互动次数 / 互动率 / 平均费用** 按 outline 与网关字段映射,无则留空或从 `interactions` 等派生并注释 |
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Excel 交付(谁来做)
|
|
154
|
+
|
|
155
|
+
若用户或运营要求交付 **xlsx**:须满足上文**最终 xlsx 版式规范**;实现仍遵守本文开头「架构约定」——**仅**由 Agent 写脚本生成,**无** CLI 内置写表命令。
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
46
159
|
## 对外客户话术(固定结构,填数来自 JSON)
|
|
47
160
|
|
|
48
161
|
首行建议:
|
|
@@ -52,7 +165,7 @@ siluzan-tso google-analysis -a <mediaCustomerId> --start <S> --end <E> --json-ou
|
|
|
52
165
|
正文模板:
|
|
53
166
|
|
|
54
167
|
```
|
|
55
|
-
您好,同步一下谷歌<S>--<E
|
|
168
|
+
您好,同步一下谷歌<S>--<E>的投放数据:
|
|
56
169
|
|
|
57
170
|
1. 消耗:共消耗<金额+币种>,平均每天消耗<金额+币种>
|
|
58
171
|
2. 展示点击:带来<曝光>次曝光,<点击>个点击;
|
|
@@ -72,34 +185,21 @@ siluzan-tso google-analysis -a <mediaCustomerId> --start <S> --end <E> --json-ou
|
|
|
72
185
|
|
|
73
186
|
## 复盘小结 + 优化建议(对内或可附在客户邮件末段)
|
|
74
187
|
|
|
75
|
-
基于同一批 JSON(尤其 `campaigns`、`keywords`、`search-terms
|
|
188
|
+
基于同一批 JSON(尤其 `campaigns`、`keywords`、`search-terms`、**`campaign-device`**、**`campaign-geo`**、`overview`):
|
|
76
189
|
|
|
77
190
|
- **复盘**:3~6 条 bullet:消耗集中度、高消耗系列/词、地域与设备差异、CTR/CPC 相对水平。
|
|
78
191
|
- **优化建议**:3~5 条可执行项(预算、否词、落地页、系列状态等),**不额外拉数**;缺数据则标 `[数据不可用:原因]`。
|
|
79
192
|
|
|
80
193
|
---
|
|
81
194
|
|
|
82
|
-
## 可选交付:多 Sheet Excel(版式约定)
|
|
83
|
-
|
|
84
|
-
无新 CLI 命令时,由 **脚本**(Node/Python + 所选 xlsx 库)从快照目录读 JSON 写出:
|
|
85
|
-
|
|
86
|
-
| Sheet 名 | 内容 |
|
|
87
|
-
| ---------- | ---- |
|
|
88
|
-
| `账户报告` | 上文「客户话术」全文 + 「复盘小结」+「优化建议」+ **广告系列**数据表(与 `campaigns` JSON 一致列) |
|
|
89
|
-
| `广告系列` | 可选:与上表相同仅表;若运营希望单 Sheet「账户报告」含表,则可省略本 Sheet |
|
|
90
|
-
| `关键词` | `keywords` 落盘表 |
|
|
91
|
-
| `搜索词` | `search-terms` 落盘表 |
|
|
92
|
-
| `设备` | `devices` 落盘表 |
|
|
93
|
-
| `国家` | `geographic` 落盘表(列名含国家/地区即可) |
|
|
94
|
-
|
|
95
|
-
列名与单位与 JSON / `references/account-analytics.md` 金额规则一致(`campaigns` 的 `budgetAmount` 为分,须 ÷100 为元等)。
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
195
|
## 与 `google-period-report.md` 的差异
|
|
100
196
|
|
|
101
197
|
| 项 | 周期报告 `google-period-report.md` | 本文 OKKI 周报 |
|
|
102
198
|
| -- | ---------------------------------- | ---------------- |
|
|
103
|
-
| 默认维度 | 8 维 + 主动追问可选追加 | **固定** `overview,campaigns,keywords,search-terms,
|
|
104
|
-
| 输出形态 | 长文分析报告 | **固定话术** + 短复盘 +
|
|
199
|
+
| 默认维度 | 8 维 + 主动追问可选追加 | **固定** `overview,campaigns,keywords,search-terms,campaign-device,campaign-geo` + `stats` + `balance` |
|
|
200
|
+
| 输出形态 | 长文分析报告 | **固定话术** + 短复盘 + **多 Sheet Excel(Agent 脚本写,非 CLI)** |
|
|
105
201
|
| 典型用户 | 内部分析 | **发客户**的同步简报 |
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|