addashboard-cli 0.2.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 +48 -0
- package/dist/commands/ads.js +139 -0
- package/dist/commands/ads.js.map +1 -0
- package/dist/commands/auth.js +75 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/authDevice.js +110 -0
- package/dist/commands/authDevice.js.map +1 -0
- package/dist/commands/authGoogle.js +196 -0
- package/dist/commands/authGoogle.js.map +1 -0
- package/dist/commands/freee.js +249 -0
- package/dist/commands/freee.js.map +1 -0
- package/dist/commands/submission.js +299 -0
- package/dist/commands/submission.js.map +1 -0
- package/dist/index.js +290 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/apiClient.js +86 -0
- package/dist/lib/apiClient.js.map +1 -0
- package/dist/lib/credentialStore.js +76 -0
- package/dist/lib/credentialStore.js.map +1 -0
- package/package.json +54 -0
- package/skills/ad-ops/README.md +139 -0
- package/skills/ad-ops/SKILL.md +146 -0
- package/skills/ad-ops/config.json +5 -0
- package/skills/invoice-issue-freee/README.md +109 -0
- package/skills/invoice-issue-freee/SKILL.md +190 -0
- package/skills/invoice-issue-freee/config.json +31 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# ad-ops skill (広告運用スキル / Claude Code + Codex CLI 両対応)
|
|
2
|
+
|
|
3
|
+
ad-dashboard (`https://macchiato.site`) の webgram CLI を Claude Code / Codex CLI から自然言語で操作するためのスキル。「広告運用」「YDA 入稿」等のキーワードで発火し、裏で `webgram` コマンドを `npx` 経由で呼び出す。インストール作業はゼロ (Node.js 18+ が入っていれば OK)。
|
|
4
|
+
|
|
5
|
+
## 何ができる?
|
|
6
|
+
|
|
7
|
+
エージェント (Claude Code / Codex) のチャットに次のように打つだけで動く:
|
|
8
|
+
|
|
9
|
+
- 「広告運用したい」「YDA に PAUSED で入稿して」「Meta のアカウント一覧見せて」
|
|
10
|
+
- 「ad-dashboard のログイン状態は?」「webgram でログアウトして」
|
|
11
|
+
- 「SmartNews に dry-run で入稿して」「TikTok のキャンペーン一覧」
|
|
12
|
+
|
|
13
|
+
裏で以下を実行:
|
|
14
|
+
|
|
15
|
+
- 認証状態確認: `webgram auth whoami`
|
|
16
|
+
- アカウント/キャンペーン参照: `webgram list --platform <媒体> --resource <r>`
|
|
17
|
+
- 入稿: `webgram submit --platform <媒体> --json-file <path>` (dry-run 既定、実入稿は `--no-dry-run --yes` 必須)
|
|
18
|
+
|
|
19
|
+
対応媒体: YDA / Meta / Google / SmartNews / ByteDance の 5 媒体。
|
|
20
|
+
|
|
21
|
+
## 利用者の初回セットアップ
|
|
22
|
+
|
|
23
|
+
### 1. Node.js が入っているか確認
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
node --version
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`v18.x` 以上が出れば OK。無ければ [nodejs.org](https://nodejs.org) から **LTS 版** をインストール。
|
|
30
|
+
|
|
31
|
+
### 2. エージェント別の Skill 配置
|
|
32
|
+
|
|
33
|
+
Skill 本体 (`SKILL.md` / `config.json` / `README.md`) は npm パッケージ `addashboard-cli` に同梱されている。
|
|
34
|
+
|
|
35
|
+
#### Claude Code の場合
|
|
36
|
+
|
|
37
|
+
Claude Code のチャットに以下を貼り付けて実行を依頼:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
addashboard-cli の ad-ops skill を ~/.claude/skills/ に配置して
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Claude が裏で `npm pack addashboard-cli` → 展開 → `cp` を実行する。手動で入れる場合:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
mkdir -p ~/.claude/skills/ad-ops /tmp/ad-ops-extract
|
|
47
|
+
cd /tmp/ad-ops-extract && npm pack addashboard-cli@latest
|
|
48
|
+
tar xzf addashboard-cli-*.tgz --strip-components=1
|
|
49
|
+
cp -r skills/ad-ops/. ~/.claude/skills/ad-ops/
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
完了すると `~/.claude/skills/ad-ops/` に `SKILL.md` / `config.json` / `README.md` が配置される。Claude Code を一度終了して開き直す (通常は不要だが認識しない時は再起動)。
|
|
53
|
+
|
|
54
|
+
#### Codex CLI の場合
|
|
55
|
+
|
|
56
|
+
Codex CLI には Claude Code 相当の skills 自動発火機能は無いので、以下いずれかで SKILL.md を context に読み込ませる。
|
|
57
|
+
|
|
58
|
+
**方式 A: プロジェクトルートの `AGENTS.md` に参照を書く (推奨)**
|
|
59
|
+
|
|
60
|
+
作業ディレクトリの `AGENTS.md` に以下を追記:
|
|
61
|
+
|
|
62
|
+
```markdown
|
|
63
|
+
## 広告運用 (ad-ops skill)
|
|
64
|
+
|
|
65
|
+
ad-dashboard の広告操作は `~/.codex/skills/ad-ops/SKILL.md` に従って `webgram` CLI (`npx -y addashboard-cli@latest`) 経由で実行する。設定は `~/.codex/skills/ad-ops/config.json` を参照。
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Skill 本体を配置:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
mkdir -p ~/.codex/skills/ad-ops /tmp/ad-ops-extract
|
|
72
|
+
cd /tmp/ad-ops-extract && npm pack addashboard-cli@latest
|
|
73
|
+
tar xzf addashboard-cli-*.tgz --strip-components=1
|
|
74
|
+
cp -r skills/ad-ops/. ~/.codex/skills/ad-ops/
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**方式 B: 都度 `--instructions` で明示読み込み**
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
codex --instructions ~/.codex/skills/ad-ops/SKILL.md "YDA に PAUSED で入稿の dry-run 走らせて"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**方式 C: `~/.codex/config.toml` の `instructions` に恒久追加** (Codex CLI のバージョンによる。詳細は Codex CLI docs 参照)
|
|
84
|
+
|
|
85
|
+
### 3. 動作確認
|
|
86
|
+
|
|
87
|
+
エージェントに以下のように投げると発火するはず:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
広告運用スキル使える?
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Claude Code なら「ad-ops skill が使えます。ad-dashboard のログイン状態を確認しましょうか?」と返り、Codex なら AGENTS.md 経由で SKILL.md の内容に沿って動く。
|
|
94
|
+
|
|
95
|
+
## 発火方法 (使い方)
|
|
96
|
+
|
|
97
|
+
エージェントに自然言語で頼むだけ。以下のキーワードのいずれかで発火する:
|
|
98
|
+
|
|
99
|
+
- **参照系**: 「YDA のアカウント見せて」「Meta のキャンペーン一覧」「広告アカウント一覧」
|
|
100
|
+
- **入稿系**: 「YDA に入稿して」「PAUSED で dry-run」「Meta に入稿の dry-run」
|
|
101
|
+
- **認証系**: 「ad-dashboard のログイン状態は?」「webgram でログアウトして」
|
|
102
|
+
- **直接指定**: 「/ad-ops」「ad-ops skill 使って」「広告運用スキルで」
|
|
103
|
+
|
|
104
|
+
### 典型フロー (YDA 入稿の例)
|
|
105
|
+
|
|
106
|
+
1. ユーザー: 「YDA のアカウント一覧見せて」
|
|
107
|
+
2. エージェント: `webgram list --platform yda --resource accounts` を実行 → 一覧を要約して提示
|
|
108
|
+
3. ユーザー: 「桑の葉茶カテキンに PAUSED で dry-run」
|
|
109
|
+
4. エージェント: fixtures/yda_poc.json を雛形に JSON を組み立て → dry-run 実行 → 結果を要約
|
|
110
|
+
5. ユーザー: 「OK、実入稿して」
|
|
111
|
+
6. エージェント: `--no-dry-run --yes` を付けて再実行 → 入稿完了
|
|
112
|
+
|
|
113
|
+
**ログインが必要な場合はエージェントが代行せず、ユーザーにターミナル実行を依頼する** (パスワードをエージェントに渡さない運用)。
|
|
114
|
+
|
|
115
|
+
## トラブルシュート
|
|
116
|
+
|
|
117
|
+
| 症状 | 対処 |
|
|
118
|
+
|---|---|
|
|
119
|
+
| Claude Code が「ad-ops スキル」を認識しない | Claude Code を再起動。`ls ~/.claude/skills/ad-ops/SKILL.md` でファイルがあるか確認 |
|
|
120
|
+
| Codex が SKILL.md の指示に従わない | `AGENTS.md` に SKILL.md への参照が書かれているか確認 / `--instructions` で明示読み込み |
|
|
121
|
+
| `command not found: npx` | Node.js が入っていない。[nodejs.org](https://nodejs.org) から LTS 版をインストール |
|
|
122
|
+
| ログインに失敗する | メール/パスワードを Web UI (`https://macchiato.site`) で確認 |
|
|
123
|
+
| エンドポイントを変えたい | `<skill dir>/config.json` の `endpoint` を編集 (`~/.claude/skills/ad-ops/config.json` or `~/.codex/skills/ad-ops/config.json`) |
|
|
124
|
+
| 入稿 JSON の必須フィールドが分からない | tarball 同梱の `fixtures/README.md` を参照 (全 5 媒体の必須フィールドを集約) |
|
|
125
|
+
|
|
126
|
+
## バージョン更新
|
|
127
|
+
|
|
128
|
+
`config.json` の `npmPackage` が `addashboard-cli@latest` になっていれば、`npx -y` が常に最新版を取ってくる (初回のみ DL、以降キャッシュ)。特定バージョンにピン止めしたい場合は `addashboard-cli@0.X.Y` に書き換える。Skill 本体 (`SKILL.md` 等) を新しくしたい場合は、方式 A の手順を再実行するだけで上書きされる。
|
|
129
|
+
|
|
130
|
+
## 参考ドキュメント
|
|
131
|
+
|
|
132
|
+
- CLI 本体の README: [cli/README.md](../../README.md) (人間向けの完走マニュアル + AI エージェント向け決定表)
|
|
133
|
+
- 入稿ボディ雛形: [cli/fixtures/README.md](../../fixtures/README.md)
|
|
134
|
+
- freee 請求書発行スキル: [../invoice-issue-freee/SKILL.md](../invoice-issue-freee/SKILL.md)
|
|
135
|
+
|
|
136
|
+
## 配布元
|
|
137
|
+
|
|
138
|
+
GitHub Releases: https://github.com/WEBGRAM-WG/ad-dashboard/releases
|
|
139
|
+
(社内 Slack `#alimie-webgram` にも URL を貼っている)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ad-ops
|
|
3
|
+
description: ad-dashboard (https://macchiato.site) の webgram CLI 経由で広告動画を YDA に半自動入稿する (現状 YDA のみ対応、Meta / TikTok は将来対応予定)。議事録 (2026-07-14) 由来の動画入稿フロー (5 ステップ + 固定デフォルト + URL 空き番号自動割当 + 一覧 OK 確認) がメイン用途。「広告運用」「広告入稿」「動画入稿」「まとめ入稿」「ASC 入稿」「YDA 入稿」「Meta 入稿」「TikTok 入稿」「webgram」「ad-dashboard」と言われたら使用。Node.js が入っていれば追加インストール不要 (`npx` 経由)。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ad-ops skill (広告運用スキル)
|
|
7
|
+
|
|
8
|
+
Google Drive から手動 DL 済みの動画を各媒体に半自動入稿するためのスキル。**現状 YDA のみ対応**、Meta / TikTok は将来対応予定。
|
|
9
|
+
|
|
10
|
+
配置・発火方法は同ディレクトリの [README.md](./README.md) 参照。
|
|
11
|
+
|
|
12
|
+
## 動画入稿フロー (メイン用途)
|
|
13
|
+
|
|
14
|
+
macOS Finder で「option キー長押し → パス名をコピー」した動画パスを、ユーザーがドラッグ&ドロップで提示するところから始まる半自動ワークフロー。
|
|
15
|
+
|
|
16
|
+
### Step 0: ログイン状態確認 (メモ)
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx -y addashboard-cli@latest auth whoami
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
* 成功 → 1 行要約して次へ
|
|
23
|
+
|
|
24
|
+
* `not_logged_in` → 「ターミナルで `npx -y addashboard-cli@latest auth login` を実行してください」と提示して停止。エージェントは代行しない (Google SSO のブラウザ操作は本人が行う)
|
|
25
|
+
|
|
26
|
+
### Step 1: 動画ファイルパスの受け取り
|
|
27
|
+
|
|
28
|
+
* ユーザーが動画ファイルの絶対パスを **ドラッグ&ドロップ** で提示 (1 本〜複数本、本数指定なしで OK)
|
|
29
|
+
|
|
30
|
+
* パスが未指定なら AskUserQuestion で提示を促す
|
|
31
|
+
|
|
32
|
+
* パスの存在確認: `ls -l <path>` で読める形式かチェック (mp4 等)
|
|
33
|
+
|
|
34
|
+
### Step 2: 入稿モードの判定
|
|
35
|
+
|
|
36
|
+
`新規` / `既存 (ASC 等まとめ入稿)` のどちらかをユーザー指示から判定。指示が無ければ AskUserQuestion で確認する。
|
|
37
|
+
|
|
38
|
+
| モード | 構成 | 予算デフォルト |
|
|
39
|
+
| -------- | ------------------------------------------ | ------------------ |
|
|
40
|
+
| 新規 | 1 キャンペーン = 1 広告セット = 1 広告 (動画本数 = キャンペーン数) | 12,000 円/日 |
|
|
41
|
+
| 既存 (ASC) | 1 キャンペーン内に複数広告をまとめる。アルゴリズムが好調クリエイティブに配信寄せ | 5 万〜10 万円/日 (人により) |
|
|
42
|
+
|
|
43
|
+
### Step 3: パラメータ収集
|
|
44
|
+
|
|
45
|
+
**固定デフォルト値** (指定が無ければこれで進める):
|
|
46
|
+
|
|
47
|
+
* アトリビューション計測期間: **1 日** (デフォルト 7 日を毎回 1 日に変更する慣習)
|
|
48
|
+
|
|
49
|
+
* CTA ボタン: **詳細を見る**
|
|
50
|
+
|
|
51
|
+
* 入札戦略: **tCPA 8,500 円** (ターゲット CPA)
|
|
52
|
+
|
|
53
|
+
* 予算: 新規 = 12,000 円、ASC = 50,000〜100,000 円
|
|
54
|
+
|
|
55
|
+
**必ずユーザー確認 or 自動生成が必要な項目**:
|
|
56
|
+
|
|
57
|
+
* **入稿先アカウント名**: アカウント名で指定可 (アカウント ID は不要、CLI 側で名前 → ID 解決)。指定なければ AskUserQuestion で聞く
|
|
58
|
+
|
|
59
|
+
* **入稿リンク (URL 末尾番号)**: 既存アカウントの入稿履歴から使用済み番号を取得し、**未使用の空き番号を自動割当**
|
|
60
|
+
|
|
61
|
+
* 連番でなくて OK。被らないことだけ守る (例: 1〜50 が使用中なら 51 以降、または途中の 7 が未使用なら 7)
|
|
62
|
+
|
|
63
|
+
* ベース URL は案件ごとに固定 (Bit.ly 系ドメイン等)。末尾パラメータ番号のみ可変
|
|
64
|
+
|
|
65
|
+
* 案件ごとの URL 一覧はシート管理されているので、そこから引く運用も可
|
|
66
|
+
|
|
67
|
+
* **キャンペーン名**: `{空き番号}_{クリエイティブ名}_{YYYY-MM-DD}` で自動生成
|
|
68
|
+
|
|
69
|
+
* **配信戦略**: `最大配信` / `tCPA (8,500 円)` の 2 択。指定なければデフォルト tCPA
|
|
70
|
+
|
|
71
|
+
### Step 4: 一覧提示 → OK 確認 (必須)
|
|
72
|
+
|
|
73
|
+
動画本数ぶんの入稿リストを **表形式で提示** し、必ず AskUserQuestion で OK 確認を取る。**OK が取れるまで Step 5 に進まない。**
|
|
74
|
+
|
|
75
|
+
| # | 媒体 | 動画ファイル名 | キャンペーン名 | 入稿リンク | 予算 | 配信戦略 |
|
|
76
|
+
| - | --- | ------------ | ------------------------ | ------------------- | ------ | ---------- |
|
|
77
|
+
| 1 | YDA | video\_A.mp4 | 07\_video\_A\_2026-07-16 | <https://.../?p=07> | 12,000 | tCPA 8,500 |
|
|
78
|
+
| 2 | YDA | video\_B.mp4 | 08\_video\_B\_2026-07-16 | <https://.../?p=08> | 12,000 | tCPA 8,500 |
|
|
79
|
+
|
|
80
|
+
URL 番号・予算・配信戦略に不満があれば Step 3 に戻ってパラメータを差し替える。
|
|
81
|
+
|
|
82
|
+
### Step 5: 順次実行
|
|
83
|
+
|
|
84
|
+
OK 後、リスト順に CLI で入稿する:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npx -y addashboard-cli@latest submit \
|
|
88
|
+
--platform <yda|meta|tiktok> \
|
|
89
|
+
--account "<アカウント名>" \
|
|
90
|
+
--video <動画パス> \
|
|
91
|
+
--campaign-name "<キャンペーン名>" \
|
|
92
|
+
--url "<入稿リンク>" \
|
|
93
|
+
--budget 12000 \
|
|
94
|
+
--bid-strategy tcpa \
|
|
95
|
+
--tcpa 8500 \
|
|
96
|
+
--attribution-days 1 \
|
|
97
|
+
--cta detail
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
* 1 本ごとに成功/失敗を報告
|
|
101
|
+
|
|
102
|
+
* 途中失敗は握りつぶさず、残りを続行するか AskUserQuestion で確認
|
|
103
|
+
|
|
104
|
+
* 完了後、キャンペーン ID / 広告 ID の一覧を要約表示
|
|
105
|
+
|
|
106
|
+
### Step 6: 管理画面 URL を開く
|
|
107
|
+
|
|
108
|
+
入稿完了後、対象媒体の管理画面 (該当キャンペーンの詳細ページ) を **`open <URL>`** **で開く**。ユーザーが目視で入稿結果を確認できるようにする。
|
|
109
|
+
|
|
110
|
+
* YDA: `https://ads-display.yahoo.co.jp/campaign/detail?accountId=<accountId>&campaignId=<campaignId>` (キャンペーン ID は Step 5 の応答から取得)
|
|
111
|
+
|
|
112
|
+
* Meta / TikTok は将来対応時に URL 形式を追記
|
|
113
|
+
|
|
114
|
+
* 複数入稿した場合は、キャンペーン一覧ページ (`https://ads-display.yahoo.co.jp/campaign/list?accountId=<accountId>`) を 1 つ開けば十分
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
open "https://ads-display.yahoo.co.jp/campaign/detail?accountId=<accountId>&campaignId=<campaignId>"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## 媒体別の注意
|
|
121
|
+
|
|
122
|
+
**現状の動画入稿対応: YDA のみ。** Meta / TikTok を指定された場合は「現状未対応、YDA のみ」と明示してから相談する。
|
|
123
|
+
|
|
124
|
+
| 媒体 | 動画入稿対応 | 入稿リンクの粒度 | 備考 |
|
|
125
|
+
| ---------------------- | -------- | ---------------------- | ---------------------------------------------- |
|
|
126
|
+
| **YDA** | ✅ 対応済み | 広告ごと | まず YDA から対応 (社内優先順位、名倉さん依頼) |
|
|
127
|
+
| **Meta** | ⏳ 将来対応予定 | 広告ごと (まとめ入稿でも広告単位で変わる) | ASC でも広告ごとに個別リンクを設定 |
|
|
128
|
+
| **TikTok / ByteDance** | ⏳ 将来対応予定 | 広告グループ単位で 1 本 | まとめ入稿は 10 本でも 20 本でも入稿リンクは 1 つ (クリエイティブグループ単位) |
|
|
129
|
+
|
|
130
|
+
***
|
|
131
|
+
|
|
132
|
+
## 備考: その他のコマンド
|
|
133
|
+
|
|
134
|
+
動画入稿フロー以外に CLI が受け付ける主なコマンド。詳細は [cli/README.md](../../README.md) と [cli/fixtures/README.md](../../fixtures/README.md) 参照。
|
|
135
|
+
|
|
136
|
+
| 用途 | コマンド |
|
|
137
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
138
|
+
| ログイン状態確認 | `npx -y addashboard-cli@latest auth whoami` |
|
|
139
|
+
| ログアウト | `npx -y addashboard-cli@latest auth logout` |
|
|
140
|
+
| ヘルプ | `npx -y addashboard-cli@latest --help` |
|
|
141
|
+
| アカウント一覧 | `npx -y addashboard-cli@latest list --platform <yda\|meta\|google\|smartnews\|bytedance> --resource accounts` |
|
|
142
|
+
| キャンペーン一覧 | `npx -y addashboard-cli@latest list --platform <媒体> --resource campaigns --account-id <id>` |
|
|
143
|
+
| 汎用入稿 (JSON) dry-run | `npx -y addashboard-cli@latest submit --platform <媒体> --json-file <path>` |
|
|
144
|
+
| 汎用入稿 (JSON) 実入稿 | `npx -y addashboard-cli@latest submit --platform <媒体> --json-file <path> --no-dry-run --yes` |
|
|
145
|
+
|
|
146
|
+
汎用入稿 (JSON ボディ直渡し) は yda / meta / google / smartnews / bytedance の 5 媒体対応。fixtures の雛形は tarball 同梱の `fixtures/*_poc.json`、各媒体の必須フィールドは `fixtures/README.md`。
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# invoice-issue-freee skill (Claude Code 用)
|
|
2
|
+
|
|
3
|
+
WEBGRAM様の入金(クライアント売上請求)を、ad-dashboard の `webgram` CLI 経由で freee 発行 → PDF保存 → Google Drive格納・請求書管理シート記入・Gmail下書きまで自動化するスキル。
|
|
4
|
+
|
|
5
|
+
**発行権限**: サーバー側 allowlist で管理 (未登録emailは 403 forbidden)。追加は運用担当者へ依頼。
|
|
6
|
+
|
|
7
|
+
## 何ができる?
|
|
8
|
+
|
|
9
|
+
Claude Code のチャットに次のように打つだけで動きます:
|
|
10
|
+
|
|
11
|
+
- 「freee で請求書出して」
|
|
12
|
+
- 「テスト御中の請求書ドラフト作って(¥300,000/広告運用代行費)」
|
|
13
|
+
- 「請求書のログイン状態確認」
|
|
14
|
+
|
|
15
|
+
裏で Claude が:
|
|
16
|
+
1. `webgram freee issue` で請求書を発行 (freee)
|
|
17
|
+
2. `report_url` から PDF を取得 (`biz-agent-data/out/YYYYMMDD_会社名.pdf` として保存)
|
|
18
|
+
3. Google Drive の月別/入金/カテゴリ配下に PDF を格納
|
|
19
|
+
4. 請求書管理シートに1行追記 (ステータス=確認待ち)
|
|
20
|
+
5. Gmail 下書きを作成 (Drive リンクを本文埋込)
|
|
21
|
+
6. Drive / シート / Gmail 下書きの3タブを `open` で表示 → 目視確認
|
|
22
|
+
|
|
23
|
+
## 利用者の初回セットアップ
|
|
24
|
+
|
|
25
|
+
### 1. Node.js が入っているか確認
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
node --version
|
|
29
|
+
```
|
|
30
|
+
`v18.x` 以上が出ればOK。
|
|
31
|
+
|
|
32
|
+
### 2. `gws` CLI がインストール済みかつ請求書管理シート/Driveにアクセスできるアカウントで認証済み
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
gws auth status
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`user:` が該当アカウントで表示されればOK。未認証なら:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
gws auth login # ブラウザで該当アカウントを選択
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 3. Claude Code に **npm パッケージからスキルを展開してもらう**
|
|
45
|
+
|
|
46
|
+
Claude Code のチャットに次のように貼り付け:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
npm の addashboard-cli パッケージから invoice-issue-freee skill を ~/.claude/skills/ に展開して
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Claude が裏で次のコマンドを実行します:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
mkdir -p ~/.claude/skills/invoice-issue-freee
|
|
56
|
+
npm pack addashboard-cli@latest --pack-destination /tmp
|
|
57
|
+
tar xzf /tmp/addashboard-cli-*.tgz -C /tmp --strip-components=1
|
|
58
|
+
cp -r /tmp/skills/invoice-issue-freee/. ~/.claude/skills/invoice-issue-freee/
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
完了すると `~/.claude/skills/invoice-issue-freee/` に SKILL.md / config.json / README.md が配置されます。
|
|
62
|
+
|
|
63
|
+
### 4. Claude Code を再起動
|
|
64
|
+
|
|
65
|
+
新しいスキルを認識させるため、Claude Code を一度終了して開き直す。
|
|
66
|
+
|
|
67
|
+
## 使い方
|
|
68
|
+
|
|
69
|
+
Claude Code に自然言語で頼むだけ:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
> freee で テスト御中に ¥300,000 の広告運用代行費 で請求書出して
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Claude が発行内容を確認 → dry-run → 本発行の同意 → PDF保存 → Drive/Sheet/Gmail → 目視URLを開く の順で進めます。
|
|
76
|
+
|
|
77
|
+
## 設定変更
|
|
78
|
+
|
|
79
|
+
### エンドポイントを変えたい
|
|
80
|
+
|
|
81
|
+
`~/.claude/skills/invoice-issue-freee/config.json` の `endpoint`:
|
|
82
|
+
- 本番: `https://macchiato.site` (デフォルト)
|
|
83
|
+
- ローカル開発: `http://localhost:3001`
|
|
84
|
+
|
|
85
|
+
### 本番用の Drive フォルダ / シートを使いたい (テスト用IDから切替)
|
|
86
|
+
|
|
87
|
+
`config.json` の `freee.drive.parentFolderId` と `freee.sheet.spreadsheetId` を本番IDに差し替え。
|
|
88
|
+
|
|
89
|
+
デフォルトはプレースホルダ (`REPLACE_ME_DRIVE_FOLDER_ID` / `REPLACE_ME_SPREADSHEET_ID`) が入っているので、初回セットアップ時に必ず自環境の値に差し替えてください。
|
|
90
|
+
|
|
91
|
+
## トラブルシュート
|
|
92
|
+
|
|
93
|
+
| 症状 | 対処 |
|
|
94
|
+
|---|---|
|
|
95
|
+
| Claude が「invoice-issue-freee スキル」を認識しない | Claude Code を再起動。`ls ~/.claude/skills/invoice-issue-freee/SKILL.md` でファイルがあるか確認 |
|
|
96
|
+
| `403 forbidden` (freee issue時) | サーバー側 allowlist 未登録 email でログインしている。運用担当者に allowlist 追加を依頼 or 登録済み email で `auth login` |
|
|
97
|
+
| `unauthorized` (freee templates時) | freee 未認可。`webgram freee login` を実行してブラウザで許可 |
|
|
98
|
+
| `deduped: true` で新規発行にならない | 同一 body_hash がキャッシュされている。description or billingDate を微修正 |
|
|
99
|
+
| Drive/Sheet が 403/404 | gws CLI が別アカウントの token を使っている。`gws auth logout` → `gws auth login` |
|
|
100
|
+
| Gmail 下書きが空になる | RAW MIME の Python heredoc に日本語コメントを混ぜている。SKILL.md の base64url encode 手順を参照 |
|
|
101
|
+
| PDF ダウンロードで座標クリックが複製ページに遷移 | メニュー座標が動的。`read_page interactive` で「PDFダウンロード」ref を取得してからクリック |
|
|
102
|
+
|
|
103
|
+
## バージョン更新
|
|
104
|
+
|
|
105
|
+
CLI 本体 (`addashboard-cli`) は `config.json` で `@latest` 指定のため、`npx` 実行のたびに自動更新されます。スキル定義 (SKILL.md / config.json) だけを最新化したい場合は、上記「初回セットアップ」の手順3を再実行してください。
|
|
106
|
+
|
|
107
|
+
## 配布元
|
|
108
|
+
|
|
109
|
+
npm public registry: https://www.npmjs.com/package/addashboard-cli
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: invoice-issue-freee
|
|
3
|
+
description: WEBGRAM様の入金(クライアント売上請求)を ad-dashboard の webgram CLI 経由で freee 発行し、report_url からPDF保存 → Drive格納・請求書管理シート記入・メール下書きまで行う。「請求書発行」「freee請求書」「請求書作成」「売上請求」「invoice発行」と言われたら使用。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# invoice-issue-freee skill (ad-dashboard CLI 配布版)
|
|
7
|
+
|
|
8
|
+
WEBGRAM様の**入金サイクル(クライアントへの売上請求)専用**スキル。webgram CLI (`webgram freee` 系サブコマンド) をラップして、freee 発行 → PDF保存 → Drive/Sheet/Gmail後続まで一気通貫で行う。
|
|
9
|
+
|
|
10
|
+
**発行権限はサーバー側 allowlist で管理**(未登録emailは 403 forbidden)。請求書送信担当者は最終目視のみで、確認後にシートのステータスを「送信待ち」に更新して送信する。
|
|
11
|
+
|
|
12
|
+
## 発火条件
|
|
13
|
+
|
|
14
|
+
- 「請求書発行」「freee請求書」「請求書作成」
|
|
15
|
+
- 「売上請求」「クライアント請求」「invoice発行」
|
|
16
|
+
- 「請求書を出して」「請求書ドラフト」(入金・クライアント文脈)
|
|
17
|
+
|
|
18
|
+
ASP/メディアへの**出金(支払)は対象外**。
|
|
19
|
+
|
|
20
|
+
## 前提
|
|
21
|
+
|
|
22
|
+
- Node.js 18+ が入っていること (webgram CLI が `npx` 経由で動く)
|
|
23
|
+
- `gws` CLI が請求書管理シート/Driveにアクセス可能なアカウントで認証済み (`gws auth status` で確認)
|
|
24
|
+
- サーバー側 allowlist に登録された email で webgram CLI にログイン済み or ログイン可能
|
|
25
|
+
|
|
26
|
+
## 実行手順(毎回)
|
|
27
|
+
|
|
28
|
+
### 0. config.json 読込 (最初に必ず)
|
|
29
|
+
|
|
30
|
+
このスキルディレクトリの `config.json` を Read して以下を取得:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"npmPackage": "addashboard-cli@latest",
|
|
35
|
+
"endpoint": "https://macchiato.site",
|
|
36
|
+
"freee": {
|
|
37
|
+
"companyId": 0,
|
|
38
|
+
"templateId": 0,
|
|
39
|
+
"drive": { "parentFolderId": "REPLACE_ME_DRIVE_FOLDER_ID", ... },
|
|
40
|
+
"sheet": { "spreadsheetId": "REPLACE_ME_SPREADSHEET_ID", ... }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
以降 `WEBGRAM_ENDPOINT=<endpoint> npx -y addashboard-cli@latest freee <sub>` で CLI 呼び出す。
|
|
46
|
+
|
|
47
|
+
### 1. ログイン確認 → 必要なら auth login / freee login
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
WEBGRAM_ENDPOINT=<endpoint> npx -y addashboard-cli@latest auth whoami
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- `not_logged_in` の場合: AskUserQuestion で email を取得(サーバー側 allowlist に登録されているもの)、パスワードは **stdin パイプ**で渡す:
|
|
54
|
+
```bash
|
|
55
|
+
printf '%s\n' '<pw>' | WEBGRAM_ENDPOINT=<endpoint> npx -y addashboard-cli@latest auth login --email <email>
|
|
56
|
+
```
|
|
57
|
+
- freee 認可されているか確認するには `webgram freee templates` を叩く。`unauthorized` 等が返れば:
|
|
58
|
+
```bash
|
|
59
|
+
WEBGRAM_ENDPOINT=<endpoint> npx -y addashboard-cli@latest freee login
|
|
60
|
+
```
|
|
61
|
+
→ ブラウザで freee 認可(人が実施)→ `✓ freee 接続完了 (company_id=...)` を確認
|
|
62
|
+
|
|
63
|
+
### 2. AskUserQuestion で発行内容を集める
|
|
64
|
+
|
|
65
|
+
- `partnerDisplayName` (取引先の表示名、例: `テスト`)
|
|
66
|
+
- `partnerId` (freee 取引先ID、`https://settings.secure.freee.co.jp/partners/<ID>` の末尾数字)
|
|
67
|
+
- `billingDate` (請求日、YYYY-MM-DD)
|
|
68
|
+
- `担当` (発行者の名前)
|
|
69
|
+
- `期日` (振込期限、YYYY-MM-DD)
|
|
70
|
+
- `カテゴリ` (代理店ASP / 業務委託 / サービス)
|
|
71
|
+
- `lines[]`: `description` / `quantity` / `unitPrice` / `taxRate`
|
|
72
|
+
|
|
73
|
+
`templateId` は `config.json.freee.templateId` 固定。
|
|
74
|
+
|
|
75
|
+
### 3. dry-run → 本発行
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# invoice.json を組み立てて一時ファイルに保存
|
|
79
|
+
cat > /tmp/invoice.json <<'JSON'
|
|
80
|
+
{ "partnerId": ..., "partnerDisplayName": "...", "billingDate": "...", "templateId": <config.json.freee.templateId>, "lines": [...] }
|
|
81
|
+
JSON
|
|
82
|
+
|
|
83
|
+
# dry-run
|
|
84
|
+
WEBGRAM_ENDPOINT=<endpoint> npx -y addashboard-cli@latest freee issue --json-file /tmp/invoice.json
|
|
85
|
+
|
|
86
|
+
# ユーザー確認後、本発行
|
|
87
|
+
WEBGRAM_ENDPOINT=<endpoint> npx -y addashboard-cli@latest freee issue --json-file /tmp/invoice.json --no-dry-run --yes
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
- 返却: `{ "invoiceId": <id>, "reportUrl": "https://invoice.secure.freee.co.jp/reports/invoices/<id>?from_public=true" }`
|
|
91
|
+
- **dedup機能(body_hashキャッシュ)**: 同一内容の再発行は既存 invoiceId を `deduped:true` で返す。取消後に同じpayloadで再発行するには description や billingDate を微修正して body_hash を変える必要あり
|
|
92
|
+
|
|
93
|
+
### 4. PDF を保存(report_url → PDF)
|
|
94
|
+
|
|
95
|
+
freee 請求書 API に PDF DL エンドポイントは無い。`report_url` の freee 帳票ページから PDF を取得する。
|
|
96
|
+
|
|
97
|
+
**Claude in Chrome で**:
|
|
98
|
+
1. `report_url` を開く
|
|
99
|
+
2. `read_page interactive` で「その他 ▼」→「**PDFダウンロード**」のrefを取得してクリック(座標決め打ちは複製ページに遷移するリスクあり)
|
|
100
|
+
3. ダウンロードされた PDF を `biz-agent-data/out/YYYYMMDD_会社名_INV-XXXXXXXXXX.pdf` にリネーム保存
|
|
101
|
+
|
|
102
|
+
**macOSダイアログfallback**(自動化から押せない環境):
|
|
103
|
+
1. 別プロセスでwatcher起動:
|
|
104
|
+
```bash
|
|
105
|
+
(while sleep 0.5; do f=$(ls -t ~/Downloads/.com.google.Chrome.* 2>/dev/null | head -1); [ -n "$f" ] && head -c 4 "$f" | grep -q "%PDF" && cp "$f" out/正規名.pdf && break; done) &
|
|
106
|
+
```
|
|
107
|
+
2. PDFダウンロードクリック後、watcher が完成一時ファイル(`~/Downloads/.com.google.Chrome.*` 先頭 `%PDF-`)を検知して cp
|
|
108
|
+
3. 完了後 watcher プロセスを kill、`~/Downloads/.com.google.Chrome.*` を削除
|
|
109
|
+
|
|
110
|
+
### 5. gws後続 (Drive/Sheet/Gmail)
|
|
111
|
+
|
|
112
|
+
`config.json.freee.drive` / `config.json.freee.sheet` の値を使う。
|
|
113
|
+
|
|
114
|
+
**Drive PDF格納**:
|
|
115
|
+
- 格納先: `parentFolderId` 配下の `YYYY-MM/入金/{カテゴリ}/`
|
|
116
|
+
- 無ければ `gws drive files.create mimeType=application/vnd.google-apps.folder` で作成
|
|
117
|
+
- PDF upload:
|
|
118
|
+
```bash
|
|
119
|
+
gws drive files create --params '{"uploadType":"multipart","fields":"id,name,webViewLink"}' \
|
|
120
|
+
--json '{"name":"<file名>","parents":["<folderId>"],"mimeType":"application/pdf"}' \
|
|
121
|
+
--upload <PDFパス>
|
|
122
|
+
```
|
|
123
|
+
- 返却された `webViewLink` を保持
|
|
124
|
+
|
|
125
|
+
**シート append**:
|
|
126
|
+
- タブ命名: `tabPattern` の `{YY.M}` を発行月に置換 (例 `【改訂版】請求(入金)26.7`)
|
|
127
|
+
- タブが無ければ `templateTabGid` を `duplicateSheet` で複製し、既存データを `values.clear` してからスタート
|
|
128
|
+
- ヘッダー行 (`headerRow=1`) を `values.get` で読み、`config.json.freee.sheet.columns` で列位置を決定 (**ヘッダー名で列解決 = 固定順で詰めない**)
|
|
129
|
+
- 1行 append (valueInputOption=USER_ENTERED):
|
|
130
|
+
```json
|
|
131
|
+
["<会社名>", <金額>, "<webViewLink>", "<担当>", "確認待ち", "<メモ>", "<期日>"]
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Gmail下書き** (`gws gmail users.drafts.create` RAW MIME、添付非対応):
|
|
135
|
+
- 宛先: 請求書送信担当者(本番) or 発行者自身(テスト)
|
|
136
|
+
- 件名: `【<月>】<会社名> 請求書ドラフト`
|
|
137
|
+
- 本文: 挨拶 + 金額サマリ + `webViewLink` を本文埋込
|
|
138
|
+
- Python3 で base64url encode:
|
|
139
|
+
```python
|
|
140
|
+
import base64
|
|
141
|
+
subject_b64 = base64.b64encode(subject.encode('utf-8')).decode()
|
|
142
|
+
mime = f'From: <me>\nTo: <to>\nSubject: =?utf-8?B?{subject_b64}?=\nContent-Type: text/plain; charset=UTF-8\nMIME-Version: 1.0\n\n{body}'
|
|
143
|
+
raw = base64.urlsafe_b64encode(mime.encode('utf-8')).decode().rstrip('=')
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### 6. 【必須】成果物3つをブラウザで open
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
open "https://drive.google.com/drive/folders/<格納先folderId>"
|
|
150
|
+
open "https://docs.google.com/spreadsheets/d/<sheetId>/edit?gid=<tabGid>"
|
|
151
|
+
open "https://mail.google.com/mail/u/0/#drafts"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Claude in Chrome の `navigate` ではなく macOSの `open` コマンド**でデフォルトブラウザ(既に該当アカウントでログイン済み)を使う。Claude in Chrome の別プロファイルで開くとログイン状態が異なりアクセス不可になる。
|
|
155
|
+
|
|
156
|
+
### 7. 請求書送信担当者に通知 (本番運用時)
|
|
157
|
+
|
|
158
|
+
`message-send` スキル経由で送信担当者に Slack/メール通知。担当者が目視 → シートステータスを「送信待ち」→ 送信。
|
|
159
|
+
|
|
160
|
+
## 自然言語 → コマンドマッピング
|
|
161
|
+
|
|
162
|
+
| ユーザー指示 | 実行 |
|
|
163
|
+
|---|---|
|
|
164
|
+
| 「請求書出して」「請求書ドラフト」 | Step 2 で発行内容ヒアリング → Step 3 dry-run → 本発行 → Step 4-6 通し |
|
|
165
|
+
| 「請求書のログイン確認」 | Step 1 whoami + `freee templates` |
|
|
166
|
+
| 「freeeログインして」 | `webgram freee login` (ブラウザ認可) |
|
|
167
|
+
|
|
168
|
+
## ハマりどころ
|
|
169
|
+
|
|
170
|
+
- **allowlist**: `webgram freee` の発行権限はサーバー側 allowlist (email) で制限。追加は運用担当者へ依頼(バックエンド env `FREEE_ALLOWED_EMAILS` または middleware コード側)。CLIログイン自体は誰でも可
|
|
171
|
+
- **CSRF**: `/api/freee` は CLI 専用 (Bearer 認証) で CSRF skip 済。ブラウザ Cookie のみのアクセスは 401
|
|
172
|
+
- **PDF DL エンドポイント無し**: 発行は API だが PDF 実体は report_url からのみ (Step 4)
|
|
173
|
+
- **partner_id 必須**: `partner_display_name` だけでは 400。使用停止の取引先でも `partner_display_name` 指定で発行自体は通る (宛名は表示名が使われる)
|
|
174
|
+
- **partners一覧CLIなし**: 現状 partnerId は freee UIから目視取得。Issue #62 で追加提案中
|
|
175
|
+
- **dedup機能**: 同一 body_hash は再発行されず既存 invoiceId が返る。取消後の再発行は payload微修正必要
|
|
176
|
+
- **access_token 6h 失効**: refresh_token で backend が自動更新。refresh 期限切れ時のみ `webgram freee login` を再実行
|
|
177
|
+
- **本番/ローカル切替**: `WEBGRAM_ENDPOINT`(本番 `https://macchiato.site` / ローカル `http://localhost:3001`)
|
|
178
|
+
- **請求書番号**: freee が自動採番 (例 `INV-0000000002`)
|
|
179
|
+
- **CLI呼び出しは `webgram <cmd>` or `npx -y addashboard-cli@latest <cmd>`**: `node .../cli/dist/index.js <cmd>` のようなdist直実行は禁止
|
|
180
|
+
- **auth login の password**: `--password` argv は `ps` 露出リスク。**stdin パイプ**で渡す (`printf '%s\n' '<pw>' | ... auth login --email <email>`)
|
|
181
|
+
- **gws token cache不整合**: 別Googleアカウントを使ってた場合、`gws auth login` で切り替えても `files list` が旧アカウント所有ファイルを返すことがある。**`gws auth logout` → `gws auth login` の再ログインでキャッシュクリア必要**
|
|
182
|
+
|
|
183
|
+
## 関連スキル / ルール
|
|
184
|
+
|
|
185
|
+
- ad-dashboard `webgram` skill (同じ配布方式)
|
|
186
|
+
- `webgram freee` コマンド (`cli/src/commands/freee.ts`)、`~/Documents/addashboard/CLAUDE.md`
|
|
187
|
+
- `gws` (Drive/Sheets/Gmail下書きの CLI)
|
|
188
|
+
- `message-send` (請求書送信担当者への通知)
|
|
189
|
+
- WEBGRAM様版 `invoice-issue-freee` (旧Python版・原典の詳細仕様)
|
|
190
|
+
- ルール: `~/.claude/rules/credential-storage-pattern.md`, プロジェクトCLAUDE.md「認証情報の二層構造」
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"npmPackage": "addashboard-cli@latest",
|
|
3
|
+
"endpoint": "https://macchiato.site",
|
|
4
|
+
"freee": {
|
|
5
|
+
"companyId": 0,
|
|
6
|
+
"templateId": 0,
|
|
7
|
+
"drive": {
|
|
8
|
+
"parentFolderId": "REPLACE_ME_DRIVE_FOLDER_ID",
|
|
9
|
+
"parentFolderName": "REPLACE_ME_請求書フォルダ名",
|
|
10
|
+
"monthPathPattern": "YYYY-MM/入金/{カテゴリ}"
|
|
11
|
+
},
|
|
12
|
+
"sheet": {
|
|
13
|
+
"spreadsheetId": "REPLACE_ME_SPREADSHEET_ID",
|
|
14
|
+
"sheetName": "REPLACE_ME_請求書管理シート名",
|
|
15
|
+
"tabPattern": "REPLACE_ME_タブ名パターン_{YY.M}",
|
|
16
|
+
"templateTabGid": 0,
|
|
17
|
+
"headerRow": 1,
|
|
18
|
+
"columns": {
|
|
19
|
+
"会社名": "A",
|
|
20
|
+
"金額": "B",
|
|
21
|
+
"請求書のリンク": "C",
|
|
22
|
+
"担当": "D",
|
|
23
|
+
"ステータス": "E",
|
|
24
|
+
"メモ": "F",
|
|
25
|
+
"期日": "G"
|
|
26
|
+
},
|
|
27
|
+
"statusInitial": "確認待ち"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"_comment": "CLI は npm public registry (addashboard-cli) から `npx -y` 経由で実行する。REPLACE_ME_* および 0 のフィールドは利用環境ごとに ~/.claude/skills/invoice-issue-freee/config.json を上書きして自分の freee company / Google Drive / Sheet の値に差し替える"
|
|
31
|
+
}
|