addashboard-cli 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -452
- package/dist/commands/ads.js +13 -1
- package/dist/commands/ads.js.map +1 -1
- package/dist/commands/pl.js +67 -0
- package/dist/commands/pl.js.map +1 -0
- package/dist/commands/review.js +62 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/submission.js +197 -0
- package/dist/commands/submission.js.map +1 -1
- package/dist/index.js +83 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/ad-ops/SKILL.md +75 -6
- package/skills/ad-ops/yda-planner.html +1238 -363
- package/skills/ad-ops//343/202/242/343/202/253/343/202/246/343/203/263/343/203/210/index.json +5 -0
- package/skills/ad-ops//343/202/242/343/202/253/343/202/246/343/203/263/343/203/210/sample_account.json +40 -0
package/README.md
CHANGED
|
@@ -1,479 +1,58 @@
|
|
|
1
|
-
#
|
|
1
|
+
# addashboard-cli
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
「install → login → 広告入稿 dry-run → 実入稿」までを 1 本のマニュアルで完走できる構成にしてある。
|
|
3
|
+
広告ダッシュボード操作用の CLI。詳細な使い方・運用フローは社内マニュアル参照。
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
> 📦 配布: **npm public registry** (`addashboard-cli` unscoped) — `npx -y addashboard-cli@latest` で追加インストール不要
|
|
5
|
+
## インストール
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## 前提
|
|
12
|
-
|
|
13
|
-
- **Node.js 18+** (`node --version` で確認。無ければ [nodejs.org](https://nodejs.org) から LTS を入れる)
|
|
14
|
-
- **macOS / Linux** (Windows は動作未確認)
|
|
15
|
-
- **ネットワーク到達性**: `registry.npmjs.org` (npm パッケージ DL) と本番エンドポイント (API) の両方に届くこと
|
|
16
|
-
- **ad-dashboard アカウント**: `@webgram.jp` の Google アカウント (推奨)。フォールバックとしてメール + パスワードも可
|
|
17
|
-
|
|
18
|
-
## クイックスタート (人間向け, 5 分)
|
|
19
|
-
|
|
20
|
-
### 1. 疎通確認 (npm public registry から取得)
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npx -y addashboard-cli@latest --version
|
|
24
|
-
# → 0.2.3
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
初回のみ npm パッケージ DL で数秒。以降は npm キャッシュから即時起動。
|
|
28
|
-
|
|
29
|
-
> 💡 毎回タイプするのが面倒ならグローバルインストール:
|
|
30
|
-
> ```bash
|
|
31
|
-
> npm install -g addashboard-cli
|
|
32
|
-
> webgram --version
|
|
33
|
-
> ```
|
|
34
|
-
> アンインストールは `npm uninstall -g addashboard-cli`。
|
|
35
|
-
|
|
36
|
-
### 2. ログイン (ターミナルから対話実行)
|
|
37
|
-
|
|
38
|
-
デフォルトは **Google アカウント (@webgram.jp) でのブラウザログイン** (loopback OAuth)。パスワードは不要。
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
webgram auth login
|
|
42
|
-
# ブラウザで Google ログインを開きます…
|
|
43
|
-
# (ブラウザで @webgram.jp アカウントを選択)
|
|
44
|
-
# ✓ Logged in as you@example.com
|
|
45
|
-
# Saved to /Users/.../.config/webgram/credentials.json (chmod 0600)
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
ブラウザが自動で開かない環境では、表示された URL を手動で開けば同じフローが完了する。
|
|
49
|
-
|
|
50
|
-
#### 非対話環境 (Claude Code / CI 等) — device flow
|
|
51
|
-
|
|
52
|
-
`stdout` が TTY でない**非対話環境では自動で Google device flow に切り替わる** (loopback ブラウザは使えないため)。TTY でも `--device` を付ければ強制できる。
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
webgram auth login # 非対話環境では自動で device flow
|
|
56
|
-
webgram auth login --device # TTY でも device flow を強制
|
|
57
|
-
|
|
58
|
-
# ────────────────────────────────────────────
|
|
59
|
-
# Google でログインしてください (ブラウザ操作が必要です)
|
|
60
|
-
# 1. ブラウザで次の URL を開く: https://www.google.com/device
|
|
61
|
-
# 2. 次のコードを入力して許可: ABCD-EFGH
|
|
62
|
-
# 許可が完了すると自動でログインが続行されます…
|
|
63
|
-
# ────────────────────────────────────────────
|
|
64
|
-
# ✓ Logged in as you@example.com
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
CLI が出力する **URL と user_code** を (別端末やスマホの) ブラウザで開いて @webgram.jp アカウントで許可すると、CLI が自動でトークンを取得して保存する。**client_secret はサーバー側で保持し、CLI には持たせない**。クライアント ID / シークレットの設定は不要 (メンバーは `webgram auth login` を実行するだけ)。
|
|
68
|
-
|
|
69
|
-
#### パスワード方式 (ROPC・deprecated フォールバック)
|
|
70
|
-
|
|
71
|
-
device flow もブラウザも使えない場合の**最終フォールバック**:
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
webgram auth login --password # email/password を prompt
|
|
75
|
-
webgram auth login --email you@example.com --password 'secret' # 非推奨: shell history に残る
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
> ⚠️ パスワード方式は deprecated。対話環境ではブラウザ loopback、非対話環境では device flow が自動で選ばれるため、通常は `--password` 不要。
|
|
79
|
-
|
|
80
|
-
### 3. ログイン確認
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
webgram auth whoami
|
|
84
|
-
# {"id":"...","email":"you@example.com","name":"...","role":"admin",...}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
未ログインなら `✗ not_logged_in` + exit 1。
|
|
88
|
-
|
|
89
|
-
## YDA 入稿クイックスタート (人間向け, 10 分)
|
|
90
|
-
|
|
91
|
-
「YDA (Yahoo Display Ads) にキャンペーンを 1 本 PAUSED 状態で入れる」までの最短ルート。他媒体 (Meta / Google / SmartNews / ByteDance) も手順はほぼ同じ (JSON テンプレートを差し替えるだけ)。
|
|
92
|
-
|
|
93
|
-
### 3-1. アカウント一覧を取得
|
|
94
|
-
|
|
95
|
-
```bash
|
|
96
|
-
webgram list --platform yda --resource accounts
|
|
97
|
-
# [
|
|
98
|
-
# { "name": "伸長ぐんぐん習慣", "id": "1002778399" },
|
|
99
|
-
# { "name": "桑の葉&茶カテキン/株式会社WEBGRAM", "id": "1002792978" },
|
|
100
|
-
# ...
|
|
101
|
-
# ]
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
> ⚠️ 一覧に出るのは **ad-dashboard の連携設定 (`ApiConnection.selectedAccounts`) に登録済みのアカウントだけ**。CLI 側でページングして全件取れるコマンドは現状無い。目的のアカウントが出ないときは、ad-dashboard の Web UI (データシンク → YDA) から `selectedAccounts` に追加する。
|
|
105
|
-
|
|
106
|
-
### 3-2. 入稿ボディ雛形をコピー
|
|
107
|
-
|
|
108
|
-
同梱の fixtures からコピーして書き換える:
|
|
7
|
+
Node.js 18+ が必要。
|
|
109
8
|
|
|
110
9
|
```bash
|
|
111
|
-
#
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
# あるいは GitHub の Web からダウンロード:
|
|
115
|
-
# https://github.com/WEBGRAM-WG/ad-dashboard/tree/main/cli/fixtures
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
`my_yda.json` を開いて 最低限 以下を書き換える:
|
|
119
|
-
|
|
120
|
-
- `accountId` — 3-1 で確認した対象アカウント ID
|
|
121
|
-
- `campaigns[0].name` — 任意のユニークな名前 (例: `商品名_20260714_PoC`)
|
|
122
|
-
- `campaigns[0].startDate` — 明日以降 (`YYYY-MM-DD`)
|
|
123
|
-
|
|
124
|
-
他フィールドの意味は [`cli/fixtures/README.md`](./fixtures/README.md) 参照。
|
|
125
|
-
|
|
126
|
-
### 3-3. dry-run (実媒体は触らない)
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
webgram submit --platform yda --json-file ./my_yda.json
|
|
130
|
-
# → dry-run が既定。実媒体には一切触らない。zod 検証と would_create のみ返る
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
`400` が返ったら応答の `error` フィールドを確認。必須項目が抜けているケースがほとんど。
|
|
134
|
-
|
|
135
|
-
### 3-4. 実入稿
|
|
136
|
-
|
|
137
|
-
dry-run が警告なしで通過したら、**同じ JSON** に対して:
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
webgram submit --platform yda --json-file ./my_yda.json --no-dry-run --yes
|
|
141
|
-
# ✓ Campaign created: campaignId=32523583
|
|
142
|
-
# ✓ AdGroup created: adGroupId=451748065
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
`--no-dry-run` と `--yes` の **両方** が必須 (`--yes` なしは exit 2 で停止)。二段階ガードで事故を防いでいる。
|
|
146
|
-
|
|
147
|
-
### 他媒体の入稿
|
|
148
|
-
|
|
149
|
-
Meta / Google / SmartNews / ByteDance も手順は同じ。JSON テンプレは `fixtures/` 配下:
|
|
150
|
-
|
|
151
|
-
| 媒体 | 必須 top-level | fixture |
|
|
152
|
-
|---|---|---|
|
|
153
|
-
| YDA | `accountId` | `yda_poc.json` / `yda_video_poc.json` |
|
|
154
|
-
| Meta | `accountId` (`act_...`) | `meta_poc.json` |
|
|
155
|
-
| Google | `customerId` | `google_poc.json` |
|
|
156
|
-
| SmartNews | `accountId` | `smartnews_poc.json` |
|
|
157
|
-
| ByteDance (TikTok) | `advertiserId` | `tiktok_poc.json` |
|
|
158
|
-
|
|
159
|
-
各媒体の必須フィールド・制約は [`cli/fixtures/README.md`](./fixtures/README.md) にまとめている。
|
|
160
|
-
|
|
161
|
-
---
|
|
162
|
-
|
|
163
|
-
## 初期設定: Skill として配置する (推奨、AI エージェント経由で使う場合)
|
|
164
|
-
|
|
165
|
-
Claude Code / Codex CLI から「広告運用」「YDA 入稿」等の自然言語で発火させたい場合、**`ad-ops` skill をエージェントの skills ディレクトリに配置する**のが最短。ターミナル直叩きで CLI を使う人はこの章をスキップして OK。
|
|
166
|
-
|
|
167
|
-
Skill 本体 (`SKILL.md` / `config.json` / `README.md`) は npm パッケージに同梱されているため、`npm root -g` 経由か tarball 展開でコピーする。
|
|
168
|
-
|
|
169
|
-
### Claude Code に配置
|
|
170
|
-
|
|
171
|
-
Claude Code のチャットに以下を貼り付けて実行を依頼:
|
|
172
|
-
|
|
173
|
-
```
|
|
174
|
-
addashboard-cli の ad-ops skill を ~/.claude/skills/ に配置して
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
Claude が裏で `npm pack addashboard-cli` → 展開 → `cp` を実行する。手動で入れる場合:
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
mkdir -p ~/.claude/skills/ad-ops /tmp/ad-ops-extract
|
|
181
|
-
cd /tmp/ad-ops-extract && npm pack addashboard-cli@latest
|
|
182
|
-
tar xzf addashboard-cli-*.tgz --strip-components=1
|
|
183
|
-
cp -r skills/ad-ops/. ~/.claude/skills/ad-ops/
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### Codex CLI に配置
|
|
187
|
-
|
|
188
|
-
Codex CLI は Claude Code のような skills 自動発火機能を持たないため、以下いずれかで SKILL.md を context に読み込ませる。
|
|
189
|
-
|
|
190
|
-
**方式 A: プロジェクトルートの `AGENTS.md` に参照を書く (推奨)**
|
|
191
|
-
|
|
192
|
-
作業ディレクトリの `AGENTS.md` に以下を追記:
|
|
193
|
-
|
|
194
|
-
```markdown
|
|
195
|
-
## 広告運用 (ad-ops skill)
|
|
196
|
-
|
|
197
|
-
ad-dashboard の広告操作は `~/.codex/skills/ad-ops/SKILL.md` に従って `webgram` CLI (`npx -y addashboard-cli@latest`) 経由で実行する。設定は `~/.codex/skills/ad-ops/config.json` を参照。
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
SKILL.md 本体を配置:
|
|
10
|
+
# 都度実行 (推奨)
|
|
11
|
+
npx -y addashboard-cli@latest --help
|
|
201
12
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
tar xzf addashboard-cli-*.tgz --strip-components=1
|
|
206
|
-
cp -r skills/ad-ops/. ~/.codex/skills/ad-ops/
|
|
13
|
+
# あるいはグローバルインストール
|
|
14
|
+
npm install -g addashboard-cli
|
|
15
|
+
webgram --help
|
|
207
16
|
```
|
|
208
17
|
|
|
209
|
-
|
|
18
|
+
## ログイン
|
|
210
19
|
|
|
211
20
|
```bash
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
**方式 C: `~/.codex/config.toml` の `instructions` に恒久追加** (Codex CLI のバージョンによる)
|
|
216
|
-
|
|
217
|
-
### 発火方法
|
|
218
|
-
|
|
219
|
-
配置後、以下のいずれかのキーワードでエージェントに投げると自動発火 (Codex は AGENTS.md 経由で読み込まれる):
|
|
220
|
-
|
|
221
|
-
| カテゴリ | 発火キーワード例 |
|
|
222
|
-
|---|---|
|
|
223
|
-
| 参照系 | 「YDA のアカウント見せて」「Meta のキャンペーン一覧」「広告アカウント一覧」 |
|
|
224
|
-
| 入稿系 | 「YDA に入稿して」「PAUSED で dry-run」「Meta に入稿の dry-run」 |
|
|
225
|
-
| 認証系 | 「ad-dashboard のログイン状態は?」「webgram でログアウトして」 |
|
|
226
|
-
| 直接指定 | 「/ad-ops」「ad-ops skill 使って」「広告運用スキルで」 |
|
|
227
|
-
|
|
228
|
-
skill 側の詳細な発火条件・実行フロー・トラブルシュートは [`skills/ad-ops/README.md`](./skills/ad-ops/README.md) 参照。
|
|
229
|
-
|
|
230
|
-
---
|
|
231
|
-
|
|
232
|
-
## AI エージェント向け決定表
|
|
233
|
-
|
|
234
|
-
Claude Code / Codex CLI などの AI エージェントが「YDA 入稿して」のような曖昧な指示を受けたときに、試行錯誤せず最短経路で完走するための決定表。
|
|
235
|
-
|
|
236
|
-
### コマンド早見表
|
|
237
|
-
|
|
238
|
-
| ユーザーがやりたいこと | 実行コマンド |
|
|
239
|
-
|---|---|
|
|
240
|
-
| 疎通確認 | `npx -y addashboard-cli@latest --help` |
|
|
241
|
-
| ログイン状態確認 | `webgram auth whoami` (成功=exit 0 / `not_logged_in`=exit 1) |
|
|
242
|
-
| ログイン (代行禁止 — 後述) | `webgram auth login` (Google SSO / device flow) |
|
|
243
|
-
| ログアウト | `webgram auth logout` |
|
|
244
|
-
| アカウント一覧 | `webgram list --platform <yda\|meta\|google\|smartnews\|bytedance> --resource accounts` |
|
|
245
|
-
| キャンペーン一覧 | `webgram list --platform <媒体> --resource campaigns --account-id <id>` |
|
|
246
|
-
| リソース一覧 (YDA/Meta/Google/ByteDance) | `webgram list --platform <媒体> --resource resources --account-id <id>` |
|
|
247
|
-
| 入稿 dry-run | `webgram submit --platform <媒体> --json-file <path>` |
|
|
248
|
-
| 実入稿 | `webgram submit --platform <媒体> --json-file <path> --no-dry-run --yes` |
|
|
249
|
-
|
|
250
|
-
### 媒体別 top-level 必須フィールド
|
|
251
|
-
|
|
252
|
-
エージェントが JSON を組む前に必ず参照する。詳細フィールドは fixtures を参照。
|
|
253
|
-
|
|
254
|
-
| 媒体 | top-level | 子ノード必須 |
|
|
255
|
-
|---|---|---|
|
|
256
|
-
| yda | `accountId` / `campaigns[]` | `name` / `goal` / `status` / `startDate` / `budget≥1` / `biddingStrategy` / `cpc≥1` / `adGroups[]` |
|
|
257
|
-
| meta | `accountId` (`act_` 付) / `campaigns[]` | `objective` / `status` / `buyingType` / `adSets[]` (`optimizationGoal`,`billingEvent`,`bidStrategy`,`dailyBudget≥1`,`startTime`) |
|
|
258
|
-
| google | `customerId` / `campaigns[]` | `advertisingChannelType` / `status` / `budgetAmountYen≥1` / `adGroups[]` (`cpcBidYen≥1`, `ads[]`) |
|
|
259
|
-
| smartnews | `accountId` / `campaigns[]` | `objective` / `status` / `startDateTime` / `adGroups[]` (`ads[].adHeadline`, `adDescription`, `adLandingPageUrl`, `mediaFileId`) |
|
|
260
|
-
| bytedance | `advertiserId` / `campaigns[]` | `objectiveType` / `adGroups[]` (`optimizationGoal`, `billingEvent`, `budgetMode`, `budget≥20`, `landingPageUrl`, `locationIds`, `scheduleType`, `placementType`, `ads[]`) |
|
|
261
|
-
|
|
262
|
-
### 制約チェックリスト (共通・媒体別)
|
|
263
|
-
|
|
264
|
-
エージェントは JSON 生成時に以下を **必ず** 確認する:
|
|
265
|
-
|
|
266
|
-
- **status は開始時点で `PAUSED` (bytedance は `DISABLE`)** — 動作確認できてから ad-dashboard UI で ACTIVE に切り替える運用
|
|
267
|
-
- **予算 0 円は不可** — YDA/Meta/Google/SmartNews は 1 以上、ByteDance は 20 以上
|
|
268
|
-
- **YDA 動画広告** — `videoPath` 必須、`thumbnailPath` を省略するとサムネ自動生成なし (Yahoo は自動生成しない)
|
|
269
|
-
- **Google Ads** — `RESPONSIVE_SEARCH_AD` は `headlines` 3 本以上・`descriptions` 2 本以上
|
|
270
|
-
- **SmartNews** — `mediaFileId` は事前に SmartNews 側にアップロード済みの画像/動画 ID が必要 (CLI からのアップロード機能なし)
|
|
271
|
-
- **ByteDance** — `budget` は 20 以上、状態は `PAUSED` ではなく `DISABLE`
|
|
272
|
-
- **dry-run 応答の見方** — `{ dry_run: true, would_create: ..., warnings: [] }` が成功。`400` は `error` フィールドを見る。生 JSON が欲しいときは `--verbose`
|
|
273
|
-
|
|
274
|
-
### ログイン未完時の対応 (最重要)
|
|
275
|
-
|
|
276
|
-
**AI エージェントは `webgram auth login` を代行実行しない**。Google SSO / device flow のユーザーブラウザ操作は本人が行う (認証 URL とコードは CLI が出力するのでそれをユーザーに提示するだけ)。
|
|
277
|
-
|
|
278
|
-
`webgram auth whoami` が `not_logged_in` を返したら、エージェントは以下のテキストをユーザーに提示して**停止**する:
|
|
279
|
-
|
|
280
|
-
> ログインが必要です。ご自身のターミナルで以下を実行してください:
|
|
281
|
-
> ```bash
|
|
282
|
-
> webgram auth login
|
|
283
|
-
> ```
|
|
284
|
-
> ブラウザで Google (@webgram.jp) アカウントを選択してください。完了後「ログインしました」とお伝えください。
|
|
285
|
-
>
|
|
286
|
-
> (非対話環境で自動で device flow になった場合は、CLI が出力する URL と user_code をブラウザで開いて許可)
|
|
287
|
-
|
|
288
|
-
ユーザーから完了報告を受けたら `webgram auth whoami` で確認してから本題を続行する。
|
|
289
|
-
|
|
290
|
-
## 接続先の切替 (ローカル開発時のみ)
|
|
291
|
-
|
|
292
|
-
通常は指定不要 (デフォルトで本番エンドポイントに接続)。ローカル開発時のみ環境変数で切り替える:
|
|
293
|
-
|
|
294
|
-
```bash
|
|
295
|
-
export WEBGRAM_ENDPOINT=http://localhost:3001
|
|
296
|
-
webgram auth login
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
ログイン時の endpoint は credentials.json に保存され、以降の `whoami` / `logout` / `list` / `submit` は同じ endpoint に向く。
|
|
300
|
-
|
|
301
|
-
## コマンドリファレンス
|
|
302
|
-
|
|
303
|
-
### `webgram auth login [--device] [--password] [--email <mail>] [--endpoint <url>]`
|
|
304
|
-
|
|
305
|
-
- 既定は Google SSO (loopback OAuth)。非対話環境では自動で device flow に切り替わる
|
|
306
|
-
- `--device` — TTY でも device flow を強制
|
|
307
|
-
- `--password` — deprecated な ROPC フォールバック。パスワードは prompt or stdin パイプで渡す (argv 直渡しは shell history に残るので避ける)
|
|
308
|
-
|
|
309
|
-
### `webgram auth whoami`
|
|
310
|
-
|
|
311
|
-
現在の `access_token` に紐づくユーザー情報を `/api/auth/me` から取得。未ログインで exit 1。
|
|
312
|
-
|
|
313
|
-
### `webgram auth logout`
|
|
314
|
-
|
|
315
|
-
サーバー側で `refresh_token` を revoke してから credentials.json を削除。idempotent。
|
|
316
|
-
|
|
317
|
-
### `webgram list --platform <p> --resource <r> [--account-id <id> --campaign-id <id>]`
|
|
318
|
-
|
|
319
|
-
- `--platform`: `yda` / `meta` / `google` / `smartnews` / `bytedance`
|
|
320
|
-
- `--resource`: `accounts` / `campaigns` / `resources` (媒体により対応差あり)
|
|
321
|
-
|
|
322
|
-
### `webgram submit --platform <p> --json-file <path> [--no-dry-run --yes] [--verbose]`
|
|
323
|
-
|
|
324
|
-
- 既定は dry-run。実入稿は `--no-dry-run --yes` の 2 フラグ必須
|
|
325
|
-
- 動画広告付きの YDA/Meta は本実行時のみ multipart upload (timeout 180s)
|
|
326
|
-
- `--verbose` でサーバー応答の raw JSON を表示
|
|
327
|
-
|
|
328
|
-
### `webgram freee login/templates/issue`
|
|
329
|
-
|
|
330
|
-
freee 請求書発行用サブコマンド。詳細は `skills/invoice-issue-freee/SKILL.md` 参照。allowlist で利用者制限あり。
|
|
331
|
-
|
|
332
|
-
### `webgram --help` / `webgram <subcommand> --help`
|
|
333
|
-
|
|
334
|
-
## 認証フローと保存先
|
|
335
|
-
|
|
336
|
-
```
|
|
337
|
-
webgram auth login
|
|
338
|
-
↓ (Google SSO: loopback OAuth or device flow)
|
|
339
|
-
↓ サーバー経由で認可コード → access_token 交換 (client_secret はサーバー側で保持)
|
|
340
|
-
↓ 200 { access_token, refresh_token, expires_in: 3600 }
|
|
341
|
-
↓
|
|
342
|
-
~/.config/webgram/credentials.json (chmod 0600)
|
|
343
|
-
{
|
|
344
|
-
"endpoint": "<本番エンドポイント>",
|
|
345
|
-
"accessToken": "eyJ...", # JWT (1h)
|
|
346
|
-
"refreshToken": "Xy9...", # 256bit base64url (90d)
|
|
347
|
-
"expiresAt": "2026-06-29T05:00:00.000Z"
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
API 呼び出し
|
|
351
|
-
↓ Authorization: Bearer <access_token>
|
|
352
|
-
├─ 200 → 結果
|
|
353
|
-
└─ 401 → 自動 refresh + retry 1 回 → まだ失敗すればエラー
|
|
21
|
+
webgram auth login # ブラウザで認証
|
|
22
|
+
webgram auth whoami # 状態確認
|
|
23
|
+
webgram auth logout
|
|
354
24
|
```
|
|
355
25
|
|
|
356
|
-
|
|
357
|
-
|---|---|
|
|
358
|
-
| パスワード保存 | しない (Google SSO ではそもそも扱わない) |
|
|
359
|
-
| credentials.json | `chmod 0600` (本人のみ読み書き) |
|
|
360
|
-
| `access_token` | 1 時間 (JWT exp claim) |
|
|
361
|
-
| `refresh_token` | 90 日 |
|
|
362
|
-
| Rate limit | 同一 IP から 15min / 5 回失敗で 429 (`--password` フォールバック時のみ) |
|
|
363
|
-
| 不正再利用検知 | 同じ `refresh_token` を 2 回使うと全 CLI トークン失効 |
|
|
364
|
-
| 通信 | HTTPS (本番) / HTTP (ローカル) |
|
|
365
|
-
|
|
366
|
-
## トラブルシューティング
|
|
367
|
-
|
|
368
|
-
### `webgram: command not found`
|
|
369
|
-
|
|
370
|
-
グローバルインストールしていない場合は `npx -y addashboard-cli@latest <cmd>` で実行するか、以下でグローバル導入:
|
|
26
|
+
## 主なコマンド
|
|
371
27
|
|
|
372
28
|
```bash
|
|
373
|
-
|
|
374
|
-
|
|
29
|
+
webgram list --platform <p> --resource <accounts|campaigns|resources> [--account-id <id>]
|
|
30
|
+
webgram submit --platform <p> --json-file <path> # dry-run 既定
|
|
31
|
+
webgram submit --platform <p> --json-file <path> --no-dry-run --yes # 実入稿
|
|
32
|
+
webgram submit-plan --plan-file <入稿計画.json> # 入稿計画の一括検証 (dry-run 既定)
|
|
33
|
+
webgram submit-plan --plan-file <入稿計画.json> --no-dry-run --yes # 1キャンペーンずつ実入稿 (再開可能)
|
|
34
|
+
webgram freee <login|templates|issue> # freee 請求書発行 (allowlist 制)
|
|
35
|
+
webgram review --team <伊藤T|松井T> [--week <YYYY-MM-DD>] # チーム週次レビュー取得 (省略時は先週)
|
|
36
|
+
webgram pl summary [--month YYYY-MM] # 予実サマリ(CV/コスト/売上/粗利/日次推移/案件別内訳/着地予測/目標、省略時は当月)
|
|
37
|
+
webgram pl projects [--month YYYY-MM] [--status <s>] [--platform <p>] # 案件別の予実明細
|
|
375
38
|
```
|
|
376
39
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
Google SSO 時は認可コードが期限切れ / 無効。再度 `webgram auth login` を実行。`--password` フォールバック時はメール/パスワードが違うので Web UI で確認。
|
|
380
|
-
|
|
381
|
-
### `✗ Login failed: network_error`
|
|
382
|
-
|
|
383
|
-
エンドポイントに繋がっていない。ネットワークを確認、ローカル開発時は backend の起動を確認。
|
|
384
|
-
|
|
385
|
-
### `✗ not_logged_in`
|
|
40
|
+
`<p>` = 対応媒体 (`yda` / `meta` / `google` / `smartnews` / `bytedance`)。`submit-plan` は現状 `yda` のみ。
|
|
41
|
+
`pl summary` / `pl projects` は JSON をそのまま出力する(要約は呼び出し側の Claude Code が行う)。
|
|
386
42
|
|
|
387
|
-
`
|
|
43
|
+
`review` はチーム × 週で全案件の週次レビュー(課題・今週のアクションプラン)を 1 回で取得する (JSON 出力)。`--week` 省略時は先週の月曜 (JST) を自動採用。要約は Claude Code / Codex (LLM) 側で行う。
|
|
388
44
|
|
|
389
|
-
|
|
45
|
+
入稿ボディ JSON の雛形と必須フィールドは [`fixtures/README.md`](./fixtures/README.md)。
|
|
46
|
+
入稿計画 JSON は同梱の YDA 入稿プランナー ([`skills/ad-ops/yda-planner.html`](./skills/ad-ops/yda-planner.html)) が書き出す。
|
|
390
47
|
|
|
391
|
-
|
|
48
|
+
## Skill として使う
|
|
392
49
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
`webgram list --platform <媒体> --resource accounts` は `ApiConnection.selectedAccounts` に登録済みのアカウントのみ返す。全件必要なら Web UI (データシンク → 対象媒体) から `selectedAccounts` を追加する。
|
|
396
|
-
|
|
397
|
-
### dry-run で意味不明なエラー ([object Object] など)
|
|
398
|
-
|
|
399
|
-
CLI 側 (`src/commands/submission.ts`) で `data.error ?? err.message` に整形済みなので、通常は raw の `[object Object]` は出ない。それでも出るときは `--verbose` を付けて再実行し、サーバー応答の raw JSON を確認。
|
|
50
|
+
Claude Code / Codex CLI 用の `ad-ops` skill (広告運用スキル・YDA入稿プランナー同梱) と `invoice-issue-freee` skill を同梱。配置手順は [`skills/ad-ops/README.md`](./skills/ad-ops/README.md)。
|
|
400
51
|
|
|
401
52
|
## 開発
|
|
402
53
|
|
|
403
|
-
### ローカルインストール (ソース clone 派)
|
|
404
|
-
|
|
405
54
|
```bash
|
|
406
|
-
git clone git@github.com:WEBGRAM-WG/ad-dashboard.git
|
|
407
|
-
cd ad-dashboard/cli
|
|
408
55
|
npm install
|
|
409
56
|
npm run build
|
|
410
|
-
npm
|
|
57
|
+
npm test
|
|
411
58
|
```
|
|
412
|
-
|
|
413
|
-
### テスト実行
|
|
414
|
-
|
|
415
|
-
```bash
|
|
416
|
-
npm test # vitest + nock、一時 dir で credentialStore/apiClient/コマンドをユニットテスト
|
|
417
|
-
npm run test:watch
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
### ローカル backend に対する動作確認
|
|
421
|
-
|
|
422
|
-
```bash
|
|
423
|
-
# 別ターミナルで backend 起動
|
|
424
|
-
cd ../backend && npm run dev # :3001
|
|
425
|
-
|
|
426
|
-
# CLI で叩く
|
|
427
|
-
export WEBGRAM_ENDPOINT=http://localhost:3001
|
|
428
|
-
webgram auth login
|
|
429
|
-
webgram auth whoami
|
|
430
|
-
webgram auth logout
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
### ディレクトリ構成
|
|
434
|
-
|
|
435
|
-
```
|
|
436
|
-
cli/
|
|
437
|
-
├── src/
|
|
438
|
-
│ ├── index.ts # commander エントリ + prompt/promptHidden
|
|
439
|
-
│ ├── commands/
|
|
440
|
-
│ │ ├── auth.ts # runLogin / runWhoami / runLogout
|
|
441
|
-
│ │ ├── authGoogle.ts # Google SSO (loopback OAuth)
|
|
442
|
-
│ │ ├── authDevice.ts # Google device flow
|
|
443
|
-
│ │ ├── ads.ts # list (accounts/campaigns/resources)
|
|
444
|
-
│ │ ├── submission.ts # submit (dry-run/実入稿、動画 upload)
|
|
445
|
-
│ │ └── freee.ts # freee 請求書発行
|
|
446
|
-
│ └── lib/
|
|
447
|
-
│ ├── credentialStore.ts # ~/.config/webgram/credentials.json (chmod 0600)
|
|
448
|
-
│ └── apiClient.ts # axios factory (Bearer 付与 + 401 auto-refresh)
|
|
449
|
-
├── fixtures/ # 入稿ボディ JSON 雛形 (媒体別)
|
|
450
|
-
├── skills/ # skills/{ad-ops, invoice-issue-freee}
|
|
451
|
-
├── test/unit/ # vitest + nock
|
|
452
|
-
├── package.json # "bin": { "webgram": "./dist/index.js" }
|
|
453
|
-
└── tsconfig.json
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
## 参照
|
|
457
|
-
|
|
458
|
-
- [`fixtures/README.md`](./fixtures/README.md) — 全 5 媒体の入稿 JSON 雛形と必須フィールド一覧
|
|
459
|
-
- [`skills/ad-ops/SKILL.md`](./skills/ad-ops/SKILL.md) — Claude Code / Codex CLI から自然言語で実行するときのマッピング (広告運用スキル)
|
|
460
|
-
- [`skills/ad-ops/README.md`](./skills/ad-ops/README.md) — Skill 配置手順と発火方法 (Claude Code + Codex CLI 両対応)
|
|
461
|
-
- [`skills/invoice-issue-freee/SKILL.md`](./skills/invoice-issue-freee/SKILL.md) — freee 請求書発行 E2E マニュアル (allowlist 制)
|
|
462
|
-
- [../CLAUDE.md](../CLAUDE.md) — ad-dashboard 全体の知識ベース (媒体別認証・DB スキーマ・デプロイ手順)
|
|
463
|
-
|
|
464
|
-
## ロードマップ
|
|
465
|
-
|
|
466
|
-
- [x] `auth login` / `whoami` / `logout` + 401 自動 refresh
|
|
467
|
-
- [x] Google SSO (loopback OAuth / 非対話環境は device flow)
|
|
468
|
-
- [x] `list` (accounts/campaigns/resources) 全 5 媒体
|
|
469
|
-
- [x] `submit` (dry-run + 実入稿) 全 5 媒体
|
|
470
|
-
- [x] `freee login/templates/issue` (allowlist 制)
|
|
471
|
-
- [x] npm public registry 配布 (`addashboard-cli`)
|
|
472
|
-
- [ ] `webgram raw <METHOD> <PATH>` (任意の REST を叩く脱出ハッチ)
|
|
473
|
-
- [ ] `webgram accounts --all` (selectedAccounts に載っていないアカウントもページングで全件取得)
|
|
474
|
-
|
|
475
|
-
---
|
|
476
|
-
|
|
477
|
-
## ライセンス
|
|
478
|
-
|
|
479
|
-
社内限定。
|
package/dist/commands/ads.js
CHANGED
|
@@ -5,7 +5,7 @@ exports.resolvePath = resolvePath;
|
|
|
5
5
|
exports.runList = runList;
|
|
6
6
|
const apiClient_1 = require("../lib/apiClient");
|
|
7
7
|
exports.ALLOWED_PLATFORMS = ['meta', 'yda', 'google', 'smartnews', 'bytedance'];
|
|
8
|
-
exports.ALLOWED_RESOURCES = ['accounts', 'campaigns', 'resources'];
|
|
8
|
+
exports.ALLOWED_RESOURCES = ['accounts', 'campaigns', 'resources', 'media'];
|
|
9
9
|
/**
|
|
10
10
|
* v5 §5.2: platform × resource → backend エンドポイント解決テーブル。
|
|
11
11
|
*
|
|
@@ -16,6 +16,9 @@ exports.ALLOWED_RESOURCES = ['accounts', 'campaigns', 'resources'];
|
|
|
16
16
|
* SmartNews は creative リソースが ad に埋込まれる仕様のため、resources は未対応。
|
|
17
17
|
* bytedance は T-05 で accounts / campaigns / resources GET を追加 (accounts は
|
|
18
18
|
* ApiConnection.selectedAccounts 由来、campaigns / resources は TikTok Marketing API v1.3 実叩き)。
|
|
19
|
+
*
|
|
20
|
+
* media は W6 (新規アカウントインポート) 用の登録画像一覧リソース。yda のみ対応
|
|
21
|
+
* (/yda/media)。他媒体は未対応 (画像一覧 API 未実装)。
|
|
19
22
|
*/
|
|
20
23
|
function resolvePath(input) {
|
|
21
24
|
const { platform, resource, accountId, campaignId } = input;
|
|
@@ -25,6 +28,10 @@ function resolvePath(input) {
|
|
|
25
28
|
if (!exports.ALLOWED_RESOURCES.includes(resource)) {
|
|
26
29
|
throw new Error(`unknown resource: ${resource} (allowed: ${exports.ALLOWED_RESOURCES.join(', ')})`);
|
|
27
30
|
}
|
|
31
|
+
// media (登録画像一覧) は yda のみ対応。他媒体は画像一覧 API 未実装のため未対応。
|
|
32
|
+
if (resource === 'media' && platform !== 'yda') {
|
|
33
|
+
throw new Error(`${platform} + media は未対応です (画像一覧は yda のみ対応)`);
|
|
34
|
+
}
|
|
28
35
|
if (platform === 'meta') {
|
|
29
36
|
if (resource === 'accounts')
|
|
30
37
|
return { path: '/api/submission/meta/accounts', query: {} };
|
|
@@ -55,6 +62,11 @@ function resolvePath(input) {
|
|
|
55
62
|
throw new Error('--account-id が必要です (yda + resources)');
|
|
56
63
|
return { path: '/api/submission/yda/resources', query: { accountId } };
|
|
57
64
|
}
|
|
65
|
+
if (resource === 'media') {
|
|
66
|
+
if (!accountId)
|
|
67
|
+
throw new Error('--account-id が必要です (yda + media)');
|
|
68
|
+
return { path: '/api/submission/yda/media', query: { accountId } };
|
|
69
|
+
}
|
|
58
70
|
}
|
|
59
71
|
if (platform === 'google') {
|
|
60
72
|
if (resource === 'accounts')
|
package/dist/commands/ads.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ads.js","sourceRoot":"","sources":["../../src/commands/ads.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"ads.js","sourceRoot":"","sources":["../../src/commands/ads.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runPlSummary = runPlSummary;
|
|
4
|
+
exports.runPlProjects = runPlProjects;
|
|
5
|
+
const apiClient_1 = require("../lib/apiClient");
|
|
6
|
+
/**
|
|
7
|
+
* axios エラーからユーザー向けエラーメッセージを抽出する。
|
|
8
|
+
* ads.ts の runList と同一方針: 401 は unauthorized、それ以外は
|
|
9
|
+
* response.data.error → Error.message → network_error の順にフォールバック。
|
|
10
|
+
*/
|
|
11
|
+
function extractError(err) {
|
|
12
|
+
const status = err?.response?.status;
|
|
13
|
+
if (status === 401)
|
|
14
|
+
return 'unauthorized';
|
|
15
|
+
return (err?.response?.data?.error ??
|
|
16
|
+
err?.message ??
|
|
17
|
+
'network_error');
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 当月または指定月の予実サマリ(CV/コスト/売上/粗利/日次推移/案件別内訳/着地予測/目標)を取得する。
|
|
21
|
+
* month 省略時はサーバー側で当月扱い(params を空にして GET する)。
|
|
22
|
+
*/
|
|
23
|
+
async function runPlSummary(input) {
|
|
24
|
+
let client;
|
|
25
|
+
try {
|
|
26
|
+
client = (input.clientFactory ?? apiClient_1.buildAuthedApiClient)(input.store);
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
return { ok: false, error: e.message };
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const res = await client.get('/api/project-pl/summary', {
|
|
33
|
+
params: input.month ? { month: input.month } : {},
|
|
34
|
+
});
|
|
35
|
+
return { ok: true, data: res.data };
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
return { ok: false, error: extractError(err) };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 案件別の予実明細を取得する。month / status / platform は定義済みのものだけ params に載せる。
|
|
43
|
+
*/
|
|
44
|
+
async function runPlProjects(input) {
|
|
45
|
+
let client;
|
|
46
|
+
try {
|
|
47
|
+
client = (input.clientFactory ?? apiClient_1.buildAuthedApiClient)(input.store);
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
return { ok: false, error: e.message };
|
|
51
|
+
}
|
|
52
|
+
const params = {};
|
|
53
|
+
if (input.month)
|
|
54
|
+
params.month = input.month;
|
|
55
|
+
if (input.status)
|
|
56
|
+
params.status = input.status;
|
|
57
|
+
if (input.platform)
|
|
58
|
+
params.platform = input.platform;
|
|
59
|
+
try {
|
|
60
|
+
const res = await client.get('/api/project-pl/projects', { params });
|
|
61
|
+
return { ok: true, data: res.data };
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
return { ok: false, error: extractError(err) };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=pl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pl.js","sourceRoot":"","sources":["../../src/commands/pl.ts"],"names":[],"mappings":";;AAoCA,oCAgBC;AAcD,sCAmBC;AApFD,gDAAwD;AASxD;;;;GAIG;AACH,SAAS,YAAY,CAAC,GAAY;IAChC,MAAM,MAAM,GAAI,GAA0C,EAAE,QAAQ,EAAE,MAAM,CAAC;IAC7E,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,cAAc,CAAC;IAC1C,OAAO,CACJ,GAAoD,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK;QAC3E,GAAa,EAAE,OAAO;QACvB,eAAe,CAChB,CAAC;AACJ,CAAC;AASD;;;GAGG;AACI,KAAK,UAAU,YAAY,CAAC,KAAqB;IACtD,IAAI,MAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,KAAK,CAAC,aAAa,IAAI,gCAAoB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC;IACpD,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,yBAAyB,EAAE;YACtD,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE;SAClD,CAAC,CAAC;QACH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;IACjD,CAAC;AACH,CAAC;AAWD;;GAEG;AACI,KAAK,UAAU,aAAa,CAAC,KAAsB;IACxD,IAAI,MAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,KAAK,CAAC,aAAa,IAAI,gCAAoB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC;IACpD,CAAC;IAED,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,IAAI,KAAK,CAAC,KAAK;QAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC5C,IAAI,KAAK,CAAC,MAAM;QAAE,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC/C,IAAI,KAAK,CAAC,QAAQ;QAAE,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAErD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACrE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;IACjD,CAAC;AACH,CAAC"}
|