@adkit/cli 1.13.5 → 1.13.6
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/dist/cli.js +69 -21
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1253,7 +1253,7 @@ async function listMetaCampaigns(client, _args, flags) {
|
|
|
1253
1253
|
}
|
|
1254
1254
|
var CAMPAIGN_FLAGS = ["name", "objective", "status", "budget-daily", "budget-total", "abo", "bid-strategy"];
|
|
1255
1255
|
var ADSET_FLAGS = ["campaign", "name", "status", "optimization", "budget-daily", "budget-total", "bid-strategy", "bid-amount", "countries", "genders", "targeting", "pixel", "event-type", "interest"];
|
|
1256
|
-
var AD_FLAGS = ["creative", "adset", "name", "status", "media", "media-format", "primary-text", "headline", "description", "cta", "url", "lead-form", "page", "post"];
|
|
1256
|
+
var AD_FLAGS = ["creative", "adset", "name", "status", "media", "media-format", "primary-text", "headline", "link-description", "cta", "url", "lead-form", "page", "post"];
|
|
1257
1257
|
var CREATIVE_FLAGS = ["page-id", "headline", "primary-text", "link-description", "link-url", "cta", "name", "image-hash", "image-url", "video-id", "force"];
|
|
1258
1258
|
var MEDIA_FLAGS = ["file", "url", "account"];
|
|
1259
1259
|
var ADSET_BID_STRATEGIES_REQUIRING_AMOUNT = /* @__PURE__ */ new Set(["cost_cap", "bid_cap"]);
|
|
@@ -1430,10 +1430,10 @@ async function createAd(client, _args, flags) {
|
|
|
1430
1430
|
}
|
|
1431
1431
|
validateFlags(flags, AD_FLAGS, "manage meta ads create");
|
|
1432
1432
|
const creativeId = typeof flags.creative === "string" ? flags.creative : void 0;
|
|
1433
|
-
const mediaFlags = ["media", "media-format", "primary-text", "headline", "description", "cta", "lead-form"];
|
|
1433
|
+
const mediaFlags = ["media", "media-format", "primary-text", "headline", "link-description", "cta", "lead-form"];
|
|
1434
1434
|
const hasMediaFlags = mediaFlags.some((f) => flags[f] !== void 0);
|
|
1435
1435
|
const postId = typeof flags.post === "string" ? flags.post : void 0;
|
|
1436
|
-
if (creativeId && hasMediaFlags) throw new CliError("INVALID_VALUE", "`--creative` cannot be combined with --media, --primary-text, --headline, --description, or --cta", "Use --creative to reference an existing creative, OR use --media/--primary-text/etc. to create a new one");
|
|
1436
|
+
if (creativeId && hasMediaFlags) throw new CliError("INVALID_VALUE", "`--creative` cannot be combined with --media, --primary-text, --headline, --link-description, or --cta", "Use --creative to reference an existing creative, OR use --media/--primary-text/etc. to create a new one");
|
|
1437
1437
|
if (postId && (creativeId || hasMediaFlags)) throw new CliError("INVALID_VALUE", "`--post` cannot be combined with --creative, --media, or text flags", "Use --post alone to create an ad from an existing post");
|
|
1438
1438
|
if (flags["lead-form"] !== void 0 && (typeof flags["lead-form"] !== "string" || !flags["lead-form"].trim())) throw new CliError("MISSING_FLAG", "Lead Form ads require an Instant Form ID. Pass --lead-form <id>.", "Copy the form ID from Meta Instant Forms and pass it as --lead-form <id>.");
|
|
1439
1439
|
if (postId) {
|
|
@@ -1466,7 +1466,7 @@ async function createAd(client, _args, flags) {
|
|
|
1466
1466
|
const mediaFormatInputs = collectFlagValues(flags, "media-format");
|
|
1467
1467
|
const primaryTexts = collectFlagValues(flags, "primary-text");
|
|
1468
1468
|
const headlines = collectFlagValues(flags, "headline");
|
|
1469
|
-
const
|
|
1469
|
+
const linkDescriptions = collectFlagValues(flags, "link-description");
|
|
1470
1470
|
if (mediaInputs.length === 0) throw new CliError("MISSING_FLAG", "Missing required flag: `--media` (or use `--creative` to reference an existing creative)", 'Run: adkit manage meta ads create --media ./hero.mp4 --primary-text "Hello" --adset as_xyz --publish');
|
|
1471
1471
|
if (mediaFormatInputs.length > 0 && mediaFormatInputs.length !== mediaInputs.length) throw new CliError("INVALID_VALUE", "Pass one --media-format value for each --media value.", "Use --media-format default for the base media, then square, vertical, or horizontal for replacements.");
|
|
1472
1472
|
const mediaFormats = mediaFormatInputs.map(readMediaFormatFlag);
|
|
@@ -1509,7 +1509,7 @@ async function createAd(client, _args, flags) {
|
|
|
1509
1509
|
const ad = { adsetId, media };
|
|
1510
1510
|
if (primaryTexts.length) ad.primaryTexts = primaryTexts;
|
|
1511
1511
|
if (headlines.length) ad.headlines = headlines;
|
|
1512
|
-
if (
|
|
1512
|
+
if (linkDescriptions.length) ad.linkDescriptions = linkDescriptions;
|
|
1513
1513
|
if (typeof flags.cta === "string") ad.cta = flags.cta;
|
|
1514
1514
|
if (typeof flags.name === "string") ad.name = flags.name;
|
|
1515
1515
|
if (typeof flags.url === "string") ad.url = flags.url;
|
|
@@ -1852,6 +1852,7 @@ var CONVERSION_UPLOAD_FLAGS = ["conversion", "gclid", "gbraid", "wbraid", "occur
|
|
|
1852
1852
|
var CHANGE_HISTORY_FLAGS = ["account", "period", "from", "to", "limit", "resource", "campaign", "ad-group"];
|
|
1853
1853
|
var KEYWORD_RESEARCH_FLAGS = ["url", "location", "language", "limit", "min-volume"];
|
|
1854
1854
|
var TARGETING_RESEARCH_FLAGS = ["limit"];
|
|
1855
|
+
var GEO_LOCATION_SEARCH_FLAGS = ["country-code", "locale", "type", "limit"];
|
|
1855
1856
|
var NUMBER_FLAG_PATTERN = /^(?:\d+|\d+\.\d+|\.\d+)(?:e[+-]?\d+)?$/iu;
|
|
1856
1857
|
function generateCampaignName2() {
|
|
1857
1858
|
return `campaign ${getDateStamp()}`;
|
|
@@ -2815,6 +2816,18 @@ async function researchInterests(client, args, flags) {
|
|
|
2815
2816
|
const path3 = `/manage/google/research/interests${qs}`;
|
|
2816
2817
|
return client.get(path3);
|
|
2817
2818
|
}
|
|
2819
|
+
async function searchGoogleGeoLocations(client, args, flags) {
|
|
2820
|
+
validateFlags(flags, GEO_LOCATION_SEARCH_FLAGS, "manage google geo-locations search");
|
|
2821
|
+
const query = args.join(" ").trim();
|
|
2822
|
+
if (!query) throw new CliError("MISSING_ARGUMENT", "Missing location query", 'Run: adkit manage google geo-locations search "Austin, Texas" --country-code US --type city');
|
|
2823
|
+
const accountId = typeof flags.account === "string" ? flags.account : void 0;
|
|
2824
|
+
const countryCode = typeof flags["country-code"] === "string" ? flags["country-code"] : void 0;
|
|
2825
|
+
const locale = typeof flags.locale === "string" ? flags.locale : void 0;
|
|
2826
|
+
const type = typeof flags.type === "string" ? flags.type : void 0;
|
|
2827
|
+
const limit = typeof flags.limit === "string" ? flags.limit : void 0;
|
|
2828
|
+
const qs = queryString({ accountId, query, countryCode, locale, type, limit });
|
|
2829
|
+
return client.get(`/manage/google/geo-locations${qs}`);
|
|
2830
|
+
}
|
|
2818
2831
|
function buildGoogleTargetingResearchQuery(args, flags, missingQueryHint) {
|
|
2819
2832
|
const q = args.join(" ").trim();
|
|
2820
2833
|
if (!q) throw new CliError("MISSING_ARGUMENT", "Missing query", missingQueryHint);
|
|
@@ -4745,7 +4758,7 @@ Flags (create \u2014 new creative from media):
|
|
|
4745
4758
|
--media <path|url> Media file or URL (repeatable). Handles upload + processing automatically for single-image/video ads
|
|
4746
4759
|
--primary-text <t> Ad body text (repeatable)
|
|
4747
4760
|
--headline <text> Headline text (repeatable)
|
|
4748
|
-
--description <t>
|
|
4761
|
+
--link-description <t> Link preview subtitle (repeatable, optional)
|
|
4749
4762
|
${FLAG.cta}
|
|
4750
4763
|
--name <name> Ad name
|
|
4751
4764
|
--url <url> Landing page URL
|
|
@@ -4807,7 +4820,7 @@ Flags (create \u2014 new creative from media):
|
|
|
4807
4820
|
--media-format <f> Optional format for each --media: default, square, vertical, horizontal
|
|
4808
4821
|
--primary-text <t> Ad body text (repeatable)
|
|
4809
4822
|
--headline <text> Headline text (repeatable)
|
|
4810
|
-
--description <t>
|
|
4823
|
+
--link-description <t> Link preview subtitle (repeatable, optional)
|
|
4811
4824
|
${FLAG.cta}
|
|
4812
4825
|
--name <name> Ad name
|
|
4813
4826
|
--url <url> Landing page URL
|
|
@@ -4843,6 +4856,7 @@ Note:
|
|
|
4843
4856
|
media [{ id: "imageHashOrVideoId" }, { id: "...", format: "vertical" }]
|
|
4844
4857
|
Normal media works on all placements. Add format only to replace a specific placement group with different media: square (Feed), vertical (Stories/Reels), horizontal (Right Column).
|
|
4845
4858
|
Do not use top-level media for carousel ads.
|
|
4859
|
+
linkDescriptions Link-preview subtitle copy for feed ads.
|
|
4846
4860
|
carouselCards
|
|
4847
4861
|
Card list for carousel ads. Each card needs headline and media.
|
|
4848
4862
|
carouselCards[].headline
|
|
@@ -5144,7 +5158,8 @@ Flags (list):
|
|
|
5144
5158
|
|
|
5145
5159
|
Note:
|
|
5146
5160
|
list returns campaign configuration only (name, status, budget).
|
|
5147
|
-
Geo targeting lives in targeting.geoLocations. Use type=country for
|
|
5161
|
+
Geo targeting lives in targeting.geoLocations. Use type=country for countries.
|
|
5162
|
+
For cities, regions, postal codes, and metros, run google geo-locations search and use the returned bare code.
|
|
5148
5163
|
Advanced geo examples: adkit manage google campaigns --help full
|
|
5149
5164
|
Display creation starts here: campaigns create --campaign-type display, then create Display ad groups and responsive_display ads.
|
|
5150
5165
|
Performance Max: campaignType "performance_max" with asset groups \u2014 build it with --data. See --help full.
|
|
@@ -5195,9 +5210,9 @@ Flags (list):
|
|
|
5195
5210
|
Notes:
|
|
5196
5211
|
Use google assets for explicit account/campaign/ad-group attachment, reusable libraries, or richer sitelinks via --data.
|
|
5197
5212
|
list returns campaign configuration only (name, status, budget).
|
|
5198
|
-
Geo targeting lives in targeting.geoLocations. Use type=country for
|
|
5199
|
-
|
|
5200
|
-
Google
|
|
5213
|
+
Geo targeting lives in targeting.geoLocations. Use type=country for countries and copy named locations from google geo-locations search.
|
|
5214
|
+
platformLocation accepts exact Google geo objects for advanced criteria and existing raw values.
|
|
5215
|
+
Google exclusions support named locations. Proximity circles belong in include.
|
|
5201
5216
|
Display campaign creation uses campaignType:"display" or --campaign-type display. Videos are not supported for Display media in v1.
|
|
5202
5217
|
Performance Max: campaignType "performance_max" with exactly one assetGroups[] entry. Text assets inline ({role,text}); image assets are uploaded via google media first, then referenced by id/resourceName. Needs an enabled conversion (publish is blocked without one). Non-retail only. Build it with --data.
|
|
5203
5218
|
View a Performance Max campaign by ID to read back assetGroups from Google. There is no separate google asset-groups command.
|
|
@@ -5207,7 +5222,7 @@ Examples:
|
|
|
5207
5222
|
adkit manage google campaigns list --account 1234567890
|
|
5208
5223
|
adkit manage google campaigns create --name "Display Prospecting" --campaign-type display --budget-daily 50 --account 1234567890
|
|
5209
5224
|
adkit manage google campaigns create --data '{"campaigns":[{"name":"Display US","campaignType":"display","budget":{"daily":50},"targeting":{"geoLocations":{"include":[{"type":"country","country":"US"}]}}}]}' --account 1234567890
|
|
5210
|
-
adkit manage google campaigns create --data '{"campaigns":[{"name":"Search
|
|
5225
|
+
adkit manage google campaigns create --data '{"campaigns":[{"name":"Austin Search","campaignType":"search","budget":{"daily":5},"targeting":{"geoLocations":{"include":[{"type":"city","code":"1026201"}]}}}]}' --account 1234567890
|
|
5211
5226
|
adkit manage google campaigns create --data '{"campaigns":[{"name":"SF Radius","campaignType":"search","budget":{"daily":5},"targeting":{"geoLocations":{"include":[{"type":"platformLocation","platform":"google","value":{"proximity":{"geo_point":{"latitude_in_micro_degrees":37774900,"longitude_in_micro_degrees":-122419400},"radius":5,"radius_units":"MILES"}}}]}}}]}' --account 1234567890
|
|
5212
5227
|
adkit manage google campaigns create --data '{"campaigns":[{"name":"PMAX Launch","campaignType":"performance_max","budget":{"daily":50},"bidStrategy":"maximize_conversions","assetGroups":[{"name":"Asset Group 1","finalUrls":["https://example.com"],"assets":[{"role":"headline","text":"Ship faster"},{"role":"headline","text":"Save hours every week"},{"role":"headline","text":"Start free today"},{"role":"long_headline","text":"Automate your ad workflow and launch in minutes"},{"role":"description","text":"Automate your workflow in minutes"},{"role":"description","text":"No credit card required"},{"role":"business_name","text":"Acme"},{"role":"logo","id":"<uploaded-asset-id>"},{"role":"marketing_image","id":"<uploaded-asset-id>"},{"role":"square_marketing_image","id":"<uploaded-asset-id>"}],"signals":[{"type":"search_theme","text":"project management software"}]}]}]}' --account 1234567890
|
|
5213
5228
|
adkit manage google campaigns update 987654321 --status paused --account 1234567890
|
|
@@ -5731,6 +5746,24 @@ Notes:
|
|
|
5731
5746
|
Topic search returns IDs for targeting.content.topics.include/exclude.
|
|
5732
5747
|
Interest search returns IDs for targeting.audience.interests.include/exclude.
|
|
5733
5748
|
Websites use direct URLs in targeting.content.websites.include/exclude. Bare numeric customAudiences IDs are treated as Google user lists (remarketing/Customer Match); for custom segments, pass a customAudiences/{id} or customers/{accountId}/customAudiences/{id} resource path.`;
|
|
5749
|
+
var GOOGLE_GEO_LOCATIONS_HELP = `adkit manage google geo-locations \u2014 Find locations for campaign targeting
|
|
5750
|
+
|
|
5751
|
+
search <place...> Find enabled Google locations and return bare codes and AdKit types
|
|
5752
|
+
|
|
5753
|
+
Flags:
|
|
5754
|
+
--account <id> Optional if one Google Ads account is connected
|
|
5755
|
+
--country-code <c> ISO country code such as US
|
|
5756
|
+
--locale <locale> Google result locale such as en
|
|
5757
|
+
--type <type> country, region, city, postal_code, or metro
|
|
5758
|
+
--limit <n> Max results (1-50, default: 10)
|
|
5759
|
+
|
|
5760
|
+
Examples:
|
|
5761
|
+
adkit manage google geo-locations search "Austin, Texas" --country-code US --type city
|
|
5762
|
+
adkit manage google geo-locations search Paris --country-code FR --locale fr
|
|
5763
|
+
|
|
5764
|
+
Supported results contain type; unmapped Google categories contain platformType.
|
|
5765
|
+
Pass type and the bare code into campaign targeting. For country, use {"type":"country","country":"US"}.
|
|
5766
|
+
AdKit builds the Google resource name.`;
|
|
5734
5767
|
var GOOGLE_MEDIA_HELP = `adkit manage google media \u2014 Upload creative media to Google Ads
|
|
5735
5768
|
|
|
5736
5769
|
upload Upload an image and return reusable Google asset IDs
|
|
@@ -5841,6 +5874,7 @@ Examples:
|
|
|
5841
5874
|
"google results keywords": GOOGLE_RESULTS_KEYWORDS_HELP,
|
|
5842
5875
|
"google change-history": GOOGLE_CHANGE_HISTORY_HELP,
|
|
5843
5876
|
"google research": GOOGLE_RESEARCH_HELP,
|
|
5877
|
+
"google geo-locations": GOOGLE_GEO_LOCATIONS_HELP,
|
|
5844
5878
|
"google media": GOOGLE_MEDIA_HELP,
|
|
5845
5879
|
"google conversions": GOOGLE_CONVERSIONS_HELP,
|
|
5846
5880
|
"tiktok accounts": `adkit manage tiktok accounts \u2014 TikTok Ads accounts
|
|
@@ -6274,6 +6308,7 @@ Entity groups:
|
|
|
6274
6308
|
results Performance metrics (campaigns, ad-groups, ads, keywords, search-terms)
|
|
6275
6309
|
change-history Recent Google Ads account changes from the last 30 days
|
|
6276
6310
|
research Keyword Planner plus Display topic/interest IDs
|
|
6311
|
+
geo-locations Find Google location codes for campaign targeting
|
|
6277
6312
|
assets Manage reusable assets (sitelinks, callouts, structured snippets, images)
|
|
6278
6313
|
media Upload images for Display creative media
|
|
6279
6314
|
|
|
@@ -6615,6 +6650,7 @@ var HELP_FULL = {
|
|
|
6615
6650
|
"google results keywords": GOOGLE_RESULTS_KEYWORDS_HELP,
|
|
6616
6651
|
"google change-history": GOOGLE_CHANGE_HISTORY_HELP,
|
|
6617
6652
|
"google research": GOOGLE_RESEARCH_HELP,
|
|
6653
|
+
"google geo-locations": GOOGLE_GEO_LOCATIONS_HELP,
|
|
6618
6654
|
"google media": GOOGLE_MEDIA_HELP,
|
|
6619
6655
|
"google conversions": GOOGLE_CONVERSIONS_HELP,
|
|
6620
6656
|
"meta research": META_RESEARCH_HELP,
|
|
@@ -6951,15 +6987,17 @@ function printSingleEntity(e, entity) {
|
|
|
6951
6987
|
const creative = ad.creative;
|
|
6952
6988
|
if (creative) {
|
|
6953
6989
|
lines.push("", " Creative", "");
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6990
|
+
const headlines = creative.headlines?.join(", ");
|
|
6991
|
+
const primaryTexts = creative.primaryTexts?.join(", ");
|
|
6992
|
+
const linkDescriptions = creative.linkDescriptions?.join(", ");
|
|
6993
|
+
const mediaItems = creative.media?.map((item) => `${item.role}:${item.id}`) ?? [];
|
|
6994
|
+
const media = mediaItems.join(", ");
|
|
6995
|
+
if (headlines) lines.push(` Headline: ${formatForTTY(headlines)}`);
|
|
6996
|
+
if (primaryTexts) lines.push(` Body: ${formatForTTY(primaryTexts)}`);
|
|
6997
|
+
if (linkDescriptions) lines.push(` Description: ${formatForTTY(linkDescriptions)}`);
|
|
6958
6998
|
if (creative.cta) lines.push(` CTA: ${formatForTTY(creative.cta)}`);
|
|
6959
|
-
if (creative.
|
|
6960
|
-
if (
|
|
6961
|
-
if (creative.thumbnailUrl) lines.push(` Thumbnail: ${formatForTTY(creative.thumbnailUrl)}`);
|
|
6962
|
-
if (creative.videoId) lines.push(` Video ID: ${formatForTTY(creative.videoId)}`);
|
|
6999
|
+
if (creative.url) lines.push(` Link: ${formatForTTY(creative.url)}`);
|
|
7000
|
+
if (media) lines.push(` Media: ${formatForTTY(media)}`);
|
|
6963
7001
|
}
|
|
6964
7002
|
if (createdAt) lines.push(` Created: ${createdAt}`);
|
|
6965
7003
|
}
|
|
@@ -7978,8 +8016,18 @@ async function main() {
|
|
|
7978
8016
|
}
|
|
7979
8017
|
break;
|
|
7980
8018
|
}
|
|
8019
|
+
case "geo-locations": {
|
|
8020
|
+
if (!action) {
|
|
8021
|
+
showHelp("google geo-locations", flags.help === "full");
|
|
8022
|
+
return;
|
|
8023
|
+
}
|
|
8024
|
+
if (action !== "search") throw new CliError("UNKNOWN_COMMAND", `Unknown action: google geo-locations ${action}`, "Available: search");
|
|
8025
|
+
data = await searchGoogleGeoLocations(client, restArgs, flags);
|
|
8026
|
+
emptyHint = "No matching Google locations found. Try a broader place name or country filter.";
|
|
8027
|
+
break;
|
|
8028
|
+
}
|
|
7981
8029
|
default:
|
|
7982
|
-
throw new CliError("UNKNOWN_COMMAND", `Unknown entity: google ${entity}`, "Available: accounts, assets, media, campaigns, ad-groups, ads, keywords, conversions, results, change-history, research");
|
|
8030
|
+
throw new CliError("UNKNOWN_COMMAND", `Unknown entity: google ${entity}`, "Available: accounts, assets, media, campaigns, ad-groups, ads, keywords, conversions, results, change-history, research, geo-locations");
|
|
7983
8031
|
}
|
|
7984
8032
|
} else if (platform2 === "tiktok") {
|
|
7985
8033
|
switch (entity) {
|
package/package.json
CHANGED