n8n-nodes-adspirer 0.2.0 → 0.3.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.
Files changed (28) hide show
  1. package/README.md +164 -194
  2. package/dist/credentials/AdspireApi.credentials.js +9 -6
  3. package/dist/credentials/AdspireApi.credentials.js.map +1 -1
  4. package/dist/nodes/Adspirer/Adspirer.node.d.ts +9 -1
  5. package/dist/nodes/Adspirer/Adspirer.node.js +205 -69
  6. package/dist/nodes/Adspirer/Adspirer.node.js.map +1 -1
  7. package/dist/nodes/Adspirer/generated/tools.d.ts +22 -0
  8. package/dist/nodes/Adspirer/generated/tools.js +5608 -0
  9. package/dist/nodes/Adspirer/generated/tools.js.map +1 -0
  10. package/dist/nodes/Adspirer/shared/build-properties.d.ts +13 -0
  11. package/dist/nodes/Adspirer/shared/build-properties.js +192 -0
  12. package/dist/nodes/Adspirer/shared/build-properties.js.map +1 -0
  13. package/dist/nodes/Adspirer/shared/descriptions.d.ts +1 -3
  14. package/dist/nodes/Adspirer/shared/descriptions.js +3 -37
  15. package/dist/nodes/Adspirer/shared/descriptions.js.map +1 -1
  16. package/dist/nodes/Adspirer/shared/toolMapping.d.ts +12 -6
  17. package/dist/nodes/Adspirer/shared/toolMapping.js +48 -107
  18. package/dist/nodes/Adspirer/shared/toolMapping.js.map +1 -1
  19. package/package.json +8 -4
  20. package/dist/credentials/AdspireOAuth2Api.credentials.d.ts +0 -10
  21. package/dist/credentials/AdspireOAuth2Api.credentials.js +0 -53
  22. package/dist/credentials/AdspireOAuth2Api.credentials.js.map +0 -1
  23. package/dist/nodes/Adspirer/resources/googleAds.d.ts +0 -3
  24. package/dist/nodes/Adspirer/resources/googleAds.js +0 -279
  25. package/dist/nodes/Adspirer/resources/googleAds.js.map +0 -1
  26. package/dist/nodes/Adspirer/resources/metaAds.d.ts +0 -3
  27. package/dist/nodes/Adspirer/resources/metaAds.js +0 -120
  28. package/dist/nodes/Adspirer/resources/metaAds.js.map +0 -1
package/README.md CHANGED
@@ -3,83 +3,35 @@
3
3
  [![npm](https://img.shields.io/npm/v/n8n-nodes-adspirer)](https://www.npmjs.com/package/n8n-nodes-adspirer)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE.md)
5
5
 
6
- [n8n](https://n8n.io/) community node for [Adspirer](https://adspirer.ai) — automate ad campaign management across Google Ads, Meta Ads, LinkedIn Ads, and TikTok Ads.
6
+ [n8n](https://n8n.io/) community node for [Adspirer](https://adspirer.ai) — orchestrate ad campaigns across **Google Ads, Meta, LinkedIn, and TikTok** from any n8n workflow.
7
7
 
8
- Skip the dashboard. Build n8n workflows that monitor performance, optimize budgets, create campaigns, and alert your teamall on autopilot.
8
+ Pick a platform, pick an operation, plug in your API key n8n does the rest.
9
9
 
10
10
  <p align="center">
11
11
  <img src="icons/adspirer.svg" alt="Adspirer" width="80" />
12
12
  </p>
13
13
 
14
- ## What is Adspirer?
14
+ ## Features
15
15
 
16
- Adspirer is an MCP (Model Context Protocol) server with **100+ advertising tools** across 4 ad platforms. It lets AI assistants manage ad campaigns through natural language — no dashboards needed.
17
-
18
- This n8n community node brings those same tools into n8n's workflow automation platform, so you can build automated ad workflows that run on schedules, respond to events, or power AI agents.
19
-
20
- **MCP Server:** [`https://mcp.adspirer.com/mcp`](https://mcp.adspirer.com/mcp)
21
- **MCP Registry:** [`com.adspirer/ads`](https://registry.modelcontextprotocol.io)
22
- **Plugin Repo:** [`amekala/ads-mcp`](https://github.com/amekala/ads-mcp)
23
-
24
- ## Operations
25
-
26
- ### Google Ads (7 operations)
27
-
28
- | Operation | Description |
29
- |-----------|-------------|
30
- | **Budget Optimization** | Get budget allocation and optimization recommendations |
31
- | **Campaign Performance** | Get performance metrics for all campaigns over a date range |
32
- | **Create PMax Campaign** | Create a new Performance Max campaign with assets |
33
- | **Create Search Campaign** | Create a new Google Search campaign with keywords and ads |
34
- | **Keyword Research** | Research keywords with real CPC, search volume, and competition data |
35
- | **Search Terms Analysis** | Analyze search term performance and find negative keyword opportunities |
36
- | **Wasted Spend Analysis** | Identify wasted ad spend and get optimization recommendations |
37
-
38
- ### Meta Ads (3 operations)
39
-
40
- | Operation | Description |
41
- |-----------|-------------|
42
- | **Ad Performance** | Analyze individual ad and creative performance with fatigue detection |
43
- | **Audience Insights** | Get audience demographics, placement analysis, and targeting insights |
44
- | **Campaign Performance** | Get performance metrics for Meta ad campaigns |
45
-
46
- ### AI Agent Compatible
47
-
48
- All operations are available as AI agent tools (`usableAsTool: true`). Add the Adspirer node as a tool to any n8n AI Agent and it can call any operation based on natural language instructions.
49
-
50
- ## Authentication
51
-
52
- ### OAuth2 (Recommended)
53
-
54
- 1. Add the Adspirer node to your workflow
55
- 2. Select **OAuth2 (Recommended)** authentication
56
- 3. Click **Connect** — a browser window opens for OAuth authorization
57
- 4. Sign in with your [Adspirer account](https://adspirer.ai) and authorize access
58
- 5. Your credentials are saved — all future workflows use the same connection
59
-
60
- No API keys to manage. OAuth tokens refresh automatically.
61
-
62
- ### API Key
63
-
64
- 1. Sign up at [adspirer.ai](https://adspirer.ai) (free tier: 15 tool calls/month)
65
- 2. Get your API key from your account settings
66
- 3. Add the Adspirer node to your workflow
67
- 4. Select **API Key** authentication
68
- 5. Paste your API key
16
+ - **~120 operations** across 5 resource groups: Google Ads, Meta Ads, LinkedIn Ads, TikTok Ads, and Utility diagnostics
17
+ - **REST-native** — calls `https://api.adspirer.ai` via standard HTTP + Bearer auth. No SSE, no JSON-RPC
18
+ - **Quota-aware** every response includes your remaining monthly allowance in `$item.json._adspirer_quota`
19
+ - **Idempotency built-in** — write operations automatically send an `Idempotency-Key` so retries don't double-charge you or duplicate campaigns
20
+ - **AI Agent compatible** — set `usableAsTool: true`, surfaces directly in n8n's AI Agent tool picker
21
+ - **Upgrade-aware errors** — a 402 quota response surfaces the Adspirer upgrade URL directly in the node's error output
69
22
 
70
23
  ## Installation
71
24
 
72
- ### n8n Community Nodes (Recommended)
25
+ ### n8n (Cloud or self-hosted)
73
26
 
74
27
  1. Open your n8n instance
75
- 2. Go to **Settings > Community Nodes**
76
- 3. Click **Install a community node**
77
- 4. Enter `n8n-nodes-adspirer`
78
- 5. Click **Install**
28
+ 2. **Settings Community Nodes → Install a community node**
29
+ 3. Enter `n8n-nodes-adspirer`
30
+ 4. Click **Install** — the node appears in the nodes panel under "Adspirer"
79
31
 
80
- The Adspirer node appears in the nodes panel, searchable by "Adspirer", "ads", "Google Ads", "Meta Ads", "campaign", "keyword research", or "ppc".
32
+ The node is searchable by: `Adspirer`, `ads`, `Google Ads`, `Meta Ads`, `LinkedIn Ads`, `TikTok Ads`, `campaign`, `keyword research`, `ppc`.
81
33
 
82
- ### Self-Hosted / Docker
34
+ ### Self-hosted via npm
83
35
 
84
36
  ```bash
85
37
  cd ~/.n8n
@@ -87,140 +39,168 @@ npm install n8n-nodes-adspirer
87
39
  # Restart n8n
88
40
  ```
89
41
 
90
- ### n8n Cloud
42
+ ## Authentication
43
+
44
+ The node uses an API key. There is currently no OAuth2 option — the hosted REST API doesn't expose public OAuth endpoints yet.
45
+
46
+ 1. Sign up at [adspirer.ai](https://adspirer.ai) — free tier includes 15 tool calls/month, no credit card
47
+ 2. Generate a key at [adspirer.ai/keys](https://adspirer.ai/keys) — keys are prefixed `sk_live_`, treat them as secrets
48
+ 3. In n8n: **Credentials → New → Adspirer API**, paste the key, save
49
+ 4. The credential test runs a free diagnostic call (`list_connected_accounts`) — expect a green ✓
50
+
51
+ ## Usage
52
+
53
+ After creating the credential:
54
+
55
+ 1. Drop the **Adspirer** node onto any workflow
56
+ 2. Pick a **Platform** — Google Ads, Meta Ads, LinkedIn Ads, TikTok Ads, or Utility
57
+ 3. Pick an **Operation** from the dropdown (operations are filtered by platform)
58
+ 4. Fill required fields. Optional fields can be left blank.
59
+ 5. Execute
60
+
61
+ Each successful execution returns:
62
+
63
+ ```json
64
+ {
65
+ "success": true,
66
+ "platform": "googleAds",
67
+ "operation": "listCampaigns",
68
+ "tool": "list_campaigns",
69
+ "text": "# 📋 Your Google Ads Campaigns\n\n**Total Campaigns:** 10\n...",
70
+ "structured": null,
71
+ "_adspirer_quota": {
72
+ "used": 8,
73
+ "limit": 150,
74
+ "tier": "plus",
75
+ "period_end": "2026-05-17"
76
+ }
77
+ }
78
+ ```
79
+
80
+ - **`text`** — human-readable markdown summary of the result
81
+ - **`structured`** — structured payload when the operation returns one (null otherwise)
82
+ - **`_adspirer_quota`** — branch on this in subsequent nodes to avoid hitting your monthly limit
83
+
84
+ ### Error handling
91
85
 
92
- Community nodes are available on n8n Cloud once verified. After verification, the node appears automatically in the nodes panel for all Cloud users.
86
+ | HTTP code | Meaning | Node behavior |
87
+ |---|---|---|
88
+ | `200` | Success | returns data |
89
+ | `400` | Tool-level error (e.g. missing account) | throws with the error message |
90
+ | `401` | Invalid/missing API key | throws with key-regeneration hint |
91
+ | `402` | Monthly quota exhausted | throws with `upgrade_url` appended to the message |
92
+ | `429` | Upstream ad platform rate-limited us | throws — enable **Retry on Fail** in node settings (30–60s backoff recommended) |
93
+ | `5xx` | Server error | throws — enable **Retry on Fail** in node settings |
93
94
 
94
- ## Example Workflows
95
+ Use n8n's per-node **Retry on Fail** setting instead of a custom backoff loop — it's the idiomatic pattern and compatible with n8n Cloud's verification requirements.
95
96
 
96
- ### 1. Daily Google Ads Performance Report to Slack
97
+ ## Example workflows
97
98
 
98
- Monitor campaign performance and get a summary in Slack every morning.
99
+ ### 1. Daily wasted-spend check across all platforms
99
100
 
100
101
  ```
101
- Schedule Trigger (daily 9am)
102
- → Adspirer: Campaign Performance (Google Ads, lookback: 1 day)
103
- → Adspirer: Campaign Performance (Meta Ads, lookback: 1 day)
104
- Code Node: merge and format cross-platform report
105
- Slack: post to #marketing channel
102
+ Schedule Trigger (daily 8am)
103
+ → Adspirer: Google Ads → Analyze Wasted Spend (lookback: 7)
104
+ → Adspirer: Meta Ads → Analyze Meta Wasted Spend (lookback: 7)
105
+ Adspirer: LinkedIn Ads Analyze LinkedIn Wasted Spend (lookback: 7)
106
+ Code: merge + threshold check
107
+ → IF > $50 wasted → Slack #marketing
106
108
  ```
107
109
 
108
- ### 2. Weekly Wasted Spend Alert
109
-
110
- Catch budget waste early with weekly automated analysis.
110
+ ### 2. New Shopify product → Google PMax campaign
111
111
 
112
112
  ```
113
- Schedule Trigger (every Monday 8am)
114
- → Adspirer: Wasted Spend Analysis (Google Ads, lookback: 7 days)
115
- → Adspirer: Budget Optimization (Google Ads, lookback: 7 days)
116
- IF Node: wasted spend > $50?
117
- Yes: Slack alert + Google Sheets log
118
- → No: skip
113
+ Shopify Trigger (new product)
114
+ → Adspirer: Google Ads Create PMax Campaign
115
+ (name: {{ $json.title }}, budget: 30, final_url: {{ $json.url }})
116
+ Slack: post campaign link
117
+ → Google Sheets: log in tracker
119
118
  ```
120
119
 
121
- ### 3. New Shopify Product Google PMax Campaign
122
-
123
- Automatically create ad campaigns when new products are added.
120
+ ### 3. Weekly cross-platform report to Google Sheets
124
121
 
125
122
  ```
126
- Shopify Trigger (new product created)
127
- → Adspirer: Create PMax Campaign (product name, URL, $30/day budget)
128
- Slack: notify marketing team with campaign details
129
- Google Sheets: log in campaign tracker
123
+ Schedule Trigger (Monday 9am)
124
+ → Adspirer: Google Ads Get Campaign Performance (lookback: 7)
125
+ Adspirer: Meta Ads Analyze Meta Ad Performance (lookback: 7)
126
+ Code: normalize metrics
127
+ → Google Sheets: append row
128
+ → Gmail: send to client
130
129
  ```
131
130
 
132
- ### 4. CRM Deal → Retargeting Campaign
131
+ ### 4. Quota-aware agent loop
133
132
 
134
- Launch retargeting when a deal moves to a new stage.
133
+ ```
134
+ Manual Trigger
135
+ → Adspirer: Utility → Get Usage Status
136
+ → IF _adspirer_quota.used < _adspirer_quota.limit * 0.8
137
+ Yes → AI Agent with Adspirer tool
138
+ No → Slack: "Quota near limit, skipping optimization run"
139
+ ```
140
+
141
+ ### 5. HubSpot deal won → LinkedIn retargeting
135
142
 
136
143
  ```
137
- HubSpot Trigger (deal stage changed to "Proposal Sent")
138
- → Adspirer: Keyword Research (brand + competitor terms)
139
- → Adspirer: Create Search Campaign (branded search, $20/day)
140
- Gmail: notify account manager
144
+ HubSpot Trigger (deal stage = "Closed Won")
145
+ → Adspirer: LinkedIn Ads → Add LinkedIn Creative (custom ad for customer)
146
+ → Adspirer: LinkedIn Ads Create LinkedIn Sponsored Content
147
+ Slack: notify account manager
141
148
  ```
142
149
 
143
- ### 5. AI Ad Manager in Slack
150
+ ## AI Agent usage
144
151
 
145
- Let your team manage ads through natural language in Slack.
152
+ Every Adspirer operation is available as an AI Agent tool (`usableAsTool: true`). Add the Adspirer node to an **AI Agent** node's tool slot, configure the agent's model (Claude / GPT-4 / etc.), and the agent can pick operations from natural-language instructions:
146
153
 
147
154
  ```
148
155
  Chat Trigger (Slack)
149
- → AI Agent (Claude / GPT-4)
150
- Adspirer node (all 10 operations available as tools)
151
- Google Sheets tool (for logging)
152
- → Slack: post response
156
+ → AI Agent (Claude)
157
+ tools: Adspirer, Google Sheets
158
+ Slack reply
153
159
  ```
154
160
 
155
- **Example conversation:**
156
- - "How are my Google Ads doing this week compared to last week?"
157
- - "Research keywords for emergency plumbing services in Chicago"
158
- - "Create a search campaign for luxury watches targeting New York with $50/day budget"
161
+ **Example prompts that work:**
162
+ - *"What are my top 3 Google Ads campaigns by ROAS this week?"*
163
+ - *"Find wasted spend across all my Meta ad sets over the last 30 days"*
164
+ - *"List all my connected ad accounts"*
159
165
 
160
- ### 6. Cross-Platform Weekly Report to Google Sheets
166
+ For **full agentic access to all ~180 Adspirer tools** (including ones that stream their response and aren't exposed by this REST-based node), use the [`n8n-nodes-mcp`](https://www.npmjs.com/package/n8n-nodes-mcp) community node pointed at `https://mcp.adspirer.com/mcp` with your `sk_live_` key as the Bearer token.
161
167
 
162
- Build a living dashboard with weekly performance data.
168
+ ## Operations summary
163
169
 
164
- ```
165
- Schedule Trigger (every Friday 5pm)
166
- Adspirer: Campaign Performance (Google Ads, 7 days)
167
- Adspirer: Campaign Performance (Meta Ads, 7 days)
168
- Code Node: normalize metrics across platforms
169
- Google Sheets: append to "Weekly Performance" sheet
170
- Gmail: send formatted report to client
171
- ```
170
+ | Platform | Exposed | Notes |
171
+ |---|---|---|
172
+ | Google Ads | ~28 | Analytics, search term / keyword research, campaign ops, demand-gen |
173
+ | Meta Ads | ~27 | Ad/audience analytics, campaign creation (single + carousel + DCO) |
174
+ | LinkedIn Ads | ~32 | Creatives, campaign groups, conversions, lead forms, wasted spend |
175
+ | TikTok Ads | ~20 | Campaign creation, geo/creative fatigue analytics |
176
+ | Utility | ~12 | Diagnostics: `list_connected_accounts`, `get_usage_status`, monitors, audits |
172
177
 
173
- ## Nodes That Pair Well With Adspirer
178
+ **~60 additional tools** (complex creatives, asset bundles, detailed audience targeting) are exposed via the [REST API](https://api.adspirer.ai/docs) directly — those use array/object argument shapes that don't flatten into n8n's field UI. Invoke them with n8n's built-in **HTTP Request** node pointed at `POST https://api.adspirer.ai/api/v1/tools/{tool_name}/execute` using the same Adspirer API credential.
174
179
 
175
- | Category | Nodes | Use Case |
176
- |----------|-------|----------|
177
- | **Triggers** | Schedule, Webhook, Cron | Start monitoring/reporting workflows |
178
- | **CRM** | HubSpot, Salesforce, Pipedrive | Deal events → campaign creation |
179
- | **E-commerce** | Shopify, WooCommerce, Stripe | Product/order events → ad campaigns |
180
- | **Messaging** | Slack, Gmail, Teams, Discord, Twilio | Alerts, reports, notifications |
181
- | **Spreadsheets** | Google Sheets, Airtable, Notion | Dashboards, logging, tracking |
182
- | **AI** | AI Agent, OpenAI, Anthropic | Natural language ad management |
183
- | **Logic** | IF, Switch, Code, Merge | Threshold checks, data formatting |
184
- | **Forms** | Typeform, Google Forms | Client briefs → campaign setup |
180
+ Live OpenAPI spec: https://api.adspirer.ai/openapi.json regenerated automatically whenever the surface changes upstream.
185
181
 
186
182
  ## Pricing
187
183
 
188
- Adspirer uses a freemium model. Tool calls in n8n count against your Adspirer plan limits:
189
-
190
- | Plan | Tool Calls/Month | Price |
191
- |------|-----------------|-------|
184
+ | Plan | Tool calls / month | Price |
185
+ |---|---|---|
192
186
  | Free | 15 | $0 |
193
187
  | Plus | 150 | $49/mo |
194
188
  | Pro | 600 | $99/mo |
195
189
  | Max | 3,000 | $199/mo |
196
190
 
197
- Sign up at [adspirer.ai](https://adspirer.ai). No credit card required for the free tier.
198
-
199
- ## Alternative: n8n Built-in MCP Nodes
191
+ Sign up at [adspirer.ai](https://adspirer.ai).
200
192
 
201
- If you prefer to use n8n's built-in MCP support (available since n8n v1.88.0) instead of this community node, you can connect directly to Adspirer's MCP server:
193
+ ## Related
202
194
 
203
- 1. Add the **MCP Client Tool** node as a sub-node to an AI Agent
204
- 2. Set Transport: **Streamable HTTP**
205
- 3. Set URL: `https://mcp.adspirer.com/mcp`
206
- 4. Authenticate via OAuth 2.1 or Bearer token
207
-
208
- This gives you access to all 100+ Adspirer tools via the AI agent. The community node (this package) provides a more structured experience with typed operations and field validation for deterministic workflows.
209
-
210
- ## Related Projects
211
-
212
- | Project | Description | Link |
213
- |---------|-------------|------|
214
- | **ads-mcp** | Adspirer MCP server registration + multi-IDE plugins (Claude Code, Cursor, Codex, OpenClaw) | [github.com/amekala/ads-mcp](https://github.com/amekala/ads-mcp) |
215
- | **Adspirer Docs** | Setup guides, platform docs, API reference | [adspirer.com/docs](https://www.adspirer.com/docs) |
216
- | **MCP Server** | Production MCP endpoint (Streamable HTTP) | `https://mcp.adspirer.com/mcp` |
217
- | **MCP Registry** | Model Context Protocol registry listing | [registry.modelcontextprotocol.io](https://registry.modelcontextprotocol.io) |
195
+ - **[Adspirer MCP server](https://mcp.adspirer.com/mcp)** the canonical tool surface, consumed by ChatGPT Connectors, Claude Desktop, and Claude Code. For n8n agentic workflows, use [`n8n-nodes-mcp`](https://www.npmjs.com/package/n8n-nodes-mcp) pointed at this URL.
196
+ - **[REST API docs](https://www.adspirer.com/docs/api-reference/introduction)** — full endpoint reference, envelope, rate limits
197
+ - **[adspirer.com](https://adspirer.com)** — product overview
218
198
 
219
199
  ## Development
220
200
 
221
201
  ### Prerequisites
222
202
 
223
- - Node.js 22 LTS (required — Node 25 has compatibility issues with `isolated-vm`)
203
+ - Node.js 22 LTS (required — Node 25 has compatibility issues with n8n-core's `isolated-vm` dependency)
224
204
  - npm
225
205
 
226
206
  ### Setup
@@ -235,66 +215,56 @@ npm install
235
215
  ### Commands
236
216
 
237
217
  ```bash
238
- npm run dev # Start n8n locally on :5678 with this node loaded (hot reload)
218
+ npm run codegen # Regenerate operations from api.adspirer.ai/openapi.json
239
219
  npm run build # Compile TypeScript → dist/
240
- npm run lint # Check code quality (must pass for verification)
241
- npm run lint:fix # Auto-fix lint issues
220
+ npm run lint # n8n community-node lint (must pass for verification)
221
+ npm run lint:fix # Autofix lint issues
222
+ npm run dev # Local n8n on :5678 with this node hot-reloaded
242
223
  npm run release # Bump version, tag, push → GH Action publishes to npm
243
224
  ```
244
225
 
245
- ### Testing Locally
226
+ ### How operations are generated
246
227
 
247
- ```bash
248
- npm run dev
249
- ```
228
+ `npm run codegen` fetches `https://api.adspirer.ai/openapi.json`, filters tool endpoints, and emits `nodes/Adspirer/generated/tools.ts` — a typed metadata array. `shared/build-properties.ts` then turns that metadata into n8n's `INodeProperties[]` at module load:
229
+
230
+ - One **Platform** dropdown (5 options)
231
+ - One **Operation** dropdown per platform, filtered by `displayOptions`
232
+ - One field per argument with the correct type (string / number / boolean / enum)
250
233
 
251
- This starts a local n8n instance at `http://localhost:5678` with the Adspirer node pre-loaded. Create a workflow, add the Adspirer node, configure credentials, and test operations against your Adspirer account.
234
+ Tools whose arguments contain nested `array` or `object` types are skipped at codegen time with a `skipped` reason stored in the metadata. They still exist on the REST API use the n8n HTTP Request node to call them.
252
235
 
253
- ### Project Structure
236
+ Idempotency-Key logic reads `x-adspirer-read-only` from the OpenAPI spec per-tool, so non-read operations automatically send an idempotency header.
237
+
238
+ ### Project structure
254
239
 
255
240
  ```
256
241
  n8n-nodes-adspirer/
257
242
  ├── credentials/
258
- ├── AdspireApi.credentials.ts # API key auth
259
- │ └── AdspireOAuth2Api.credentials.ts # OAuth 2.1 auth
260
- ├── nodes/
261
- └── Adspirer/
262
- ├── Adspirer.node.ts # Main node definition
263
- ├── Adspirer.node.json # Codex metadata (categories, AI descriptions)
264
- ├── adspirer.svg # Icon (light mode)
265
- ├── adspirer.dark.svg # Icon (dark mode)
266
- ├── resources/
267
- ├── googleAds.ts # Google Ads operations + field definitions
268
- └── metaAds.ts # Meta Ads operations + field definitions
269
- │ └── shared/
270
- └── descriptions.ts # Shared field definitions
271
- ├── icons/ # Credential-level icons
272
- ├── .github/workflows/
273
- ├── ci.yml # Lint + build on PR
274
- └── publish.yml # npm publish with provenance attestation
275
- ├── package.json
276
- ├── tsconfig.json
277
- └── eslint.config.mjs
278
- ```
279
-
280
- ### Publishing
281
-
282
- Releases are published to npm via GitHub Actions with provenance attestation (required for n8n Creator Portal verification). The workflow triggers on semver tags:
283
-
284
- ```bash
285
- npm run release # Interactive: bumps version, updates changelog, tags, pushes
243
+ └── AdspireApi.credentials.ts # API key Bearer auth, credential-test
244
+ ├── nodes/Adspirer/
245
+ ├── Adspirer.node.ts # Main node — execute() loop, error mapping
246
+ ├── Adspirer.node.json # Codex metadata (categories, AI hints)
247
+ ├── generated/
248
+ │ └── tools.ts # GENERATED from OpenAPI, do not hand-edit
249
+ ├── shared/
250
+ ├── build-properties.ts # Turns TOOLS metadata → INodeProperties[]
251
+ ├── toolMapping.ts # resolveTool, buildToolArguments, isWriteTool
252
+ └── descriptions.ts # re-exports platformSelect
253
+ ├── adspirer.svg / .dark.svg # Node icons
254
+ ├── scripts/
255
+ └── generate-operations.js # Codegen (fetch OpenAPI → emit tools.ts)
256
+ ├── spec/
257
+ │ └── openapi.json # Cached spec for reproducible builds
258
+ ├── icons/ # Credential-level icons
259
+ └── .github/workflows/ # CI + provenance-attested npm publish
286
260
  ```
287
261
 
288
- The GitHub Action then builds, lints, and publishes to npm with OIDC provenance signing.
289
-
290
262
  ## Support
291
263
 
292
- - **Email:** abhi@adspirer.com
293
- - **Issues:** [github.com/amekala/n8n-nodes-adspirer/issues](https://github.com/amekala/n8n-nodes-adspirer/issues)
294
- - **Adspirer Issues:** [github.com/amekala/ads-mcp/issues](https://github.com/amekala/ads-mcp/issues)
295
264
  - **Website:** [adspirer.ai](https://adspirer.ai)
296
- - **Docs:** [adspirer.com/docs](https://www.adspirer.com/docs)
297
- - **Server Status:** [mcp.adspirer.com/health](https://mcp.adspirer.com/health)
265
+ - **REST API docs:** [adspirer.com/docs/api-reference](https://www.adspirer.com/docs/api-reference/introduction)
266
+ - **Issues:** [github.com/amekala/n8n-nodes-adspirer/issues](https://github.com/amekala/n8n-nodes-adspirer/issues)
267
+ - **Email:** abhi@adspirer.com
298
268
 
299
269
  ## License
300
270
 
@@ -6,8 +6,8 @@ class AdspireApi {
6
6
  this.name = 'adspireApi';
7
7
  this.displayName = 'Adspirer API';
8
8
  this.icon = { light: 'file:../icons/adspirer.svg', dark: 'file:../icons/adspirer.dark.svg' };
9
- this.documentationUrl = 'https://www.adspirer.com/docs/quickstart';
10
- this.description = 'Sign up at adspirer.ai, then get your API key from your account settings.';
9
+ this.documentationUrl = 'https://www.adspirer.com/docs/api-reference/introduction';
10
+ this.description = 'Generate an API key at https://adspirer.ai/keys. Keys are prefixed sk_live_ treat them as secrets.';
11
11
  this.properties = [
12
12
  {
13
13
  displayName: 'API Key',
@@ -15,7 +15,9 @@ class AdspireApi {
15
15
  type: 'string',
16
16
  typeOptions: { password: true },
17
17
  default: '',
18
- description: 'Your Adspirer API key. Get one at adspirer.com/settings.',
18
+ placeholder: 'sk_live_...',
19
+ required: true,
20
+ description: 'Your Adspirer API key from https://adspirer.ai/keys',
19
21
  },
20
22
  ];
21
23
  this.authenticate = {
@@ -28,9 +30,10 @@ class AdspireApi {
28
30
  };
29
31
  this.test = {
30
32
  request: {
31
- baseURL: 'https://mcp.adspirer.com',
32
- url: '/api/v1/actions/health',
33
- method: 'GET',
33
+ baseURL: 'https://api.adspirer.ai',
34
+ url: '/api/v1/tools/list_connected_accounts/execute',
35
+ method: 'POST',
36
+ body: { arguments: {} },
34
37
  },
35
38
  };
36
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AdspireApi.credentials.js","sourceRoot":"","sources":["../../credentials/AdspireApi.credentials.ts"],"names":[],"mappings":";;;AAQA,MAAa,UAAU;IAAvB;QACC,SAAI,GAAG,YAAY,CAAC;QAEpB,gBAAW,GAAG,cAAc,CAAC;QAE7B,SAAI,GAAS,EAAE,KAAK,EAAE,4BAA4B,EAAE,IAAI,EAAE,iCAAiC,EAAE,CAAC;QAE9F,qBAAgB,GAAG,0CAA0C,CAAC;QAE9D,gBAAW,GACV,2EAA2E,CAAC;QAE7E,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,0DAA0D;aACvE;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,aAAa,EAAE,kCAAkC;iBACjD;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,0BAA0B;gBACnC,GAAG,EAAE,wBAAwB;gBAC7B,MAAM,EAAE,KAAK;aACb;SACD,CAAC;IACH,CAAC;CAAA;AAvCD,gCAuCC"}
1
+ {"version":3,"file":"AdspireApi.credentials.js","sourceRoot":"","sources":["../../credentials/AdspireApi.credentials.ts"],"names":[],"mappings":";;;AAQA,MAAa,UAAU;IAAvB;QACC,SAAI,GAAG,YAAY,CAAC;QAEpB,gBAAW,GAAG,cAAc,CAAC;QAE7B,SAAI,GAAS,EAAE,KAAK,EAAE,4BAA4B,EAAE,IAAI,EAAE,iCAAiC,EAAE,CAAC;QAE9F,qBAAgB,GAAG,0DAA0D,CAAC;QAE9E,gBAAW,GACV,sGAAsG,CAAC;QAExG,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,aAAa;gBAC1B,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,qDAAqD;aAClE;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,aAAa,EAAE,kCAAkC;iBACjD;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,yBAAyB;gBAClC,GAAG,EAAE,+CAA+C;gBACpD,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;aACvB;SACD,CAAC;IACH,CAAC;CAAA;AA1CD,gCA0CC"}
@@ -1,5 +1,13 @@
1
- import { type IExecuteFunctions, type INodeExecutionData, type INodeType, type INodeTypeDescription } from 'n8n-workflow';
1
+ import { type IExecuteFunctions, type INodeExecutionData, type INodeType, type INodeTypeDescription, type ISupplyDataFunctions, type SupplyData } from 'n8n-workflow';
2
2
  export declare class Adspirer implements INodeType {
3
3
  description: INodeTypeDescription;
4
4
  execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ /**
6
+ * AI Agent (LangChain) integration. n8n's ToolsAgent invokes supplyData()
7
+ * on every node wired into its `ai_tool` slot. We return a DynamicStructuredTool
8
+ * whose schema is derived from the tool metadata we generated from the REST
9
+ * OpenAPI spec — so the agent sees typed, described arguments and can call
10
+ * the tool without our node doing argument discovery at prompt time.
11
+ */
12
+ supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData>;
5
13
  }