n8n-nodes-pinterest 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 +47 -0
- package/dist/credentials/PinterestCookieApi.credentials.d.ts +7 -0
- package/dist/credentials/PinterestCookieApi.credentials.js +29 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +7 -0
- package/dist/nodes/PinterestCookie/PinterestCookie.node.d.ts +10 -0
- package/dist/nodes/PinterestCookie/PinterestCookie.node.js +367 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# n8n-nodes-pinterest
|
|
2
|
+
|
|
3
|
+
Community n8n nodes for Pinterest using cookie-based authentication that mimics the web flow.
|
|
4
|
+
|
|
5
|
+
Supports:
|
|
6
|
+
|
|
7
|
+
- Cookie-based authentication (session cookie)
|
|
8
|
+
- List boards (current user)
|
|
9
|
+
- Create a Pin with a binary image input
|
|
10
|
+
|
|
11
|
+
Notes:
|
|
12
|
+
|
|
13
|
+
- Uses undocumented web endpoints; use at your own risk
|
|
14
|
+
- May violate Pinterest's Terms of Service and can break without notice
|
|
15
|
+
- Consider proxies if Pinterest flags your IP
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
npm install n8n-nodes-pinterest
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Restart n8n. The node and credential will appear in the editor.
|
|
24
|
+
|
|
25
|
+
## Credentials
|
|
26
|
+
|
|
27
|
+
Add a new credential "Pinterest Cookie" and paste your `_pinterest_sess` value from a logged-in browser session. Optionally set a proxy.
|
|
28
|
+
|
|
29
|
+
## Node usage
|
|
30
|
+
|
|
31
|
+
### Pinterest Cookie Node: Board → Get Many
|
|
32
|
+
Lists boards via Pinterest web resource endpoint.
|
|
33
|
+
|
|
34
|
+
### Pinterest Cookie Node: Pin → Create
|
|
35
|
+
Creates a pin using cookie-based authentication.
|
|
36
|
+
|
|
37
|
+
Inputs:
|
|
38
|
+
|
|
39
|
+
- Board (select from available boards)
|
|
40
|
+
- Binary Property (e.g. `data`)
|
|
41
|
+
- Optional: Title, Description, Link, Alt Text
|
|
42
|
+
|
|
43
|
+
Binary image comes from the input item's binary property. The node uploads the image to the `upload_url` from VIPResource, derives the final `image_url` from the `ETag`, then creates the Pin via `PinResource/create/`.
|
|
44
|
+
|
|
45
|
+
## Disclaimer
|
|
46
|
+
|
|
47
|
+
This package uses cookie-based authentication and undocumented endpoints. Use at your own risk and in accordance with Pinterest's Terms of Service.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PinterestCookieApi = void 0;
|
|
4
|
+
class PinterestCookieApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'pinterestCookieApi';
|
|
7
|
+
this.displayName = 'Pinterest Cookie';
|
|
8
|
+
this.documentationUrl = 'https://www.pinterest.com';
|
|
9
|
+
this.properties = [
|
|
10
|
+
{
|
|
11
|
+
displayName: 'Pinterest Session Cookie (_pinterest_sess)',
|
|
12
|
+
name: 'pinterestSess',
|
|
13
|
+
type: 'string',
|
|
14
|
+
typeOptions: { password: true },
|
|
15
|
+
default: '',
|
|
16
|
+
required: true,
|
|
17
|
+
description: 'Value of the _pinterest_sess cookie from a logged-in session',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
displayName: 'Proxy',
|
|
21
|
+
name: 'proxy',
|
|
22
|
+
type: 'string',
|
|
23
|
+
default: '',
|
|
24
|
+
description: 'Optional HTTP proxy (e.g. http://user:pass@host:port)',
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.PinterestCookieApi = PinterestCookieApi;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.credentials = exports.nodes = void 0;
|
|
4
|
+
const PinterestCookie_node_1 = require("./nodes/PinterestCookie/PinterestCookie.node");
|
|
5
|
+
const PinterestCookieApi_credentials_1 = require("./credentials/PinterestCookieApi.credentials");
|
|
6
|
+
exports.nodes = [new PinterestCookie_node_1.PinterestCookie()];
|
|
7
|
+
exports.credentials = [PinterestCookieApi_credentials_1.PinterestCookieApi];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class PinterestCookie implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
methods: {
|
|
5
|
+
loadOptions: {
|
|
6
|
+
getBoardsCookie(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PinterestCookie = void 0;
|
|
4
|
+
function randomCsrf() {
|
|
5
|
+
// similar to plugin: base64 of microtime + random
|
|
6
|
+
const seed = `${Date.now()}${Math.floor(Math.random() * 100000)}`;
|
|
7
|
+
return Buffer.from(seed).toString('base64');
|
|
8
|
+
}
|
|
9
|
+
function buildCommonHeaders(csrf) {
|
|
10
|
+
return {
|
|
11
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0',
|
|
12
|
+
'x-pinterest-pws-handler': 'www/[username].js',
|
|
13
|
+
'x-CSRFToken': csrf,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function buildCookieHeader(sess, csrf) {
|
|
17
|
+
return `_pinterest_sess=${sess}; csrftoken=${csrf};`;
|
|
18
|
+
}
|
|
19
|
+
const PINTEREST_BASE = 'https://www.pinterest.com';
|
|
20
|
+
class PinterestCookie {
|
|
21
|
+
constructor() {
|
|
22
|
+
this.description = {
|
|
23
|
+
displayName: 'Pinterest (Cookie)',
|
|
24
|
+
name: 'pinterestCookie',
|
|
25
|
+
icon: 'fa:pinterest',
|
|
26
|
+
group: ['output'],
|
|
27
|
+
version: 1,
|
|
28
|
+
subtitle: '={{$parameter["resource"] + ": " + $parameter["operation"]}}',
|
|
29
|
+
description: 'Pinterest via cookie method (web endpoints)',
|
|
30
|
+
defaults: { name: 'Pinterest (Cookie)' },
|
|
31
|
+
inputs: ['main'],
|
|
32
|
+
outputs: ['main'],
|
|
33
|
+
credentials: [
|
|
34
|
+
{ name: 'pinterestCookieApi', required: true },
|
|
35
|
+
],
|
|
36
|
+
properties: [
|
|
37
|
+
{
|
|
38
|
+
displayName: 'Resource',
|
|
39
|
+
name: 'resource',
|
|
40
|
+
type: 'options',
|
|
41
|
+
noDataExpression: true,
|
|
42
|
+
options: [
|
|
43
|
+
{ name: 'Pin', value: 'pin' },
|
|
44
|
+
{ name: 'Board', value: 'board' },
|
|
45
|
+
{ name: 'Me', value: 'me' },
|
|
46
|
+
],
|
|
47
|
+
default: 'pin',
|
|
48
|
+
},
|
|
49
|
+
// Pin operations
|
|
50
|
+
{
|
|
51
|
+
displayName: 'Operation',
|
|
52
|
+
name: 'operation',
|
|
53
|
+
type: 'options',
|
|
54
|
+
displayOptions: { show: { resource: ['pin'] } },
|
|
55
|
+
options: [
|
|
56
|
+
{ name: 'Create', value: 'create', action: 'Create a pin' },
|
|
57
|
+
],
|
|
58
|
+
default: 'create',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
displayName: 'Board',
|
|
62
|
+
name: 'boardId',
|
|
63
|
+
type: 'options',
|
|
64
|
+
typeOptions: { loadOptionsMethod: 'getBoardsCookie' },
|
|
65
|
+
displayOptions: { show: { resource: ['pin'], operation: ['create'] } },
|
|
66
|
+
default: '',
|
|
67
|
+
required: true,
|
|
68
|
+
description: 'Board to pin to',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
displayName: 'Binary Property',
|
|
72
|
+
name: 'binaryProperty',
|
|
73
|
+
type: 'string',
|
|
74
|
+
default: 'data',
|
|
75
|
+
required: true,
|
|
76
|
+
displayOptions: { show: { resource: ['pin'], operation: ['create'] } },
|
|
77
|
+
description: 'Name of the binary property containing the image',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
displayName: 'Title',
|
|
81
|
+
name: 'title',
|
|
82
|
+
type: 'string',
|
|
83
|
+
default: '',
|
|
84
|
+
displayOptions: { show: { resource: ['pin'], operation: ['create'] } },
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
displayName: 'Description',
|
|
88
|
+
name: 'description',
|
|
89
|
+
type: 'string',
|
|
90
|
+
default: '',
|
|
91
|
+
displayOptions: { show: { resource: ['pin'], operation: ['create'] } },
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
displayName: 'Additional Fields',
|
|
95
|
+
name: 'additionalFields',
|
|
96
|
+
type: 'collection',
|
|
97
|
+
placeholder: 'Add Field',
|
|
98
|
+
default: {},
|
|
99
|
+
displayOptions: { show: { resource: ['pin'], operation: ['create'] } },
|
|
100
|
+
options: [
|
|
101
|
+
{ displayName: 'Alt Text', name: 'alt_text', type: 'string', default: '' },
|
|
102
|
+
{ displayName: 'Link', name: 'link', type: 'string', default: '' },
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
// Board ops
|
|
106
|
+
{
|
|
107
|
+
displayName: 'Operation',
|
|
108
|
+
name: 'boardOperation',
|
|
109
|
+
type: 'options',
|
|
110
|
+
displayOptions: { show: { resource: ['board'] } },
|
|
111
|
+
options: [
|
|
112
|
+
{ name: 'Get Many', value: 'getAll', action: 'List boards' },
|
|
113
|
+
],
|
|
114
|
+
default: 'getAll',
|
|
115
|
+
},
|
|
116
|
+
// Me ops
|
|
117
|
+
{
|
|
118
|
+
displayName: 'Operation',
|
|
119
|
+
name: 'meOperation',
|
|
120
|
+
type: 'options',
|
|
121
|
+
displayOptions: { show: { resource: ['me'] } },
|
|
122
|
+
options: [
|
|
123
|
+
{ name: 'Get', value: 'get', action: 'Get my info' },
|
|
124
|
+
],
|
|
125
|
+
default: 'get',
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
};
|
|
129
|
+
this.methods = {
|
|
130
|
+
loadOptions: {
|
|
131
|
+
async getBoardsCookie() {
|
|
132
|
+
var _a, _b;
|
|
133
|
+
const creds = (await this.getCredentials('pinterestCookieApi'));
|
|
134
|
+
const pinterestSess = String(creds.pinterestSess || creds.pinterestsess || '');
|
|
135
|
+
const proxy = creds.proxy || '';
|
|
136
|
+
const csrf = randomCsrf();
|
|
137
|
+
const headers = {
|
|
138
|
+
...buildCommonHeaders(csrf),
|
|
139
|
+
Cookie: buildCookieHeader(pinterestSess, csrf),
|
|
140
|
+
};
|
|
141
|
+
// Fetch username first (like plugin getMyInfo)
|
|
142
|
+
const meResp = (await this.helpers.request({
|
|
143
|
+
method: 'GET',
|
|
144
|
+
uri: `${PINTEREST_BASE}/resource/HomefeedBadgingResource/get/`,
|
|
145
|
+
headers,
|
|
146
|
+
proxy: proxy || undefined,
|
|
147
|
+
}));
|
|
148
|
+
const meJson = JSON.parse(meResp);
|
|
149
|
+
const username = String(((_b = (_a = meJson.client_context) === null || _a === void 0 ? void 0 : _a.user) === null || _b === void 0 ? void 0 : _b.username) || '');
|
|
150
|
+
const boards = [];
|
|
151
|
+
let bookmark = '';
|
|
152
|
+
while (true) {
|
|
153
|
+
const data = {
|
|
154
|
+
options: {
|
|
155
|
+
isPrefetch: false,
|
|
156
|
+
privacy_filter: 'all',
|
|
157
|
+
sort: 'custom',
|
|
158
|
+
field_set_key: 'profile_grid_item',
|
|
159
|
+
username,
|
|
160
|
+
page_size: 25,
|
|
161
|
+
group_by: 'visibility',
|
|
162
|
+
include_archived: true,
|
|
163
|
+
redux_normalize_feed: true,
|
|
164
|
+
...(bookmark ? { bookmarks: [bookmark] } : {}),
|
|
165
|
+
},
|
|
166
|
+
context: {},
|
|
167
|
+
};
|
|
168
|
+
const qs = { data: JSON.stringify(data) };
|
|
169
|
+
const resp = (await this.helpers.request({
|
|
170
|
+
method: 'GET',
|
|
171
|
+
uri: `${PINTEREST_BASE}/resource/BoardsResource/get/`,
|
|
172
|
+
qs,
|
|
173
|
+
headers,
|
|
174
|
+
proxy: proxy || undefined,
|
|
175
|
+
json: true,
|
|
176
|
+
}));
|
|
177
|
+
const resource = resp.resource_response || {};
|
|
178
|
+
const pageBoards = resource.data || [];
|
|
179
|
+
for (const b of pageBoards) {
|
|
180
|
+
boards.push({ id: String(b.id), name: String(b.name || b.id) });
|
|
181
|
+
}
|
|
182
|
+
const next = String(resource.bookmark || '');
|
|
183
|
+
if (!next || next === '-end-')
|
|
184
|
+
break;
|
|
185
|
+
bookmark = next;
|
|
186
|
+
}
|
|
187
|
+
return boards.map((b) => ({ name: b.name, value: b.id }));
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
async execute() {
|
|
193
|
+
var _a, _b, _c, _d;
|
|
194
|
+
const items = this.getInputData();
|
|
195
|
+
const returnData = [];
|
|
196
|
+
const creds = (await this.getCredentials('pinterestCookieApi'));
|
|
197
|
+
const pinterestSess = String(creds.pinterestSess || creds.pinterestsess || '');
|
|
198
|
+
const proxy = creds.proxy || '';
|
|
199
|
+
for (let i = 0; i < items.length; i++) {
|
|
200
|
+
try {
|
|
201
|
+
const resource = this.getNodeParameter('resource', i);
|
|
202
|
+
const csrf = randomCsrf();
|
|
203
|
+
const baseHeaders = buildCommonHeaders(csrf);
|
|
204
|
+
const cookieHeader = buildCookieHeader(pinterestSess, csrf);
|
|
205
|
+
if (resource === 'me') {
|
|
206
|
+
const resp = (await this.helpers.request({
|
|
207
|
+
method: 'GET',
|
|
208
|
+
uri: `${PINTEREST_BASE}/resource/HomefeedBadgingResource/get/`,
|
|
209
|
+
headers: { ...baseHeaders, Cookie: cookieHeader },
|
|
210
|
+
proxy: proxy || undefined,
|
|
211
|
+
}));
|
|
212
|
+
const json = JSON.parse(resp);
|
|
213
|
+
returnData.push({ json });
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
if (resource === 'board') {
|
|
217
|
+
// Fetch username first to scope boards
|
|
218
|
+
const meResp = (await this.helpers.request({
|
|
219
|
+
method: 'GET',
|
|
220
|
+
uri: `${PINTEREST_BASE}/resource/HomefeedBadgingResource/get/`,
|
|
221
|
+
headers: { ...baseHeaders, Cookie: cookieHeader },
|
|
222
|
+
proxy: proxy || undefined,
|
|
223
|
+
}));
|
|
224
|
+
const meJson = JSON.parse(meResp);
|
|
225
|
+
const username = String(((_b = (_a = meJson.client_context) === null || _a === void 0 ? void 0 : _a.user) === null || _b === void 0 ? void 0 : _b.username) || '');
|
|
226
|
+
const resp = (await this.helpers.request({
|
|
227
|
+
method: 'GET',
|
|
228
|
+
uri: `${PINTEREST_BASE}/resource/BoardsResource/get/`,
|
|
229
|
+
qs: {
|
|
230
|
+
data: JSON.stringify({
|
|
231
|
+
options: {
|
|
232
|
+
isPrefetch: false,
|
|
233
|
+
privacy_filter: 'all',
|
|
234
|
+
sort: 'custom',
|
|
235
|
+
field_set_key: 'profile_grid_item',
|
|
236
|
+
username,
|
|
237
|
+
page_size: 25,
|
|
238
|
+
group_by: 'visibility',
|
|
239
|
+
include_archived: true,
|
|
240
|
+
redux_normalize_feed: true,
|
|
241
|
+
},
|
|
242
|
+
context: {},
|
|
243
|
+
}),
|
|
244
|
+
},
|
|
245
|
+
headers: { ...baseHeaders, Cookie: cookieHeader },
|
|
246
|
+
proxy: proxy || undefined,
|
|
247
|
+
json: true,
|
|
248
|
+
}));
|
|
249
|
+
returnData.push({ json: resp });
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
if (resource === 'pin') {
|
|
253
|
+
const operation = this.getNodeParameter('operation', i);
|
|
254
|
+
if (operation === 'create') {
|
|
255
|
+
const boardId = this.getNodeParameter('boardId', i);
|
|
256
|
+
const binaryProperty = this.getNodeParameter('binaryProperty', i);
|
|
257
|
+
const title = this.getNodeParameter('title', i, '');
|
|
258
|
+
const description = this.getNodeParameter('description', i, '');
|
|
259
|
+
const additionalFields = this.getNodeParameter('additionalFields', i, {});
|
|
260
|
+
const binary = (_c = items[i].binary) === null || _c === void 0 ? void 0 : _c[binaryProperty];
|
|
261
|
+
if (!binary)
|
|
262
|
+
throw new Error(`Binary property "${binaryProperty}" is missing on item ${i}`);
|
|
263
|
+
// Step 1: request upload slot
|
|
264
|
+
const vipResp = (await this.helpers.request({
|
|
265
|
+
method: 'POST',
|
|
266
|
+
uri: `${PINTEREST_BASE}/resource/VIPResource/create/`,
|
|
267
|
+
form: {
|
|
268
|
+
source_url: '/pin-builder/',
|
|
269
|
+
data: '{"options":{"type":"pinimage"},"context":{}}',
|
|
270
|
+
},
|
|
271
|
+
headers: { ...baseHeaders, Cookie: cookieHeader },
|
|
272
|
+
proxy: proxy || undefined,
|
|
273
|
+
}));
|
|
274
|
+
const vip = JSON.parse(vipResp);
|
|
275
|
+
const res = vip.resource_response || {};
|
|
276
|
+
const data = res.data || {};
|
|
277
|
+
const uploadUrl = String(data.upload_url || '');
|
|
278
|
+
const uploadParams = data.upload_parameters || {};
|
|
279
|
+
if (!uploadUrl)
|
|
280
|
+
throw new Error('Failed to get upload URL');
|
|
281
|
+
// Step 2: upload image
|
|
282
|
+
const buffer = Buffer.from(binary.data, 'base64');
|
|
283
|
+
const contentType = binary.mimeType || 'image/jpeg';
|
|
284
|
+
const formData = {};
|
|
285
|
+
for (const [k, v] of Object.entries(uploadParams))
|
|
286
|
+
formData[k] = String(v);
|
|
287
|
+
formData['file'] = {
|
|
288
|
+
value: buffer,
|
|
289
|
+
options: {
|
|
290
|
+
filename: 'blob',
|
|
291
|
+
contentType,
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
const uploadResp = (await this.helpers.request({
|
|
295
|
+
method: 'POST',
|
|
296
|
+
uri: uploadUrl,
|
|
297
|
+
headers: {
|
|
298
|
+
Accept: '*/*',
|
|
299
|
+
'Accept-Encoding': 'gzip',
|
|
300
|
+
'User-Agent': baseHeaders['User-Agent'],
|
|
301
|
+
Origin: 'https://www.pinterest.com',
|
|
302
|
+
Referer: 'https://www.pinterest.com',
|
|
303
|
+
},
|
|
304
|
+
formData,
|
|
305
|
+
proxy: proxy || undefined,
|
|
306
|
+
// get full response to read headers
|
|
307
|
+
resolveWithFullResponse: true,
|
|
308
|
+
simple: false,
|
|
309
|
+
}));
|
|
310
|
+
const etagRaw = uploadResp.headers['etag'] || uploadResp.headers['ETag'] || '';
|
|
311
|
+
const etag = String(etagRaw).replace(/"/g, '');
|
|
312
|
+
if (!etag)
|
|
313
|
+
throw new Error('Upload failed: missing ETag');
|
|
314
|
+
// compute imageUrl like plugin
|
|
315
|
+
const imageUrl = `https://i.pinimg.com/736x/${etag[0]}${etag[1]}/${etag[2]}${etag[3]}/${etag[4]}${etag[5]}/${etag}.jpg`;
|
|
316
|
+
// Step 3: create pin
|
|
317
|
+
const sendData = {
|
|
318
|
+
options: {
|
|
319
|
+
board_id: boardId,
|
|
320
|
+
field_set_key: 'create_success',
|
|
321
|
+
skip_pin_create_log: true,
|
|
322
|
+
description,
|
|
323
|
+
alt_text: additionalFields.alt_text || '',
|
|
324
|
+
link: additionalFields.link || '',
|
|
325
|
+
title,
|
|
326
|
+
image_url: imageUrl,
|
|
327
|
+
method: 'uploaded',
|
|
328
|
+
upload_metric: { source: 'pinner_upload_standalone' },
|
|
329
|
+
user_mention_tags: [],
|
|
330
|
+
no_fetch_context_on_resource: false,
|
|
331
|
+
},
|
|
332
|
+
context: {},
|
|
333
|
+
};
|
|
334
|
+
const createResp = (await this.helpers.request({
|
|
335
|
+
method: 'POST',
|
|
336
|
+
uri: `${PINTEREST_BASE}/resource/PinResource/create/`,
|
|
337
|
+
form: {
|
|
338
|
+
source_url: '/pin-builder/',
|
|
339
|
+
data: JSON.stringify(sendData),
|
|
340
|
+
},
|
|
341
|
+
headers: { ...baseHeaders, Cookie: cookieHeader },
|
|
342
|
+
proxy: proxy || undefined,
|
|
343
|
+
}));
|
|
344
|
+
const created = JSON.parse(createResp);
|
|
345
|
+
const createdRes = created.resource_response || {};
|
|
346
|
+
const pinData = createdRes.data || {};
|
|
347
|
+
const id = String(pinData.id || '');
|
|
348
|
+
if (!id) {
|
|
349
|
+
const message = createdRes.message || ((_d = createdRes.error) === null || _d === void 0 ? void 0 : _d.message) || 'Create failed';
|
|
350
|
+
throw new Error(String(message));
|
|
351
|
+
}
|
|
352
|
+
returnData.push({ json: { id, link: `https://www.pinterest.com/pin/${id}` } });
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
if (this.continueOnFail()) {
|
|
358
|
+
returnData.push({ json: { error: error.message }, pairedItem: { item: i } });
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
throw error;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return [returnData];
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
exports.PinterestCookie = PinterestCookie;
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-pinterest",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "n8n community nodes for Pinterest v5 API (list boards, create pins)",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"n8n",
|
|
8
|
+
"pinterest",
|
|
9
|
+
"pins",
|
|
10
|
+
"boards"
|
|
11
|
+
],
|
|
12
|
+
"author": "Community",
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"main": "dist/index.js",
|
|
15
|
+
"types": "dist/index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist/**"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc -p ."
|
|
21
|
+
},
|
|
22
|
+
"n8n": {
|
|
23
|
+
"credentials": [
|
|
24
|
+
"dist/credentials/PinterestCookieApi.credentials.js"
|
|
25
|
+
],
|
|
26
|
+
"nodes": [
|
|
27
|
+
"dist/nodes/PinterestCookie/PinterestCookie.node.js"
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^18.19.0",
|
|
32
|
+
"n8n-core": "^1.58.0",
|
|
33
|
+
"n8n-workflow": "^1.58.0",
|
|
34
|
+
"typescript": "^5.4.5"
|
|
35
|
+
}
|
|
36
|
+
}
|