n8n-nodes-substack-new 0.0.1
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/LICENSE.md +19 -0
- package/README.md +139 -0
- package/dist/credentials/SubstackGatewayApi.credentials.d.ts +9 -0
- package/dist/credentials/SubstackGatewayApi.credentials.js +61 -0
- package/dist/credentials/SubstackGatewayApi.credentials.js.map +1 -0
- package/dist/nodes/SubstackGateway/Comment.fields.d.ts +2 -0
- package/dist/nodes/SubstackGateway/Comment.fields.js +36 -0
- package/dist/nodes/SubstackGateway/Comment.fields.js.map +1 -0
- package/dist/nodes/SubstackGateway/Comment.operations.d.ts +8 -0
- package/dist/nodes/SubstackGateway/Comment.operations.js +44 -0
- package/dist/nodes/SubstackGateway/Comment.operations.js.map +1 -0
- package/dist/nodes/SubstackGateway/Note.fields.d.ts +2 -0
- package/dist/nodes/SubstackGateway/Note.fields.js +150 -0
- package/dist/nodes/SubstackGateway/Note.fields.js.map +1 -0
- package/dist/nodes/SubstackGateway/Note.operations.d.ts +11 -0
- package/dist/nodes/SubstackGateway/Note.operations.js +109 -0
- package/dist/nodes/SubstackGateway/Note.operations.js.map +1 -0
- package/dist/nodes/SubstackGateway/Post.fields.d.ts +2 -0
- package/dist/nodes/SubstackGateway/Post.fields.js +66 -0
- package/dist/nodes/SubstackGateway/Post.fields.js.map +1 -0
- package/dist/nodes/SubstackGateway/Post.operations.d.ts +10 -0
- package/dist/nodes/SubstackGateway/Post.operations.js +74 -0
- package/dist/nodes/SubstackGateway/Post.operations.js.map +1 -0
- package/dist/nodes/SubstackGateway/Profile.fields.d.ts +2 -0
- package/dist/nodes/SubstackGateway/Profile.fields.js +61 -0
- package/dist/nodes/SubstackGateway/Profile.fields.js.map +1 -0
- package/dist/nodes/SubstackGateway/Profile.operations.d.ts +10 -0
- package/dist/nodes/SubstackGateway/Profile.operations.js +72 -0
- package/dist/nodes/SubstackGateway/Profile.operations.js.map +1 -0
- package/dist/nodes/SubstackGateway/Substack.node.d.ts +11 -0
- package/dist/nodes/SubstackGateway/Substack.node.js +148 -0
- package/dist/nodes/SubstackGateway/Substack.node.js.map +1 -0
- package/dist/nodes/SubstackGateway/Substack.node.json +22 -0
- package/dist/nodes/SubstackGateway/SubstackUtils.d.ts +12 -0
- package/dist/nodes/SubstackGateway/SubstackUtils.js +59 -0
- package/dist/nodes/SubstackGateway/SubstackUtils.js.map +1 -0
- package/dist/nodes/SubstackGateway/shared/DataFormatters.d.ts +9 -0
- package/dist/nodes/SubstackGateway/shared/DataFormatters.js +73 -0
- package/dist/nodes/SubstackGateway/shared/DataFormatters.js.map +1 -0
- package/dist/nodes/SubstackGateway/shared/OperationHandler.d.ts +11 -0
- package/dist/nodes/SubstackGateway/shared/OperationHandler.js +44 -0
- package/dist/nodes/SubstackGateway/shared/OperationHandler.js.map +1 -0
- package/dist/nodes/SubstackGateway/shared/OperationUtils.d.ts +5 -0
- package/dist/nodes/SubstackGateway/shared/OperationUtils.js +35 -0
- package/dist/nodes/SubstackGateway/shared/OperationUtils.js.map +1 -0
- package/dist/nodes/SubstackGateway/shared/SubstackGatewayClient.d.ts +69 -0
- package/dist/nodes/SubstackGateway/shared/SubstackGatewayClient.js +222 -0
- package/dist/nodes/SubstackGateway/shared/SubstackGatewayClient.js.map +1 -0
- package/dist/nodes/SubstackGateway/substack.svg +7 -0
- package/dist/nodes/SubstackGateway/types.d.ts +51 -0
- package/dist/nodes/SubstackGateway/types.js +3 -0
- package/dist/nodes/SubstackGateway/types.js.map +1 -0
- package/dist/package.json +67 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +66 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright 2025 Jakub Slys
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
5
|
+
the Software without restriction, including without limitation the rights to
|
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
8
|
+
so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# n8n-nodes-substack-new
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://github.com/jakub-k-slys/n8n-nodes-substack-new/actions/workflows/test.yaml)
|
|
5
|
+
|
|
6
|
+
`n8n-nodes-substack-new` is an n8n community package for working with Substack through a gateway-backed client. It ships two related surfaces:
|
|
7
|
+
|
|
8
|
+
- The `Substack Gateway` n8n node for workflows
|
|
9
|
+
- A small typed `SubstackClient` exported from the package for direct programmatic use
|
|
10
|
+
|
|
11
|
+
This repository no longer wraps a separate `substack-api` package. The client implementation lives in this codebase under [`nodes/SubstackGateway/shared/SubstackGatewayClient.ts`](/Users/jakubslys/n8n-nodes-substack-new/nodes/SubstackGateway/shared/SubstackGatewayClient.ts).
|
|
12
|
+
|
|
13
|
+
## What It Supports
|
|
14
|
+
|
|
15
|
+
- Profile operations
|
|
16
|
+
- Get your own profile
|
|
17
|
+
- Get a profile by publication slug
|
|
18
|
+
- List followed profiles or followed user IDs
|
|
19
|
+
- Post operations
|
|
20
|
+
- List posts from your own publication
|
|
21
|
+
- List posts from another publication by slug
|
|
22
|
+
- Fetch a post by ID
|
|
23
|
+
- Note operations
|
|
24
|
+
- List notes from your own publication
|
|
25
|
+
- List notes from another publication by slug
|
|
26
|
+
- Fetch a note by ID
|
|
27
|
+
- Create a note with optional attached link
|
|
28
|
+
- Comment operations
|
|
29
|
+
- List comments for a post by ID
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
Install the package into your n8n environment:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install n8n-nodes-substack-new
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Then restart n8n and install `n8n-nodes-substack-new` as a community package if needed by your deployment model.
|
|
40
|
+
|
|
41
|
+
## Credentials
|
|
42
|
+
|
|
43
|
+
The node uses a credential named `SubstackGateway API` with three fields:
|
|
44
|
+
|
|
45
|
+
- `Publication Address`
|
|
46
|
+
- Full publication URL such as `https://myblog.substack.com`
|
|
47
|
+
- `Gateway URL`
|
|
48
|
+
- Optional gateway base URL
|
|
49
|
+
- Defaults to `https://substack-gateway.vercel.app`
|
|
50
|
+
- `API Key`
|
|
51
|
+
- Bearer token expected by the gateway
|
|
52
|
+
|
|
53
|
+
## Quick Example
|
|
54
|
+
|
|
55
|
+
List recent posts from your own publication:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"nodes": [
|
|
60
|
+
{
|
|
61
|
+
"name": "Get Recent Posts",
|
|
62
|
+
"type": "n8n-nodes-substack-new.substack",
|
|
63
|
+
"parameters": {
|
|
64
|
+
"resource": "post",
|
|
65
|
+
"operation": "getAll",
|
|
66
|
+
"limit": 10
|
|
67
|
+
},
|
|
68
|
+
"credentials": {
|
|
69
|
+
"substackApi": "your-credential-id"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Create a note:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"nodes": [
|
|
81
|
+
{
|
|
82
|
+
"name": "Create Note",
|
|
83
|
+
"type": "n8n-nodes-substack-new.substack",
|
|
84
|
+
"parameters": {
|
|
85
|
+
"resource": "note",
|
|
86
|
+
"operation": "create",
|
|
87
|
+
"body": "Published from n8n",
|
|
88
|
+
"visibility": "everyone",
|
|
89
|
+
"attachment": "none"
|
|
90
|
+
},
|
|
91
|
+
"credentials": {
|
|
92
|
+
"substackApi": "your-credential-id"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Direct Client Usage
|
|
100
|
+
|
|
101
|
+
The package also exports a typed client:
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import { SubstackClient } from 'n8n-nodes-substack-new';
|
|
105
|
+
|
|
106
|
+
const client = new SubstackClient({
|
|
107
|
+
publicationUrl: 'https://myblog.substack.com',
|
|
108
|
+
token: process.env.SUBSTACK_GATEWAY_TOKEN!,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const ownProfile = await client.ownProfile();
|
|
112
|
+
|
|
113
|
+
for await (const post of ownProfile.posts()) {
|
|
114
|
+
console.log(post.title);
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Documentation
|
|
119
|
+
|
|
120
|
+
- [Introduction](docs/introduction.md)
|
|
121
|
+
- [Installation](docs/installation.md)
|
|
122
|
+
- [Quickstart](docs/quickstart.md)
|
|
123
|
+
- [n8n Usage](docs/n8n-usage.md)
|
|
124
|
+
- [API Reference](docs/api-reference.md)
|
|
125
|
+
- [Examples](docs/examples.md)
|
|
126
|
+
- [Architecture](docs/design.md)
|
|
127
|
+
- [Development](docs/development.md)
|
|
128
|
+
- [Testing](docs/testing.md)
|
|
129
|
+
|
|
130
|
+
Resource-specific docs:
|
|
131
|
+
|
|
132
|
+
- [Profiles](docs/resources/profile.md)
|
|
133
|
+
- [Posts](docs/resources/post.md)
|
|
134
|
+
- [Notes](docs/resources/note.md)
|
|
135
|
+
- [Comments](docs/resources/comment.md)
|
|
136
|
+
|
|
137
|
+
## License
|
|
138
|
+
|
|
139
|
+
[MIT](LICENSE.md)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
export declare class SubstackApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
documentationUrl: string;
|
|
6
|
+
properties: INodeProperties[];
|
|
7
|
+
authenticate: IAuthenticateGeneric;
|
|
8
|
+
test: ICredentialTestRequest;
|
|
9
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SubstackApi = void 0;
|
|
4
|
+
class SubstackApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'substackGatewayApi';
|
|
7
|
+
this.displayName = 'SubstackGateway API';
|
|
8
|
+
this.documentationUrl = 'https://github.com/jakub-k-slys/n8n-nodes-substack';
|
|
9
|
+
this.properties = [
|
|
10
|
+
{
|
|
11
|
+
displayName: 'Publication Address',
|
|
12
|
+
name: 'publicationAddress',
|
|
13
|
+
type: 'string',
|
|
14
|
+
default: '',
|
|
15
|
+
placeholder: 'https://myblog.substack.com',
|
|
16
|
+
description: 'The full URL of your SubstackGateway publication (must include http:// or https://)',
|
|
17
|
+
required: true,
|
|
18
|
+
validateType: 'url',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
displayName: 'Gateway URL',
|
|
22
|
+
name: 'gatewayUrl',
|
|
23
|
+
type: 'string',
|
|
24
|
+
default: 'https://substack-gateway.vercel.app',
|
|
25
|
+
description: 'Optional SubstackGateway Gateway base URL. Use this when routing requests through a self-hosted gateway.',
|
|
26
|
+
required: false,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
displayName: 'API Key',
|
|
30
|
+
name: 'apiKey',
|
|
31
|
+
type: 'string',
|
|
32
|
+
default: '',
|
|
33
|
+
typeOptions: {
|
|
34
|
+
password: true,
|
|
35
|
+
},
|
|
36
|
+
description: 'Bearer token used by the SubstackGateway Gateway (for example a base64-encoded JSON containing SubstackGateway session cookies)',
|
|
37
|
+
required: true,
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
this.authenticate = {
|
|
41
|
+
type: 'generic',
|
|
42
|
+
properties: {
|
|
43
|
+
headers: {
|
|
44
|
+
Cookie: '=substack.sid={{$credentials.apiKey}}',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
this.test = {
|
|
49
|
+
request: {
|
|
50
|
+
baseURL: '=https://{{$credentials.publicationAddress}}',
|
|
51
|
+
url: '/api/v1/subscription',
|
|
52
|
+
method: 'GET',
|
|
53
|
+
headers: {
|
|
54
|
+
Cookie: '=substack.sid={{$credentials.apiKey}}',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.SubstackApi = SubstackApi;
|
|
61
|
+
//# sourceMappingURL=SubstackGatewayApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubstackGatewayApi.credentials.js","sourceRoot":"","sources":["../../credentials/SubstackGatewayApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,WAAW;IAAxB;QACC,SAAI,GAAG,oBAAoB,CAAC;QAC5B,gBAAW,GAAG,qBAAqB,CAAC;QACpC,qBAAgB,GAAG,oDAAoD,CAAC;QACxE,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,qBAAqB;gBAClC,IAAI,EAAE,oBAAoB;gBAC1B,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,6BAA6B;gBAC1C,WAAW,EAAE,qFAAqF;gBAClG,QAAQ,EAAE,IAAI;gBACd,YAAY,EAAE,KAAK;aACnB;YAED;gBACC,WAAW,EAAE,aAAa;gBAC1B,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,qCAAqC;gBAC9C,WAAW,EACV,0GAA0G;gBAC3G,QAAQ,EAAE,KAAK;aACf;YACD;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE;oBACZ,QAAQ,EAAE,IAAI;iBACd;gBACD,WAAW,EACV,iIAAiI;gBAClI,QAAQ,EAAE,IAAI;aACd;SACD,CAAC;QAIF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,MAAM,EAAE,uCAAuC;iBAC/C;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,8CAA8C;gBACvD,GAAG,EAAE,sBAAsB;gBAC3B,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE;oBACR,MAAM,EAAE,uCAAuC;iBAC/C;aACD;SACD,CAAC;IACH,CAAC;CAAA;AA5DD,kCA4DC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.commentFields = void 0;
|
|
4
|
+
exports.commentFields = [
|
|
5
|
+
{
|
|
6
|
+
displayName: 'Post ID',
|
|
7
|
+
name: 'postId',
|
|
8
|
+
type: 'number',
|
|
9
|
+
default: 0,
|
|
10
|
+
description: 'The ID of the post to get comments for',
|
|
11
|
+
displayOptions: {
|
|
12
|
+
show: {
|
|
13
|
+
resource: ['comment'],
|
|
14
|
+
operation: ['getAll'],
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
required: true,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
displayName: 'Limit',
|
|
21
|
+
name: 'limit',
|
|
22
|
+
type: 'number',
|
|
23
|
+
default: 50,
|
|
24
|
+
description: 'Max number of results to return',
|
|
25
|
+
displayOptions: {
|
|
26
|
+
show: {
|
|
27
|
+
resource: ['comment'],
|
|
28
|
+
operation: ['getAll'],
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
typeOptions: {
|
|
32
|
+
minValue: 1,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
//# sourceMappingURL=Comment.fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Comment.fields.js","sourceRoot":"","sources":["../../../nodes/SubstackGateway/Comment.fields.ts"],"names":[],"mappings":";;;AAEa,QAAA,aAAa,GAAsB;IAI/C;QACC,WAAW,EAAE,SAAS;QACtB,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,wCAAwC;QACrD,cAAc,EAAE;YACf,IAAI,EAAE;gBACL,QAAQ,EAAE,CAAC,SAAS,CAAC;gBACrB,SAAS,EAAE,CAAC,QAAQ,CAAC;aACrB;SACD;QACD,QAAQ,EAAE,IAAI;KACd;IACD;QACC,WAAW,EAAE,OAAO;QACpB,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,iCAAiC;QAC9C,cAAc,EAAE;YACf,IAAI,EAAE;gBACL,QAAQ,EAAE,CAAC,SAAS,CAAC;gBACrB,SAAS,EAAE,CAAC,QAAQ,CAAC;aACrB;SACD;QACD,WAAW,EAAE;YACZ,QAAQ,EAAE,CAAC;SACX;KACD;CACD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IExecuteFunctions, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
import { SubstackClient } from './shared/SubstackGatewayClient';
|
|
3
|
+
import { IStandardResponse } from './types';
|
|
4
|
+
export declare enum CommentOperation {
|
|
5
|
+
GetAll = "getAll"
|
|
6
|
+
}
|
|
7
|
+
export declare const commentOperations: INodeProperties[];
|
|
8
|
+
export declare const commentOperationHandlers: Record<CommentOperation, (executeFunctions: IExecuteFunctions, client: SubstackClient, publicationAddress: string, itemIndex: number) => Promise<IStandardResponse>>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.commentOperationHandlers = exports.commentOperations = exports.CommentOperation = void 0;
|
|
4
|
+
const DataFormatters_1 = require("./shared/DataFormatters");
|
|
5
|
+
const OperationUtils_1 = require("./shared/OperationUtils");
|
|
6
|
+
const OperationHandler_1 = require("./shared/OperationHandler");
|
|
7
|
+
var CommentOperation;
|
|
8
|
+
(function (CommentOperation) {
|
|
9
|
+
CommentOperation["GetAll"] = "getAll";
|
|
10
|
+
})(CommentOperation || (exports.CommentOperation = CommentOperation = {}));
|
|
11
|
+
exports.commentOperations = [
|
|
12
|
+
{
|
|
13
|
+
displayName: 'Operation',
|
|
14
|
+
name: 'operation',
|
|
15
|
+
type: 'options',
|
|
16
|
+
default: 'getAll',
|
|
17
|
+
noDataExpression: true,
|
|
18
|
+
displayOptions: {
|
|
19
|
+
show: {
|
|
20
|
+
resource: ['comment'],
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
options: [
|
|
24
|
+
{
|
|
25
|
+
name: 'Get All Comments',
|
|
26
|
+
value: CommentOperation.GetAll,
|
|
27
|
+
description: 'Get all comments for a specific post',
|
|
28
|
+
action: 'Get all comments',
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
async function getAll(executeFunctions, client, publicationAddress, itemIndex) {
|
|
34
|
+
return OperationHandler_1.OperationHandler.execute(executeFunctions, itemIndex, async () => {
|
|
35
|
+
const postId = OperationUtils_1.OperationUtils.parseNumericParam(executeFunctions.getNodeParameter('postId', itemIndex), 'postId');
|
|
36
|
+
const limit = OperationHandler_1.OperationHandler.getLimit(executeFunctions, itemIndex);
|
|
37
|
+
const post = await client.postForId(postId);
|
|
38
|
+
return OperationHandler_1.OperationHandler.collectFromIterable(post.comments(), limit, (comment) => DataFormatters_1.DataFormatters.formatComment(comment, postId));
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
exports.commentOperationHandlers = {
|
|
42
|
+
[CommentOperation.GetAll]: getAll,
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=Comment.operations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Comment.operations.js","sourceRoot":"","sources":["../../../nodes/SubstackGateway/Comment.operations.ts"],"names":[],"mappings":";;;AAGA,4DAAyD;AACzD,4DAAyD;AACzD,gEAA6D;AAE7D,IAAY,gBAEX;AAFD,WAAY,gBAAgB;IAC3B,qCAAiB,CAAA;AAClB,CAAC,EAFW,gBAAgB,gCAAhB,gBAAgB,QAE3B;AAEY,QAAA,iBAAiB,GAAsB;IACnD;QACC,WAAW,EAAE,WAAW;QACxB,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,QAAQ;QACjB,gBAAgB,EAAE,IAAI;QACtB,cAAc,EAAE;YACf,IAAI,EAAE;gBACL,QAAQ,EAAE,CAAC,SAAS,CAAC;aACrB;SACD;QACD,OAAO,EAAE;YACR;gBACC,IAAI,EAAE,kBAAkB;gBACxB,KAAK,EAAE,gBAAgB,CAAC,MAAM;gBAC9B,WAAW,EAAE,sCAAsC;gBACnD,MAAM,EAAE,kBAAkB;aAC1B;SACD;KACD;CACD,CAAC;AAEF,KAAK,UAAU,MAAM,CACpB,gBAAmC,EACnC,MAAsB,EACtB,kBAA0B,EAC1B,SAAiB;IAEjB,OAAO,mCAAgB,CAAC,OAAO,CAAC,gBAAgB,EAAE,SAAS,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,MAAM,GAAG,+BAAc,CAAC,iBAAiB,CAC9C,gBAAgB,CAAC,gBAAgB,CAAC,QAAQ,EAAE,SAAS,CAAC,EACtD,QAAQ,CACR,CAAC;QACF,MAAM,KAAK,GAAG,mCAAgB,CAAC,QAAQ,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;QAErE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,OAAO,mCAAgB,CAAC,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAC/E,+BAAc,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAC7C,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC;AAEY,QAAA,wBAAwB,GAQjC;IACH,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM;CACjC,CAAC"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.noteFields = void 0;
|
|
4
|
+
exports.noteFields = [
|
|
5
|
+
{
|
|
6
|
+
displayName: 'Body',
|
|
7
|
+
name: 'body',
|
|
8
|
+
type: 'string',
|
|
9
|
+
default: '',
|
|
10
|
+
description: 'The content of the note. Supports Markdown formatting.',
|
|
11
|
+
displayOptions: {
|
|
12
|
+
show: {
|
|
13
|
+
resource: ['note'],
|
|
14
|
+
operation: ['create'],
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
required: true,
|
|
18
|
+
typeOptions: {
|
|
19
|
+
rows: 4,
|
|
20
|
+
},
|
|
21
|
+
placeholder: 'Write your note content here... (Supports Markdown: **bold**, *italic*, # headings, [links](url), - lists)',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
displayName: 'Visibility',
|
|
25
|
+
name: 'visibility',
|
|
26
|
+
type: 'options',
|
|
27
|
+
default: 'everyone',
|
|
28
|
+
description: 'Who can see this note',
|
|
29
|
+
displayOptions: {
|
|
30
|
+
show: {
|
|
31
|
+
resource: ['note'],
|
|
32
|
+
operation: ['create'],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
options: [
|
|
36
|
+
{
|
|
37
|
+
name: 'Everyone',
|
|
38
|
+
value: 'everyone',
|
|
39
|
+
description: 'Public note visible to everyone',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'Subscribers',
|
|
43
|
+
value: 'subscribers',
|
|
44
|
+
description: 'Visible only to subscribers',
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
displayName: 'Attachment',
|
|
50
|
+
name: 'attachment',
|
|
51
|
+
type: 'options',
|
|
52
|
+
default: 'none',
|
|
53
|
+
description: 'Add an attachment to the note',
|
|
54
|
+
displayOptions: {
|
|
55
|
+
show: {
|
|
56
|
+
resource: ['note'],
|
|
57
|
+
operation: ['create'],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
options: [
|
|
61
|
+
{
|
|
62
|
+
name: 'None',
|
|
63
|
+
value: 'none',
|
|
64
|
+
description: 'No attachment',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'Link',
|
|
68
|
+
value: 'link',
|
|
69
|
+
description: 'Attach a link to the note',
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
displayName: 'Link URL',
|
|
75
|
+
name: 'linkUrl',
|
|
76
|
+
type: 'string',
|
|
77
|
+
default: '',
|
|
78
|
+
description: 'URL to attach to the note',
|
|
79
|
+
displayOptions: {
|
|
80
|
+
show: {
|
|
81
|
+
resource: ['note'],
|
|
82
|
+
operation: ['create'],
|
|
83
|
+
attachment: ['link'],
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
required: true,
|
|
87
|
+
placeholder: 'https://example.com',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
displayName: 'Limit',
|
|
91
|
+
name: 'limit',
|
|
92
|
+
type: 'number',
|
|
93
|
+
default: 50,
|
|
94
|
+
description: 'Max number of results to return',
|
|
95
|
+
displayOptions: {
|
|
96
|
+
show: {
|
|
97
|
+
resource: ['note'],
|
|
98
|
+
operation: ['get'],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
typeOptions: {
|
|
102
|
+
minValue: 1,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
displayName: 'Slug',
|
|
107
|
+
name: 'slug',
|
|
108
|
+
type: 'string',
|
|
109
|
+
default: '',
|
|
110
|
+
description: 'The publication slug (subdomain)',
|
|
111
|
+
displayOptions: {
|
|
112
|
+
show: {
|
|
113
|
+
resource: ['note'],
|
|
114
|
+
operation: ['getNotesBySlug'],
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
required: true,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
displayName: 'Limit',
|
|
121
|
+
name: 'limit',
|
|
122
|
+
type: 'number',
|
|
123
|
+
default: 50,
|
|
124
|
+
description: 'Max number of results to return',
|
|
125
|
+
displayOptions: {
|
|
126
|
+
show: {
|
|
127
|
+
resource: ['note'],
|
|
128
|
+
operation: ['getNotesBySlug'],
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
typeOptions: {
|
|
132
|
+
minValue: 1,
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
displayName: 'Note ID',
|
|
137
|
+
name: 'noteId',
|
|
138
|
+
type: 'string',
|
|
139
|
+
default: '',
|
|
140
|
+
description: 'The ID of the note to retrieve',
|
|
141
|
+
displayOptions: {
|
|
142
|
+
show: {
|
|
143
|
+
resource: ['note'],
|
|
144
|
+
operation: ['getNoteById'],
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
required: true,
|
|
148
|
+
},
|
|
149
|
+
];
|
|
150
|
+
//# sourceMappingURL=Note.fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Note.fields.js","sourceRoot":"","sources":["../../../nodes/SubstackGateway/Note.fields.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IExecuteFunctions, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
import { SubstackClient } from './shared/SubstackGatewayClient';
|
|
3
|
+
import { IStandardResponse } from './types';
|
|
4
|
+
export declare enum NoteOperation {
|
|
5
|
+
Create = "create",
|
|
6
|
+
Get = "get",
|
|
7
|
+
GetNotesBySlug = "getNotesBySlug",
|
|
8
|
+
GetNoteById = "getNoteById"
|
|
9
|
+
}
|
|
10
|
+
export declare const noteOperations: INodeProperties[];
|
|
11
|
+
export declare const noteOperationHandlers: Record<NoteOperation, (executeFunctions: IExecuteFunctions, client: SubstackClient, publicationAddress: string, itemIndex: number) => Promise<IStandardResponse>>;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.noteOperationHandlers = exports.noteOperations = exports.NoteOperation = void 0;
|
|
4
|
+
const SubstackUtils_1 = require("./SubstackUtils");
|
|
5
|
+
const DataFormatters_1 = require("./shared/DataFormatters");
|
|
6
|
+
const OperationUtils_1 = require("./shared/OperationUtils");
|
|
7
|
+
const OperationHandler_1 = require("./shared/OperationHandler");
|
|
8
|
+
var NoteOperation;
|
|
9
|
+
(function (NoteOperation) {
|
|
10
|
+
NoteOperation["Create"] = "create";
|
|
11
|
+
NoteOperation["Get"] = "get";
|
|
12
|
+
NoteOperation["GetNotesBySlug"] = "getNotesBySlug";
|
|
13
|
+
NoteOperation["GetNoteById"] = "getNoteById";
|
|
14
|
+
})(NoteOperation || (exports.NoteOperation = NoteOperation = {}));
|
|
15
|
+
exports.noteOperations = [
|
|
16
|
+
{
|
|
17
|
+
displayName: 'Operation',
|
|
18
|
+
name: 'operation',
|
|
19
|
+
type: 'options',
|
|
20
|
+
default: 'get',
|
|
21
|
+
noDataExpression: true,
|
|
22
|
+
displayOptions: {
|
|
23
|
+
show: {
|
|
24
|
+
resource: ['note'],
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
options: [
|
|
28
|
+
{
|
|
29
|
+
name: 'Create Note',
|
|
30
|
+
value: NoteOperation.Create,
|
|
31
|
+
description: 'Create a new SubstackGateway note',
|
|
32
|
+
action: 'Create note',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'Get Notes',
|
|
36
|
+
value: NoteOperation.Get,
|
|
37
|
+
description: 'Get notes from own profile',
|
|
38
|
+
action: 'Get notes',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'Get Notes From Profile by Slug',
|
|
42
|
+
value: NoteOperation.GetNotesBySlug,
|
|
43
|
+
description: 'Get notes from a profile by its publication slug',
|
|
44
|
+
action: 'Get notes by slug',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'Get Note by ID',
|
|
48
|
+
value: NoteOperation.GetNoteById,
|
|
49
|
+
description: 'Get a specific note by its ID',
|
|
50
|
+
action: 'Get note by ID',
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
];
|
|
55
|
+
async function get(executeFunctions, client, publicationAddress, itemIndex) {
|
|
56
|
+
return OperationHandler_1.OperationHandler.execute(executeFunctions, itemIndex, async () => {
|
|
57
|
+
const limit = OperationHandler_1.OperationHandler.getLimit(executeFunctions, itemIndex);
|
|
58
|
+
const profile = await OperationHandler_1.OperationHandler.resolveProfile(client);
|
|
59
|
+
return OperationHandler_1.OperationHandler.collectFromIterable(profile.notes(), limit, (note) => DataFormatters_1.DataFormatters.formatNote(note, publicationAddress));
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
async function getNotesBySlug(executeFunctions, client, publicationAddress, itemIndex) {
|
|
63
|
+
return OperationHandler_1.OperationHandler.execute(executeFunctions, itemIndex, async () => {
|
|
64
|
+
const slug = executeFunctions.getNodeParameter('slug', itemIndex);
|
|
65
|
+
const limit = OperationHandler_1.OperationHandler.getLimit(executeFunctions, itemIndex);
|
|
66
|
+
const profile = await OperationHandler_1.OperationHandler.resolveProfile(client, slug);
|
|
67
|
+
return OperationHandler_1.OperationHandler.collectFromIterable(profile.notes(), limit, (note) => DataFormatters_1.DataFormatters.formatNote(note, publicationAddress));
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
async function getNoteById(executeFunctions, client, publicationAddress, itemIndex) {
|
|
71
|
+
return OperationHandler_1.OperationHandler.execute(executeFunctions, itemIndex, async () => {
|
|
72
|
+
const noteId = OperationUtils_1.OperationUtils.parseNumericParam(executeFunctions.getNodeParameter('noteId', itemIndex), 'noteId');
|
|
73
|
+
const note = await client.noteForId(noteId);
|
|
74
|
+
return DataFormatters_1.DataFormatters.formatNote(note, publicationAddress);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
async function create(executeFunctions, client, publicationAddress, itemIndex) {
|
|
78
|
+
return OperationHandler_1.OperationHandler.execute(executeFunctions, itemIndex, async () => {
|
|
79
|
+
const body = executeFunctions.getNodeParameter('body', itemIndex);
|
|
80
|
+
const visibility = executeFunctions.getNodeParameter('visibility', itemIndex, 'everyone');
|
|
81
|
+
const attachment = executeFunctions.getNodeParameter('attachment', itemIndex, 'none');
|
|
82
|
+
const linkUrl = attachment === 'link'
|
|
83
|
+
? executeFunctions.getNodeParameter('linkUrl', itemIndex)
|
|
84
|
+
: undefined;
|
|
85
|
+
if (!body || !body.trim()) {
|
|
86
|
+
throw new Error('Note must contain at least one paragraph with content - body cannot be empty');
|
|
87
|
+
}
|
|
88
|
+
const ownProfile = await client.ownProfile();
|
|
89
|
+
const response = await ownProfile.publishNote(body.trim(), linkUrl ? { attachment: linkUrl } : undefined);
|
|
90
|
+
return {
|
|
91
|
+
success: true,
|
|
92
|
+
noteId: response.id.toString(),
|
|
93
|
+
body: body.trim(),
|
|
94
|
+
url: SubstackUtils_1.SubstackUtils.formatUrl(publicationAddress, `/p/${response.id}`),
|
|
95
|
+
date: new Date().toISOString(),
|
|
96
|
+
status: 'published',
|
|
97
|
+
visibility,
|
|
98
|
+
attachment,
|
|
99
|
+
linkUrl,
|
|
100
|
+
};
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
exports.noteOperationHandlers = {
|
|
104
|
+
[NoteOperation.Create]: create,
|
|
105
|
+
[NoteOperation.Get]: get,
|
|
106
|
+
[NoteOperation.GetNotesBySlug]: getNotesBySlug,
|
|
107
|
+
[NoteOperation.GetNoteById]: getNoteById,
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=Note.operations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Note.operations.js","sourceRoot":"","sources":["../../../nodes/SubstackGateway/Note.operations.ts"],"names":[],"mappings":"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"}
|