Loading...
Loading...
The Shopping Ads skill delivers end-to-end management of Google Shopping campaigns and Merchant Center product feeds.
npx skill4agent add itallstartedwithaidea/agent-skills shopping-adsflowchart TD
A[Merchant Center] --> B[Feed Analysis Engine]
B --> C[Attribute Audit]
C --> C1[Title Optimization]
C --> C2[Description Enrichment]
C --> C3[Category Mapping]
C --> C4[Image Quality Check]
C --> C5[GTIN/MPN Validation]
B --> D[Custom Label Strategy]
D --> D1[Label 0: Margin Tier]
D --> D2[Label 1: Best Sellers]
D --> D3[Label 2: Seasonality]
D --> D4[Label 3: Price Range]
D --> D5[Label 4: New vs Existing]
B --> E[Competitive Intelligence]
E --> E1[Price Benchmarks]
E --> E2[Click Share]
E --> E3[Impression Share]
C1 --> F[Optimized Feed]
C2 --> F
C3 --> F
C4 --> F
C5 --> F
D1 --> F
D2 --> F
D3 --> F
D4 --> F
D5 --> F
F --> G[Campaign Structure]
G --> G1[Standard Shopping\nPriority Tiers]
G --> G2[PMax Shopping\nAsset Group Segmentation]
E1 --> H[Bid Strategy]
E2 --> H
E3 --> H
G1 --> H
G2 --> H
H --> I[Performance Monitoring]
I --> J[Product-Level ROAS]
I --> K[Query-Level Analysis]
I --> L[Competitive Position Tracking]async function auditProductFeed(merchantId) {
const products = await getMerchantProducts(merchantId);
const diagnostics = await getFeedDiagnostics(merchantId);
const audit = {
totalProducts: products.length,
activeProducts: products.filter(p => p.status === 'active').length,
disapproved: products.filter(p => p.status === 'disapproved'),
warnings: diagnostics.warnings,
attributeAnalysis: analyzeAttributes(products),
titleOptimization: auditTitles(products),
descriptionQuality: auditDescriptions(products),
imageQuality: auditImages(products),
pricingAnalysis: analyzePricing(products),
customLabelStrategy: designCustomLabels(products)
};
return audit;
}
function auditTitles(products) {
const issues = [];
for (const product of products) {
const title = product.title;
if (title.length < 25) {
issues.push({ productId: product.id, issue: 'Title too short', current: title });
}
if (title.length > 150) {
issues.push({ productId: product.id, issue: 'Title exceeds optimal length', current: title });
}
if (!title.toLowerCase().includes(product.brand?.toLowerCase())) {
issues.push({ productId: product.id, issue: 'Brand missing from title', current: title });
}
const optimizedTitle = buildOptimizedTitle(product);
if (optimizedTitle !== title) {
issues.push({
productId: product.id,
issue: 'Title can be optimized',
current: title,
recommended: optimizedTitle
});
}
}
return { issues, optimizationRate: issues.length / products.length };
}
function buildOptimizedTitle(product) {
const components = [
product.brand,
product.title.replace(product.brand, '').trim(),
product.color,
product.size,
product.material,
product.gender
].filter(Boolean);
const optimized = components.join(' - ');
return optimized.substring(0, 150);
}
function designCustomLabels(products) {
const performanceData = products.map(p => ({
id: p.id,
revenue: p.revenue30d,
cost: p.cost30d,
roas: p.revenue30d / Math.max(p.cost30d, 0.01),
margin: p.margin,
clicks: p.clicks30d,
conversions: p.conversions30d
}));
return {
customLabel0: {
name: 'Margin Tier',
values: assignMarginTiers(performanceData),
biddingImplication: 'Higher bids on high-margin products'
},
customLabel1: {
name: 'Performance Tier',
values: assignPerformanceTiers(performanceData),
biddingImplication: 'Aggressive bids on top performers, reduced on low performers'
},
customLabel2: {
name: 'Seasonality',
values: assignSeasonality(products),
biddingImplication: 'Boost seasonal products during peak periods'
},
customLabel3: {
name: 'Price Competitiveness',
values: assignPriceCompetitiveness(products),
biddingImplication: 'Higher bids when price-competitive, lower when overpriced'
},
customLabel4: {
name: 'Product Lifecycle',
values: products.map(p => ({
productId: p.id,
label: p.daysListed < 30 ? 'new_arrival' : p.daysListed > 180 ? 'clearance' : 'established'
})),
biddingImplication: 'Promotional bids for new arrivals and clearance'
}
};
}function buildSupplementalFeed(products, enrichmentData) {
return products.map(product => ({
id: product.id,
custom_label_0: enrichmentData[product.id]?.marginTier,
custom_label_1: enrichmentData[product.id]?.performanceTier,
custom_label_2: enrichmentData[product.id]?.seasonality,
custom_label_3: enrichmentData[product.id]?.priceCompetitiveness,
custom_label_4: enrichmentData[product.id]?.lifecycle,
sale_price: enrichmentData[product.id]?.promotionalPrice,
promotion_id: enrichmentData[product.id]?.activePromotion
}));
}
function analyzeCompetitivePricing(products, benchmarkData) {
return products.map(product => {
const benchmark = benchmarkData[product.id];
if (!benchmark) return { productId: product.id, status: 'no_benchmark_data' };
const pricePosition = product.price / benchmark.benchmarkPrice;
return {
productId: product.id,
yourPrice: product.price,
benchmarkPrice: benchmark.benchmarkPrice,
priceIndex: pricePosition,
status: pricePosition <= 0.95 ? 'price_leader'
: pricePosition <= 1.05 ? 'competitive'
: pricePosition <= 1.15 ? 'slightly_above'
: 'overpriced',
clickShareImpact: estimateClickShareImpact(pricePosition),
recommendation: pricePosition > 1.15
? 'Consider price reduction or value-add messaging'
: 'Maintain current pricing strategy'
};
});
}| Platform | Supported |
|---|---|
| Claude Code | ✅ |
| Cursor | ✅ |
| Codex | ✅ |
| Gemini | ✅ |