node-red-contrib-letmepost 0.1.0
Node-RED nodes for letmepost.dev — publish to Bluesky, X/Twitter, LinkedIn, Instagram, Threads, Facebook, Pinterest and TikTok through one API, plus a signed webhook trigger.
node-red-contrib-letmepost
Node-RED nodes for letmepost.dev — the open-source social-media publishing API. Publish or schedule to Bluesky, X/Twitter, LinkedIn, Instagram, Threads, Facebook, Pinterest and TikTok through one API, and trigger flows from signed webhook deliveries.
Nodes
| Node | What it does |
|---|---|
letmepost-config |
Config node holding your API key and base URL. |
letmepost-publish |
Publish or schedule a post (POST /v1/posts). |
letmepost-get-post |
Fetch a post and its attempts (GET /v1/posts/{id}). |
letmepost-list-accounts |
List connected accounts (GET /v1/accounts). |
letmepost-webhook |
Trigger a flow on a signature-verified webhook event. |
Install
From your Node-RED user directory (~/.node-red):
npm install node-red-contrib-letmepost
Or in the editor: Menu → Manage palette → Install and search for
node-red-contrib-letmepost. Restart Node-RED.
Requires Node.js 18+ (uses the global fetch) and Node-RED 3.0+.
Configure credentials
- Mint an API key in the letmepost dashboard under Settings → API Keys
(
lmp_live_…for production,lmp_test_…for the test environment). - Drop any letmepost node onto a flow, open it, and next to Connection
click the pencil to add a new
letmepost-config. - Paste the key into API Key. Leave Base URL as
https://api.letmepost.devunless you self-host.
The key is stored encrypted in Node-RED's credentials store, never in the flow JSON.
Nodes in detail
letmepost-publish
Publishes or schedules a post. Each node field can be overridden by the matching
msg property (msg wins; otherwise the node config is used).
- Account IDs — comma-separated IDs, or an array on
msg.accountIds. Each becomes a target{ accountId }. - Platform — used only when no account IDs are given; auto-resolves to the
single connected account for that platform (e.g.
bluesky). - Text — applied to every target.
- First Comment — auto-posted reply where the platform supports it.
- Schedule At — ISO-8601 timestamp in the future; queues the batch (HTTP
202, status
queued). - Profile ID, Idempotency Key — optional. The idempotency key is sent as
the
Idempotency-Keyheader so retries never double-post. msg.media— optional array of MediaInput objects, passed through verbatim (e.g.[{ "kind": "image", "mediaId": "med_…" }]).msg.payload.targets— advanced: ifmsg.payloadalready contains atargetsarray, the whole payload is sent as the request body and the fields above are ignored. Use this to build arbitrary multi-target / per-target override shapes.
Output msg.payload is the CreatePostResponse envelope:
{ id, status, createdAt, results[] }. The node status reflects the batch
status (published / partial_failed / failed / queued).
letmepost-get-post
GET /v1/posts/{id}. Set Post ID on the node or msg.postId. Output
msg.payload is the PostDetail (the post row plus attempts[]).
letmepost-list-accounts
GET /v1/accounts. Optional Profile ID filter (or msg.profileId). Output
msg.payload is the array of Account objects. Feed an account's id into the
publish node's Account IDs.
letmepost-webhook
Triggers a flow when letmepost delivers an event. It registers an HTTP POST
route at the configured URL Path, verifies the signature, and emits the
event only when valid.
This node does not register itself with the API. Webhook endpoints are
created from the letmepost dashboard — the registration API is a
dashboard-session operation and does not accept an lmp_live_ API key. Register
the URL by hand:
Setup
- Pick a URL Path (default
/letmepost-webhook). Your public URL is the Node-RED base URL plus this path, e.g.https://your-host:1880/letmepost-webhook. Node-RED has to be reachable from the public internet for letmepost to deliver to it. - In the letmepost dashboard, go to Settings → Webhooks, add an endpoint,
and paste that public URL. Choose the event types you want
(
post.published,post.failed,token.expiring, …) or subscribe to all. - Copy the
signingSecret(whsec_…) the dashboard shows once at creation into the node's Signing Secret field.
Verification. Each delivery carries
X-Letmepost-Signature: sha256=<hex>, an HMAC-SHA256 of the raw request body
keyed by the signing secret (no timestamp). The node recomputes it over the
exact received bytes and compares in constant time. Deliveries that fail get a
401 and are dropped; malformed JSON gets a 400.
Output: msg.payload is the parsed event, msg.topic is the event type.
Errors
Action nodes report API failures via node.error(err, msg), so a Catch node
downstream can handle them. The message surfaces the letmepost error code, the
failed rule, the remediation, and the requestId.