siluzan-tso-cli 1.1.58-beta.2 → 1.1.58-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.js +65 -6
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/references/analytics/account-analytics.md +3 -2
- package/dist/skill/references/core/cli-enums.md +1 -1
- package/dist/skill/references/core/playbooks.md +2 -2
- package/dist/skill/references/report-templates/okki-weekly-google-client.md +8 -8
- package/dist/skill/report-templates/okki-weekly-google-client.md +8 -8
- package/dist/skill/scripts/install.ps1 +1 -1
- package/dist/skill/scripts/install.sh +1 -1
- package/dist/skill/snippets/handoff-p6-okki.md +2 -2
- 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.58-beta.
|
|
54
|
+
> **注意**:当前为测试版(1.1.58-beta.3),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
|
|
55
55
|
|
|
56
56
|
| 助手 | 建议 `--ai` |
|
|
57
57
|
| ----------------------- | ------------------------------------ |
|
package/dist/index.js
CHANGED
|
@@ -6082,6 +6082,7 @@ var init_wrap_snapshot_envelope = __esm({
|
|
|
6082
6082
|
"geo-matched": "countries",
|
|
6083
6083
|
"campaign-geo": "countries",
|
|
6084
6084
|
"campaign-geo-matched": "countries",
|
|
6085
|
+
"geo-targeted": "countries",
|
|
6085
6086
|
"campaign-device": "devices",
|
|
6086
6087
|
audience: "audience"
|
|
6087
6088
|
};
|
|
@@ -6297,6 +6298,7 @@ var init_google_analysis = __esm({
|
|
|
6297
6298
|
"geo-matched",
|
|
6298
6299
|
"campaign-geo",
|
|
6299
6300
|
"campaign-geo-matched",
|
|
6301
|
+
"geo-targeted",
|
|
6300
6302
|
"campaign-device",
|
|
6301
6303
|
"audience",
|
|
6302
6304
|
"asset-images",
|
|
@@ -6331,6 +6333,10 @@ var init_google_analysis = __esm({
|
|
|
6331
6333
|
"campaign-geo-matched": [
|
|
6332
6334
|
"// \u4E2D\u6587\u8BD1\u540D\uFF1A`countryOrRegionZh`\uFF08\u7531 `countryOrRegion` \u7ECF geo-en2zh.json \u7FFB\u8BD1\uFF0C\u76EE\u524D\u8986\u76D6 105 \u4E2A\u56FD\u5BB6/\u5730\u533A\uFF1B\u672A\u547D\u4E2D\u65F6\u8BE5\u5B57\u6BB5\u7F3A\u7701\uFF09\u3002"
|
|
6333
6335
|
],
|
|
6336
|
+
"geo-targeted": [
|
|
6337
|
+
"// \u5F53\u524D\u4ECD\u5728\u6295\u653E\u7684\u5B9A\u4F4D\uFF08\u5DF2\u79FB\u9664\u56FD\u5BB6\u4E0D\u4F1A\u51FA\u73B0\uFF09\u3002\u4E2D\u6587\u8BD1\u540D\uFF1A`countryOrRegionZh`\uFF08\u7531 `countryOrRegion` \u7ECF geo-en2zh.json \u7FFB\u8BD1\uFF1B\u672A\u547D\u4E2D\u65F6\u8BE5\u5B57\u6BB5\u7F3A\u7701\uFF09\u3002",
|
|
6338
|
+
"// `ctr` \u5DF2\u6298\u6210 0~1 \u5C0F\u6570\uFF1B`conversionRate` \u7F51\u5173\u672C\u8EAB\u5C31\u662F 0~1\uFF0C\u4E0D\u8981\u518D \xF7100\u3002"
|
|
6339
|
+
],
|
|
6334
6340
|
"geo-matched": [
|
|
6335
6341
|
"// \u4E2D\u6587\u8BD1\u540D\uFF1A`countryOrRegionZh`\uFF08\u7531 `countryOrRegion` \u7ECF geo-en2zh.json \u7FFB\u8BD1\uFF0C\u76EE\u524D\u8986\u76D6 105 \u4E2A\u56FD\u5BB6/\u5730\u533A\uFF1B\u672A\u547D\u4E2D\u65F6\u8BE5\u5B57\u6BB5\u7F3A\u7701\uFF09\u3002"
|
|
6336
6342
|
]
|
|
@@ -7397,11 +7403,17 @@ var init_sections = __esm({
|
|
|
7397
7403
|
},
|
|
7398
7404
|
{
|
|
7399
7405
|
name: "campaign-geo-matched",
|
|
7400
|
-
description: "\u76F8\u7B26\u5730\u7406\u4F4D\u7F6E\uFF08Matched locations\uFF0Cuser_location_view\uFF09\u7CFB\u5217\u7EA7\u660E\u7EC6 GET \u2026/campaigns/reports/geo/matched/combined",
|
|
7406
|
+
description: "\u76F8\u7B26\u5730\u7406\u4F4D\u7F6E\uFF08Matched locations\uFF0Cuser_location_view\uFF09\u7CFB\u5217\u7EA7\u660E\u7EC6 GET \u2026/campaigns/reports/geo/matched/combined\u3002\u542B\u65E5\u671F\u5185\u66FE\u7ECF\u547D\u4E2D\u3001\u540E\u6765\u5DF2\u79FB\u9664\u7684\u56FD\u5BB6",
|
|
7401
7407
|
dateMode: "range",
|
|
7402
7408
|
path: (id) => `/reporting/media-account/${id}/campaigns/reports/geo/matched/combined`,
|
|
7403
7409
|
campaignGeoFilterOption: true
|
|
7404
7410
|
},
|
|
7411
|
+
{
|
|
7412
|
+
name: "geo-targeted",
|
|
7413
|
+
description: "\u5F53\u524D\u4ECD\u5728\u6295\u653E\u7684\u5730\u7406\u4F4D\u7F6E\uFF08\u672A\u79FB\u9664\u7684 campaign location criterion\uFF09GET \u2026/campaignmanagement/v2/targetedlocations\u3002\u4E0D\u542B\u5DF2\u5220\u9664\u56FD\u5BB6\uFF1BOKKI \u56FD\u5BB6\u8868\u7528\u8FD9\u4E2A",
|
|
7414
|
+
dateMode: "range",
|
|
7415
|
+
path: (id) => `/campaignmanagement/v2/targetedlocations/${id}`
|
|
7416
|
+
},
|
|
7405
7417
|
{
|
|
7406
7418
|
name: "campaign-device",
|
|
7407
7419
|
description: "\u5E7F\u544A\u7CFB\u5217\u7EF4\u5EA6\u8BBE\u5907 GET \u2026/campaigns/reports/device\uFF08GetCampaignDeviceReport\uFF1B\u884C\u53EF\u542B campaign/adGroup\uFF09",
|
|
@@ -7805,6 +7817,47 @@ var init_normalize_overview = __esm({
|
|
|
7805
7817
|
}
|
|
7806
7818
|
});
|
|
7807
7819
|
|
|
7820
|
+
// src/commands/google-analysis/geo-targeted.ts
|
|
7821
|
+
function isRecord3(value) {
|
|
7822
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
7823
|
+
}
|
|
7824
|
+
function finiteNumber(value) {
|
|
7825
|
+
const n = typeof value === "number" ? value : Number(value);
|
|
7826
|
+
return Number.isFinite(n) ? n : 0;
|
|
7827
|
+
}
|
|
7828
|
+
function extractRows(raw) {
|
|
7829
|
+
if (Array.isArray(raw)) return raw.filter(isRecord3);
|
|
7830
|
+
if (!isRecord3(raw)) return [];
|
|
7831
|
+
if (Array.isArray(raw.data)) return raw.data.filter(isRecord3);
|
|
7832
|
+
if (isRecord3(raw.data) && Array.isArray(raw.data.data)) return raw.data.data.filter(isRecord3);
|
|
7833
|
+
return [];
|
|
7834
|
+
}
|
|
7835
|
+
function targetedLocationsToGeographic(raw) {
|
|
7836
|
+
const countries = extractRows(raw).map((row) => ({
|
|
7837
|
+
countryCriteriaId: row.id,
|
|
7838
|
+
countryOrRegion: typeof row.locationName === "string" ? row.locationName : "",
|
|
7839
|
+
campaignId: row.campaignId == null ? void 0 : String(row.campaignId),
|
|
7840
|
+
campaignName: typeof row.campaignName === "string" ? row.campaignName : "",
|
|
7841
|
+
impressions: finiteNumber(row.impressions),
|
|
7842
|
+
clicks: finiteNumber(row.clicks),
|
|
7843
|
+
ctr: finiteNumber(row.ctr) / 100,
|
|
7844
|
+
spend: finiteNumber(row.spend),
|
|
7845
|
+
conversions: finiteNumber(row.conversions),
|
|
7846
|
+
allConversions: finiteNumber(row.allConversions),
|
|
7847
|
+
averageCpc: finiteNumber(row.averageCpc),
|
|
7848
|
+
conversionRate: finiteNumber(row.conversionRate),
|
|
7849
|
+
costPerConversion: finiteNumber(row.costPerConversion),
|
|
7850
|
+
interactions: finiteNumber(row.interactions),
|
|
7851
|
+
interactionRate: row.interactionRate ?? null
|
|
7852
|
+
}));
|
|
7853
|
+
return { countries };
|
|
7854
|
+
}
|
|
7855
|
+
var init_geo_targeted = __esm({
|
|
7856
|
+
"src/commands/google-analysis/geo-targeted.ts"() {
|
|
7857
|
+
"use strict";
|
|
7858
|
+
}
|
|
7859
|
+
});
|
|
7860
|
+
|
|
7808
7861
|
// src/commands/google-analysis/match-type-en2zh.json
|
|
7809
7862
|
var match_type_en2zh_default;
|
|
7810
7863
|
var init_match_type_en2zh = __esm({
|
|
@@ -102947,6 +103000,7 @@ function annotateZhFields(payload, section) {
|
|
|
102947
103000
|
case "campaign-geo":
|
|
102948
103001
|
case "campaign-geo-matched":
|
|
102949
103002
|
case "geo-matched":
|
|
103003
|
+
case "geo-targeted":
|
|
102950
103004
|
case "geographic": {
|
|
102951
103005
|
const rows = payload.countries;
|
|
102952
103006
|
annotateArrayRows(rows, "countryOrRegion", "countryOrRegionZh", GEO_DICT2);
|
|
@@ -103100,6 +103154,10 @@ async function fetchGoogleAnalysisSectionJson(config, fullPath, verbose, name2,
|
|
|
103100
103154
|
return fetchSection();
|
|
103101
103155
|
case "campaign-geo-matched":
|
|
103102
103156
|
return fetchSection();
|
|
103157
|
+
case "geo-targeted":
|
|
103158
|
+
return targetedLocationsToGeographic(
|
|
103159
|
+
await fetchJson(config, fullPath, verbose, label2, http2)
|
|
103160
|
+
);
|
|
103103
103161
|
case "campaign-device":
|
|
103104
103162
|
return fetchSection();
|
|
103105
103163
|
case "audience":
|
|
@@ -103303,6 +103361,7 @@ var init_fetch = __esm({
|
|
|
103303
103361
|
init_normalize_rates();
|
|
103304
103362
|
init_normalize_money();
|
|
103305
103363
|
init_normalize_overview();
|
|
103364
|
+
init_geo_targeted();
|
|
103306
103365
|
init_translate_fields();
|
|
103307
103366
|
init_daily_metrics_range();
|
|
103308
103367
|
}
|
|
@@ -103870,7 +103929,7 @@ function formatOkkiWeeklyReportErrors(result) {
|
|
|
103870
103929
|
...lines,
|
|
103871
103930
|
"",
|
|
103872
103931
|
"\u8BF7\u8865\u5168 narrative.sheetAnalysis.<sheet>.{summary,suggestions}\uFF085 \u4E2A Sheet\uFF09\u4E0E narrative.review.<dimension>.{overview,summary,suggestion}\uFF08\u56FA\u5B9A 5 \u7EF4\uFF1A\u8D26\u6237/\u5173\u952E\u8BCD/\u641C\u7D22\u5B57\u8BCD/\u8BBE\u5907/\u56FD\u5BB6\uFF09\u540E\u91CD\u65B0\u6267\u884C okki-render\u3002",
|
|
103873
|
-
"\u8868\u683C\u6570\u636E\u987B\u7531 --snapshot-dir \u4ECE google-analysis \u5FEB\u7167\u5408\u5E76\uFF08campaigns / keywords / search-terms / campaign-device /
|
|
103932
|
+
"\u8868\u683C\u6570\u636E\u987B\u7531 --snapshot-dir \u4ECE google-analysis \u5FEB\u7167\u5408\u5E76\uFF08campaigns / keywords / search-terms / campaign-device / geo-targeted\uFF09\u3002\u7981\u6B62\u624B\u5199 xlsx\u3002"
|
|
103874
103933
|
].join("\n");
|
|
103875
103934
|
}
|
|
103876
103935
|
var OKKI_SHEET_KEYS, OKKI_REVIEW_KEYS, OKKI_SNAPSHOT_SECTIONS, SHEET_LABELS, REVIEW_LABELS, SNAPSHOT_HINTS;
|
|
@@ -103897,7 +103956,7 @@ var init_okki_report_content = __esm({
|
|
|
103897
103956
|
"keywords",
|
|
103898
103957
|
"search-terms",
|
|
103899
103958
|
"campaign-device",
|
|
103900
|
-
"
|
|
103959
|
+
"geo-targeted"
|
|
103901
103960
|
];
|
|
103902
103961
|
SHEET_LABELS = {
|
|
103903
103962
|
campaigns: "\u8D26\u6237\u62A5\u544A",
|
|
@@ -103918,7 +103977,7 @@ var init_okki_report_content = __esm({
|
|
|
103918
103977
|
keywords: "google-analysis --sections keywords",
|
|
103919
103978
|
"search-terms": "google-analysis --sections search-terms",
|
|
103920
103979
|
"campaign-device": "\u987B\u62C9 campaign-device\uFF08\u6309\u7CFB\u5217\u62C6\u884C\uFF09\uFF0C\u7981\u6B62\u7528\u8D26\u6237\u7EA7 devices \u4EE3\u66FF",
|
|
103921
|
-
"
|
|
103980
|
+
"geo-targeted": "\u987B\u62C9 geo-targeted\uFF08\u5F53\u524D\u4ECD\u5728\u6295\u653E\u7684\u5730\u7406\u4F4D\u7F6E\uFF09\u3002\u7981\u6B62\u7528 campaign-geo-matched / geographic / campaign-geo\uFF1A\u524D\u8005\u4F1A\u628A\u5DF2\u79FB\u9664\u7684\u56FD\u5BB6\u4E5F\u7B97\u8FDB\u65E5\u671F\u533A\u95F4"
|
|
103922
103981
|
};
|
|
103923
103982
|
}
|
|
103924
103983
|
});
|
|
@@ -104058,7 +104117,7 @@ async function mergeOkkiSnapshotIntoReport(payload, snapshotDir) {
|
|
|
104058
104117
|
keywords: items2(sectionMap.get("keywords")),
|
|
104059
104118
|
searchTerms: items2(sectionMap.get("search-terms")),
|
|
104060
104119
|
devices: deviceRows2,
|
|
104061
|
-
geo: items2(sectionMap.get("
|
|
104120
|
+
geo: items2(sectionMap.get("geo-targeted"))
|
|
104062
104121
|
},
|
|
104063
104122
|
facts: {
|
|
104064
104123
|
devices: summarizeOkkiDeviceSpend(deviceRows2)
|
|
@@ -106389,7 +106448,7 @@ function registerGoogleAnalysisCommands(program2) {
|
|
|
106389
106448
|
"\u6839\u636E Agent \u64B0\u5199\u7684 OKKI \u53D9\u4E8B JSON \u751F\u6210 5 Sheet xlsx\uFF08\u6821\u9A8C\u6BCF Sheet \u5206\u6790 + \u8D26\u6237 Sheet 5 \u7EF4\u6570\u636E\u590D\u76D8\uFF0C\u7F3A\u9879\u62D2\u7EDD\u6E32\u67D3\uFF09"
|
|
106390
106449
|
).requiredOption("--data <file>", "Agent \u4EA7\u51FA\u7684 okki-weekly-report.json").requiredOption(
|
|
106391
106450
|
"--snapshot-dir <dir>",
|
|
106392
|
-
"google-analysis --json-out \u76EE\u5F55\uFF08\u987B\u542B campaigns / keywords / search-terms / campaign-device /
|
|
106451
|
+
"google-analysis --json-out \u76EE\u5F55\uFF08\u987B\u542B campaigns / keywords / search-terms / campaign-device / geo-targeted\uFF09"
|
|
106393
106452
|
).option("--out <file>", "\u8F93\u51FA xlsx \u8DEF\u5F84\uFF08\u9ED8\u8BA4\u540C --data \u76EE\u5F55\u7684 okki-weekly-report.xlsx\uFF09").action(async (opts) => {
|
|
106394
106453
|
await runGoogleAnalysisOkkiRender({
|
|
106395
106454
|
dataFile: opts.data,
|
package/dist/skill/_meta.json
CHANGED
|
@@ -129,7 +129,8 @@ siluzan-tso google-analysis -a <id> --exclude materials,gold-account --json-out
|
|
|
129
129
|
| `geographic` | 地域分布(账户级 `GeographicSectionData`,网关侧常按国家聚合) |
|
|
130
130
|
| `geo-matched` | 相符地理位置(Matched locations,`user_location_view`)账户级按国家/地区汇总 |
|
|
131
131
|
| `campaign-geo` | 广告系列维度地理(可选 `--cost-greater` / `--click-greater` / `--conversions-greater` 与网关一致) |
|
|
132
|
-
| `campaign-geo-matched` | 相符地理位置(Matched locations
|
|
132
|
+
| `campaign-geo-matched` | 相符地理位置(Matched locations)系列级明细(可选同上阈值参数)。日期区间内曾经命中、后来已移除的国家仍会出数 |
|
|
133
|
+
| `geo-targeted` | 当前仍在投放的地理位置(未移除的定位)。OKKI 国家表用这个,不含已删除国家 |
|
|
133
134
|
| `campaign-device` | 广告系列维度设备(行可含系列/组)。`deviceType` 字面量多为 **`Desktop` / `Mobile` / `Tablet`**(Title Case)或中文「计算机 / 移动设备」,**不是** `DESKTOP`/`MOBILE`。出价调整展示用 `bidModifierDisplay`(对齐 Google 后台:未设置=`—`,`0.6`=`-40%`);`bidModifier` 仍是倍率,禁止自行换成正百分比 |
|
|
134
135
|
| `audience` | 受众;可选 `--audience-type` |
|
|
135
136
|
| `asset-images` | 图片素材 |
|
|
@@ -161,7 +162,7 @@ siluzan-tso google-analysis -a <id> --exclude materials,gold-account --json-out
|
|
|
161
162
|
|
|
162
163
|
| 桶 | 维度 | 读法 |
|
|
163
164
|
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
|
|
164
|
-
| **列表** | `keywords`、`search-terms`、`campaigns`、`campaign-hour`、`ads`、`extensions`、`devices`、`geographic`、`geo-matched`、`campaign-geo`、`campaign-geo-matched`、`campaign-device`、`audience`、`asset-images`、`videos`、`materials`、`daily-metrics`、`conversion-actions` | `d.items[]` |
|
|
165
|
+
| **列表** | `keywords`、`search-terms`、`campaigns`、`campaign-hour`、`ads`、`extensions`、`devices`、`geographic`、`geo-matched`、`campaign-geo`、`campaign-geo-matched`、`geo-targeted`、`campaign-device`、`audience`、`asset-images`、`videos`、`materials`、`daily-metrics`、`conversion-actions` | `d.items[]` |
|
|
165
166
|
| **汇总** | `overview`、`resource-counts`、`dimension-summary`、`gold-account`、`ads-index`、`final-urls`、`campaign-types` | `d.record` |
|
|
166
167
|
|
|
167
168
|
脚本示例(Node)—— 所有维度同一套读法:
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
| 命令 | 选项 | 合法值 |
|
|
24
24
|
| ------------------------------------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
25
|
-
| google-analysis, google-analysis-batch run | --sections | overview \| keywords \| search-terms \| campaigns \| campaign-hour \| ads \| extensions \| devices \| geographic \| geo-matched \| campaign-geo \| campaign-geo-matched \| campaign-device \| audience \| asset-images \| videos \| materials \| resource-counts \| conversion-actions \| daily-metrics \| gold-account \| ads-index \| final-urls \| dimension-summary \| campaign-types |
|
|
25
|
+
| google-analysis, google-analysis-batch run | --sections | overview \| keywords \| search-terms \| campaigns \| campaign-hour \| ads \| extensions \| devices \| geographic \| geo-matched \| campaign-geo \| campaign-geo-matched \| geo-targeted \| campaign-device \| audience \| asset-images \| videos \| materials \| resource-counts \| conversion-actions \| daily-metrics \| gold-account \| ads-index \| final-urls \| dimension-summary \| campaign-types |
|
|
26
26
|
|
|
27
27
|
> 逗号分隔;省略=全部。`final-urls`、`campaign-types` 不传日期。
|
|
28
28
|
|
|
@@ -141,9 +141,9 @@
|
|
|
141
141
|
- **步骤**:
|
|
142
142
|
1. (可选)Read `subagent-orchestration.md` § P6 决定是否分阶段委派。
|
|
143
143
|
2. `list-accounts -m Google -k <用户给的账户号>`(`928-780-1878` 可原样,CLI 去连字符)确认 `mediaCustomerId`;无 `-k` 的默认首页或 `itemCount < total` **禁止**判定未绑定。确认 `--start` / `--end`。
|
|
144
|
-
3. 同一 `--json-out` 目录执行模板命令组合:`stats`、`balance`、`google-analysis --sections overview,campaigns,keywords,search-terms,campaign-device,
|
|
144
|
+
3. 同一 `--json-out` 目录执行模板命令组合:`stats`、`balance`、`google-analysis --sections overview,campaigns,keywords,search-terms,campaign-device,geo-targeted`。
|
|
145
145
|
4. 脚本读盘 → 只写 `okki-weekly-report.json` 的 `meta` + `narrative`(5 Sheet 表末分析 + 账户 Sheet 固定 5 维数据复盘;表为空也须写)。`deviceType` 是 `Desktop`/`Mobile`,禁止 `.get("DESKTOP")`,按大小写不敏感分类累加后再写设备金额。
|
|
146
|
-
5. `google-analysis okki-render --data ./okki-weekly-report.json --snapshot-dir ./snap-okki --out <xlsx>`。缺分析 / 缺 5 维复盘 / 缺 `campaign-device` 或 `
|
|
146
|
+
5. `google-analysis okki-render --data ./okki-weekly-report.json --snapshot-dir ./snap-okki --out <xlsx>`。缺分析 / 缺 5 维复盘 / 缺 `campaign-device` 或 `geo-targeted` 会拒绝出文件;按 stderr 补 JSON 后重跑。**禁止** Agent 手写 xlsx。
|
|
147
147
|
6. 按 `okki-weekly-google-client.md` **默认 7 条话术**填数,放进代码块,一条一行(第 6 条的 ①②③ 也各占一行)。禁止合成一段,禁止改成「一、二、三、四」。上一轮或其他账户的话术不算本轮骨架;只有用户**本轮**粘贴全文或点名增删某一条时才改被点名的条目。数值与 xlsx 一致。
|
|
148
148
|
- **产物**:`okki-render` 写出的 `.xlsx` 路径(缺文件 = 未完成)+ 对话内客户话术;**不**按 P4 默认 9 章追加。仅用户明确「只要话术 / 不要文件」时才省略 xlsx。
|
|
149
149
|
|
|
@@ -59,7 +59,7 @@ siluzan-tso google-analysis okki-render \
|
|
|
59
59
|
- `narrative`(**Agent 必填,唯一由 Agent 撰写的内容**):
|
|
60
60
|
- `sheetAnalysis.{campaigns,keywords,searchTerms,devices,geo}`:每个 Sheet 各 `{summary[](≥1), suggestions[](≥1)}`。**表为空也必须写**(例如「本周期无搜索词,暂无加词/否词建议」)。
|
|
61
61
|
- `review.{account,keywords,searchTerms,devices,geo}`:账户 Sheet「数据复盘」固定 5 维,每维 `{overview, summary, suggestion}` 均非空。
|
|
62
|
-
- `tables` / `kpis`:Agent 可省略;**render 以快照覆盖**。设备/国家只认 `campaign-device` / `
|
|
62
|
+
- `tables` / `kpis`:Agent 可省略;**render 以快照覆盖**。设备/国家只认 `campaign-device` / `geo-targeted`。
|
|
63
63
|
- `facts.devices`:render **合并后**才写入,写 JSON 时还没有这组数。设备消耗/占比必须在写 `narrative` 前由脚本从 `campaign-device` 累加(见下方「拉数」)。
|
|
64
64
|
- `campaign-device` 的 `deviceType` 字面量是 **`Desktop` / `Mobile` / `Tablet`**(Title Case)或中文「计算机 / 移动设备 / 平板」。**禁止** `totals.get("DESKTOP")` / `.get("MOBILE")`(键对不上就是 0,会写成「消耗¥0」)。`okki-render` **原样画出** Agent 的设备建议,不改写口吻。
|
|
65
65
|
|
|
@@ -81,14 +81,15 @@ siluzan-tso stats -m Google -a <mediaCustomerId> --start <S> --end <E> --json-ou
|
|
|
81
81
|
siluzan-tso balance -m Google -a <mediaCustomerId> --json-out ./snap-okki
|
|
82
82
|
|
|
83
83
|
siluzan-tso google-analysis -a <mediaCustomerId> --start <S> --end <E> --json-out ./snap-okki \
|
|
84
|
-
--sections overview,campaigns,keywords,search-terms,campaign-device,
|
|
84
|
+
--sections overview,campaigns,keywords,search-terms,campaign-device,geo-targeted
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
**说明**:
|
|
88
88
|
|
|
89
89
|
- `stats`:区间消耗 / 曝光 / 点击 / 转化 / CTR / CPC,与账户级周报摘要对齐;金额用 `*Display` 或文档规定的展示字段。
|
|
90
90
|
- `balance`:**当前**余额(非历史快照),话术写「截至查询时点」。
|
|
91
|
-
-
|
|
91
|
+
- 「设备」Sheet 用 **`campaign-device`**(按系列拆行),不要用账户级 `devices`。
|
|
92
|
+
- 「国家」Sheet **必须**用 **`geo-targeted`**(当前仍在投放的定位,和 Google「地理位置报告」一致)。账户中途改过国家时,**不要**用 `campaign-geo-matched`(相符地理位置,会把已经删掉的国家也算进这个日期区间),也不要用 `geographic` / `campaign-geo`(后者还会带上已移除系列的历史定位)。落盘文件名为 `campaign-device-<id>.json`、`geo-targeted-<id>.json`。
|
|
92
93
|
- **设备合计(写 narrative 前必做)**:按 `deviceType` **分类累加** `spend` / `conversions`,不要用原始字面量当字典键。生产常见值是 `Desktop` / `Mobile`,不是 `DESKTOP` / `MOBILE`。
|
|
93
94
|
|
|
94
95
|
```js
|
|
@@ -107,7 +108,6 @@ function deviceKind(deviceType) {
|
|
|
107
108
|
```
|
|
108
109
|
|
|
109
110
|
占比用「该类费用 ÷ 设备费用合计」,不是行数或展示次数。桌面费用 ≥ 移动时,不要写「移动端为主要消耗 / 移动端占比高」。
|
|
110
|
-
- 可选:`campaign-geo-matched` 支持 `--cost-greater` / `--click-greater` / `--conversions-greater`(见 `references/analytics/account-analytics.md`)。
|
|
111
111
|
- TopN、占比、洞察在写 `narrative` 前由脚本对 JSON 完成,禁止心算。
|
|
112
112
|
- 写 JSON 前先读各 `<section>-<id>.outline.txt` 再读 `.json`。
|
|
113
113
|
- 合计行、CTR/CPA、日期标题、Sheet 列顺序由 `okki-render` 计算,Agent 不要往 JSON 里填表格行。
|
|
@@ -142,7 +142,7 @@ function deviceKind(deviceType) {
|
|
|
142
142
|
| 2 | `关键词` | `keywords` |
|
|
143
143
|
| 3 | `搜索词` | `search-terms` |
|
|
144
144
|
| 4 | `设备` | **`campaign-device-*.json`**(按系列/组拆行) |
|
|
145
|
-
| 5 | `国家` | **`
|
|
145
|
+
| 5 | `国家` | **`geo-targeted-*.json`**(当前仍在投放的地理位置,按系列/地域拆行;不含已移除国家) |
|
|
146
146
|
|
|
147
147
|
### 各 Sheet 共同版式
|
|
148
148
|
|
|
@@ -234,7 +234,7 @@ function deviceKind(deviceType) {
|
|
|
234
234
|
| R1 | `地理位置报告` |
|
|
235
235
|
| R2 | 统计区间 |
|
|
236
236
|
| R3(A→M,13 列) | `地理位置` \| `广告系列` \| `展示次数` \| `互动次数` \| `互动率` \| `费用` \| `平均费用` \| `点击次数` \| `点击率` \| `所有转化次数` \| `转化次数` \| `每次转化费用` \| `转化率` |
|
|
237
|
-
| R4… | `
|
|
237
|
+
| R4… | `geo-targeted-*.json` 的 `items[]`(`schemaVersion 3` 行统一在 `items`):`countryOrRegion`→地理位置;`campaignName`→「广告系列」;`allConversions`→「所有转化次数」;`conversions`→「转化次数」;**互动次数**→`interactions`,缺省/为 0 时回退 `clicks`(当前定位接口常不回 interactions);**互动率**→`interactionRate`(字符串须解析)或 `互动次数/impressions`,回退后仍为 0 才填 `—`;**平均费用** = `spend / 互动次数`(同样先 interactions 再 clicks),分母为 0 时填 `—`;`ctr` / `conversionRate` 直接写入;其余列按 outline 映射 |
|
|
238
238
|
| 表末「分析」 | **总结**:Top 国家/地区消耗与转化、高消耗低转化地域、系列×地域组合。**建议**:地域加价/降价、排除或单独系列(须写国家/地区名 + 表中费用/转化/CPA),1~3 条 |
|
|
239
239
|
|
|
240
240
|
---
|
|
@@ -286,7 +286,7 @@ function deviceKind(deviceType) {
|
|
|
286
286
|
| 3 水平判定 | **搜索消耗 ≥60%**:`<3%` 偏低,`3%~5%` 正常,`>5%` 优秀,括号写「搜索正常水平 3%~5%」。**展示消耗 ≥60%**:`<1%` 偏低,`1%~2%` 正常,`>2%` 优秀,括号写「展示正常水平 1%~2%」。其余写「整体」,并说明依据(如搜索消耗占比)。括号里只留这一句判定,不要把本表规则贴给客户 |
|
|
287
287
|
| 4 CPC | `averageCpc`,或 `cost / clicks` |
|
|
288
288
|
| 5 转化数 | 默认 `conversions` |
|
|
289
|
-
| 5.1 / 5.2 | `keywords` / `
|
|
289
|
+
| 5.1 / 5.2 | `keywords` / `geo-targeted` 中 `conversions > 0`,按词或国家合计,最多 5 个,写成「名称(N 个,CPA 金额)」;没有则写「本周期暂无带转化关键词」或「本周期暂无带转化国家/地区」 |
|
|
290
290
|
| 6 优化建议 | 同批 JSON,3~5 条,每条单独一行;不额外拉数。用户若限定「只写预算/否词」,按该范围写,条数仍各自成行 |
|
|
291
291
|
| 7 余额 | `balance` 当前余额,标注截至查询时点 |
|
|
292
292
|
|
|
@@ -316,6 +316,6 @@ function deviceKind(deviceType) {
|
|
|
316
316
|
|
|
317
317
|
| 项 | `google-period-report.md` | 本文 OKKI 周报 |
|
|
318
318
|
| -------- | ------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
319
|
-
| 默认维度 | 8 维 + 主动追问追加 | **固定** `overview,campaigns,keywords,search-terms,campaign-device,
|
|
319
|
+
| 默认维度 | 8 维 + 主动追问追加 | **固定** `overview,campaigns,keywords,search-terms,campaign-device,geo-targeted` + `stats` + `balance` |
|
|
320
320
|
| 输出形态 | 长文分析报告(默认 HTML,`google-analysis render`) | **必产** 5 Sheet `.xlsx`(`google-analysis okki-render`)+ 客户话术(默认 7 条、一条一行);「表格形式」= Excel;**禁止**对话 Markdown 表 / 手写 HTML / Agent 手写 xlsx / 另写一套话术标题 |
|
|
321
321
|
| 典型用户 | 内部分析 | **发客户**的同步简报 |
|
|
@@ -59,7 +59,7 @@ siluzan-tso google-analysis okki-render \
|
|
|
59
59
|
- `narrative`(**Agent 必填,唯一由 Agent 撰写的内容**):
|
|
60
60
|
- `sheetAnalysis.{campaigns,keywords,searchTerms,devices,geo}`:每个 Sheet 各 `{summary[](≥1), suggestions[](≥1)}`。**表为空也必须写**(例如「本周期无搜索词,暂无加词/否词建议」)。
|
|
61
61
|
- `review.{account,keywords,searchTerms,devices,geo}`:账户 Sheet「数据复盘」固定 5 维,每维 `{overview, summary, suggestion}` 均非空。
|
|
62
|
-
- `tables` / `kpis`:Agent 可省略;**render 以快照覆盖**。设备/国家只认 `campaign-device` / `
|
|
62
|
+
- `tables` / `kpis`:Agent 可省略;**render 以快照覆盖**。设备/国家只认 `campaign-device` / `geo-targeted`。
|
|
63
63
|
- `facts.devices`:render **合并后**才写入,写 JSON 时还没有这组数。设备消耗/占比必须在写 `narrative` 前由脚本从 `campaign-device` 累加(见下方「拉数」)。
|
|
64
64
|
- `campaign-device` 的 `deviceType` 字面量是 **`Desktop` / `Mobile` / `Tablet`**(Title Case)或中文「计算机 / 移动设备 / 平板」。**禁止** `totals.get("DESKTOP")` / `.get("MOBILE")`(键对不上就是 0,会写成「消耗¥0」)。`okki-render` **原样画出** Agent 的设备建议,不改写口吻。
|
|
65
65
|
|
|
@@ -81,14 +81,15 @@ siluzan-tso stats -m Google -a <mediaCustomerId> --start <S> --end <E> --json-ou
|
|
|
81
81
|
siluzan-tso balance -m Google -a <mediaCustomerId> --json-out ./snap-okki
|
|
82
82
|
|
|
83
83
|
siluzan-tso google-analysis -a <mediaCustomerId> --start <S> --end <E> --json-out ./snap-okki \
|
|
84
|
-
--sections overview,campaigns,keywords,search-terms,campaign-device,
|
|
84
|
+
--sections overview,campaigns,keywords,search-terms,campaign-device,geo-targeted
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
**说明**:
|
|
88
88
|
|
|
89
89
|
- `stats`:区间消耗 / 曝光 / 点击 / 转化 / CTR / CPC,与账户级周报摘要对齐;金额用 `*Display` 或文档规定的展示字段。
|
|
90
90
|
- `balance`:**当前**余额(非历史快照),话术写「截至查询时点」。
|
|
91
|
-
-
|
|
91
|
+
- 「设备」Sheet 用 **`campaign-device`**(按系列拆行),不要用账户级 `devices`。
|
|
92
|
+
- 「国家」Sheet **必须**用 **`geo-targeted`**(当前仍在投放的定位,和 Google「地理位置报告」一致)。账户中途改过国家时,**不要**用 `campaign-geo-matched`(相符地理位置,会把已经删掉的国家也算进这个日期区间),也不要用 `geographic` / `campaign-geo`(后者还会带上已移除系列的历史定位)。落盘文件名为 `campaign-device-<id>.json`、`geo-targeted-<id>.json`。
|
|
92
93
|
- **设备合计(写 narrative 前必做)**:按 `deviceType` **分类累加** `spend` / `conversions`,不要用原始字面量当字典键。生产常见值是 `Desktop` / `Mobile`,不是 `DESKTOP` / `MOBILE`。
|
|
93
94
|
|
|
94
95
|
```js
|
|
@@ -107,7 +108,6 @@ function deviceKind(deviceType) {
|
|
|
107
108
|
```
|
|
108
109
|
|
|
109
110
|
占比用「该类费用 ÷ 设备费用合计」,不是行数或展示次数。桌面费用 ≥ 移动时,不要写「移动端为主要消耗 / 移动端占比高」。
|
|
110
|
-
- 可选:`campaign-geo-matched` 支持 `--cost-greater` / `--click-greater` / `--conversions-greater`(见 `references/analytics/account-analytics.md`)。
|
|
111
111
|
- TopN、占比、洞察在写 `narrative` 前由脚本对 JSON 完成,禁止心算。
|
|
112
112
|
- 写 JSON 前先读各 `<section>-<id>.outline.txt` 再读 `.json`。
|
|
113
113
|
- 合计行、CTR/CPA、日期标题、Sheet 列顺序由 `okki-render` 计算,Agent 不要往 JSON 里填表格行。
|
|
@@ -142,7 +142,7 @@ function deviceKind(deviceType) {
|
|
|
142
142
|
| 2 | `关键词` | `keywords` |
|
|
143
143
|
| 3 | `搜索词` | `search-terms` |
|
|
144
144
|
| 4 | `设备` | **`campaign-device-*.json`**(按系列/组拆行) |
|
|
145
|
-
| 5 | `国家` | **`
|
|
145
|
+
| 5 | `国家` | **`geo-targeted-*.json`**(当前仍在投放的地理位置,按系列/地域拆行;不含已移除国家) |
|
|
146
146
|
|
|
147
147
|
### 各 Sheet 共同版式
|
|
148
148
|
|
|
@@ -234,7 +234,7 @@ function deviceKind(deviceType) {
|
|
|
234
234
|
| R1 | `地理位置报告` |
|
|
235
235
|
| R2 | 统计区间 |
|
|
236
236
|
| R3(A→M,13 列) | `地理位置` \| `广告系列` \| `展示次数` \| `互动次数` \| `互动率` \| `费用` \| `平均费用` \| `点击次数` \| `点击率` \| `所有转化次数` \| `转化次数` \| `每次转化费用` \| `转化率` |
|
|
237
|
-
| R4… | `
|
|
237
|
+
| R4… | `geo-targeted-*.json` 的 `items[]`(`schemaVersion 3` 行统一在 `items`):`countryOrRegion`→地理位置;`campaignName`→「广告系列」;`allConversions`→「所有转化次数」;`conversions`→「转化次数」;**互动次数**→`interactions`,缺省/为 0 时回退 `clicks`(当前定位接口常不回 interactions);**互动率**→`interactionRate`(字符串须解析)或 `互动次数/impressions`,回退后仍为 0 才填 `—`;**平均费用** = `spend / 互动次数`(同样先 interactions 再 clicks),分母为 0 时填 `—`;`ctr` / `conversionRate` 直接写入;其余列按 outline 映射 |
|
|
238
238
|
| 表末「分析」 | **总结**:Top 国家/地区消耗与转化、高消耗低转化地域、系列×地域组合。**建议**:地域加价/降价、排除或单独系列(须写国家/地区名 + 表中费用/转化/CPA),1~3 条 |
|
|
239
239
|
|
|
240
240
|
---
|
|
@@ -286,7 +286,7 @@ function deviceKind(deviceType) {
|
|
|
286
286
|
| 3 水平判定 | **搜索消耗 ≥60%**:`<3%` 偏低,`3%~5%` 正常,`>5%` 优秀,括号写「搜索正常水平 3%~5%」。**展示消耗 ≥60%**:`<1%` 偏低,`1%~2%` 正常,`>2%` 优秀,括号写「展示正常水平 1%~2%」。其余写「整体」,并说明依据(如搜索消耗占比)。括号里只留这一句判定,不要把本表规则贴给客户 |
|
|
287
287
|
| 4 CPC | `averageCpc`,或 `cost / clicks` |
|
|
288
288
|
| 5 转化数 | 默认 `conversions` |
|
|
289
|
-
| 5.1 / 5.2 | `keywords` / `
|
|
289
|
+
| 5.1 / 5.2 | `keywords` / `geo-targeted` 中 `conversions > 0`,按词或国家合计,最多 5 个,写成「名称(N 个,CPA 金额)」;没有则写「本周期暂无带转化关键词」或「本周期暂无带转化国家/地区」 |
|
|
290
290
|
| 6 优化建议 | 同批 JSON,3~5 条,每条单独一行;不额外拉数。用户若限定「只写预算/否词」,按该范围写,条数仍各自成行 |
|
|
291
291
|
| 7 余额 | `balance` 当前余额,标注截至查询时点 |
|
|
292
292
|
|
|
@@ -316,6 +316,6 @@ function deviceKind(deviceType) {
|
|
|
316
316
|
|
|
317
317
|
| 项 | `google-period-report.md` | 本文 OKKI 周报 |
|
|
318
318
|
| -------- | ------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
319
|
-
| 默认维度 | 8 维 + 主动追问追加 | **固定** `overview,campaigns,keywords,search-terms,campaign-device,
|
|
319
|
+
| 默认维度 | 8 维 + 主动追问追加 | **固定** `overview,campaigns,keywords,search-terms,campaign-device,geo-targeted` + `stats` + `balance` |
|
|
320
320
|
| 输出形态 | 长文分析报告(默认 HTML,`google-analysis render`) | **必产** 5 Sheet `.xlsx`(`google-analysis okki-render`)+ 客户话术(默认 7 条、一条一行);「表格形式」= Excel;**禁止**对话 Markdown 表 / 手写 HTML / Agent 手写 xlsx / 另写一套话术标题 |
|
|
321
321
|
| 典型用户 | 内部分析 | **发客户**的同步简报 |
|
|
@@ -9,7 +9,7 @@ $ErrorActionPreference = 'Stop'
|
|
|
9
9
|
# -- Package info (injected at build time) ------------------------------------
|
|
10
10
|
$PKG_NAME = 'siluzan-tso-cli'
|
|
11
11
|
# PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
|
|
12
|
-
$PKG_VERSION = '1.1.58-beta.
|
|
12
|
+
$PKG_VERSION = '1.1.58-beta.3'
|
|
13
13
|
$CLI_BIN = 'siluzan-tso'
|
|
14
14
|
$SKILL_LABEL = 'Siluzan TSO'
|
|
15
15
|
$INSTALL_CMD = 'npm install -g siluzan-tso-cli@beta'
|
|
@@ -9,7 +9,7 @@ set -euo pipefail
|
|
|
9
9
|
# -- Package info (injected at build time) ------------------------------------
|
|
10
10
|
readonly PKG_NAME="siluzan-tso-cli"
|
|
11
11
|
# PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
|
|
12
|
-
readonly PKG_VERSION="1.1.58-beta.
|
|
12
|
+
readonly PKG_VERSION="1.1.58-beta.3"
|
|
13
13
|
readonly CLI_BIN="siluzan-tso"
|
|
14
14
|
readonly SKILL_LABEL="Siluzan TSO"
|
|
15
15
|
readonly INSTALL_CMD="npm install -g siluzan-tso-cli@beta"
|
|
@@ -28,7 +28,7 @@ siluzan-tso stats -m Google -a <mediaCustomerId> --start <S> --end <E> --json-ou
|
|
|
28
28
|
siluzan-tso balance -m Google -a <mediaCustomerId> --json-out ./snap-okki
|
|
29
29
|
|
|
30
30
|
siluzan-tso google-analysis -a <mediaCustomerId> --start <S> --end <E> --json-out ./snap-okki \
|
|
31
|
-
--sections overview,campaigns,keywords,search-terms,campaign-device,
|
|
31
|
+
--sections overview,campaigns,keywords,search-terms,campaign-device,geo-targeted
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
**returnSchema**: 仅回传 exitCode、manifestFile、writtenFiles、outlineFiles、stderrTail、summary(无编造数字)。
|
|
@@ -55,6 +55,6 @@ siluzan-tso google-analysis -a <mediaCustomerId> --start <S> --end <E> --json-ou
|
|
|
55
55
|
--out ./okki-weekly-report.xlsx
|
|
56
56
|
```
|
|
57
57
|
失败则按 stderr 补 JSON 后重跑,不得改用手写表。
|
|
58
|
-
4. 设备/国家必须来自 `campaign-device` / `
|
|
58
|
+
4. 设备/国家必须来自 `campaign-device` / `geo-targeted`(由 render 校验)。国家不要用 `campaign-geo-matched`,那会把已移除的国家算进来。
|
|
59
59
|
|
|
60
60
|
**returnSchema**: xlsx 路径 + `okki-render` exitCode + 客户话术文本(默认 7 条、一条一行)。勿贴 xlsx 二进制。
|