n8n-nodes-socialswarm 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 +63 -0
- package/dist/credentials/SocialSwarmApi.credentials.d.ts +8 -0
- package/dist/credentials/SocialSwarmApi.credentials.js +35 -0
- package/dist/nodes/SocialSwarm/SocialSwarm.node.d.ts +4 -0
- package/dist/nodes/SocialSwarm/SocialSwarm.node.js +91 -0
- package/dist/nodes/SocialSwarm/socialswarm.svg +18 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# n8n-nodes-socialswarm
|
|
2
|
+
|
|
3
|
+
Turn any article, blog post, or block of text into ready-to-post **X/Twitter thread variants** — each built around a different hook (curiosity, challenge, story, stat, question). Powered by [SocialSwarm](https://social-swarm.vercel.app).
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
Adds a **SocialSwarm** node with one operation — **Generate Thread** — that takes text or a URL and returns multiple thread variants as structured JSON, ready to schedule, post, or hand off to another node.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
**In n8n (self-hosted):** Settings → Community Nodes → Install → `n8n-nodes-socialswarm`.
|
|
12
|
+
|
|
13
|
+
**Manual:** `npm install n8n-nodes-socialswarm` in your n8n custom nodes folder.
|
|
14
|
+
|
|
15
|
+
## Credentials
|
|
16
|
+
|
|
17
|
+
You need a **SocialSwarm API key**. Subscribe to a plan on the [developer portal](https://social-swarm-main-aa77a19.zuplo.site) to get one, then add it under **Credentials → SocialSwarm API**.
|
|
18
|
+
|
|
19
|
+
## Node: Generate Thread
|
|
20
|
+
|
|
21
|
+
| Field | Description |
|
|
22
|
+
|---|---|
|
|
23
|
+
| **Source Type** | `Text` (paste content) or `URL` (fetch and repurpose a page) |
|
|
24
|
+
| **Source Text** | The content to repurpose (shown for Text) |
|
|
25
|
+
| **Source URL** | The page to fetch (shown for URL) |
|
|
26
|
+
| **Number of Variants** | 3 or 5 hook-varied thread variants |
|
|
27
|
+
|
|
28
|
+
### Output
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"variants": [
|
|
33
|
+
{
|
|
34
|
+
"hook": "curiosity",
|
|
35
|
+
"tweetCount": 5,
|
|
36
|
+
"tweets": [
|
|
37
|
+
{ "text": "Most people get this backwards. Here's why:", "charCount": 43 }
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"meta": { "variantCount": 3 }
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Example workflow
|
|
46
|
+
|
|
47
|
+
**RSS → SocialSwarm → Buffer:** trigger on a new blog post, generate 3 thread variants from its URL, and push the first variant to your scheduler. Content repurposing on autopilot.
|
|
48
|
+
|
|
49
|
+
## Build & publish (maintainers)
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install
|
|
53
|
+
npm run build # compiles TS to dist/ (add nodes/SocialSwarm/socialswarm.svg first)
|
|
54
|
+
npm publish --access public
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The node is **declarative** (routing-based, no `execute()`), so it's easy to extend — add operations by adding entries to the `Operation` options array.
|
|
58
|
+
|
|
59
|
+
## Links
|
|
60
|
+
|
|
61
|
+
- Website: https://social-swarm.vercel.app
|
|
62
|
+
- API docs / portal: https://social-swarm-main-aa77a19.zuplo.site
|
|
63
|
+
- Gateway base URL: `https://social-swarm-main-aa77a19.zuplo.app`
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { IAuthenticateGeneric, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
export declare class SocialSwarmApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
documentationUrl: string;
|
|
6
|
+
properties: INodeProperties[];
|
|
7
|
+
authenticate: IAuthenticateGeneric;
|
|
8
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SocialSwarmApi = void 0;
|
|
4
|
+
// SocialSwarm API key credential.
|
|
5
|
+
// The key is the consumer's subscription key issued by the SocialSwarm
|
|
6
|
+
// developer portal — billing/metering happen at the gateway, so nothing here
|
|
7
|
+
// touches the origin's secrets.
|
|
8
|
+
class SocialSwarmApi {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.name = 'socialSwarmApi';
|
|
11
|
+
this.displayName = 'SocialSwarm API';
|
|
12
|
+
this.documentationUrl = 'https://social-swarm-main-aa77a19.zuplo.site';
|
|
13
|
+
this.properties = [
|
|
14
|
+
{
|
|
15
|
+
displayName: 'API Key',
|
|
16
|
+
name: 'apiKey',
|
|
17
|
+
type: 'string',
|
|
18
|
+
typeOptions: { password: true },
|
|
19
|
+
default: '',
|
|
20
|
+
required: true,
|
|
21
|
+
description: 'Your SocialSwarm API key. Subscribe to a plan on the developer portal to get one.',
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
// Injects `Authorization: Bearer <key>` on every request.
|
|
25
|
+
this.authenticate = {
|
|
26
|
+
type: 'generic',
|
|
27
|
+
properties: {
|
|
28
|
+
headers: {
|
|
29
|
+
Authorization: '=Bearer {{$credentials.apiKey}}',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.SocialSwarmApi = SocialSwarmApi;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SocialSwarm = void 0;
|
|
4
|
+
// Declarative n8n node — no execute() needed. Each parameter routes itself
|
|
5
|
+
// into the POST /v1/generate request body. Auth comes from the
|
|
6
|
+
// SocialSwarmApi credential (Bearer token).
|
|
7
|
+
class SocialSwarm {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.description = {
|
|
10
|
+
displayName: 'SocialSwarm',
|
|
11
|
+
name: 'socialSwarm',
|
|
12
|
+
icon: 'file:socialswarm.svg',
|
|
13
|
+
group: ['transform'],
|
|
14
|
+
version: 1,
|
|
15
|
+
subtitle: '=Generate {{$parameter["variantCount"]}} thread variants',
|
|
16
|
+
description: 'Turn any text or URL into ready-to-post X/Twitter thread variants',
|
|
17
|
+
defaults: { name: 'SocialSwarm' },
|
|
18
|
+
inputs: ['main'],
|
|
19
|
+
outputs: ['main'],
|
|
20
|
+
credentials: [{ name: 'socialSwarmApi', required: true }],
|
|
21
|
+
requestDefaults: {
|
|
22
|
+
baseURL: 'https://social-swarm-main-aa77a19.zuplo.app',
|
|
23
|
+
headers: { 'Content-Type': 'application/json' },
|
|
24
|
+
},
|
|
25
|
+
properties: [
|
|
26
|
+
{
|
|
27
|
+
displayName: 'Operation',
|
|
28
|
+
name: 'operation',
|
|
29
|
+
type: 'options',
|
|
30
|
+
noDataExpression: true,
|
|
31
|
+
options: [
|
|
32
|
+
{
|
|
33
|
+
name: 'Generate Thread',
|
|
34
|
+
value: 'generate',
|
|
35
|
+
action: 'Generate thread variants from text or a URL',
|
|
36
|
+
routing: {
|
|
37
|
+
request: { method: 'POST', url: '/v1/generate' },
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
default: 'generate',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
displayName: 'Source Type',
|
|
45
|
+
name: 'sourceType',
|
|
46
|
+
type: 'options',
|
|
47
|
+
options: [
|
|
48
|
+
{ name: 'Text', value: 'text' },
|
|
49
|
+
{ name: 'URL', value: 'url' },
|
|
50
|
+
],
|
|
51
|
+
default: 'text',
|
|
52
|
+
description: 'Whether to repurpose pasted text or fetch and repurpose a URL',
|
|
53
|
+
routing: { request: { body: { sourceType: '={{$value}}' } } },
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
displayName: 'Source Text',
|
|
57
|
+
name: 'sourceText',
|
|
58
|
+
type: 'string',
|
|
59
|
+
typeOptions: { rows: 6 },
|
|
60
|
+
displayOptions: { show: { sourceType: ['text'] } },
|
|
61
|
+
default: '',
|
|
62
|
+
description: 'The article or content to repurpose (~100+ characters works best)',
|
|
63
|
+
routing: { request: { body: { sourceText: '={{$value}}' } } },
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
displayName: 'Source URL',
|
|
67
|
+
name: 'sourceUrl',
|
|
68
|
+
type: 'string',
|
|
69
|
+
displayOptions: { show: { sourceType: ['url'] } },
|
|
70
|
+
default: '',
|
|
71
|
+
placeholder: 'https://example.com/blog/my-article',
|
|
72
|
+
description: 'URL to fetch and repurpose into threads',
|
|
73
|
+
routing: { request: { body: { sourceUrl: '={{$value}}' } } },
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
displayName: 'Number of Variants',
|
|
77
|
+
name: 'variantCount',
|
|
78
|
+
type: 'options',
|
|
79
|
+
options: [
|
|
80
|
+
{ name: '3 Variants', value: 3 },
|
|
81
|
+
{ name: '5 Variants', value: 5 },
|
|
82
|
+
],
|
|
83
|
+
default: 3,
|
|
84
|
+
description: 'How many hook-varied thread variants to generate',
|
|
85
|
+
routing: { request: { body: { variantCount: '={{$value}}' } } },
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.SocialSwarm = SocialSwarm;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 60 60" role="img" aria-label="SocialSwarm">
|
|
2
|
+
<rect width="60" height="60" rx="13" fill="#1D9BF0"/>
|
|
3
|
+
<g stroke="#FFFFFF" stroke-width="2" stroke-opacity="0.8" stroke-linecap="round">
|
|
4
|
+
<line x1="30" y1="30" x2="30" y2="12"/>
|
|
5
|
+
<line x1="30" y1="30" x2="47.1" y2="24.4"/>
|
|
6
|
+
<line x1="30" y1="30" x2="40.6" y2="44.6"/>
|
|
7
|
+
<line x1="30" y1="30" x2="19.4" y2="44.6"/>
|
|
8
|
+
<line x1="30" y1="30" x2="12.9" y2="24.4"/>
|
|
9
|
+
</g>
|
|
10
|
+
<g fill="#FFFFFF">
|
|
11
|
+
<circle cx="30" cy="30" r="6"/>
|
|
12
|
+
<circle cx="30" cy="12" r="3.6"/>
|
|
13
|
+
<circle cx="47.1" cy="24.4" r="3.6"/>
|
|
14
|
+
<circle cx="40.6" cy="44.6" r="3.6"/>
|
|
15
|
+
<circle cx="19.4" cy="44.6" r="3.6"/>
|
|
16
|
+
<circle cx="12.9" cy="24.4" r="3.6"/>
|
|
17
|
+
</g>
|
|
18
|
+
</svg>
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-socialswarm",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "n8n community node to turn any text or URL into ready-to-post X/Twitter thread variants with SocialSwarm.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"socialswarm",
|
|
8
|
+
"twitter",
|
|
9
|
+
"x",
|
|
10
|
+
"threads",
|
|
11
|
+
"content",
|
|
12
|
+
"ai"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"homepage": "https://social-swarm.vercel.app",
|
|
16
|
+
"author": {
|
|
17
|
+
"name": "SocialSwarm"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/rarrifund/socialswarm.git"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18.10"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc && node -e \"require('fs').copyFileSync('nodes/SocialSwarm/socialswarm.svg','dist/nodes/SocialSwarm/socialswarm.svg')\"",
|
|
28
|
+
"dev": "tsc --watch",
|
|
29
|
+
"prepublishOnly": "npm run build"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"n8n": {
|
|
35
|
+
"n8nNodesApiVersion": 1,
|
|
36
|
+
"credentials": [
|
|
37
|
+
"dist/credentials/SocialSwarmApi.credentials.js"
|
|
38
|
+
],
|
|
39
|
+
"nodes": [
|
|
40
|
+
"dist/nodes/SocialSwarm/SocialSwarm.node.js"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"n8n-workflow": "*"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^18.16.0",
|
|
48
|
+
"n8n-workflow": "*",
|
|
49
|
+
"typescript": "^5.4.0"
|
|
50
|
+
}
|
|
51
|
+
}
|