amazonads-cli 0.1.0
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 +136 -0
- package/build/amazon-ads-client.d.ts +29 -0
- package/build/amazon-ads-client.d.ts.map +1 -0
- package/build/amazon-ads-client.js +323 -0
- package/build/amazon-ads-client.js.map +1 -0
- package/build/commands/ads.d.ts +6 -0
- package/build/commands/ads.d.ts.map +1 -0
- package/build/commands/ads.js +49 -0
- package/build/commands/ads.js.map +1 -0
- package/build/commands/auth.d.ts +3 -0
- package/build/commands/auth.d.ts.map +1 -0
- package/build/commands/auth.js +176 -0
- package/build/commands/auth.js.map +1 -0
- package/build/commands/campaigns.d.ts +6 -0
- package/build/commands/campaigns.d.ts.map +1 -0
- package/build/commands/campaigns.js +175 -0
- package/build/commands/campaigns.js.map +1 -0
- package/build/commands/keywords.d.ts +6 -0
- package/build/commands/keywords.d.ts.map +1 -0
- package/build/commands/keywords.js +79 -0
- package/build/commands/keywords.js.map +1 -0
- package/build/commands/profiles.d.ts +4 -0
- package/build/commands/profiles.d.ts.map +1 -0
- package/build/commands/profiles.js +32 -0
- package/build/commands/profiles.js.map +1 -0
- package/build/commands/reports.d.ts +6 -0
- package/build/commands/reports.d.ts.map +1 -0
- package/build/commands/reports.js +37 -0
- package/build/commands/reports.js.map +1 -0
- package/build/config.d.ts +13 -0
- package/build/config.d.ts.map +1 -0
- package/build/config.js +54 -0
- package/build/config.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +42 -0
- package/build/index.js.map +1 -0
- package/build/output.d.ts +8 -0
- package/build/output.d.ts.map +1 -0
- package/build/output.js +45 -0
- package/build/output.js.map +1 -0
- package/package.json +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Amazon Ads CLI
|
|
2
|
+
|
|
3
|
+
A command-line interface for the Amazon Ads API. Manage campaigns, keywords, and product ads directly from your terminal.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/cprice70/amazonads-cli.git
|
|
9
|
+
cd amazonads-cli
|
|
10
|
+
npm install
|
|
11
|
+
npm run build
|
|
12
|
+
npm link
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Authentication
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
amazonads auth login
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
This will prompt for your Amazon Ads API Client ID and Client Secret, open a browser to complete OAuth, and save credentials to `~/.config/amazonads-cli/config.json`.
|
|
22
|
+
|
|
23
|
+
You can also create the config file manually:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"clientId": "amzn1.application-oa2-client.xxxxxxxxxxxx",
|
|
28
|
+
"clientSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
29
|
+
"refreshToken": "Atzr|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
30
|
+
"region": "NA",
|
|
31
|
+
"sandbox": false,
|
|
32
|
+
"defaultProfileId": "1234567890"
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
| Field | Values | Notes |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `clientId` | `amzn1.application-oa2-client.xxx` | From Amazon Ads API console |
|
|
39
|
+
| `clientSecret` | string | From Amazon Ads API console |
|
|
40
|
+
| `refreshToken` | `Atzr\|xxx` | Obtained via `auth login` or existing token |
|
|
41
|
+
| `region` | `NA`, `EU`, `FE` | North America, Europe, Far East |
|
|
42
|
+
| `sandbox` | `true` / `false` | Use test API endpoint |
|
|
43
|
+
| `defaultProfileId` | numeric string | Avoids needing `--profile` on every command |
|
|
44
|
+
|
|
45
|
+
Environment variables override the config file: `AMAZON_ADS_CLIENT_ID`, `AMAZON_ADS_CLIENT_SECRET`, `AMAZON_ADS_REFRESH_TOKEN`, `AMAZON_ADS_REGION`, `AMAZON_ADS_SANDBOX`, `AMAZON_ADS_PROFILE_ID`.
|
|
46
|
+
|
|
47
|
+
## Commands
|
|
48
|
+
|
|
49
|
+
### Auth
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
amazonads auth login # OAuth login, saves credentials
|
|
53
|
+
amazonads auth status # Show current config (masked)
|
|
54
|
+
amazonads auth logout # Delete config file
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Profiles
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
amazonads profiles
|
|
61
|
+
amazonads profiles --json
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Lists all advertising profiles on your account. Run this first to get profile IDs.
|
|
65
|
+
|
|
66
|
+
### Campaigns
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# List campaigns
|
|
70
|
+
amazonads campaigns list --profile <id>
|
|
71
|
+
amazonads campaigns list --profile <id> --state enabled
|
|
72
|
+
amazonads campaigns list --profile <id> --type sponsoredBrands
|
|
73
|
+
amazonads campaigns list --profile <id> --json
|
|
74
|
+
|
|
75
|
+
# Campaign performance report (async — may return a report ID if still processing)
|
|
76
|
+
amazonads campaigns performance --profile <id> --campaign <id> --start 2024-01-01 --end 2024-01-31
|
|
77
|
+
|
|
78
|
+
# Create a campaign (always created in PAUSED state)
|
|
79
|
+
amazonads campaigns create \
|
|
80
|
+
--profile <id> \
|
|
81
|
+
--name "My Campaign" \
|
|
82
|
+
--type sponsoredProducts \
|
|
83
|
+
--targeting MANUAL \
|
|
84
|
+
--budget 10.00 \
|
|
85
|
+
--start 2024-07-01
|
|
86
|
+
|
|
87
|
+
# Archive a campaign
|
|
88
|
+
amazonads campaigns archive --profile <id> --campaign <id> --type sponsoredProducts
|
|
89
|
+
amazonads campaigns archive --profile <id> --campaign <id> --type sponsoredProducts --confirm
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Campaign types:** `sponsoredProducts`, `sponsoredBrands`, `sponsoredDisplay`
|
|
93
|
+
|
|
94
|
+
### Keywords
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# List keywords
|
|
98
|
+
amazonads keywords list --profile <id>
|
|
99
|
+
amazonads keywords list --profile <id> --campaign <campaign-id>
|
|
100
|
+
amazonads keywords list --profile <id> --campaign <campaign-id> --ad-group <ad-group-id>
|
|
101
|
+
|
|
102
|
+
# Update keyword bid
|
|
103
|
+
amazonads keywords update-bid --profile <id> --keyword <keyword-id> --bid 1.25
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Product Ads
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
amazonads product-ads list --profile <id>
|
|
110
|
+
amazonads product-ads list --profile <id> --campaign <campaign-id>
|
|
111
|
+
amazonads product-ads list --profile <id> --campaign <campaign-id> --ad-group <ad-group-id>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Reports
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Check status of / download a report by ID
|
|
118
|
+
amazonads reports get --profile <id> --report <report-id>
|
|
119
|
+
amazonads reports get --profile <id> --report <report-id> --json
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Use this to retrieve a pending report returned by `campaigns performance`.
|
|
123
|
+
|
|
124
|
+
## Output
|
|
125
|
+
|
|
126
|
+
All commands support `--json` to output raw API responses instead of a formatted table.
|
|
127
|
+
|
|
128
|
+
## Development
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npm run build # Compile TypeScript
|
|
132
|
+
npm run test # Run tests
|
|
133
|
+
npm run watch # Watch mode
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Requires Node.js 18+.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface AmazonAdsConfig {
|
|
2
|
+
clientId?: string;
|
|
3
|
+
clientSecret?: string;
|
|
4
|
+
refreshToken?: string;
|
|
5
|
+
region?: string;
|
|
6
|
+
sandbox?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare class AmazonAdsClient {
|
|
9
|
+
private config;
|
|
10
|
+
private accessToken?;
|
|
11
|
+
private tokenExpiry?;
|
|
12
|
+
constructor(overrides?: Partial<AmazonAdsConfig>);
|
|
13
|
+
private getEndpoint;
|
|
14
|
+
private ensureAccessToken;
|
|
15
|
+
private sleep;
|
|
16
|
+
private isRetryableError;
|
|
17
|
+
private makeRequest;
|
|
18
|
+
getProfiles(): Promise<unknown>;
|
|
19
|
+
getCampaigns(profileId: string, state?: string, campaignType?: string): Promise<unknown>;
|
|
20
|
+
getCampaignPerformance(profileId: string, campaignId: string, startDate: string, endDate: string): Promise<unknown>;
|
|
21
|
+
private downloadReport;
|
|
22
|
+
getReport(profileId: string, reportId: string): Promise<unknown>;
|
|
23
|
+
getKeywords(profileId: string, campaignId?: string, adGroupId?: string): Promise<unknown>;
|
|
24
|
+
updateKeywordBid(profileId: string, keywordId: string, bid: number): Promise<unknown>;
|
|
25
|
+
createCampaign(profileId: string, name: string, campaignType: string, targetingType: string, dailyBudget: number, startDate: string): Promise<unknown>;
|
|
26
|
+
getProductAds(profileId: string, campaignId?: string, adGroupId?: string): Promise<unknown>;
|
|
27
|
+
archiveCampaign(profileId: string, campaignId: string, campaignType: string): Promise<unknown>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=amazon-ads-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amazon-ads-client.d.ts","sourceRoot":"","sources":["../src/amazon-ads-client.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAC,CAAS;gBAEjB,SAAS,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAYhD,OAAO,CAAC,WAAW;YAmBL,iBAAiB;YAwCjB,KAAK;IAInB,OAAO,CAAC,gBAAgB;YAKV,WAAW;IA2EnB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,OAAO,CAAC;IAsBb,sBAAsB,CAC1B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC;YAoFL,cAAc;IAYtB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA8BhE,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC;IAiBb,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,OAAO,CAAC;IAcb,cAAc,CAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC;IA8Bb,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC;IAiBb,eAAe,CACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC;CAqBpB"}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import zlib from "zlib";
|
|
2
|
+
import { promisify } from "util";
|
|
3
|
+
const gunzip = promisify(zlib.gunzip);
|
|
4
|
+
export class AmazonAdsClient {
|
|
5
|
+
config;
|
|
6
|
+
accessToken;
|
|
7
|
+
tokenExpiry;
|
|
8
|
+
constructor(overrides) {
|
|
9
|
+
// Load configuration from environment variables, then apply overrides
|
|
10
|
+
this.config = {
|
|
11
|
+
clientId: process.env.AMAZON_ADS_CLIENT_ID,
|
|
12
|
+
clientSecret: process.env.AMAZON_ADS_CLIENT_SECRET,
|
|
13
|
+
refreshToken: process.env.AMAZON_ADS_REFRESH_TOKEN,
|
|
14
|
+
region: process.env.AMAZON_ADS_REGION || "NA",
|
|
15
|
+
sandbox: process.env.AMAZON_ADS_SANDBOX === "true",
|
|
16
|
+
...overrides,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
getEndpoint() {
|
|
20
|
+
const { region, sandbox } = this.config;
|
|
21
|
+
if (sandbox) {
|
|
22
|
+
return "https://advertising-api-test.amazon.com";
|
|
23
|
+
}
|
|
24
|
+
switch (region) {
|
|
25
|
+
case "NA":
|
|
26
|
+
return "https://advertising-api.amazon.com";
|
|
27
|
+
case "EU":
|
|
28
|
+
return "https://advertising-api-eu.amazon.com";
|
|
29
|
+
case "FE":
|
|
30
|
+
return "https://advertising-api-fe.amazon.com";
|
|
31
|
+
default:
|
|
32
|
+
return "https://advertising-api.amazon.com";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async ensureAccessToken() {
|
|
36
|
+
// Check if we have a valid access token
|
|
37
|
+
if (this.accessToken && this.tokenExpiry && Date.now() < this.tokenExpiry) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// Refresh the access token
|
|
41
|
+
const { clientId, clientSecret, refreshToken } = this.config;
|
|
42
|
+
if (!clientId || !clientSecret || !refreshToken) {
|
|
43
|
+
throw new Error("Missing Amazon Ads credentials. Please run 'amazonads auth login' or set AMAZON_ADS_CLIENT_ID, AMAZON_ADS_CLIENT_SECRET, and AMAZON_ADS_REFRESH_TOKEN environment variables.");
|
|
44
|
+
}
|
|
45
|
+
const tokenData = new URLSearchParams({
|
|
46
|
+
grant_type: "refresh_token",
|
|
47
|
+
refresh_token: refreshToken,
|
|
48
|
+
client_id: clientId,
|
|
49
|
+
client_secret: clientSecret,
|
|
50
|
+
});
|
|
51
|
+
const response = await fetch("https://api.amazon.com/auth/o2/token", {
|
|
52
|
+
method: "POST",
|
|
53
|
+
headers: {
|
|
54
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
55
|
+
},
|
|
56
|
+
body: tokenData.toString(),
|
|
57
|
+
});
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
const error = await response.text();
|
|
60
|
+
throw new Error(`Failed to refresh access token: ${error}`);
|
|
61
|
+
}
|
|
62
|
+
const data = await response.json();
|
|
63
|
+
this.accessToken = data.access_token;
|
|
64
|
+
this.tokenExpiry = Date.now() + (data.expires_in - 60) * 1000; // Refresh 1 minute before expiry
|
|
65
|
+
}
|
|
66
|
+
async sleep(ms) {
|
|
67
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
68
|
+
}
|
|
69
|
+
isRetryableError(status) {
|
|
70
|
+
// Retry on rate limit (429) and server errors (5xx)
|
|
71
|
+
return status === 429 || (status >= 500 && status < 600);
|
|
72
|
+
}
|
|
73
|
+
async makeRequest(method, path, profileId, body, contentType) {
|
|
74
|
+
await this.ensureAccessToken();
|
|
75
|
+
const url = `${this.getEndpoint()}${path}`;
|
|
76
|
+
const ct = contentType || "application/json";
|
|
77
|
+
const headers = {
|
|
78
|
+
"Authorization": `Bearer ${this.accessToken}`,
|
|
79
|
+
"Amazon-Advertising-API-ClientId": this.config.clientId,
|
|
80
|
+
};
|
|
81
|
+
// Only set Content-Type and Accept for requests with a body
|
|
82
|
+
if (body) {
|
|
83
|
+
headers["Content-Type"] = ct;
|
|
84
|
+
headers["Accept"] = ct;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
headers["Accept"] = "application/json";
|
|
88
|
+
}
|
|
89
|
+
if (profileId) {
|
|
90
|
+
headers["Amazon-Advertising-API-Scope"] = profileId;
|
|
91
|
+
}
|
|
92
|
+
const options = {
|
|
93
|
+
method,
|
|
94
|
+
headers,
|
|
95
|
+
};
|
|
96
|
+
if (body) {
|
|
97
|
+
options.body = JSON.stringify(body);
|
|
98
|
+
}
|
|
99
|
+
// Retry logic with exponential backoff
|
|
100
|
+
const maxRetries = 3;
|
|
101
|
+
let lastError = null;
|
|
102
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
103
|
+
const response = await fetch(url, options);
|
|
104
|
+
if (response.ok) {
|
|
105
|
+
// Handle empty responses (like DELETE)
|
|
106
|
+
const text = await response.text();
|
|
107
|
+
if (!text) {
|
|
108
|
+
return { success: true, campaignId: path.split("/").pop() };
|
|
109
|
+
}
|
|
110
|
+
return JSON.parse(text);
|
|
111
|
+
}
|
|
112
|
+
const errorText = await response.text();
|
|
113
|
+
// Check if we should retry
|
|
114
|
+
if (this.isRetryableError(response.status) && attempt < maxRetries) {
|
|
115
|
+
// Exponential backoff: 1s, 2s, 4s
|
|
116
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
117
|
+
// Check for Retry-After header
|
|
118
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
119
|
+
const waitTime = retryAfter ? parseInt(retryAfter, 10) * 1000 : delay;
|
|
120
|
+
await this.sleep(Math.min(waitTime, 10000)); // Cap at 10 seconds
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
lastError = new Error(`Amazon Ads API error (${response.status}): ${errorText}`);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
throw lastError || new Error("Request failed after retries");
|
|
127
|
+
}
|
|
128
|
+
async getProfiles() {
|
|
129
|
+
return this.makeRequest("GET", "/v2/profiles");
|
|
130
|
+
}
|
|
131
|
+
async getCampaigns(profileId, state, campaignType) {
|
|
132
|
+
// v3 API uses POST with filters in body
|
|
133
|
+
let path = "/sp/campaigns/list";
|
|
134
|
+
let contentType = "application/vnd.spcampaign.v3+json";
|
|
135
|
+
if (campaignType === "sponsoredBrands") {
|
|
136
|
+
path = "/sb/v4/campaigns/list";
|
|
137
|
+
contentType = "application/vnd.sbcampaignresource.v4+json";
|
|
138
|
+
}
|
|
139
|
+
else if (campaignType === "sponsoredDisplay") {
|
|
140
|
+
path = "/sd/campaigns/list";
|
|
141
|
+
contentType = "application/vnd.sdcampaign.v3+json";
|
|
142
|
+
}
|
|
143
|
+
const body = {};
|
|
144
|
+
if (state) {
|
|
145
|
+
body.stateFilter = { include: [state.toUpperCase()] };
|
|
146
|
+
}
|
|
147
|
+
return this.makeRequest("POST", path, profileId, body, contentType);
|
|
148
|
+
}
|
|
149
|
+
async getCampaignPerformance(profileId, campaignId, startDate, endDate) {
|
|
150
|
+
// v3 reporting API - create async report
|
|
151
|
+
const contentType = "application/vnd.createasyncreportrequest.v3+json";
|
|
152
|
+
const reportBody = {
|
|
153
|
+
name: `Campaign ${campaignId} Performance Report`,
|
|
154
|
+
startDate,
|
|
155
|
+
endDate,
|
|
156
|
+
configuration: {
|
|
157
|
+
adProduct: "SPONSORED_PRODUCTS",
|
|
158
|
+
groupBy: ["campaign"],
|
|
159
|
+
columns: [
|
|
160
|
+
"campaignId",
|
|
161
|
+
"campaignName",
|
|
162
|
+
"impressions",
|
|
163
|
+
"clicks",
|
|
164
|
+
"cost",
|
|
165
|
+
"spend",
|
|
166
|
+
"sales14d",
|
|
167
|
+
"purchases14d",
|
|
168
|
+
"unitsSoldClicks14d",
|
|
169
|
+
"clickThroughRate",
|
|
170
|
+
"costPerClick",
|
|
171
|
+
],
|
|
172
|
+
reportTypeId: "spCampaigns",
|
|
173
|
+
timeUnit: "SUMMARY",
|
|
174
|
+
format: "GZIP_JSON",
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
// Step 1: Create the report
|
|
178
|
+
const createResponse = await this.makeRequest("POST", "/reporting/reports", profileId, reportBody, contentType);
|
|
179
|
+
const reportId = createResponse.reportId;
|
|
180
|
+
// Step 2: Poll until report is ready (max 5 seconds)
|
|
181
|
+
const maxAttempts = 5;
|
|
182
|
+
const pollInterval = 1000; // 1 second
|
|
183
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
184
|
+
const statusResponse = await this.makeRequest("GET", `/reporting/reports/${reportId}`, profileId);
|
|
185
|
+
if (statusResponse.status === "COMPLETED" && statusResponse.url) {
|
|
186
|
+
// Step 3: Download and decompress the report
|
|
187
|
+
const reportData = await this.downloadReport(statusResponse.url);
|
|
188
|
+
// Filter to requested campaign if specified
|
|
189
|
+
if (campaignId && Array.isArray(reportData)) {
|
|
190
|
+
const filtered = reportData.filter((row) => String(row.campaignId) === campaignId);
|
|
191
|
+
return filtered.length > 0 ? filtered : reportData;
|
|
192
|
+
}
|
|
193
|
+
return reportData;
|
|
194
|
+
}
|
|
195
|
+
if (statusResponse.status === "FAILURE") {
|
|
196
|
+
throw new Error(`Report generation failed for reportId: ${reportId}`);
|
|
197
|
+
}
|
|
198
|
+
// Wait before next poll
|
|
199
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
200
|
+
}
|
|
201
|
+
// Return pending status with reportId so user can check later
|
|
202
|
+
return {
|
|
203
|
+
status: "PENDING",
|
|
204
|
+
message: `Report still processing after ${maxAttempts * pollInterval / 1000} seconds`,
|
|
205
|
+
reportId,
|
|
206
|
+
checkUrl: `/reporting/reports/${reportId}`,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
async downloadReport(url) {
|
|
210
|
+
const response = await fetch(url);
|
|
211
|
+
if (!response.ok) {
|
|
212
|
+
throw new Error(`Failed to download report: ${response.status}`);
|
|
213
|
+
}
|
|
214
|
+
const buffer = await response.arrayBuffer();
|
|
215
|
+
const decompressed = await gunzip(Buffer.from(buffer));
|
|
216
|
+
return JSON.parse(decompressed.toString("utf-8"));
|
|
217
|
+
}
|
|
218
|
+
async getReport(profileId, reportId) {
|
|
219
|
+
const statusResponse = await this.makeRequest("GET", `/reporting/reports/${reportId}`, profileId);
|
|
220
|
+
if (statusResponse.status === "COMPLETED" && statusResponse.url) {
|
|
221
|
+
const reportData = await this.downloadReport(statusResponse.url);
|
|
222
|
+
return {
|
|
223
|
+
status: "COMPLETED",
|
|
224
|
+
data: reportData,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
if (statusResponse.status === "FAILURE") {
|
|
228
|
+
return {
|
|
229
|
+
status: "FAILURE",
|
|
230
|
+
reason: statusResponse.failureReason || "Unknown error",
|
|
231
|
+
reportId,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
return {
|
|
235
|
+
status: statusResponse.status,
|
|
236
|
+
message: "Report still processing. Try again in a few seconds.",
|
|
237
|
+
reportId,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
async getKeywords(profileId, campaignId, adGroupId) {
|
|
241
|
+
const path = "/sp/keywords/list";
|
|
242
|
+
const contentType = "application/vnd.spkeyword.v3+json";
|
|
243
|
+
const body = {};
|
|
244
|
+
if (campaignId) {
|
|
245
|
+
body.campaignIdFilter = { include: [campaignId] };
|
|
246
|
+
}
|
|
247
|
+
if (adGroupId) {
|
|
248
|
+
body.adGroupIdFilter = { include: [adGroupId] };
|
|
249
|
+
}
|
|
250
|
+
return this.makeRequest("POST", path, profileId, body, contentType);
|
|
251
|
+
}
|
|
252
|
+
async updateKeywordBid(profileId, keywordId, bid) {
|
|
253
|
+
const contentType = "application/vnd.spkeyword.v3+json";
|
|
254
|
+
const body = {
|
|
255
|
+
keywords: [
|
|
256
|
+
{
|
|
257
|
+
keywordId,
|
|
258
|
+
bid,
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
};
|
|
262
|
+
return this.makeRequest("PUT", "/sp/keywords", profileId, body, contentType);
|
|
263
|
+
}
|
|
264
|
+
async createCampaign(profileId, name, campaignType, targetingType, dailyBudget, startDate) {
|
|
265
|
+
let path = "/sp/campaigns";
|
|
266
|
+
let contentType = "application/vnd.spcampaign.v3+json";
|
|
267
|
+
if (campaignType === "sponsoredBrands") {
|
|
268
|
+
path = "/sb/v4/campaigns";
|
|
269
|
+
contentType = "application/vnd.sbcampaignresource.v4+json";
|
|
270
|
+
}
|
|
271
|
+
else if (campaignType === "sponsoredDisplay") {
|
|
272
|
+
path = "/sd/campaigns";
|
|
273
|
+
contentType = "application/vnd.sdcampaign.v3+json";
|
|
274
|
+
}
|
|
275
|
+
const body = {
|
|
276
|
+
campaigns: [
|
|
277
|
+
{
|
|
278
|
+
name,
|
|
279
|
+
targetingType,
|
|
280
|
+
state: "PAUSED", // Default to PAUSED for safety - won't spend money
|
|
281
|
+
budget: {
|
|
282
|
+
budgetType: "DAILY",
|
|
283
|
+
budget: dailyBudget,
|
|
284
|
+
},
|
|
285
|
+
startDate,
|
|
286
|
+
},
|
|
287
|
+
],
|
|
288
|
+
};
|
|
289
|
+
return this.makeRequest("POST", path, profileId, body, contentType);
|
|
290
|
+
}
|
|
291
|
+
async getProductAds(profileId, campaignId, adGroupId) {
|
|
292
|
+
const path = "/sp/productAds/list";
|
|
293
|
+
const contentType = "application/vnd.spproductad.v3+json";
|
|
294
|
+
const body = {};
|
|
295
|
+
if (campaignId) {
|
|
296
|
+
body.campaignIdFilter = { include: [campaignId] };
|
|
297
|
+
}
|
|
298
|
+
if (adGroupId) {
|
|
299
|
+
body.adGroupIdFilter = { include: [adGroupId] };
|
|
300
|
+
}
|
|
301
|
+
return this.makeRequest("POST", path, profileId, body, contentType);
|
|
302
|
+
}
|
|
303
|
+
async archiveCampaign(profileId, campaignId, campaignType) {
|
|
304
|
+
// v3 API: DELETE endpoint with campaignIdFilter in body
|
|
305
|
+
let path = "/sp/campaigns/delete";
|
|
306
|
+
let contentType = "application/vnd.spcampaign.v3+json";
|
|
307
|
+
if (campaignType === "sponsoredBrands") {
|
|
308
|
+
path = "/sb/v4/campaigns/delete";
|
|
309
|
+
contentType = "application/vnd.sbcampaignresource.v4+json";
|
|
310
|
+
}
|
|
311
|
+
else if (campaignType === "sponsoredDisplay") {
|
|
312
|
+
path = "/sd/campaigns/delete";
|
|
313
|
+
contentType = "application/vnd.sdcampaign.v3+json";
|
|
314
|
+
}
|
|
315
|
+
const body = {
|
|
316
|
+
campaignIdFilter: {
|
|
317
|
+
include: [campaignId],
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
return this.makeRequest("POST", path, profileId, body, contentType);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=amazon-ads-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amazon-ads-client.js","sourceRoot":"","sources":["../src/amazon-ads-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { AmazonAdsClient } from "../amazon-ads-client.js";
|
|
3
|
+
export declare function registerAdsCommands(program: Command, client: AmazonAdsClient, resolveProfileId: (opts: {
|
|
4
|
+
profile?: string;
|
|
5
|
+
}) => string): void;
|
|
6
|
+
//# sourceMappingURL=ads.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ads.d.ts","sourceRoot":"","sources":["../../src/commands/ads.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAuB1D,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,eAAe,EACvB,gBAAgB,EAAE,CAAC,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,MAAM,GACvD,IAAI,CA0CN"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { printTable, printJson, printError, colorState } from "../output.js";
|
|
2
|
+
function resolveAds(data) {
|
|
3
|
+
if (Array.isArray(data))
|
|
4
|
+
return data;
|
|
5
|
+
const resp = data;
|
|
6
|
+
if (resp.productAds && Array.isArray(resp.productAds))
|
|
7
|
+
return resp.productAds;
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
10
|
+
export function registerAdsCommands(program, client, resolveProfileId) {
|
|
11
|
+
const productAds = program.command("product-ads").description("Manage product ads");
|
|
12
|
+
productAds
|
|
13
|
+
.command("list")
|
|
14
|
+
.description("List product ads")
|
|
15
|
+
.option("--profile <id>", "Profile ID")
|
|
16
|
+
.option("--campaign <id>", "Filter by campaign ID")
|
|
17
|
+
.option("--ad-group <id>", "Filter by ad group ID")
|
|
18
|
+
.option("--json", "Output as JSON")
|
|
19
|
+
.action(async (opts) => {
|
|
20
|
+
try {
|
|
21
|
+
const profileId = resolveProfileId(opts);
|
|
22
|
+
const data = await client.getProductAds(profileId, opts.campaign, opts.adGroup);
|
|
23
|
+
if (opts.json) {
|
|
24
|
+
printJson(data);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const list = resolveAds(data);
|
|
28
|
+
if (list.length === 0) {
|
|
29
|
+
console.log("No product ads found.");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const headers = ["Ad ID", "ASIN", "SKU", "State", "Campaign ID", "Ad Group ID"];
|
|
33
|
+
const rows = list.map((a) => [
|
|
34
|
+
String(a.adId || ""),
|
|
35
|
+
a.asin || "",
|
|
36
|
+
a.sku || "",
|
|
37
|
+
colorState(a.state || ""),
|
|
38
|
+
String(a.campaignId || ""),
|
|
39
|
+
String(a.adGroupId || ""),
|
|
40
|
+
]);
|
|
41
|
+
printTable(headers, rows);
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
printError(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=ads.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ads.js","sourceRoot":"","sources":["../../src/commands/ads.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAe7E,SAAS,UAAU,CAAC,IAAa;IAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,IAAmB,CAAC;IACpD,MAAM,IAAI,GAAG,IAA0B,CAAC;IACxC,IAAI,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC,UAAU,CAAC;IAC9E,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,OAAgB,EAChB,MAAuB,EACvB,gBAAwD;IAExD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC;IAEpF,UAAU;SACP,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,kBAAkB,CAAC;SAC/B,MAAM,CAAC,gBAAgB,EAAE,YAAY,CAAC;SACtC,MAAM,CAAC,iBAAiB,EAAE,uBAAuB,CAAC;SAClD,MAAM,CAAC,iBAAiB,EAAE,uBAAuB,CAAC;SAClD,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;SAClC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAEhF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,SAAS,CAAC,IAAI,CAAC,CAAC;gBAChB,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;gBACrC,OAAO;YACT,CAAC;YAED,MAAM,OAAO,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC;YAChF,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBAC3B,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;gBACpB,CAAC,CAAC,IAAI,IAAI,EAAE;gBACZ,CAAC,CAAC,GAAG,IAAI,EAAE;gBACX,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBACzB,MAAM,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC;gBAC1B,MAAM,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC;aAC1B,CAAC,CAAC;YAEH,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmL3D"}
|