@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.
- package/README.md +105 -36
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Meta Creative Buckets
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
13
|
+
## What you get
|
|
15
14
|
|
|
16
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
68
|
+
The scripts are plain Node and run on their own:
|
|
28
69
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
100
|
+
## What the script does
|
|
50
101
|
|
|
51
|
-
|
|
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
|
-
|
|
54
|
-
and opens the dashboard in your browser.
|
|
109
|
+
## Output
|
|
55
110
|
|
|
56
|
-
|
|
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
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
##
|
|
133
|
+
## Metrics glossary
|
|
66
134
|
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
-
|
|
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
|
-
|
|
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
|
-
##
|
|
143
|
+
## License
|
|
74
144
|
|
|
75
|
-
|
|
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