Skip to main content

noon-ads

Noon Ad Manager — campaigns (Auto / Manual / Brand), tuning audits, keyword research, negatives, Vantage analytics. Covers Targets / Customer Queries / Export Data flows. Load for any noon ads work — review, audit, tune, create. References under references/ for the tuning playbook (ads-tuning.md), creation guide (ads-creation.md), and keyword research (ads-keyword-research.md).

الانتقال إلى التثبيت

معلومات المصدر

المستودع
zpoint/vibe-seller
آخر نشاط في المصدر
١١ أغسطس ٢٠٢٦ في ٠٩:١١
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٦٨
التفرعات
١٤

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
4 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
noon-ads
description
Noon Ad Manager — campaigns (Auto / Manual / Brand), tuning audits, keyword research, negatives, Vantage analytics. Covers Targets / Customer Queries / Export Data flows. Load for any noon ads work — review, audit, tune, create. References under references/ for the tuning playbook (ads-tuning.md), creation guide (ads-creation.md), and keyword research (ads-keyword-research.md).
requires
["noon-shared"]
gates
["ad_completeness_review","ad_negation_allowlist","ad_execution_fidelity"]
# Noon — Ad Manager > **PREREQUISITE:** Read `../noon-shared/SKILL.md` for login, page > structure, and common patterns. ## 0. FIRST — declare what this task is for **Before any browser action, call `vibe_seller_declare_ad_task`.** This is a precondition, not a courtesy: a report with no declaration behind it is refused. Two things follow from the declaration and cannot be changed afterwards — how much the completeness gate asks of you, and whether the user gets a review console. Read them off what the person actually asked for, not off what you expect to find once you look. | They asked for | `kind` | `scope` | |---|---|---| | "审计一下广告" / "review our ads" | `audit` | omit `combos` — whole store | | "复核 widget-006 在 amazon 的广告" | `audit` | that platform+country, those campaign ids | | "把这三个词的出价降下来" | `audit` | those campaigns | | "帮 widget-006 建关键词广告" | `create` | the market you are creating in | | "执行刚才确认的调整" | `execute` | the campaigns being changed | | "我们 SA 的 ACOS 大概多少" | `investigate` | the market asked about | **Numbers or changes?** That is the line between `investigate` and `audit`, and it matters more than the table above. If the answer the person wants is a FIGURE — what did we spend, what is our ROAS, how did last month go — that is `investigate`, however many markets it spans: you are reading, not proposing. If they want to know what to CHANGE, or asked "is this right?", that is `audit`, and it opens a review console. Observed live: a plain "how much did we spend on ads this month, and what came back?" was declared a whole-store `audit`, which put five marketplaces of drill work behind a question that wanted four numbers. And the other way round, observed in CI: "review the keyword bids on <campaign>" was declared `investigate`, so the bid recommendations it produced reached the user with no console to approve them on. **If you got it wrong, correct it upward.** If you declared `investigate` and the work turned out to produce decisions — a table telling someone to raise, cut, pause or negate — call `vibe_seller_declare_ad_task` again with `kind: "audit"` and the same scope, or a narrower one. That is the ONLY kind change allowed inside a turn, and it is allowed because it only ever makes you owe more: the coverage obligation appears and the user gets the console. Going the other way (`audit` → `investigate`), adding a marketplace, or widening the campaign list are all still refused, and still need a new message from the user. Do not instead delete your recommendations to fit the declaration — the person asked what to change. **There is no `edit` kind.** A request to change specific bids is an `audit` whose scope names those campaigns — the user still reviews the change before it is applied, and the scope is what makes it small. **The scope trap:** omitting `combos` means EVERY marketplace this store sells on, and you will be held to all of them. Omit it only when the request really is store-wide. A store selling on five marketplaces has been asked for all five because a one-product task left the field out. **If the request names a product, not a campaign** ("widget-006 的广告"), declare the MARKET now and the campaigns later. You cannot know campaign ids before you have looked, and declaring a market with no campaign list means **every campaign in it** — which is how a one-product request turns into an audit owing a whole marketplace. So: declare `{kind, combos, products}` first, enumerate the campaign list, find the campaigns carrying that SKU family, then call the tool AGAIN with the same kind and the same combos plus `campaigns: [...]`. That second call is a **narrowing refinement** and is accepted within the same turn. **Refining may only ever remove reach.** Same kind, same marketplaces, and a campaign list going from "all of them" to a named subset. You cannot add a marketplace, change the kind, or widen the campaign list — a wider scope needs a new message from the user. If a gate asks for something outside your scope, say so in your result and let the user redirect you; do not try to re-declare around it. **When the user sends a NEW message that changes what you are doing, declare again.** That is a new phase, and it is the only way a declaration changes. Two cases you will hit often: - "现在把刚创建的广告复核一下" after a `create` phase → declare `audit`, and its scope may name the campaigns you created earlier in this same task. - The review console submits the user's decisions back as a follow-up message → declare `execute`, scoped to the campaigns that submission actually names. --- Mechanics for noon Ad Manager. The actual *thinking* — when to create / tune / kill a campaign, how to research keywords — lives in the three reference files (see § 11). **URL**: `https://admanager.noon.partners/en-{cc}/home?mpCode=noon&project=PRJ{project_id}` Left nav is an **icon rail** (not a text `ul[role=menu]`): **Campaigns**, **Recommendations**, **Budget**, **Vantage**, **Billing**, **Settings** — the labels render as `role=menuitem` spans, so match by text, not by `ul[role=menu] a`. > ⚠️ **The Ad Manager was redesigned (verified live 2026-07-21).** The > `/home` landing is now an **Overview** dashboard (KPI panels + > promos), NOT the campaign list. The "Ad Manager" card carries three > tabs — **Overview | Performance | Campaigns** — and the campaign list > lives under the **Campaigns** tab at `…/home?…&tab=campaigns`. A page > that also shows a **Sale Event Optimizer** widget (event budget/bid > boosts) and a **Recommendations** panel is the current build. See § 2 > for how to enumerate the list — the old paginator is gone. ## 1. Campaigns Overview Metrics Overview-tab KPI cards: | Metric | Formula / Notes | |--------|-----------------| | ROAS | Return on Ad Spend = Revenue / Spends | | Revenue | Total ad-attributed revenue | | Spends | Total ad spend | | eCPC | Effective Cost Per Click | | CTR | Click-Through Rate = Clicks / Views | | Orders | Ad-attributed orders | | Clicks | Total clicks on ads | | Views | Total ad impressions | | ATC | Add To Cart count | | CvR | Conversion Rate (shown on campaign detail) | A time-series performance chart below lets you toggle any metric. ## 2. Campaign List — Filters, True Totals, Full Enumeration Open the **Campaigns** tab (`…/home?…&tab=campaigns`). Filters above the list: - **Search** box (by campaign name) - **Date range** (default `Last 30 days`) - **Ad Type**: `All types` / `Product` / `Brand` / `Display` - **Targeting**: `All targeting` / `Auto` / `Manual` - **Status count control** (segmented): `Live N` · `Paused N` · `All N` + a `More status filter` dropdown. The counts are the **true totals** for the current filter — read them directly; there is no page math. - **Export all campaigns** (top-right of the list) — a list-level bulk export (distinct from the per-tab Export Data in § 7). Columns (horizontally scrollable): Campaign, Status, Budget, Revenue, ROAS, Ad Spend, eCPC, Orders, Views, Clicks, ATC, … Actions. ### Enumerate EVERY campaign — the paginator is gone The Ant-Design pager (`li.ant-pagination-item-N`, "15 items per page") **no longer exists**. The list is now a **lazy-loaded, inner-scroll table**: only ~15–20 rows render on first paint, and **`window.scroll` does nothing** — you must scroll the list's own container until every row loads. Skipping this silently under-counts: an unscrolled read that sees the first ~20 rows can miss more than half the Live campaigns when the `Live N` chip is much larger, which then fails the completeness gate. > ⚠️ **Enumerate LIVE from the scrolled list — never from a pre-existing > or downloaded export file.** A leftover `Campaign_*.csv` / > `Export all campaigns` file in `~/.vibe-seller/downloads/` (from a > prior run, or a first-paint export before you scrolled) captures only > the rows that were loaded when it was written — typically the first > ~20. Drilling that file makes the audit look done at `20/20` while the > account has far more Live campaigns. (Live failure this fixes: an agent > reused a 20-row export and reported noon SA `20/20` when the `Live` > chip showed **45**.) **Any campaign set whose count is below the > `Live N` chip is stale — re-enumerate by scrolling (below); and if you > do use `Export all campaigns`, first scroll the list fully, then verify > the file's row count equals the chip before trusting it.** **What you owe is what you DECLARED.** `./AUDIT_TARGETS.json` lists every country the store is configured for — the MENU, written by the server from Settings. Your `vibe_seller_declare_ad_task` call turns part of it into an obligation: the countries you declared each need their own `AUDIT_SCOPE.json` combo entry (step 4) AND their own `## noon <CC>` report section; declaring no combos at all (a whole-store audit) means you owe every country in the file. Do NOT expand past your declaration because the menu is longer — reporting on a market nobody asked about is an out-of-scope gap. A country with genuinely no Live campaigns is still written down — an entry with `"active_ids": []` and `"total_active": 0`, plus a section saying so; 可以为空,但不能不写。Omitting a declared combo is a `[基线]` gap that blocks submission. Phase 1 (Discover) MUST, per country: 1. **Read the true total** from the status chips — the `Live N` / `All N` numbers are your completeness target. The chip *label* (`Live` today) is English on the noon partner console, but rely on the **number** and the **`/campaign/details/` links** — both language-neutral — so this works whatever the seller-market locale; don't key on the label word: ```bash browser-use <<'PY' print(js("return JSON.stringify([...document.querySelectorAll('*')].filter(e=>e.children.length<=2 && /^(Live|Paused|All)\\s*\\d+$/i.test(e.textContent.replace(/\\s+/g,' ').trim())).map(e=>e.textContent.replace(/\\s+/g,' ').trim()))")) PY ``` 2. **Scroll the list container to the bottom** (match its class by the `CampaignListRevamp_` prefix — the hashed suffix changes per build; fall back to any inner `overflow-y:auto` scroller taller than its viewport). Repeat until the campaign-link count stops growing: ```bash browser-use <<'PY' for _ in range(12): js("[...document.querySelectorAll('*')].filter(e=>{var s=getComputedStyle(e);return (s.overflowY==='auto'||s.overflowY==='scroll') && e.scrollHeight>e.clientHeight+50;}).forEach(e=>e.scrollTop=e.scrollHeight)") wait(1) print("links:", js('return document.querySelectorAll("a[href*=\\"/campaign/details/\\"]").length')) PY ``` 3. **Extract IDs** with the still-valid `a[href*="/campaign/details/"]` read (§ 3) and de-dupe. Only when the distinct count matches the chip total (e.g. `Live N`) is the manifest complete. Re-run this whole loop **after every country switch** (`/en-{cc}/`). 4. **Persist the scope — required for audits.** Append this combo to `./AUDIT_SCOPE.json` at the task root, with the de-duped ids **and** the `Live N` chip number: ```json {"combos": [ {"platform": "noon", "country": "AE", "total_active": 45, "total_active_source": "chip:Live 45", "active_ids": ["C_DEMO0001", "C_DEMO0002"]} ]} ``` The server requires `total_active == len(active_ids)`, and rejects the scope when they disagree. That is deliberate: the chip is rendered by the server and does **not** depend on how far you scrolled, so a half-scrolled list (20 ids, chip 45) is caught as stale instead of being accepted as a complete `20/20` audit. If they disagree, keep scrolling — don't "fix" it by editing the number down. Every id you list must then get its own `### <id> | … ` drill block in the report. Full field reference: `amazon-ads/references/audit-quickref.md` Step 1. **`total_active_source` is required, and for noon it is the chip reading** — `"chip:Live N"`, the number you read in step 1. Without it the combo is a `[基线]` gap. Reason: `total_active == len(active_ids)` only proves the two numbers agree, not that either was *observed* — trivially true when both come from the same parse (observed live: a run declared a 12-campaign marketplace as `4/4` because its script silently dropped files it couldn't read, and every check passed). The chip form isn't verifiable from disk the way Amazon's `"bulk:<file>.xlsx"` is, but writing the reading down turns an invented total from an omission into a claim the reviewer can check against the live page. Read the chip; don't back-fill it from the id count. ## 3. Campaign Detail Page **URL**: `admanager.noon.partners/en-{cc}/campaign/details/{campaign_id}?mpCode=noon&project=PRJ{project_id}` Campaign ID format: `C_{alphanumeric}` (10 alphanumerics after the underscore, e.g. `C_XXXXXXXXXX`). **Campaign ID extraction** from the campaigns list (IDs are in `<a href>` attributes, not visible text): ```bash browser-use <<'PY' print(js(""" var links = document.querySelectorAll('a[href*="/campaign/details/"]'); var data = []; links.forEach(function(l) { var m = l.href.match(/\\/campaign\\/details\\/([^?]+)/); if (m) data.push({name: l.textContent.trim(), id: m[1]}); }); return JSON.stringify(data); """)) PY ``` > ⚠️ **The link extraction above only returns the rows currently > rendered.** The list lazy-loads on inner scroll, so a raw read > captures ~15–20 of what may be many more. **Enumerate the full set > via the § 2 procedure** (read the `Live N` / `All N` chip totals, then > scroll the list container until the distinct link count matches). > Treat a single unscrolled read as a spot-check, never the full set — > under-counting here fails the completeness gate. **Campaign names can be misleading.** Verify actual products via the **Products tab** — do not trust the campaign name. A campaign named "mouse004 Auto" may target keyboard SKUs, not a mouse. Header shows: campaign name, Status badge, Budget, **Top-of-Search boost** (displayed as `Top Slot: N%` between Budget and Bidding Strategy for manual campaigns with TOS configured), Bidding Strategy, Running From date, Last Updated. **Top-right action icons:** a date-range picker, **pause/resume**, **duplicate**, and a round **blue pencil = Edit** (opens the campaign editor — see § 9 for adding/removing keywords & negatives). `target_filter` query param on the Targets tab switches the view: `target_filter=all` (positive keywords, default) vs `target_filter=negative` (negative keywords). **Brand Ads have different CTR/ROAS norms.** Brand Video ads measure view-through differently — never compare CTR directly to Product Ads. A `brand video` CTR of 0.23% is not "weak" vs product ad peers at 1.7–6.7%. Compare Brand Ads only against other Brand Ads, or against the brand ad's own historical ROAS. **Brand Ad "Creative" row.** The Products tab may show a "Creative" row (logo/video element) that accumulates clicks with zero attributed orders — noon can't attribute conversions to the creative. If Creative spend > 20% of campaign budget, flag it; calculate ROAS both with and without the Creative row for true product performance. KPI cards (same 10 metrics as overview, scoped to this campaign). Performance chart with metric toggles: ROAS, Revenue, Spends, eCPC, CTR, CvR, Orders, Clicks, Views, ATC. **4 Sub-tabs on campaign detail:** | Tab | Purpose | |-----|---------| | Products | SKUs in this campaign with per-SKU metrics | | Placements | Ad placement performance | | **Targets** | **Keywords** with match types and bids |
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub