@adkit/cli 1.13.4 → 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 +87 -25
- 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);
|
|
@@ -3211,10 +3224,10 @@ var CAMPAIGN_LIST_FLAGS3 = ["campaign-ids", "limit", "offset"];
|
|
|
3211
3224
|
var AD_GROUP_LIST_FLAGS3 = ["campaign-ids", "ad-group-ids", "limit", "offset"];
|
|
3212
3225
|
var AD_LIST_FLAGS3 = ["campaign-ids", "limit", "offset"];
|
|
3213
3226
|
var CAMPAIGN_CREATE_FLAGS3 = ["name", "status", "budget-daily", "budget-lifetime", "end-date"];
|
|
3214
|
-
var AD_GROUP_CREATE_FLAGS2 = ["campaign", "name", "objective", "status", "budget-daily", "budget-lifetime"];
|
|
3227
|
+
var AD_GROUP_CREATE_FLAGS2 = ["campaign", "name", "objective", "status", "budget-daily", "budget-lifetime", "bid-strategy", "optimization", "bid-amount"];
|
|
3215
3228
|
var AD_CREATE_FLAGS2 = ["ad-group", "existing-post", "name", "status"];
|
|
3216
3229
|
var CAMPAIGN_UPDATE_FLAGS3 = ["name", "status", "budget-lifetime", "end-date"];
|
|
3217
|
-
var AD_GROUP_UPDATE_FLAGS2 = ["name", "status", "budget-daily", "budget-lifetime", "start-date", "end-date"];
|
|
3230
|
+
var AD_GROUP_UPDATE_FLAGS2 = ["name", "status", "budget-daily", "budget-lifetime", "start-date", "end-date", "bid-strategy", "optimization", "bid-amount"];
|
|
3218
3231
|
var AD_UPDATE_FLAGS2 = ["name", "status"];
|
|
3219
3232
|
var TARGETING_SEARCH_FLAGS = ["account", "facet", "query", "limit"];
|
|
3220
3233
|
var RESULTS_FLAGS2 = ["level", "period", "fields", "breakdowns", "from", "to", "sort", "limit", "offset"];
|
|
@@ -3386,6 +3399,10 @@ function buildLinkedInAdGroupPayload(flags) {
|
|
|
3386
3399
|
const budget = buildLinkedInBudget(flags);
|
|
3387
3400
|
if (budget) payload.budget = budget;
|
|
3388
3401
|
if (typeof flags.objective === "string") payload.objective = flags.objective;
|
|
3402
|
+
if (typeof flags["bid-strategy"] === "string") payload.bidStrategy = flags["bid-strategy"];
|
|
3403
|
+
if (typeof flags.optimization === "string") payload.optimization = flags.optimization;
|
|
3404
|
+
const bidAmount = readNumberFlag3(flags, "bid-amount");
|
|
3405
|
+
if (bidAmount !== void 0) payload.bidAmount = bidAmount;
|
|
3389
3406
|
if (typeof flags.status === "string") payload.status = flags.status;
|
|
3390
3407
|
return payload;
|
|
3391
3408
|
}
|
|
@@ -3415,6 +3432,10 @@ function buildLinkedInAdGroupUpdatePayload(flags) {
|
|
|
3415
3432
|
if (typeof flags["end-date"] === "string") payload.endDate = flags["end-date"];
|
|
3416
3433
|
const budget = buildLinkedInBudget(flags);
|
|
3417
3434
|
if (budget) payload.budget = budget;
|
|
3435
|
+
if (typeof flags["bid-strategy"] === "string") payload.bidStrategy = flags["bid-strategy"];
|
|
3436
|
+
if (typeof flags.optimization === "string") payload.optimization = flags.optimization;
|
|
3437
|
+
const bidAmount = readNumberFlag3(flags, "bid-amount");
|
|
3438
|
+
if (bidAmount !== void 0) payload.bidAmount = bidAmount;
|
|
3418
3439
|
return payload;
|
|
3419
3440
|
}
|
|
3420
3441
|
function buildLinkedInAdUpdatePayload(flags) {
|
|
@@ -4737,7 +4758,7 @@ Flags (create \u2014 new creative from media):
|
|
|
4737
4758
|
--media <path|url> Media file or URL (repeatable). Handles upload + processing automatically for single-image/video ads
|
|
4738
4759
|
--primary-text <t> Ad body text (repeatable)
|
|
4739
4760
|
--headline <text> Headline text (repeatable)
|
|
4740
|
-
--description <t>
|
|
4761
|
+
--link-description <t> Link preview subtitle (repeatable, optional)
|
|
4741
4762
|
${FLAG.cta}
|
|
4742
4763
|
--name <name> Ad name
|
|
4743
4764
|
--url <url> Landing page URL
|
|
@@ -4799,7 +4820,7 @@ Flags (create \u2014 new creative from media):
|
|
|
4799
4820
|
--media-format <f> Optional format for each --media: default, square, vertical, horizontal
|
|
4800
4821
|
--primary-text <t> Ad body text (repeatable)
|
|
4801
4822
|
--headline <text> Headline text (repeatable)
|
|
4802
|
-
--description <t>
|
|
4823
|
+
--link-description <t> Link preview subtitle (repeatable, optional)
|
|
4803
4824
|
${FLAG.cta}
|
|
4804
4825
|
--name <name> Ad name
|
|
4805
4826
|
--url <url> Landing page URL
|
|
@@ -4835,6 +4856,7 @@ Note:
|
|
|
4835
4856
|
media [{ id: "imageHashOrVideoId" }, { id: "...", format: "vertical" }]
|
|
4836
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).
|
|
4837
4858
|
Do not use top-level media for carousel ads.
|
|
4859
|
+
linkDescriptions Link-preview subtitle copy for feed ads.
|
|
4838
4860
|
carouselCards
|
|
4839
4861
|
Card list for carousel ads. Each card needs headline and media.
|
|
4840
4862
|
carouselCards[].headline
|
|
@@ -5136,7 +5158,8 @@ Flags (list):
|
|
|
5136
5158
|
|
|
5137
5159
|
Note:
|
|
5138
5160
|
list returns campaign configuration only (name, status, budget).
|
|
5139
|
-
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.
|
|
5140
5163
|
Advanced geo examples: adkit manage google campaigns --help full
|
|
5141
5164
|
Display creation starts here: campaigns create --campaign-type display, then create Display ad groups and responsive_display ads.
|
|
5142
5165
|
Performance Max: campaignType "performance_max" with asset groups \u2014 build it with --data. See --help full.
|
|
@@ -5187,9 +5210,9 @@ Flags (list):
|
|
|
5187
5210
|
Notes:
|
|
5188
5211
|
Use google assets for explicit account/campaign/ad-group attachment, reusable libraries, or richer sitelinks via --data.
|
|
5189
5212
|
list returns campaign configuration only (name, status, budget).
|
|
5190
|
-
Geo targeting lives in targeting.geoLocations. Use type=country for
|
|
5191
|
-
|
|
5192
|
-
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.
|
|
5193
5216
|
Display campaign creation uses campaignType:"display" or --campaign-type display. Videos are not supported for Display media in v1.
|
|
5194
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.
|
|
5195
5218
|
View a Performance Max campaign by ID to read back assetGroups from Google. There is no separate google asset-groups command.
|
|
@@ -5199,7 +5222,7 @@ Examples:
|
|
|
5199
5222
|
adkit manage google campaigns list --account 1234567890
|
|
5200
5223
|
adkit manage google campaigns create --name "Display Prospecting" --campaign-type display --budget-daily 50 --account 1234567890
|
|
5201
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
|
|
5202
|
-
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
|
|
5203
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
|
|
5204
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
|
|
5205
5228
|
adkit manage google campaigns update 987654321 --status paused --account 1234567890
|
|
@@ -5723,6 +5746,24 @@ Notes:
|
|
|
5723
5746
|
Topic search returns IDs for targeting.content.topics.include/exclude.
|
|
5724
5747
|
Interest search returns IDs for targeting.audience.interests.include/exclude.
|
|
5725
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.`;
|
|
5726
5767
|
var GOOGLE_MEDIA_HELP = `adkit manage google media \u2014 Upload creative media to Google Ads
|
|
5727
5768
|
|
|
5728
5769
|
upload Upload an image and return reusable Google asset IDs
|
|
@@ -5833,6 +5874,7 @@ Examples:
|
|
|
5833
5874
|
"google results keywords": GOOGLE_RESULTS_KEYWORDS_HELP,
|
|
5834
5875
|
"google change-history": GOOGLE_CHANGE_HISTORY_HELP,
|
|
5835
5876
|
"google research": GOOGLE_RESEARCH_HELP,
|
|
5877
|
+
"google geo-locations": GOOGLE_GEO_LOCATIONS_HELP,
|
|
5836
5878
|
"google media": GOOGLE_MEDIA_HELP,
|
|
5837
5879
|
"google conversions": GOOGLE_CONVERSIONS_HELP,
|
|
5838
5880
|
"tiktok accounts": `adkit manage tiktok accounts \u2014 TikTok Ads accounts
|
|
@@ -6020,7 +6062,7 @@ Examples:
|
|
|
6020
6062
|
|
|
6021
6063
|
list List ad groups
|
|
6022
6064
|
create Create an ad group draft
|
|
6023
|
-
update <id> Update an ad group (rename,
|
|
6065
|
+
update <id> Update an ad group (rename, status, budget, bidding, dates, targeting)
|
|
6024
6066
|
<id> View ad group details
|
|
6025
6067
|
|
|
6026
6068
|
Naming note:
|
|
@@ -6037,10 +6079,13 @@ ${FLAG.data}
|
|
|
6037
6079
|
--ad-group-ids <ids> Comma-separated ad group IDs for filtered reads
|
|
6038
6080
|
--campaign <id> Parent campaign ID (create only)
|
|
6039
6081
|
--name <name> Ad group name
|
|
6040
|
-
--objective <type> brand_awareness, engagement, website_visits, video_views, website_conversions
|
|
6082
|
+
--objective <type> brand_awareness, engagement, website_visits, video_views, website_conversions, lead_generation
|
|
6041
6083
|
--status <s> create: active or draft (defaults to draft). update: active, paused, or archived
|
|
6042
6084
|
--budget-daily <n> Daily budget in account currency
|
|
6043
6085
|
--budget-lifetime <n> Lifetime budget in account currency
|
|
6086
|
+
--bid-strategy <s> maximum_delivery, manual, target_cost, cost_cap
|
|
6087
|
+
--optimization <s> clicks, impressions, conversions, video_views, leads, qualified_leads, reach
|
|
6088
|
+
--bid-amount <n> Bid/target/cap in account currency; required except for maximum_delivery
|
|
6044
6089
|
--start-date <date> YYYY-MM-DD (update only)
|
|
6045
6090
|
--end-date <date> YYYY-MM-DD (update only)
|
|
6046
6091
|
|
|
@@ -6053,9 +6098,12 @@ Targeting (--data only):
|
|
|
6053
6098
|
|
|
6054
6099
|
Notes:
|
|
6055
6100
|
A live ad group can never go back to draft. targeting on update is a full replace (send the whole targeting object via --data).
|
|
6101
|
+
Explicit bidding on create requires a compatible --objective. Bidding changes are atomic: send --bid-strategy and --optimization together. manual, target_cost, and cost_cap also require --bid-amount; maximum_delivery rejects it.
|
|
6102
|
+
LinkedIn further constrains bidding by objective and creative format.
|
|
6056
6103
|
|
|
6057
6104
|
Examples:
|
|
6058
6105
|
adkit manage linkedin ad-groups create --campaign 628940516 --name "US Broad" --budget-daily 50 --objective website_visits
|
|
6106
|
+
adkit manage linkedin ad-groups create --campaign 628940516 --name "US Manual CPC" --objective website_visits --bid-strategy manual --optimization clicks --bid-amount 8
|
|
6059
6107
|
adkit manage linkedin ad-groups update 361387516 --account 512345678 --status paused
|
|
6060
6108
|
adkit manage linkedin ad-groups create --data '{"adGroups":[{"campaignId":"628940516","name":"US Senior Eng","budget":{"daily":50},"targeting":{"geoLocations":{"include":[{"type":"country","code":"103644278"}]},"audience":{"seniorities":{"include":["6"]},"customAudiences":{"include":["123456"]}}}}]}'`.trim(),
|
|
6061
6109
|
"linkedin ads": `adkit manage linkedin ads \u2014 LinkedIn ads
|
|
@@ -6260,6 +6308,7 @@ Entity groups:
|
|
|
6260
6308
|
results Performance metrics (campaigns, ad-groups, ads, keywords, search-terms)
|
|
6261
6309
|
change-history Recent Google Ads account changes from the last 30 days
|
|
6262
6310
|
research Keyword Planner plus Display topic/interest IDs
|
|
6311
|
+
geo-locations Find Google location codes for campaign targeting
|
|
6263
6312
|
assets Manage reusable assets (sitelinks, callouts, structured snippets, images)
|
|
6264
6313
|
media Upload images for Display creative media
|
|
6265
6314
|
|
|
@@ -6601,6 +6650,7 @@ var HELP_FULL = {
|
|
|
6601
6650
|
"google results keywords": GOOGLE_RESULTS_KEYWORDS_HELP,
|
|
6602
6651
|
"google change-history": GOOGLE_CHANGE_HISTORY_HELP,
|
|
6603
6652
|
"google research": GOOGLE_RESEARCH_HELP,
|
|
6653
|
+
"google geo-locations": GOOGLE_GEO_LOCATIONS_HELP,
|
|
6604
6654
|
"google media": GOOGLE_MEDIA_HELP,
|
|
6605
6655
|
"google conversions": GOOGLE_CONVERSIONS_HELP,
|
|
6606
6656
|
"meta research": META_RESEARCH_HELP,
|
|
@@ -6937,15 +6987,17 @@ function printSingleEntity(e, entity) {
|
|
|
6937
6987
|
const creative = ad.creative;
|
|
6938
6988
|
if (creative) {
|
|
6939
6989
|
lines.push("", " Creative", "");
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
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)}`);
|
|
6944
6998
|
if (creative.cta) lines.push(` CTA: ${formatForTTY(creative.cta)}`);
|
|
6945
|
-
if (creative.
|
|
6946
|
-
if (
|
|
6947
|
-
if (creative.thumbnailUrl) lines.push(` Thumbnail: ${formatForTTY(creative.thumbnailUrl)}`);
|
|
6948
|
-
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)}`);
|
|
6949
7001
|
}
|
|
6950
7002
|
if (createdAt) lines.push(` Created: ${createdAt}`);
|
|
6951
7003
|
}
|
|
@@ -7964,8 +8016,18 @@ async function main() {
|
|
|
7964
8016
|
}
|
|
7965
8017
|
break;
|
|
7966
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
|
+
}
|
|
7967
8029
|
default:
|
|
7968
|
-
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");
|
|
7969
8031
|
}
|
|
7970
8032
|
} else if (platform2 === "tiktok") {
|
|
7971
8033
|
switch (entity) {
|
package/package.json
CHANGED