n8n-nodes-postwire 0.2.3 → 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.
package/README.md CHANGED
@@ -1,59 +1,117 @@
1
1
  # n8n-nodes-postwire
2
2
 
3
- Publish one idea to every social network from n8n — with **a different post written for each one**, not the same text pasted everywhere.
3
+ Publish one idea to every social network from n8n — with **a different post written for each network**, not the same text pasted everywhere.
4
4
 
5
- [PostWire](https://postwire.io) handles the part that usually stops an n8n workflow: TikTok, Instagram and YouTube all require an approved developer app, and TikTok's App Review asks for a demo video of the integration you cannot build until you are approved. PostWire already holds those approvals, so connecting an account is a single OAuth click.
6
-
7
- ## What the node does
8
-
9
- | Operation | What it does |
10
- |---|---|
11
- | **Write a Post per Network** | One idea in, a native draft out per network — correct length, hashtag conventions, an SEO title and tags for YouTube, a hook-first caption for TikTok, link-in-comment for LinkedIn. Does not publish. |
12
- | **Publish** | Sends to every selected network in one call. |
13
- | **Write and Publish** | Both, in one node. |
14
- | **Schedule** | Queues a post for later, and validates it **now** — so a missing video surfaces while you are watching, not at 7am tomorrow. |
15
- | **Get Account** | Plan, posts used this month, connected accounts. |
5
+ This is the official n8n node for [PostWire](https://postwire.io), maintained by the PostWire team. PostWire already holds the platform approvals TikTok, Instagram (Meta) and YouTube require for publishing apps, so connecting an account is one OAuth click — there is no developer app or App Review on your side.
16
6
 
17
7
  Networks: TikTok · Instagram · YouTube · LinkedIn · X · Facebook · Reddit · Bluesky · Mastodon · Telegram · Discord.
18
8
 
19
9
  ## Install
20
10
 
21
- **n8n Cloud** — Settings → Community nodes → Install → `n8n-nodes-postwire`
11
+ **n8n Cloud and self-hosted** — Settings → Community nodes → Install → `n8n-nodes-postwire`.
22
12
 
23
- **Self-hosted** — Settings → Community nodes → Install, or:
13
+ Self-hosted, from the command line:
24
14
 
25
15
  ```bash
26
- npm install n8n-nodes-postwire
16
+ cd ~/.n8n/nodes && npm install n8n-nodes-postwire
27
17
  ```
28
18
 
29
19
  ## Credentials
30
20
 
31
- 1. Get a free API key at [postwire.io/dashboard.html](https://postwire.io/dashboard.html) and connect the accounts you want to post to.
32
- 2. In n8n, create a **PostWire API** credential and paste the key.
33
- 3. Press **Test** — it calls `/api/me` and returns your plan and connected accounts, so a wrong key fails now rather than at publish time.
21
+ 1. Create a free account at [postwire.io/dashboard.html](https://postwire.io/dashboard.html) and connect the networks you want to post to (Accounts).
22
+ 2. Copy your API key from **API & MCP**.
23
+ 3. In n8n, create a **PostWire API** credential, paste the key and press **Test** — it calls `GET /api/me`, so a wrong key fails now rather than at publish time.
34
24
 
35
25
  Free plan: one brand with every network it connects, 30 posts a month, no card.
36
26
 
37
- ## Nothing half-publishes
27
+ ## Resources and operations
28
+
29
+ | Resource | Operation | What it does |
30
+ |---|---|---|
31
+ | **Post** | **Publish** | Publishes now to one or more networks. *Content* can be **Smart Distribute** (one idea in, a native post per network), **Same Text on Every Network**, or **Drafts From a Previous Step** (for approval flows). |
32
+ | | **Write Drafts** | Preview only: writes a native draft per network — right length, hook, hashtags, YouTube title and tags — and publishes nothing. Also returns a readable `preview` for Slack/Telegram/email approval. |
33
+ | | **Schedule** | Queues a post for later. Connections and media are checked **now**, so a missing video shows up while you watch, not at 7am tomorrow. |
34
+ | | **Plan Week** | One topic in, up to five days of different posts out (a lesson, a mistake, a number, a question, behind the scenes), already scheduled one per day at the hour you choose, in the workflow's time zone. Text networks only. |
35
+ | | **Get Status** | Whether a TikTok or YouTube upload has finished processing. |
36
+ | **Scheduled Post** | Get Many · Update · Cancel | Read the queue, move a post to another time, or cancel it. |
37
+ | **Brand** | Get Many · Create · Rename · Delete | A brand is one business with all its networks — what PostWire plans count. |
38
+ | **Connection** | Get Many · Check Health · Create Connect Link | See connected accounts, ask a network whether a connection can still publish, or create a one-hour link a client can use to connect *their* account to your PostWire (agencies). |
39
+ | **Account** | Get | Plan, posts used this month, connected networks. |
40
+ | **Media** | Upload | Hosts a binary from a previous node and returns a public URL the networks can download. |
41
+
42
+ The node is also available as an **AI agent tool** (`usableAsTool`): attach it to an AI Agent node and the agent can write drafts or publish.
43
+
44
+ ## Media: the part that usually fails
45
+
46
+ TikTok and YouTube only publish video; Instagram needs a photo or a video. The networks **download the file from a link**, with no login — so the most common failure is a link that opens a page instead of the file.
38
47
 
39
- The most common way a cross-posting workflow goes wrong is a partial send: you ask for four networks and two go out. This node checks before anything is published — that each network is connected, that the caption is inside that platform's character limit, and that video networks actually have a video. If any of them would fail, the whole call is refused and the error tells you which one and what to change.
48
+ - **Media → Binary File** (recommended): put a Google Drive *Download*, HTTP Request or Read File node before PostWire. The node uploads the file (up to 50 MB) and PostWire hosts it for 30 days.
49
+ - **Media → URL**: a public `https://` link straight to the `.mp4`/`.jpg` (up to 1 GB). Before anything is sent, the node checks the link the way the networks will: reachable without a login, a file and not a web page, under 1 GB, and a video when a video network is selected. Google Drive, Dropbox (`dl=0`), OneDrive and "link to a post" URLs are recognised and the error says exactly what to change.
40
50
 
41
- The node also validates media in the editor, so `youtube will not accept a post without a video` appears before you run the workflow rather than after.
51
+ ## Nothing half-publishes, nothing double-posts
52
+
53
+ - PostWire refuses the whole call if any selected network is not connected, instead of publishing to half of them.
54
+ - Shared text over a network's limit is shortened for that network (X 280, Bluesky 300, Mastodon 500…) instead of failing.
55
+ - **Idempotency Key** (Options): PostWire refuses a second post with the same key for 24 hours. With Smart Distribute the node sets one automatically per execution, so n8n's *Retry On Fail* can never post the same thing twice.
56
+ - **Dry Run** (Options): checks connections, media and length and returns exactly what would go out, per network — without publishing.
42
57
 
43
58
  ## Output
44
59
 
45
- **Publish** returns one n8n item per network, so you can wire a Filter or IF node straight onto the failures:
60
+ **Publish** returns one item per network, so a Filter or IF node can act on failures alone:
46
61
 
47
62
  ```json
48
- { "ok": true, "platform": "x", "id": "1934…", "url": "https://x.com/…" }
49
- { "ok": false, "platform": "youtube", "error": "youtube needs a video…", "code": "media_required" }
63
+ { "ok": true, "platform": "x", "id": "1934…", "url": "https://x.com/…" }
64
+ { "ok": false, "platform": "youtube", "error": "…", "hint": "YouTube could not download the media. It must be a public https link…" }
50
65
  ```
51
66
 
52
- **Write a Post per Network** returns `{ drafts: { "<platform>": { text, title?, tags? } } }`.
67
+ If **no** network was published, the step fails (so a scheduled workflow cannot go silent for weeks), with the reason and the fix.
68
+
69
+ **Write Drafts** returns:
70
+
71
+ ```json
72
+ {
73
+ "drafts": { "linkedin": { "text": "…" }, "youtube": { "text": "…", "title": "…", "tags": ["…"] } },
74
+ "platforms": ["linkedin", "youtube"],
75
+ "preview": "*LinkedIn*\n…\n\n*YouTube*\n…"
76
+ }
77
+ ```
78
+
79
+ Map `{{ $json.drafts }}` into a later Publish with *Content → Drafts From a Previous Step*.
80
+
81
+ ## Errors say what to do
82
+
83
+ Every refusal from the API carries a code, and the node turns it into a message plus the fix:
84
+
85
+ | Code | What you see |
86
+ |---|---|
87
+ | `not_connected` | Which network, and where to connect it (or send a client a Connect Link) |
88
+ | `media_required` | Which network needs a video/photo, and how to add one |
89
+ | `media_unreachable` | Why PostWire could not download the file (403, 404, a Drive page…) — nothing was published |
90
+ | `too_long` | The limit and how far over it the text is |
91
+ | `limit_reached`, `brand_limit_reached` | The plan limit and the upgrade link |
92
+ | `duplicate_post` | That the post was already sent moments ago and was not sent twice |
93
+ | 401 | Fix the API key in the credential |
94
+ | 429 | Daily AI-draft cap per plan, or a burst limit — wait or add a Wait node |
95
+
96
+ ## Examples
97
+
98
+ **RSS → a native post per network**
99
+
100
+ `RSS Feed Trigger` → `PostWire: Post → Publish` (Content: Smart Distribute, Idea: `{{ $json.title }} — {{ $json.contentSnippet }} {{ $json.link }}`, Networks: LinkedIn, X, Bluesky, Options → Idempotency Key: `{{ $json.guid }}`).
101
+
102
+ **Google Drive video → TikTok, Reels and Shorts**
103
+
104
+ `Google Drive Trigger` → `Google Drive: Download` → `PostWire: Post → Publish` (Media: Binary File, Networks: TikTok, Instagram, YouTube, Idea: `{{ $json.name }}`).
105
+
106
+ **Approve in Slack before anything goes out**
107
+
108
+ `PostWire: Write Drafts` → `Slack: Send and Wait for Approval` (message: `{{ $json.preview }}`) → `IF approved` → `PostWire: Publish` (Content: Drafts From a Previous Step, Drafts: `{{ $('Write drafts').item.json.drafts }}`).
109
+
110
+ Ready-to-import templates: [n8n.io/creators/postwire](https://n8n.io/creators/postwire/).
53
111
 
54
112
  ## Pricing
55
113
 
56
- Priced per **brand** — one business with all of its networks — not per channel or per social account. Adding a fifth network to a brand never changes the bill.
114
+ Priced per **brand** — one business with all of its networks — not per channel. Adding a fifth network to a brand never changes the bill.
57
115
 
58
116
  | | Brands | Posts/month | |
59
117
  |---|---|---|---|
@@ -62,9 +120,15 @@ Priced per **brand** — one business with all of its networks — not per chann
62
120
  | Pro | 10 | 2,000 | $29/mo |
63
121
  | Agency | 50 | 15,000 | $99/mo |
64
122
 
65
- ## Also available
123
+ ## Compatibility
124
+
125
+ Tested with n8n 2.40. Workflows built with version 1 of the node (package 0.1.x–0.2.x) keep working unchanged; new nodes use version 2.
126
+
127
+ ## Resources
66
128
 
67
- A REST API and a hosted MCP server (`https://postwire.io/api/mcp`) for AI agents in Claude, Cursor or VS Code. See [postwire.io/mcp](https://postwire.io/mcp/).
129
+ - [PostWire API reference (OpenAPI)](https://postwire.io/openapi.json)
130
+ - [n8n + PostWire guide](https://postwire.io/n8n-social-media-automation/)
131
+ - [n8n community nodes documentation](https://docs.n8n.io/integrations/community-nodes/)
68
132
 
69
133
  ## License
70
134
 
@@ -1,14 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PostWireApi = void 0;
4
- // PostWire authenticates with a single bearer key. The `test` block below is what makes n8n's
5
- // "Test connection" button meaningful: /api/me returns the plan, the month's usage and the
6
- // connected accounts, so a wrong key fails immediately instead of at publish time.
7
4
  class PostWireApi {
8
5
  constructor() {
9
6
  this.name = 'postWireApi';
10
7
  this.displayName = 'PostWire API';
11
- // Both variants: the badge is a dark square, which disappears against n8n's dark theme.
12
8
  this.icon = { light: 'file:postwire.svg', dark: 'file:postwire.dark.svg' };
13
9
  this.documentationUrl = 'https://postwire.io/n8n-social-media-automation/';
14
10
  this.properties = [
@@ -28,8 +24,6 @@ class PostWireApi {
28
24
  properties: {
29
25
  headers: {
30
26
  Authorization: '=Bearer {{$credentials.apiKey}}',
31
- // Read server-side to tell n8n traffic apart from the dashboard. npm download counts
32
- // turned out to be a scanner floor, so this header is the only honest usage signal.
33
27
  'X-PostWire-Source': 'n8n',
34
28
  },
35
29
  },
@@ -44,3 +38,4 @@ class PostWireApi {
44
38
  }
45
39
  }
46
40
  exports.PostWireApi = PostWireApi;
41
+ //# sourceMappingURL=PostWireApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostWireApi.credentials.js","sourceRoot":"","sources":["../../credentials/PostWireApi.credentials.ts"],"names":[],"mappings":";;;AAWA,MAAa,WAAW;IAAxB;QACC,SAAI,GAAG,aAAa,CAAC;QAErB,gBAAW,GAAG,cAAc,CAAC;QAG7B,SAAI,GAAS,EAAE,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,wBAAwB,EAAE,CAAC;QAE5E,qBAAgB,GAAG,kDAAkD,CAAC;QAEtE,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,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,aAAa;gBAC1B,WAAW,EACV,4KAA4K;aAC7K;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,aAAa,EAAE,iCAAiC;oBAGhD,mBAAmB,EAAE,KAAK;iBAC1B;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,qBAAqB;gBAC9B,GAAG,EAAE,SAAS;gBACd,MAAM,EAAE,KAAK;aACb;SACD,CAAC;IACH,CAAC;CAAA;AA3CD,kCA2CC"}
@@ -0,0 +1,9 @@
1
+ import type { INodeProperties } from 'n8n-workflow';
2
+ export declare const resourceProperty: INodeProperties;
3
+ export declare const operationProperties: INodeProperties[];
4
+ export declare const postProperties: INodeProperties[];
5
+ export declare const scheduledPostProperties: INodeProperties[];
6
+ export declare const brandProperties: INodeProperties[];
7
+ export declare const connectionProperties: INodeProperties[];
8
+ export declare const accountProperties: INodeProperties[];
9
+ export declare const mediaProperties: INodeProperties[];