@openfn/language-mailchimp 0.4.1 → 0.6.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 +0 -30
- package/dist/index.cjs +234 -64
- package/dist/index.js +204 -49
- package/package.json +4 -4
- package/types/Adaptor.d.ts +104 -7
- package/types/Utils.d.ts +3 -0
package/README.md
CHANGED
|
@@ -12,36 +12,6 @@ official
|
|
|
12
12
|
[configuration-schema](https://docs.openfn.org/adaptors/packages/mailchimp-configuration-schema/)
|
|
13
13
|
definition.
|
|
14
14
|
|
|
15
|
-
#### sample expression with multiple operations
|
|
16
|
-
|
|
17
|
-
```js
|
|
18
|
-
upsertMembers({
|
|
19
|
-
listId: 'someId',
|
|
20
|
-
users: state =>
|
|
21
|
-
state.response.body.rows.map(u => ({
|
|
22
|
-
email: u.email,
|
|
23
|
-
status: u.allow_other_emails ? 'subscribed' : 'unsubscribed',
|
|
24
|
-
mergeFields: { FNAME: u.first_name, LNAME: u.last_name },
|
|
25
|
-
})),
|
|
26
|
-
options: {},
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
tagMembers({
|
|
30
|
-
listId: 'someId', // All Subscribers
|
|
31
|
-
tagId: 'someTag', // User
|
|
32
|
-
members: state => state.response.body.rows.map(u => u.email),
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
tagMembers({
|
|
36
|
-
listId: 'someId', // All Subscribers
|
|
37
|
-
tagId: 'someTag', // Other Emails Allowed
|
|
38
|
-
members: state =>
|
|
39
|
-
state.response.body.rows
|
|
40
|
-
.filter(u => u.allow_other_emails)
|
|
41
|
-
.map(u => u.email),
|
|
42
|
-
});
|
|
43
|
-
```
|
|
44
|
-
|
|
45
15
|
## Development
|
|
46
16
|
|
|
47
17
|
Clone the [adaptors monorepo](https://github.com/OpenFn/adaptors). Follow the
|
package/dist/index.cjs
CHANGED
|
@@ -25,23 +25,34 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
25
25
|
// src/index.js
|
|
26
26
|
var src_exports = {};
|
|
27
27
|
__export(src_exports, {
|
|
28
|
-
|
|
28
|
+
addMember: () => addMember,
|
|
29
|
+
alterState: () => import_language_common3.alterState,
|
|
30
|
+
archiveMember: () => archiveMember,
|
|
29
31
|
axios: () => import_axios.default,
|
|
30
|
-
dataPath: () =>
|
|
31
|
-
dataValue: () =>
|
|
32
|
+
dataPath: () => import_language_common3.dataPath,
|
|
33
|
+
dataValue: () => import_language_common3.dataValue,
|
|
32
34
|
default: () => src_default,
|
|
33
|
-
|
|
35
|
+
deleteMember: () => deleteMember,
|
|
36
|
+
each: () => import_language_common3.each,
|
|
34
37
|
execute: () => execute,
|
|
35
|
-
field: () =>
|
|
36
|
-
fields: () =>
|
|
37
|
-
fn: () =>
|
|
38
|
-
|
|
38
|
+
field: () => import_language_common3.field,
|
|
39
|
+
fields: () => import_language_common3.fields,
|
|
40
|
+
fn: () => import_language_common3.fn,
|
|
41
|
+
get: () => get,
|
|
42
|
+
lastReferenceValue: () => import_language_common3.lastReferenceValue,
|
|
43
|
+
listAudienceInfo: () => listAudienceInfo,
|
|
44
|
+
listAudiences: () => listAudiences,
|
|
39
45
|
listBatches: () => listBatches,
|
|
46
|
+
listMembers: () => listMembers,
|
|
40
47
|
md5: () => import_md5.default,
|
|
41
|
-
merge: () =>
|
|
42
|
-
|
|
48
|
+
merge: () => import_language_common3.merge,
|
|
49
|
+
post: () => post,
|
|
50
|
+
request: () => request,
|
|
51
|
+
sourceValue: () => import_language_common3.sourceValue,
|
|
43
52
|
startBatch: () => startBatch,
|
|
44
53
|
tagMembers: () => tagMembers,
|
|
54
|
+
updateMember: () => updateMember,
|
|
55
|
+
updateMemberTags: () => updateMemberTags,
|
|
45
56
|
upsertMembers: () => upsertMembers
|
|
46
57
|
});
|
|
47
58
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -49,115 +60,274 @@ module.exports = __toCommonJS(src_exports);
|
|
|
49
60
|
// src/Adaptor.js
|
|
50
61
|
var Adaptor_exports = {};
|
|
51
62
|
__export(Adaptor_exports, {
|
|
52
|
-
|
|
63
|
+
addMember: () => addMember,
|
|
64
|
+
alterState: () => import_language_common3.alterState,
|
|
65
|
+
archiveMember: () => archiveMember,
|
|
53
66
|
axios: () => import_axios.default,
|
|
54
|
-
dataPath: () =>
|
|
55
|
-
dataValue: () =>
|
|
56
|
-
|
|
67
|
+
dataPath: () => import_language_common3.dataPath,
|
|
68
|
+
dataValue: () => import_language_common3.dataValue,
|
|
69
|
+
deleteMember: () => deleteMember,
|
|
70
|
+
each: () => import_language_common3.each,
|
|
57
71
|
execute: () => execute,
|
|
58
|
-
field: () =>
|
|
59
|
-
fields: () =>
|
|
60
|
-
fn: () =>
|
|
61
|
-
|
|
72
|
+
field: () => import_language_common3.field,
|
|
73
|
+
fields: () => import_language_common3.fields,
|
|
74
|
+
fn: () => import_language_common3.fn,
|
|
75
|
+
get: () => get,
|
|
76
|
+
lastReferenceValue: () => import_language_common3.lastReferenceValue,
|
|
77
|
+
listAudienceInfo: () => listAudienceInfo,
|
|
78
|
+
listAudiences: () => listAudiences,
|
|
62
79
|
listBatches: () => listBatches,
|
|
80
|
+
listMembers: () => listMembers,
|
|
63
81
|
md5: () => import_md5.default,
|
|
64
|
-
merge: () =>
|
|
65
|
-
|
|
82
|
+
merge: () => import_language_common3.merge,
|
|
83
|
+
post: () => post,
|
|
84
|
+
request: () => request,
|
|
85
|
+
sourceValue: () => import_language_common3.sourceValue,
|
|
66
86
|
startBatch: () => startBatch,
|
|
67
87
|
tagMembers: () => tagMembers,
|
|
88
|
+
updateMember: () => updateMember,
|
|
89
|
+
updateMemberTags: () => updateMemberTags,
|
|
68
90
|
upsertMembers: () => upsertMembers
|
|
69
91
|
});
|
|
70
|
-
var
|
|
92
|
+
var import_md5 = __toESM(require("md5"), 1);
|
|
71
93
|
var import_axios = __toESM(require("axios"), 1);
|
|
72
94
|
var import_mailchimp_marketing = __toESM(require("@mailchimp/mailchimp_marketing"), 1);
|
|
73
|
-
var
|
|
95
|
+
var import_util = require("@openfn/language-common/util");
|
|
74
96
|
var import_language_common2 = require("@openfn/language-common");
|
|
97
|
+
|
|
98
|
+
// src/Utils.js
|
|
99
|
+
var import_language_common = require("@openfn/language-common");
|
|
100
|
+
var import_undici = require("undici");
|
|
101
|
+
var client;
|
|
102
|
+
var getClient = (baseUrl) => {
|
|
103
|
+
if (client) {
|
|
104
|
+
return client;
|
|
105
|
+
}
|
|
106
|
+
return new import_undici.Client(baseUrl);
|
|
107
|
+
};
|
|
108
|
+
function handleResponse(response, state, callback) {
|
|
109
|
+
const nextState = {
|
|
110
|
+
...(0, import_language_common.composeNextState)(state, response),
|
|
111
|
+
response
|
|
112
|
+
};
|
|
113
|
+
if (callback)
|
|
114
|
+
return callback(nextState);
|
|
115
|
+
return nextState;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/Adaptor.js
|
|
119
|
+
var import_language_common3 = require("@openfn/language-common");
|
|
75
120
|
function execute(...operations) {
|
|
76
121
|
const initialState = {
|
|
77
122
|
references: [],
|
|
78
123
|
data: null
|
|
79
124
|
};
|
|
80
125
|
return (state) => {
|
|
81
|
-
return (0,
|
|
126
|
+
return (0, import_language_common2.execute)(
|
|
127
|
+
createClient,
|
|
128
|
+
...operations,
|
|
129
|
+
cleanupState
|
|
130
|
+
)({
|
|
82
131
|
...initialState,
|
|
83
132
|
...state
|
|
84
133
|
});
|
|
85
134
|
};
|
|
86
135
|
}
|
|
87
|
-
function
|
|
136
|
+
function createClient(state) {
|
|
137
|
+
const { apiKey, server } = state.configuration;
|
|
138
|
+
const baseUrl = `https://${server}.api.mailchimp.com`;
|
|
139
|
+
const apiClient = getClient(baseUrl);
|
|
140
|
+
import_mailchimp_marketing.default.setConfig({ apiKey, server });
|
|
141
|
+
return { ...state, apiClient, client: import_mailchimp_marketing.default };
|
|
142
|
+
}
|
|
143
|
+
function cleanupState(state) {
|
|
144
|
+
if (state == null ? void 0 : state.apiClient)
|
|
145
|
+
delete state.apiClient;
|
|
146
|
+
if (state == null ? void 0 : state.client)
|
|
147
|
+
delete state.client;
|
|
148
|
+
return state;
|
|
149
|
+
}
|
|
150
|
+
function upsertMembers(params, callback = (s) => s) {
|
|
88
151
|
return (state) => {
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
152
|
+
const [resolvedParams] = (0, import_util.expandReferences)(state, params);
|
|
153
|
+
const defaultOptions2 = {
|
|
154
|
+
update_existing: true,
|
|
155
|
+
sync_tags: false
|
|
156
|
+
};
|
|
157
|
+
const { listId: listId2, users, options } = resolvedParams;
|
|
158
|
+
const opts = { ...defaultOptions2, ...options };
|
|
159
|
+
const membersList = users.map((member2) => ({
|
|
160
|
+
email_address: member2.email,
|
|
161
|
+
status: member2.status,
|
|
162
|
+
merge_fields: member2.mergeFields,
|
|
163
|
+
tags: member2.tags
|
|
164
|
+
}));
|
|
165
|
+
return state.client.lists.batchListMembers(listId2, {
|
|
166
|
+
...opts,
|
|
167
|
+
members: membersList
|
|
168
|
+
}).then((response) => handleResponse(response, state, callback));
|
|
105
169
|
};
|
|
106
170
|
}
|
|
107
|
-
function tagMembers(params) {
|
|
171
|
+
function tagMembers(params, callback = (s) => s) {
|
|
108
172
|
return (state) => {
|
|
109
|
-
const
|
|
110
|
-
const { listId, tagId, members } =
|
|
111
|
-
|
|
112
|
-
return import_mailchimp_marketing.default.lists.batchSegmentMembers({ members_to_add: members }, listId, tagId).then((response) => {
|
|
113
|
-
const nextState = (0, import_language_common.composeNextState)(state, response);
|
|
114
|
-
return nextState;
|
|
115
|
-
});
|
|
173
|
+
const [resolvedParams] = (0, import_util.expandReferences)(state, params);
|
|
174
|
+
const { listId: listId2, tagId, members } = resolvedParams;
|
|
175
|
+
return state.client.lists.batchSegmentMembers({ members_to_add: members }, listId2, tagId).then((response) => handleResponse(response, state, callback));
|
|
116
176
|
};
|
|
117
177
|
}
|
|
118
|
-
function startBatch(params) {
|
|
178
|
+
function startBatch(params, callback = (s) => s) {
|
|
119
179
|
return (state) => {
|
|
120
|
-
const
|
|
121
|
-
const { operations } =
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
180
|
+
const [resolvedParams] = (0, import_util.expandReferences)(state, params);
|
|
181
|
+
const { operations } = resolvedParams;
|
|
182
|
+
return state.client.batches.start({ operations: [...operations] }).then((response) => handleResponse(response, state, callback));
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function listBatches(params, callback = (s) => s) {
|
|
186
|
+
return (state) => {
|
|
187
|
+
const [resolvedParams] = (0, import_util.expandReferences)(state, params);
|
|
188
|
+
return state.client.batches.list(resolvedParams).then((response) => handleResponse(response, state, callback));
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
function listMembers(params, callback = (s) => s) {
|
|
192
|
+
return (state) => {
|
|
193
|
+
const [resolvedParams] = (0, import_util.expandReferences)(state, params);
|
|
194
|
+
const { listId: listId2, ...otherParams } = resolvedParams;
|
|
195
|
+
return state.client.lists.getListMembersInfo(listId2, otherParams).then((response) => handleResponse(response, state, callback));
|
|
128
196
|
};
|
|
129
197
|
}
|
|
130
|
-
function
|
|
198
|
+
function addMember(params, callback = (s) => s) {
|
|
131
199
|
return (state) => {
|
|
200
|
+
const [resolvedParams] = (0, import_util.expandReferences)(state, params);
|
|
201
|
+
const { listId: listId2, member: member2 } = resolvedParams;
|
|
202
|
+
return state.client.lists.addListMember(listId2, ...member2).then((response) => handleResponse(response, state, callback));
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function updateMember(params = { listId, subscriberHash, member }, callback = (s) => s) {
|
|
206
|
+
return (state) => {
|
|
207
|
+
const requiredParams = ["listId", "subscriberHash"];
|
|
208
|
+
const [resolvedParams] = (0, import_util.expandReferences)(state, params);
|
|
209
|
+
assertKeys(resolvedParams, requiredParams);
|
|
210
|
+
const { listId: listId2, subscriberHash: subscriberHash2, member: member2 } = resolvedParams;
|
|
211
|
+
return state.client.lists.updateListMember(listId2, subscriberHash2, member2).then((response) => handleResponse(response, state, callback));
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function updateMemberTags(params, callback = (s) => s) {
|
|
215
|
+
return (state) => {
|
|
216
|
+
const [resolvedParams] = (0, import_util.expandReferences)(state, params);
|
|
217
|
+
const { listId: listId2, subscriberHash: subscriberHash2, tags } = resolvedParams;
|
|
218
|
+
return state.client.lists.updateListMemberTags(listId2, subscriberHash2, { tags }).then((response) => handleResponse(response, state, callback));
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function archiveMember(params, callback = (s) => s) {
|
|
222
|
+
return (state) => {
|
|
223
|
+
const [resolvedParams] = (0, import_util.expandReferences)(state, params);
|
|
224
|
+
const { listId: listId2, subscriberHash: subscriberHash2 } = resolvedParams;
|
|
225
|
+
return state.client.lists.deleteListMember(listId2, subscriberHash2).then((response) => handleResponse(response, state, callback));
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
function deleteMember(params, callback = (s) => s) {
|
|
229
|
+
return (state) => {
|
|
230
|
+
const [resolvedParams] = (0, import_util.expandReferences)(state, params);
|
|
231
|
+
const { listId: listId2, subscriberHash: subscriberHash2 } = resolvedParams;
|
|
232
|
+
return state.client.lists.deleteListMemberPermanent(listId2, subscriberHash2).then((response) => handleResponse(response, state, callback));
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
function listAudiences(query, callback = (s) => s) {
|
|
236
|
+
return (state) => {
|
|
237
|
+
const [resolvedQuery] = (0, import_util.expandReferences)(state, query);
|
|
238
|
+
return state.client.lists.getAllLists(resolvedQuery).then((response) => handleResponse(response, state, callback));
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function listAudienceInfo(query, callback = (s) => s) {
|
|
242
|
+
return (state) => {
|
|
243
|
+
const [resolvedQuery] = (0, import_util.expandReferences)(state, query);
|
|
244
|
+
const { listId: listId2, ...queries } = resolvedQuery;
|
|
245
|
+
return state.client.lists.getList(listId2, queries).then((response) => handleResponse(response, state, callback));
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
var defaultOptions = {
|
|
249
|
+
query: {},
|
|
250
|
+
body: void 0
|
|
251
|
+
};
|
|
252
|
+
var assertOK = (response, fullUrl) => {
|
|
253
|
+
if (response.statusCode >= 400) {
|
|
254
|
+
const defaultErrorMesssage = `Request to ${fullUrl} failed with status: ${response.statusCode}`;
|
|
255
|
+
const error = new Error(defaultErrorMesssage);
|
|
256
|
+
error.code = response.statusCode;
|
|
257
|
+
error.url = fullUrl;
|
|
258
|
+
throw error;
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
var request = (method, path, options, callback) => {
|
|
262
|
+
return async (state) => {
|
|
263
|
+
const apiVersion = "3.0";
|
|
132
264
|
const { apiKey, server } = state.configuration;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
265
|
+
const [resolvedMethod, resolvedPath, resolvedOptions] = (0, import_util.expandReferences)(
|
|
266
|
+
state,
|
|
267
|
+
method,
|
|
268
|
+
path,
|
|
269
|
+
options
|
|
270
|
+
);
|
|
271
|
+
const { query, body } = { ...defaultOptions, ...resolvedOptions };
|
|
272
|
+
const apiToken = Buffer.from(`openfn:${apiKey}`, "utf-8").toString(
|
|
273
|
+
"base64"
|
|
274
|
+
);
|
|
275
|
+
const headers = {
|
|
276
|
+
"Content-Type": "application/json",
|
|
277
|
+
Authorization: `Basic ${apiToken}`
|
|
278
|
+
};
|
|
279
|
+
const urlPath = `/${apiVersion}${resolvedPath}`;
|
|
280
|
+
const response = await state.apiClient.request({
|
|
281
|
+
method: resolvedMethod,
|
|
282
|
+
path: urlPath,
|
|
283
|
+
headers,
|
|
284
|
+
query,
|
|
285
|
+
body: body ? JSON.stringify(body) : void 0
|
|
138
286
|
});
|
|
287
|
+
assertOK(response, `https://${server}.api.mailchimp.com${urlPath}`);
|
|
288
|
+
const responseBody = await response.body.json();
|
|
289
|
+
const nextState = {
|
|
290
|
+
data: responseBody,
|
|
291
|
+
response: responseBody
|
|
292
|
+
};
|
|
293
|
+
if (callback)
|
|
294
|
+
return callback(nextState);
|
|
295
|
+
return nextState;
|
|
139
296
|
};
|
|
140
|
-
}
|
|
297
|
+
};
|
|
298
|
+
var get = (path, query, callback) => request("GET", path, { query }, callback);
|
|
299
|
+
var post = (path, body, query, callback) => request("POST", path, { body, query }, callback);
|
|
141
300
|
|
|
142
301
|
// src/index.js
|
|
143
302
|
var src_default = Adaptor_exports;
|
|
144
303
|
// Annotate the CommonJS export names for ESM import in node:
|
|
145
304
|
0 && (module.exports = {
|
|
305
|
+
addMember,
|
|
146
306
|
alterState,
|
|
307
|
+
archiveMember,
|
|
147
308
|
axios,
|
|
148
309
|
dataPath,
|
|
149
310
|
dataValue,
|
|
311
|
+
deleteMember,
|
|
150
312
|
each,
|
|
151
313
|
execute,
|
|
152
314
|
field,
|
|
153
315
|
fields,
|
|
154
316
|
fn,
|
|
317
|
+
get,
|
|
155
318
|
lastReferenceValue,
|
|
319
|
+
listAudienceInfo,
|
|
320
|
+
listAudiences,
|
|
156
321
|
listBatches,
|
|
322
|
+
listMembers,
|
|
157
323
|
md5,
|
|
158
324
|
merge,
|
|
325
|
+
post,
|
|
326
|
+
request,
|
|
159
327
|
sourceValue,
|
|
160
328
|
startBatch,
|
|
161
329
|
tagMembers,
|
|
330
|
+
updateMember,
|
|
331
|
+
updateMemberTags,
|
|
162
332
|
upsertMembers
|
|
163
333
|
});
|
package/dist/index.js
CHANGED
|
@@ -7,32 +7,62 @@ var __export = (target, all) => {
|
|
|
7
7
|
// src/Adaptor.js
|
|
8
8
|
var Adaptor_exports = {};
|
|
9
9
|
__export(Adaptor_exports, {
|
|
10
|
+
addMember: () => addMember,
|
|
10
11
|
alterState: () => alterState,
|
|
12
|
+
archiveMember: () => archiveMember,
|
|
11
13
|
axios: () => axios,
|
|
12
14
|
dataPath: () => dataPath,
|
|
13
15
|
dataValue: () => dataValue,
|
|
16
|
+
deleteMember: () => deleteMember,
|
|
14
17
|
each: () => each,
|
|
15
18
|
execute: () => execute,
|
|
16
19
|
field: () => field,
|
|
17
20
|
fields: () => fields,
|
|
18
21
|
fn: () => fn,
|
|
22
|
+
get: () => get,
|
|
19
23
|
lastReferenceValue: () => lastReferenceValue,
|
|
24
|
+
listAudienceInfo: () => listAudienceInfo,
|
|
25
|
+
listAudiences: () => listAudiences,
|
|
20
26
|
listBatches: () => listBatches,
|
|
27
|
+
listMembers: () => listMembers,
|
|
21
28
|
md5: () => md5,
|
|
22
29
|
merge: () => merge,
|
|
30
|
+
post: () => post,
|
|
31
|
+
request: () => request,
|
|
23
32
|
sourceValue: () => sourceValue,
|
|
24
33
|
startBatch: () => startBatch,
|
|
25
34
|
tagMembers: () => tagMembers,
|
|
35
|
+
updateMember: () => updateMember,
|
|
36
|
+
updateMemberTags: () => updateMemberTags,
|
|
26
37
|
upsertMembers: () => upsertMembers
|
|
27
38
|
});
|
|
28
|
-
import {
|
|
29
|
-
execute as commonExecute,
|
|
30
|
-
composeNextState,
|
|
31
|
-
expandReferences
|
|
32
|
-
} from "@openfn/language-common";
|
|
33
|
-
import axios from "axios";
|
|
34
|
-
import client from "@mailchimp/mailchimp_marketing";
|
|
35
39
|
import md5 from "md5";
|
|
40
|
+
import axios from "axios";
|
|
41
|
+
import client2 from "@mailchimp/mailchimp_marketing";
|
|
42
|
+
import { expandReferences } from "@openfn/language-common/util";
|
|
43
|
+
import { execute as commonExecute } from "@openfn/language-common";
|
|
44
|
+
|
|
45
|
+
// src/Utils.js
|
|
46
|
+
import { composeNextState } from "@openfn/language-common";
|
|
47
|
+
import { Client, MockAgent } from "undici";
|
|
48
|
+
var client;
|
|
49
|
+
var getClient = (baseUrl) => {
|
|
50
|
+
if (client) {
|
|
51
|
+
return client;
|
|
52
|
+
}
|
|
53
|
+
return new Client(baseUrl);
|
|
54
|
+
};
|
|
55
|
+
function handleResponse(response, state, callback) {
|
|
56
|
+
const nextState = {
|
|
57
|
+
...composeNextState(state, response),
|
|
58
|
+
response
|
|
59
|
+
};
|
|
60
|
+
if (callback)
|
|
61
|
+
return callback(nextState);
|
|
62
|
+
return nextState;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// src/Adaptor.js
|
|
36
66
|
import {
|
|
37
67
|
fn,
|
|
38
68
|
alterState,
|
|
@@ -51,86 +81,211 @@ function execute(...operations) {
|
|
|
51
81
|
data: null
|
|
52
82
|
};
|
|
53
83
|
return (state) => {
|
|
54
|
-
return commonExecute(
|
|
84
|
+
return commonExecute(
|
|
85
|
+
createClient,
|
|
86
|
+
...operations,
|
|
87
|
+
cleanupState
|
|
88
|
+
)({
|
|
55
89
|
...initialState,
|
|
56
90
|
...state
|
|
57
91
|
});
|
|
58
92
|
};
|
|
59
93
|
}
|
|
60
|
-
function
|
|
94
|
+
function createClient(state) {
|
|
95
|
+
const { apiKey, server } = state.configuration;
|
|
96
|
+
const baseUrl = `https://${server}.api.mailchimp.com`;
|
|
97
|
+
const apiClient = getClient(baseUrl);
|
|
98
|
+
client2.setConfig({ apiKey, server });
|
|
99
|
+
return { ...state, apiClient, client: client2 };
|
|
100
|
+
}
|
|
101
|
+
function cleanupState(state) {
|
|
102
|
+
if (state == null ? void 0 : state.apiClient)
|
|
103
|
+
delete state.apiClient;
|
|
104
|
+
if (state == null ? void 0 : state.client)
|
|
105
|
+
delete state.client;
|
|
106
|
+
return state;
|
|
107
|
+
}
|
|
108
|
+
function upsertMembers(params, callback = (s) => s) {
|
|
109
|
+
return (state) => {
|
|
110
|
+
const [resolvedParams] = expandReferences(state, params);
|
|
111
|
+
const defaultOptions2 = {
|
|
112
|
+
update_existing: true,
|
|
113
|
+
sync_tags: false
|
|
114
|
+
};
|
|
115
|
+
const { listId: listId2, users, options } = resolvedParams;
|
|
116
|
+
const opts = { ...defaultOptions2, ...options };
|
|
117
|
+
const membersList = users.map((member2) => ({
|
|
118
|
+
email_address: member2.email,
|
|
119
|
+
status: member2.status,
|
|
120
|
+
merge_fields: member2.mergeFields,
|
|
121
|
+
tags: member2.tags
|
|
122
|
+
}));
|
|
123
|
+
return state.client.lists.batchListMembers(listId2, {
|
|
124
|
+
...opts,
|
|
125
|
+
members: membersList
|
|
126
|
+
}).then((response) => handleResponse(response, state, callback));
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function tagMembers(params, callback = (s) => s) {
|
|
61
130
|
return (state) => {
|
|
62
|
-
const
|
|
63
|
-
const { listId,
|
|
64
|
-
client.
|
|
65
|
-
return Promise.all(
|
|
66
|
-
users.map(
|
|
67
|
-
(user) => client.lists.setListMember(listId, md5(user.email), {
|
|
68
|
-
email_address: user.email,
|
|
69
|
-
status_if_new: user.status,
|
|
70
|
-
merge_fields: user.mergeFields
|
|
71
|
-
}).then((response) => {
|
|
72
|
-
state.references.push(response);
|
|
73
|
-
})
|
|
74
|
-
)
|
|
75
|
-
).then(() => {
|
|
76
|
-
return state;
|
|
77
|
-
});
|
|
131
|
+
const [resolvedParams] = expandReferences(state, params);
|
|
132
|
+
const { listId: listId2, tagId, members } = resolvedParams;
|
|
133
|
+
return state.client.lists.batchSegmentMembers({ members_to_add: members }, listId2, tagId).then((response) => handleResponse(response, state, callback));
|
|
78
134
|
};
|
|
79
135
|
}
|
|
80
|
-
function
|
|
136
|
+
function startBatch(params, callback = (s) => s) {
|
|
81
137
|
return (state) => {
|
|
82
|
-
const
|
|
83
|
-
const {
|
|
84
|
-
client.
|
|
85
|
-
return client.lists.batchSegmentMembers({ members_to_add: members }, listId, tagId).then((response) => {
|
|
86
|
-
const nextState = composeNextState(state, response);
|
|
87
|
-
return nextState;
|
|
88
|
-
});
|
|
138
|
+
const [resolvedParams] = expandReferences(state, params);
|
|
139
|
+
const { operations } = resolvedParams;
|
|
140
|
+
return state.client.batches.start({ operations: [...operations] }).then((response) => handleResponse(response, state, callback));
|
|
89
141
|
};
|
|
90
142
|
}
|
|
91
|
-
function
|
|
143
|
+
function listBatches(params, callback = (s) => s) {
|
|
92
144
|
return (state) => {
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
145
|
+
const [resolvedParams] = expandReferences(state, params);
|
|
146
|
+
return state.client.batches.list(resolvedParams).then((response) => handleResponse(response, state, callback));
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function listMembers(params, callback = (s) => s) {
|
|
150
|
+
return (state) => {
|
|
151
|
+
const [resolvedParams] = expandReferences(state, params);
|
|
152
|
+
const { listId: listId2, ...otherParams } = resolvedParams;
|
|
153
|
+
return state.client.lists.getListMembersInfo(listId2, otherParams).then((response) => handleResponse(response, state, callback));
|
|
101
154
|
};
|
|
102
155
|
}
|
|
103
|
-
function
|
|
156
|
+
function addMember(params, callback = (s) => s) {
|
|
104
157
|
return (state) => {
|
|
158
|
+
const [resolvedParams] = expandReferences(state, params);
|
|
159
|
+
const { listId: listId2, member: member2 } = resolvedParams;
|
|
160
|
+
return state.client.lists.addListMember(listId2, ...member2).then((response) => handleResponse(response, state, callback));
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function updateMember(params = { listId, subscriberHash, member }, callback = (s) => s) {
|
|
164
|
+
return (state) => {
|
|
165
|
+
const requiredParams = ["listId", "subscriberHash"];
|
|
166
|
+
const [resolvedParams] = expandReferences(state, params);
|
|
167
|
+
assertKeys(resolvedParams, requiredParams);
|
|
168
|
+
const { listId: listId2, subscriberHash: subscriberHash2, member: member2 } = resolvedParams;
|
|
169
|
+
return state.client.lists.updateListMember(listId2, subscriberHash2, member2).then((response) => handleResponse(response, state, callback));
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function updateMemberTags(params, callback = (s) => s) {
|
|
173
|
+
return (state) => {
|
|
174
|
+
const [resolvedParams] = expandReferences(state, params);
|
|
175
|
+
const { listId: listId2, subscriberHash: subscriberHash2, tags } = resolvedParams;
|
|
176
|
+
return state.client.lists.updateListMemberTags(listId2, subscriberHash2, { tags }).then((response) => handleResponse(response, state, callback));
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function archiveMember(params, callback = (s) => s) {
|
|
180
|
+
return (state) => {
|
|
181
|
+
const [resolvedParams] = expandReferences(state, params);
|
|
182
|
+
const { listId: listId2, subscriberHash: subscriberHash2 } = resolvedParams;
|
|
183
|
+
return state.client.lists.deleteListMember(listId2, subscriberHash2).then((response) => handleResponse(response, state, callback));
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function deleteMember(params, callback = (s) => s) {
|
|
187
|
+
return (state) => {
|
|
188
|
+
const [resolvedParams] = expandReferences(state, params);
|
|
189
|
+
const { listId: listId2, subscriberHash: subscriberHash2 } = resolvedParams;
|
|
190
|
+
return state.client.lists.deleteListMemberPermanent(listId2, subscriberHash2).then((response) => handleResponse(response, state, callback));
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function listAudiences(query, callback = (s) => s) {
|
|
194
|
+
return (state) => {
|
|
195
|
+
const [resolvedQuery] = expandReferences(state, query);
|
|
196
|
+
return state.client.lists.getAllLists(resolvedQuery).then((response) => handleResponse(response, state, callback));
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function listAudienceInfo(query, callback = (s) => s) {
|
|
200
|
+
return (state) => {
|
|
201
|
+
const [resolvedQuery] = expandReferences(state, query);
|
|
202
|
+
const { listId: listId2, ...queries } = resolvedQuery;
|
|
203
|
+
return state.client.lists.getList(listId2, queries).then((response) => handleResponse(response, state, callback));
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
var defaultOptions = {
|
|
207
|
+
query: {},
|
|
208
|
+
body: void 0
|
|
209
|
+
};
|
|
210
|
+
var assertOK = (response, fullUrl) => {
|
|
211
|
+
if (response.statusCode >= 400) {
|
|
212
|
+
const defaultErrorMesssage = `Request to ${fullUrl} failed with status: ${response.statusCode}`;
|
|
213
|
+
const error = new Error(defaultErrorMesssage);
|
|
214
|
+
error.code = response.statusCode;
|
|
215
|
+
error.url = fullUrl;
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
var request = (method, path, options, callback) => {
|
|
220
|
+
return async (state) => {
|
|
221
|
+
const apiVersion = "3.0";
|
|
105
222
|
const { apiKey, server } = state.configuration;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
223
|
+
const [resolvedMethod, resolvedPath, resolvedOptions] = expandReferences(
|
|
224
|
+
state,
|
|
225
|
+
method,
|
|
226
|
+
path,
|
|
227
|
+
options
|
|
228
|
+
);
|
|
229
|
+
const { query, body } = { ...defaultOptions, ...resolvedOptions };
|
|
230
|
+
const apiToken = Buffer.from(`openfn:${apiKey}`, "utf-8").toString(
|
|
231
|
+
"base64"
|
|
232
|
+
);
|
|
233
|
+
const headers = {
|
|
234
|
+
"Content-Type": "application/json",
|
|
235
|
+
Authorization: `Basic ${apiToken}`
|
|
236
|
+
};
|
|
237
|
+
const urlPath = `/${apiVersion}${resolvedPath}`;
|
|
238
|
+
const response = await state.apiClient.request({
|
|
239
|
+
method: resolvedMethod,
|
|
240
|
+
path: urlPath,
|
|
241
|
+
headers,
|
|
242
|
+
query,
|
|
243
|
+
body: body ? JSON.stringify(body) : void 0
|
|
111
244
|
});
|
|
245
|
+
assertOK(response, `https://${server}.api.mailchimp.com${urlPath}`);
|
|
246
|
+
const responseBody = await response.body.json();
|
|
247
|
+
const nextState = {
|
|
248
|
+
data: responseBody,
|
|
249
|
+
response: responseBody
|
|
250
|
+
};
|
|
251
|
+
if (callback)
|
|
252
|
+
return callback(nextState);
|
|
253
|
+
return nextState;
|
|
112
254
|
};
|
|
113
|
-
}
|
|
255
|
+
};
|
|
256
|
+
var get = (path, query, callback) => request("GET", path, { query }, callback);
|
|
257
|
+
var post = (path, body, query, callback) => request("POST", path, { body, query }, callback);
|
|
114
258
|
|
|
115
259
|
// src/index.js
|
|
116
260
|
var src_default = Adaptor_exports;
|
|
117
261
|
export {
|
|
262
|
+
addMember,
|
|
118
263
|
alterState,
|
|
264
|
+
archiveMember,
|
|
119
265
|
axios,
|
|
120
266
|
dataPath,
|
|
121
267
|
dataValue,
|
|
122
268
|
src_default as default,
|
|
269
|
+
deleteMember,
|
|
123
270
|
each,
|
|
124
271
|
execute,
|
|
125
272
|
field,
|
|
126
273
|
fields,
|
|
127
274
|
fn,
|
|
275
|
+
get,
|
|
128
276
|
lastReferenceValue,
|
|
277
|
+
listAudienceInfo,
|
|
278
|
+
listAudiences,
|
|
129
279
|
listBatches,
|
|
280
|
+
listMembers,
|
|
130
281
|
md5,
|
|
131
282
|
merge,
|
|
283
|
+
post,
|
|
284
|
+
request,
|
|
132
285
|
sourceValue,
|
|
133
286
|
startBatch,
|
|
134
287
|
tagMembers,
|
|
288
|
+
updateMember,
|
|
289
|
+
updateMemberTags,
|
|
135
290
|
upsertMembers
|
|
136
291
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfn/language-mailchimp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "An OpenFn adaptor for use with Mailchimp",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"author": "Open Function Group",
|
|
@@ -15,17 +15,17 @@
|
|
|
15
15
|
"@mailchimp/mailchimp_marketing": "^3.0.80",
|
|
16
16
|
"@openfn/language-common": "^1.8.1",
|
|
17
17
|
"axios": "^0.21.2",
|
|
18
|
-
"md5": "^2.3.0"
|
|
18
|
+
"md5": "^2.3.0",
|
|
19
|
+
"undici": "^5.22.1"
|
|
19
20
|
},
|
|
20
21
|
"devDependencies": {
|
|
21
22
|
"@openfn/buildtools": "^1.0.2",
|
|
22
23
|
"@openfn/simple-ast": "0.4.1",
|
|
23
24
|
"assertion-error": "^1.1.0",
|
|
24
|
-
"chai": "^3.
|
|
25
|
+
"chai": "^4.3.6",
|
|
25
26
|
"deep-eql": "^0.1.3",
|
|
26
27
|
"esno": "^0.16.3",
|
|
27
28
|
"mocha": "^7.2.0",
|
|
28
|
-
"nock": "^12.0.3",
|
|
29
29
|
"rimraf": "^3.0.2"
|
|
30
30
|
},
|
|
31
31
|
"repository": {
|
package/types/Adaptor.d.ts
CHANGED
|
@@ -12,33 +12,130 @@
|
|
|
12
12
|
*/
|
|
13
13
|
export function execute(...operations: Operations): Operation;
|
|
14
14
|
/**
|
|
15
|
-
* Add
|
|
15
|
+
* Add or update a list members
|
|
16
16
|
* @example
|
|
17
|
-
* upsertMembers(
|
|
17
|
+
* upsertMembers((state) => ({
|
|
18
|
+
* listId: "someId",
|
|
19
|
+
* users: state.response.body.rows.map((u) => ({
|
|
20
|
+
* email: u.email,
|
|
21
|
+
* status: u.allow_other_emails ? "subscribed" : "unsubscribed",
|
|
22
|
+
* mergeFields: { FNAME: u.first_name, LNAME: u.last_name },
|
|
23
|
+
* })),
|
|
24
|
+
* }));
|
|
18
25
|
* @function
|
|
19
26
|
* @param {object} params - a listId, users, and options
|
|
27
|
+
* @param {function} [callback] - Optional callback to handle the response
|
|
20
28
|
* @returns {Operation}
|
|
21
29
|
*/
|
|
22
|
-
export function upsertMembers(params: object): Operation;
|
|
30
|
+
export function upsertMembers(params: object, callback?: Function): Operation;
|
|
23
31
|
/**
|
|
24
32
|
* Tag members with a particular tag
|
|
25
33
|
* @example
|
|
26
|
-
* tagMembers(
|
|
34
|
+
* tagMembers((state) => ({
|
|
35
|
+
* listId: "someId", // All Subscribers list
|
|
36
|
+
* tagId: "someTag", // User tag
|
|
37
|
+
* members: state.response.body.rows.map((u) => u.email),
|
|
38
|
+
* }));
|
|
39
|
+
* @example
|
|
40
|
+
* tagMembers((state) => ({
|
|
41
|
+
* listId: "someId",
|
|
42
|
+
* tagId: "someTag",
|
|
43
|
+
* members: state.response.body.rows
|
|
44
|
+
* .filter((u) => u.allow_other_emails)
|
|
45
|
+
* .map((u) => u.email),
|
|
46
|
+
* }));
|
|
27
47
|
* @function
|
|
28
48
|
* @param {object} params - a tagId, members, and a list
|
|
49
|
+
* @param {function} [callback] - Optional callback to handle the response
|
|
29
50
|
* @returns {Operation}
|
|
30
51
|
*/
|
|
31
|
-
export function tagMembers(params: object): Operation;
|
|
52
|
+
export function tagMembers(params: object, callback?: Function): Operation;
|
|
32
53
|
/**
|
|
33
54
|
* Start a batch with a list of operations.
|
|
34
55
|
* @example
|
|
35
56
|
* startBatch(params)
|
|
36
57
|
* @function
|
|
37
58
|
* @param {object} params - operations batch job
|
|
59
|
+
* @param {function} [callback] - Optional callback to handle the response
|
|
60
|
+
* @returns {Operation}
|
|
61
|
+
*/
|
|
62
|
+
export function startBatch(params: object, callback?: Function): Operation;
|
|
63
|
+
/**
|
|
64
|
+
* listBatches
|
|
65
|
+
* @function
|
|
66
|
+
* @param {object} params - a listId, and options
|
|
67
|
+
* @param {function} [callback] - Optional callback to handle the response
|
|
68
|
+
* @returns {Operation}
|
|
69
|
+
*/
|
|
70
|
+
export function listBatches(params: object, callback?: Function): Operation;
|
|
71
|
+
/**
|
|
72
|
+
* listMembers
|
|
73
|
+
* @function
|
|
74
|
+
* @param {object} params - a listId, and options
|
|
75
|
+
* @param {function} [callback] - Optional callback to handle the response
|
|
76
|
+
* @returns {Operation}
|
|
77
|
+
*/
|
|
78
|
+
export function listMembers(params: object, callback?: Function): Operation;
|
|
79
|
+
/**
|
|
80
|
+
* addMember to a list
|
|
81
|
+
* @function
|
|
82
|
+
* @param {object} params - a listId, and options
|
|
83
|
+
* @param {function} [callback] - Optional callback to handle the response
|
|
84
|
+
* @returns {Operation}
|
|
85
|
+
*/
|
|
86
|
+
export function addMember(params: object, callback?: Function): Operation;
|
|
87
|
+
/**
|
|
88
|
+
* updateMember
|
|
89
|
+
* @function
|
|
90
|
+
* @param {object} params - a listId,subscriberHash and member
|
|
91
|
+
* @param {function} [callback] - Optional callback to handle the response
|
|
92
|
+
* @returns {Operation}
|
|
93
|
+
*/
|
|
94
|
+
export function updateMember(params?: object, callback?: Function): Operation;
|
|
95
|
+
/**
|
|
96
|
+
* updateMemberTags
|
|
97
|
+
* @function
|
|
98
|
+
* @param {object} params - a listId, and options
|
|
99
|
+
* @param {function} [callback] - Optional callback to handle the response
|
|
100
|
+
* @returns {Operation}
|
|
101
|
+
*/
|
|
102
|
+
export function updateMemberTags(params: object, callback?: Function): Operation;
|
|
103
|
+
/**
|
|
104
|
+
* archiveMember in a list
|
|
105
|
+
* @function
|
|
106
|
+
* @param {object} params - a listId, and options
|
|
107
|
+
* @param {function} [callback] - Optional callback to handle the response
|
|
108
|
+
* @returns {Operation}
|
|
109
|
+
*/
|
|
110
|
+
export function archiveMember(params: object, callback?: Function): Operation;
|
|
111
|
+
/**
|
|
112
|
+
* Permanently delete a member from a list
|
|
113
|
+
* @function
|
|
114
|
+
* @param {object} params - a listId, and options
|
|
115
|
+
* @param {function} [callback] - Optional callback to handle the response
|
|
116
|
+
* @returns {Operation}
|
|
117
|
+
*/
|
|
118
|
+
export function deleteMember(params: object, callback?: Function): Operation;
|
|
119
|
+
/**
|
|
120
|
+
* Get information about all lists in the account.
|
|
121
|
+
* @function
|
|
122
|
+
* @param {object} query - Query parameters
|
|
123
|
+
* @param {function} [callback] - Optional callback to handle the response
|
|
124
|
+
* @returns {Operation}
|
|
125
|
+
*/
|
|
126
|
+
export function listAudiences(query: object, callback?: Function): Operation;
|
|
127
|
+
/**
|
|
128
|
+
* Get information about a specific list in your Mailchimp account.
|
|
129
|
+
* Results include list members who have signed up but haven't confirmed their subscription yet and unsubscribed or cleaned.
|
|
130
|
+
* @function
|
|
131
|
+
* @param {object} query - listId and query parameters
|
|
132
|
+
* @param {function} [callback] - Optional callback to handle the response
|
|
38
133
|
* @returns {Operation}
|
|
39
134
|
*/
|
|
40
|
-
export function
|
|
41
|
-
export function
|
|
135
|
+
export function listAudienceInfo(query: object, callback?: Function): Operation;
|
|
136
|
+
export function request(method: string, path: string, options: any, callback?: Function): Operation;
|
|
137
|
+
export function get(path: string, query: object, callback?: Function): Operation;
|
|
138
|
+
export function post(path: string, body: object, query: object, callback?: Function): Operation;
|
|
42
139
|
import axios from "axios";
|
|
43
140
|
export { axios, md5 };
|
|
44
141
|
export { fn, alterState, dataPath, dataValue, each, field, fields, lastReferenceValue, merge, sourceValue } from "@openfn/language-common";
|
package/types/Utils.d.ts
ADDED