@ads-repo/meta-creative-buckets 1.0.0 → 1.0.1

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.
Files changed (2) hide show
  1. package/README.md +105 -36
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # Meta Creative Buckets
2
2
 
3
- A Claude Code skill that reads your Meta ad account and plots every creative on a
4
- spend vs efficiency grid, so each ad lands in one of four buckets:
3
+ Sort every creative in your Meta ad account into **Scale**, **Wait**, **Kill** or **Not enough data** on a Spend × CRR grid. The output is a single self-contained HTML file with the quadrant chart, a time slider that replays the window day by day, and a sortable creative table — no server, no database, no Google Sheet in between.
5
4
 
6
5
  ```
7
6
  CRR bad (high) │ Wait │ Kill
@@ -11,66 +10,136 @@ spend vs efficiency grid, so each ad lands in one of four buckets:
11
10
  low spend enough spend
12
11
  ```
13
12
 
14
- The output is a single self-contained HTML file that opens in your browser.
13
+ ## What you get
15
14
 
16
- ## Install
15
+ - One HTML file with all data embedded, opens straight off disk
16
+ - **Quadrant scatter** — one bubble per ad, area ∝ spend, X = spend (log), Y = CRR %
17
+ - **Time slider** — replays the window day by day, with Day / Week / Month granularity and a date-range picker
18
+ - **Live thresholds** — target CRR and spend gate as sliders, both seeded from your own account
19
+ - **Spend distribution bar** — what share of budget sits in each bucket
20
+ - **Creative table** — spend, revenue, purchases, CRR, ROAS, last-3-day trend, CTR, active days, all sortable
21
+ - Cascading filters: campaign / ad set / ad, status, Active-only toggle
22
+ - Day-over-day ▲▼ arrows once you have run it twice
23
+ - Password-locked copy for client sharing (`encrypt-dashboard.cjs`)
24
+ - adsrepo.com brand styling (Raleway font, orange accent #ff5722)
25
+
26
+ ## The metric
27
+
28
+ **CRR = spend ÷ purchase revenue**, as a percentage, on the 7-day-click window.
29
+
30
+ It is ROAS upside down: CRR 40% means 40 € of ads per 100 € of sales, so **lower is better** (CRR 40% = ROAS 2.5).
31
+
32
+ | Bucket | Rule (target CRR `T`, spend gate `S`) |
33
+ |---|---|
34
+ | **Not enough data** | `spend < S` — under the gate, never judged |
35
+ | **Scale** | `spend ≥ S` and `CRR ≤ T` — earning well, give it more |
36
+ | **Wait** | `spend ≥ S` and `T < CRR < 3T` — mediocre, watch it |
37
+ | **Kill** | `spend ≥ S` and `CRR ≥ 3T` — burning money |
38
+
39
+ Both thresholds are computed from your account at build time, not hardcoded: the target starts at your blended CRR, the spend gate at the 75th percentile of per-ad spend (floored at 3 × AOV). Both are sliders — that is only the opening position.
40
+
41
+ ## Requirements
42
+
43
+ - **Node.js 18+** ([download](https://nodejs.org))
44
+ - **A Meta access token** with the `ads_read` permission
45
+ - **Your ad account id** — the `act_…` number in the Ads Manager URL
46
+ - An account that tracks **purchases**: the grid is built on revenue, so lead-gen accounts have nothing on the Y axis
47
+
48
+ No npm dependencies — the scripts use only Node's standard library.
49
+
50
+ ## Installation
51
+
52
+ ### Option A — Claude Code (recommended)
17
53
 
18
54
  ```bash
19
55
  npm install -g @ads-repo/meta-creative-buckets
20
56
  ```
21
57
 
22
- That copies the skill into `~/.claude/skills/meta-creative-buckets`. Restart Claude
23
- Code and it will pick it up.
58
+ That copies the skill into `~/.claude/skills/meta-creative-buckets/`, available in every session. Restart Claude Code, then say:
24
59
 
25
- ## Setup
60
+ > build the creative buckets dashboard
61
+
62
+ Claude picks the skill up from the trigger phrase, fetches the data and opens the dashboard.
63
+
64
+ **Manual install** (if you would rather not install globally): unzip the ZIP from [adsrepo.com](https://adsrepo.com/products/meta-creative-buckets) and move the `meta-creative-buckets/` folder into `~/.claude/skills/` or `<project>/.claude/skills/`, then restart Claude Code. Nothing to `npm install` — there are no dependencies.
65
+
66
+ ### Option B — Standalone CLI (no Claude Code)
26
67
 
27
- You need two values from Meta.
68
+ The scripts are plain Node and run on their own:
28
69
 
29
- **1. An access token** with the `ads_read` permission. The quickest route is the
30
- [Graph API Explorer](https://developers.facebook.com/tools/explorer/): pick your app,
31
- add the `ads_read` scope, generate the token. That one expires in about an hour - for
32
- repeat use, exchange it for a long-lived token or create a System User token in
33
- Business Manager.
70
+ ```bash
71
+ cd ~/.claude/skills/meta-creative-buckets
72
+ node scripts/fetch-buckets-data.cjs 30
73
+ node scripts/build-buckets-matrix.cjs
74
+ ```
75
+
76
+ ## Setup
34
77
 
35
- **2. Your ad account id** - the `act_…` number in the Ads Manager URL.
78
+ Get a token with the `ads_read` scope from the [Graph API Explorer](https://developers.facebook.com/tools/explorer/): pick your app, add the scope, generate. That token expires in about an hour — for repeat use, exchange it for a long-lived token or create a System User token in Business Manager.
36
79
 
37
- Put both in a `.env` file in your project root:
80
+ Then put both values in a `.env` file in your project root (see `env.example`):
38
81
 
39
82
  ```bash
40
83
  META_ACCESS_TOKEN=your-token-here
41
84
  META_AD_ACCOUNT_ID=act_1234567890
42
85
  ```
43
86
 
44
- Reading several accounts from one project? Suffix each pair with a client slug
45
- (`META_ACCESS_TOKEN_ACME_CZ`) and pass `--client acme-cz`.
87
+ Reading several accounts from one project? Suffix each pair with a client slug and pass the flag:
88
+
89
+ ```bash
90
+ META_ACCESS_TOKEN_ACME_CZ=...
91
+ META_AD_ACCOUNT_ID_ACME_CZ=act_9876543210
92
+ ```
93
+
94
+ ```bash
95
+ node scripts/fetch-buckets-data.cjs 30 --client acme-cz
96
+ ```
46
97
 
47
- ## Use it
98
+ Optionally add `buckets.config.json` in the project root for a nicer header (account name, logo). Every field is optional — see `buckets.config.example.json`.
48
99
 
49
- In Claude Code, say:
100
+ ## What the script does
50
101
 
51
- > build the creative buckets dashboard
102
+ 1. Read the account currency and name from the Meta API (never guessed from the account name)
103
+ 2. Fetch 30 days of daily ad-level spend and purchase revenue, falling back to day-by-day if Meta refuses the bulk range
104
+ 3. Collect the ids that actually spent, then look up creative metadata for just those in batches of 40
105
+ 4. Work out CRR, ROAS, CTR and AOV per creative from the summed atoms, never averaged from daily rates
106
+ 5. Compute the starting thresholds from your own numbers
107
+ 6. Write one self-contained HTML file and open it in your browser
52
108
 
53
- It pulls 30 days of ad-level spend and purchase revenue, works out CRR per creative,
54
- and opens the dashboard in your browser.
109
+ ## Output
55
110
 
56
- ## The metric
111
+ ```
112
+ data/meta-ads/<client>/
113
+ ├── buckets-latest.json # per-ad summary + daily series
114
+ ├── history/YYYYMMDD-buckets.json # dated snapshot, drives the ▲▼ arrows
115
+ └── buckets-matrix.html # the dashboard
116
+ ```
117
+
118
+ The HTML works fully offline once generated. Email it, host it on a static server, or open it locally.
119
+
120
+ Custom window: `node scripts/fetch-buckets-data.cjs 60 2026-09-07` fetches 60 days ending on that date. Passing yesterday avoids a partial final day.
57
121
 
58
- **CRR = spend ÷ purchase revenue**, on the 7-day-click window. It is ROAS upside down:
59
- CRR 40% means 40 € of ads per 100 € of sales, so **lower is better** (CRR 40% = ROAS 2.5).
122
+ ## Troubleshooting
60
123
 
61
- Both thresholds are computed from your own account at build time - the target starts at
62
- your blended CRR, the spend gate at the 75th percentile of per-ad spend - and both are
63
- live sliders you can move.
124
+ | Problem | Fix |
125
+ |---|---|
126
+ | `credentials missing` | Add `META_ACCESS_TOKEN` and `META_AD_ACCOUNT_ID` to `.env` in your project root, not in the skill folder |
127
+ | `Invalid OAuth access token` | The Graph API Explorer token expired (about an hour). Generate a new one, or switch to a System User token |
128
+ | Blank creative thumbnails | Meta rate-limits the creative lookup on busy accounts. Every number is still correct — wait 15-30 min and run `node scripts/fetch-creative-meta.cjs` to patch them in |
129
+ | `too many calls` (error 80004) | Give the account a quiet 15-30 minutes; consecutive runs keep the rolling window full. Raise `META_API_RATE_LIMIT_DELAY` in `.env` if it persists |
130
+ | Every ad in "Not enough data" | Normal on accounts where spend concentrates in a few creatives. Drag the spend gate slider down to judge more of them |
131
+ | Dashboard opens empty | Check the account actually had spend in the window, and that it tracks purchase events |
64
132
 
65
- ## Requires
133
+ ## Metrics glossary
66
134
 
67
- - Node.js 18+
68
- - Claude Code
69
- - A Meta ad account that tracks purchases (the grid is built on revenue)
135
+ - **CRR** — spend ÷ purchase revenue, as a %. Lower is better. ROAS upside down
136
+ - **Target CRR** — the line between Scale and Wait. Starts at your account's blended CRR
137
+ - **Spend gate** — minimum spend before an ad is judged at all. Starts at the 75th percentile of per-ad spend, floored at 3 × AOV
138
+ - **CRR 3D** — the same ratio over the last three days, so you can see where a creative is heading
139
+ - **No revenue yet** — ads with spend but no purchases sit in a separate strip, placed by spend only. They are never "Wait": there is nothing to wait on without a single sale
70
140
 
71
- No npm dependencies: the scripts use only Node's standard library.
141
+ **Two attribution notes worth knowing.** Revenue is read from the named `7d_click` sub-field of `action_values`, not Meta's plain `value` — that one is the account default attribution (click + view) and can overstate revenue by roughly a third. And summing revenue across ads gives a higher number than the same period read at account level, typically +8-12%, because one purchase touched by two ads is credited to both. Per-ad CRR is sound for ranking creatives against each other; read the true blended CRR at account level.
72
142
 
73
- ## Docs
143
+ ## License
74
144
 
75
- Full walkthrough, bucket rules and the two Meta API details worth knowing:
76
- <https://adsrepo.com/products/meta-creative-buckets>
145
+ Copyright (c) 2026 Tomas Kliment / adsrepo.com. All rights reserved. See LICENSE for terms.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ads-repo/meta-creative-buckets",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Sort your Meta creatives into Scale, Wait and Kill on a spend vs CRR grid — drop-in Claude Code skill",
5
5
  "keywords": [
6
6
  "claude-code",