From c31fa0a9285501b71abacbc25fd4951c587086c8 Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Mon, 31 Jul 2023 19:10:01 +0300 Subject: [PATCH 1/9] wip: cleanup and improvements --- packages/mailchimp/src/Adaptor.js | 90 ++++++++++++++++--------------- packages/mailchimp/src/Utils.js | 10 ++++ 2 files changed, 57 insertions(+), 43 deletions(-) create mode 100644 packages/mailchimp/src/Utils.js diff --git a/packages/mailchimp/src/Adaptor.js b/packages/mailchimp/src/Adaptor.js index d5e608f82..c37cf798b 100644 --- a/packages/mailchimp/src/Adaptor.js +++ b/packages/mailchimp/src/Adaptor.js @@ -1,13 +1,10 @@ - -import { - execute as commonExecute, - composeNextState, - expandReferences, -} from '@openfn/language-common'; +import md5 from 'md5'; import axios from 'axios'; import client from '@mailchimp/mailchimp_marketing'; -import md5 from 'md5'; -import { resolve } from 'path'; +import { expandReferences } from '@openfn/language-common/util'; +import { execute as commonExecute } from '@openfn/language-common'; + +import { handleResponse } from './Utils'; /** * Execute a sequence of operations. @@ -28,13 +25,28 @@ export function execute(...operations) { }; return state => { - return commonExecute(...operations)({ + return commonExecute( + createClient, + ...operations, + cleanupState + )({ ...initialState, ...state, }); }; } +function createClient(state) { + const { apiKey, server } = state.configuration; + // TODO: throws an error if apiKey not specified in configuration + client.setConfig({ apiKey, server }); + return { ...state, client: client }; +} + +function cleanupState(state) { + delete state.client; + return state; +} /** * Add members to a particular audience * @example @@ -45,14 +57,15 @@ export function execute(...operations) { */ export function upsertMembers(params) { return state => { - const { apiKey, server } = state.configuration; - const { listId, users, options } = expandReferences(params)(state); + // const { apiKey, server } = state.configuration; + const [resolvedParams] = expandReferences(state, params); + const { listId, users, options } = resolvedParams; - client.setConfig({ apiKey, server }); + // client.setConfig({ apiKey, server }); return Promise.all( users.map(user => - client.lists + state.client.lists .setListMember(listId, md5(user.email), { email_address: user.email, status_if_new: user.status, @@ -76,19 +89,16 @@ export function upsertMembers(params) { * @param {object} params - a tagId, members, and a list * @returns {Operation} */ -export function tagMembers(params) { +export function tagMembers(params, callback = s => s) { return state => { - const { apiKey, server } = state.configuration; - const { listId, tagId, members } = expandReferences(params)(state); - - client.setConfig({ apiKey, server }); + // const { apiKey, server } = state.configuration; + const [resolvedParams] = expandReferences(state, params); + const { listId, tagId, members } = resolvedParams; + // client.setConfig({ apiKey, server }); - return client.lists + return state.client.lists .batchSegmentMembers({ members_to_add: members }, listId, tagId) - .then(response => { - const nextState = composeNextState(state, response); - return nextState; - }); + .then(response => handleResponse(response, state, callback)); }; } @@ -100,34 +110,28 @@ export function tagMembers(params) { * @param {object} params - operations batch job * @returns {Operation} */ -export function startBatch(params) { +export function startBatch(params, callback = s => s) { return state => { - const { apiKey, server } = state.configuration; - const { operations } = expandReferences(params)(state); + // const { apiKey, server } = state.configuration; + const [resolvedParams] = expandReferences(state, params); + const { operations } = resolvedParams; + // client.setConfig({ apiKey, server }); - client.setConfig({ apiKey, server }); - - return client.batches + return state.client.batches .start({ operations: [...operations] }) - .then(response => { - console.log(response); - const nextState = composeNextState(state, response); - return nextState; - }); + .then(response => handleResponse(response, state, callback)); }; } -export function listBatches(params) { +export function listBatches(params, callback = s => s) { return state => { - const { apiKey, server } = state.configuration; - - client.setConfig({ apiKey, server }); + // const { apiKey, server } = state.configuration; + // client.setConfig({ apiKey, server }); + const [resolvedParams] = expandReferences(state, params); - return client.batches.list().then(response => { - console.log(response); - const nextState = composeNextState(state, response); - return nextState; - }); + return state.client.batches + .list() + .then(response => handleResponse(response, state, callback)); }; } diff --git a/packages/mailchimp/src/Utils.js b/packages/mailchimp/src/Utils.js new file mode 100644 index 000000000..f0e4222e3 --- /dev/null +++ b/packages/mailchimp/src/Utils.js @@ -0,0 +1,10 @@ +import { composeNextState } from '@openfn/language-common'; + +export function handleResponse(response, state, callback) { + const nextState = { + ...composeNextState(state, response), + response, + }; + if (callback) return callback(nextState); + return nextState; +} From 2c66b53dca247d0274f78b21fd236bc50416cd42 Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Tue, 1 Aug 2023 10:50:03 +0300 Subject: [PATCH 2/9] update test to include state.configuration --- packages/mailchimp/test/index.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/mailchimp/test/index.js b/packages/mailchimp/test/index.js index 70b396b8e..9fbe40cb5 100644 --- a/packages/mailchimp/test/index.js +++ b/packages/mailchimp/test/index.js @@ -9,7 +9,12 @@ const { execute, post } = Adaptor; describe('execute', () => { it('executes each operation in sequence', done => { - let state = {}; + let state = { + configuration: { + apiKey: 'somEThINGkeyish', + server: 'https://mailchimp.com/api', + }, + }; let operations = [ state => { return { counter: 1 }; @@ -31,12 +36,17 @@ describe('execute', () => { }); it('assigns references, data to the initialState', () => { - let state = {}; + let state = { + configuration: { + apiKey: 'somEThINGkeyish', + server: 'https://mailchimp.com/api', + }, + }; let finalState = execute()(state); execute()(state).then(finalState => { - expect(finalState).to.eql({ references: [], data: null }); + expect(finalState).to.eql({ ...state, references: [], data: null }); }); }); }); From 906f628d22a94cd3ff549739ab263e491311eefd Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Tue, 1 Aug 2023 10:57:09 +0300 Subject: [PATCH 3/9] remove examples --- packages/mailchimp/README.md | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/packages/mailchimp/README.md b/packages/mailchimp/README.md index 92888fe30..b2d1ae7d9 100644 --- a/packages/mailchimp/README.md +++ b/packages/mailchimp/README.md @@ -12,36 +12,6 @@ official [configuration-schema](https://docs.openfn.org/adaptors/packages/mailchimp-configuration-schema/) definition. -#### sample expression with multiple operations - -```js -upsertMembers({ - listId: 'someId', - users: state => - state.response.body.rows.map(u => ({ - email: u.email, - status: u.allow_other_emails ? 'subscribed' : 'unsubscribed', - mergeFields: { FNAME: u.first_name, LNAME: u.last_name }, - })), - options: {}, -}); - -tagMembers({ - listId: 'someId', // All Subscribers - tagId: 'someTag', // User - members: state => state.response.body.rows.map(u => u.email), -}); - -tagMembers({ - listId: 'someId', // All Subscribers - tagId: 'someTag', // Other Emails Allowed - members: state => - state.response.body.rows - .filter(u => u.allow_other_emails) - .map(u => u.email), -}); -``` - ## Development Clone the [adaptors monorepo](https://github.com/OpenFn/adaptors). Follow the From fbe0b7cf6d56fab1087c39191b06e58781863233 Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Tue, 1 Aug 2023 10:57:18 +0300 Subject: [PATCH 4/9] wip: add examples --- packages/mailchimp/src/Adaptor.js | 182 ++++++++++++++++++++++++++---- 1 file changed, 159 insertions(+), 23 deletions(-) diff --git a/packages/mailchimp/src/Adaptor.js b/packages/mailchimp/src/Adaptor.js index c37cf798b..5947d287e 100644 --- a/packages/mailchimp/src/Adaptor.js +++ b/packages/mailchimp/src/Adaptor.js @@ -39,6 +39,7 @@ export function execute(...operations) { function createClient(state) { const { apiKey, server } = state.configuration; // TODO: throws an error if apiKey not specified in configuration + // TODO: should we set a default server if server not defined? client.setConfig({ apiKey, server }); return { ...state, client: client }; } @@ -48,53 +49,90 @@ function cleanupState(state) { return state; } /** - * Add members to a particular audience + * Add or update a list members * @example - * upsertMembers(params) + * upsertMembers((state) => ({ + * listId: "someId", + * users: state.response.body.rows.map((u) => ({ + * email: u.email, + * status: u.allow_other_emails ? "subscribed" : "unsubscribed", + * mergeFields: { FNAME: u.first_name, LNAME: u.last_name }, + * })), + * })); * @function * @param {object} params - a listId, users, and options + * @param {function} [callback] - Optional callback to handle the response * @returns {Operation} */ -export function upsertMembers(params) { +// TODO: Add jsdoc for params ={ path, query, body} +// TODO: Add examples +export function upsertMembers(params, callback = s => s) { return state => { - // const { apiKey, server } = state.configuration; const [resolvedParams] = expandReferences(state, params); + // TODO: Add support for options + // TODO: rename users to members const { listId, users, options } = resolvedParams; - // client.setConfig({ apiKey, server }); - - return Promise.all( - users.map(user => - state.client.lists - .setListMember(listId, md5(user.email), { - email_address: user.email, - status_if_new: user.status, - merge_fields: user.mergeFields, - }) - .then(response => { - state.references.push(response); - }) - ) - ).then(() => { - return state; + const membersList = []; + users.forEach(member => { + const memberDetails = { + email_address: member.email, + status: member.status, + merge_fields: member.mergeFields, + }; + membersList.push(memberDetails); }); + + return state.client.lists + .batchListMembers(listId, { + members: membersList, + update_existing: true, + }) + .then(response => handleResponse(response, state, callback)); + + // return Promise.all( + // users.map(user => + // state.client.lists + // .setListMember(listId, md5(user.email), { + // email_address: user.email, + // status_if_new: user.status, + // merge_fields: user.mergeFields, + // }) + // .then(response => { + // state.references.push(response); + // }) + // ) + // ).then(() => { + // return state; + // }); }; } /** * Tag members with a particular tag * @example - * tagMembers(params) + * tagMembers((state) => ({ + * listId: "someId", // All Subscribers + * tagId: "someTag", // User + * members: state.response.body.rows.map((u) => u.email), + * })); + * @example + * tagMembers((state) => ({ + * listId: "someId", // All Subscribers + * tagId: "someTag", // Other Emails Allowed + * members: state.response.body.rows + * .filter((u) => u.allow_other_emails) + * .map((u) => u.email), + * })); * @function * @param {object} params - a tagId, members, and a list + * @param {function} [callback] - Optional callback to handle the response * @returns {Operation} */ export function tagMembers(params, callback = s => s) { return state => { - // const { apiKey, server } = state.configuration; const [resolvedParams] = expandReferences(state, params); const { listId, tagId, members } = resolvedParams; - // client.setConfig({ apiKey, server }); return state.client.lists .batchSegmentMembers({ members_to_add: members }, listId, tagId) @@ -108,6 +146,7 @@ export function tagMembers(params, callback = s => s) { * startBatch(params) * @function * @param {object} params - operations batch job + * @param {function} [callback] - Optional callback to handle the response * @returns {Operation} */ export function startBatch(params, callback = s => s) { @@ -123,6 +162,13 @@ export function startBatch(params, callback = s => s) { }; } +/** + * listBatches + * @function + * @param {object} params - a listId, and options + * @param {function} [callback] - Optional callback to handle the response + * @returns {Operation} + */ export function listBatches(params, callback = s => s) { return state => { // const { apiKey, server } = state.configuration; @@ -135,6 +181,96 @@ export function listBatches(params, callback = s => s) { }; } +/** + * listMembers + * @function + * @param {object} params - a listId, and options + * @param {function} [callback] - Optional callback to handle the response + * @returns {Operation} + */ +export function listMembers(params, callback = s => s) { + return state => { + const [resolvedParams] = expandReferences(state, params); + + const { listId } = resolvedParams; + return state.client.getListMembersInfo + .list(listId) + .then(response => handleResponse(response, state, callback)); + }; +} + +/** + * addMember to a list + * @function + * @param {object} params - a listId, and options + * @param {function} [callback] - Optional callback to handle the response + * @returns {Operation} + */ +export function addMember(params, callback = s => s) { + return state => { + const [resolvedParams] = expandReferences(state, params); + + const { listId, member } = resolvedParams; + return state.client.addListMember + .list(listId, ...member) + .then(response => handleResponse(response, state, callback)); + }; +} + +/** + * updateMemberTags + * @function + * @param {object} params - a listId, and options + * @param {function} [callback] - Optional callback to handle the response + * @returns {Operation} + */ +export function updateMemberTags(params, callback = s => s) { + return state => { + const [resolvedParams] = expandReferences(state, params); + + const { listId, subscriberHash, tags } = resolvedParams; + return state.client.updateListMemberTags + .list(listId, subscriberHash, { tags: tags }) + .then(response => handleResponse(response, state, callback)); + }; +} + +/** + * archiveMember in a list + * @function + * @param {object} params - a listId, and options + * @param {function} [callback] - Optional callback to handle the response + * @returns {Operation} + */ +export function archiveMember(params, callback = s => s) { + return state => { + const [resolvedParams] = expandReferences(state, params); + + const { listId, subscriberHash } = resolvedParams; + return state.client.deleteListMember + .list(listId, subscriberHash) + .then(response => handleResponse(response, state, callback)); + }; +} + +/** + * Permanently delete a member from a list + * @function + * @param {object} params - a listId, and options + * @param {function} [callback] - Optional callback to handle the response + * @returns {Operation} + */ +export function deleteMember(params, callback = s => s) { + return state => { + const [resolvedParams] = expandReferences(state, params); + + const { listId, subscriberHash } = resolvedParams; + return state.client.deleteListMemberPermanent + .list(listId, subscriberHash) + .then(response => handleResponse(response, state, callback)); + }; +} + // Note that we expose the entire axios package to the user here. export { axios, md5 }; From 2c7f555cc5289bf312f60d6303c4801b9a5ca24b Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Tue, 1 Aug 2023 15:49:58 +0300 Subject: [PATCH 5/9] minor improvements --- packages/mailchimp/src/Adaptor.js | 117 +++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 28 deletions(-) diff --git a/packages/mailchimp/src/Adaptor.js b/packages/mailchimp/src/Adaptor.js index 5947d287e..7489ddee7 100644 --- a/packages/mailchimp/src/Adaptor.js +++ b/packages/mailchimp/src/Adaptor.js @@ -71,7 +71,12 @@ export function upsertMembers(params, callback = s => s) { const [resolvedParams] = expandReferences(state, params); // TODO: Add support for options // TODO: rename users to members + const defaultOptions = { + update_existing: true, + sync_tags: false, + }; const { listId, users, options } = resolvedParams; + const opts = { ...defaultOptions, ...options }; const membersList = []; users.forEach(member => { @@ -79,32 +84,17 @@ export function upsertMembers(params, callback = s => s) { email_address: member.email, status: member.status, merge_fields: member.mergeFields, + tags: member.tags, }; membersList.push(memberDetails); }); return state.client.lists .batchListMembers(listId, { + ...opts, members: membersList, - update_existing: true, }) .then(response => handleResponse(response, state, callback)); - - // return Promise.all( - // users.map(user => - // state.client.lists - // .setListMember(listId, md5(user.email), { - // email_address: user.email, - // status_if_new: user.status, - // merge_fields: user.mergeFields, - // }) - // .then(response => { - // state.references.push(response); - // }) - // ) - // ).then(() => { - // return state; - // }); }; } @@ -192,9 +182,45 @@ export function listMembers(params, callback = s => s) { return state => { const [resolvedParams] = expandReferences(state, params); - const { listId } = resolvedParams; - return state.client.getListMembersInfo - .list(listId) + const { listId, ...otherParams } = resolvedParams; + return state.client.lists + .getListMembersInfo(listId, otherParams) + .then(response => handleResponse(response, state, callback)); + }; +} + +/** + * Get information about all avaliable segments for a specific list + * @function + * @param {object} params - a listId, and options + * @param {function} [callback] - Optional callback to handle the response + * @returns {Operation} + */ +export function listSegments(params, callback = s => s) { + return state => { + const [resolvedParams] = expandReferences(state, params); + + const { listId, ...otherParams } = resolvedParams; + return state.client.lists + .listSegments(listId, otherParams) + .then(response => handleResponse(response, state, callback)); + }; +} + +/** + * Get information about members in saved segment. + * @function + * @param {object} params - a listId,segmentId and options + * @param {function} [callback] - Optional callback to handle the response + * @returns {Operation} + */ +export function getSegmentMembers(params, callback = s => s) { + return state => { + const [resolvedParams] = expandReferences(state, params); + + const { listId, segmentId, ...otherParams } = resolvedParams; + return state.client.lists + .getSegmentMembersList(listId, segmentId, otherParams) .then(response => handleResponse(response, state, callback)); }; } @@ -211,8 +237,8 @@ export function addMember(params, callback = s => s) { const [resolvedParams] = expandReferences(state, params); const { listId, member } = resolvedParams; - return state.client.addListMember - .list(listId, ...member) + return state.client.lists + .addListMember(listId, ...member) .then(response => handleResponse(response, state, callback)); }; } @@ -229,8 +255,8 @@ export function updateMemberTags(params, callback = s => s) { const [resolvedParams] = expandReferences(state, params); const { listId, subscriberHash, tags } = resolvedParams; - return state.client.updateListMemberTags - .list(listId, subscriberHash, { tags: tags }) + return state.client.lists + .updateListMemberTags(listId, subscriberHash, { tags: tags }) .then(response => handleResponse(response, state, callback)); }; } @@ -247,8 +273,8 @@ export function archiveMember(params, callback = s => s) { const [resolvedParams] = expandReferences(state, params); const { listId, subscriberHash } = resolvedParams; - return state.client.deleteListMember - .list(listId, subscriberHash) + return state.client.lists + .deleteListMember(listId, subscriberHash) .then(response => handleResponse(response, state, callback)); }; } @@ -265,8 +291,43 @@ export function deleteMember(params, callback = s => s) { const [resolvedParams] = expandReferences(state, params); const { listId, subscriberHash } = resolvedParams; - return state.client.deleteListMemberPermanent - .list(listId, subscriberHash) + return state.client.lists + .deleteListMemberPermanent(listId, subscriberHash) + .then(response => handleResponse(response, state, callback)); + }; +} + +/** + * Get information about all lists in the account. + * @function + * @param {object} query - Query parameters + * @param {function} [callback] - Optional callback to handle the response + * @returns {Operation} + */ +export function getAllLists(query, callback = s => s) { + return state => { + const [resolvedQuery] = expandReferences(state, query); + + return state.client.lists + .getAllLists(resolvedQuery) + .then(response => handleResponse(response, state, callback)); + }; +} + +/** + * Search for tags on a list by name + * @function + * @param {object} query - Query parameters + * @param {function} [callback] - Optional callback to handle the response + * @returns {Operation} + */ +export function searchTag(query, callback = s => s) { + return state => { + const [resolvedQuery] = expandReferences(state, query); + const { listId, name } = resolvedQuery; + + return state.client.lists + .tagSearch(listId, { name: name }) .then(response => handleResponse(response, state, callback)); }; } From 8e39ee16063750c4ac72a82a3c630deb06c63ce4 Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Tue, 1 Aug 2023 15:53:58 +0300 Subject: [PATCH 6/9] add changeset --- .changeset/smooth-countries-move.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .changeset/smooth-countries-move.md diff --git a/.changeset/smooth-countries-move.md b/.changeset/smooth-countries-move.md new file mode 100644 index 000000000..463625fd2 --- /dev/null +++ b/.changeset/smooth-countries-move.md @@ -0,0 +1,15 @@ +--- +'@openfn/language-mailchimp': minor +--- + +Add new functions + +- listMembers() +- listSegments() +- getSegmentMembers() +- addMember() +- updateMemberTags() +- archiveMembers() +- deleteMember() +- getAllList() +- searchTag() From 7e3aa1ba5837a943b3be070769b7bdb07714eaa4 Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Tue, 1 Aug 2023 17:45:11 +0300 Subject: [PATCH 7/9] update lists/audiences function --- packages/mailchimp/src/Adaptor.js | 84 ++++++++++++------------------- 1 file changed, 32 insertions(+), 52 deletions(-) diff --git a/packages/mailchimp/src/Adaptor.js b/packages/mailchimp/src/Adaptor.js index 7489ddee7..adf8cd17e 100644 --- a/packages/mailchimp/src/Adaptor.js +++ b/packages/mailchimp/src/Adaptor.js @@ -78,16 +78,12 @@ export function upsertMembers(params, callback = s => s) { const { listId, users, options } = resolvedParams; const opts = { ...defaultOptions, ...options }; - const membersList = []; - users.forEach(member => { - const memberDetails = { - email_address: member.email, - status: member.status, - merge_fields: member.mergeFields, - tags: member.tags, - }; - membersList.push(memberDetails); - }); + const membersList = users.map(member => ({ + email_address: member.email, + status: member.status, + merge_fields: member.mergeFields, + tags: member.tags, + })); return state.client.lists .batchListMembers(listId, { @@ -102,14 +98,14 @@ export function upsertMembers(params, callback = s => s) { * Tag members with a particular tag * @example * tagMembers((state) => ({ - * listId: "someId", // All Subscribers - * tagId: "someTag", // User + * listId: "someId", // All Subscribers list + * tagId: "someTag", // User tag * members: state.response.body.rows.map((u) => u.email), * })); * @example * tagMembers((state) => ({ - * listId: "someId", // All Subscribers - * tagId: "someTag", // Other Emails Allowed + * listId: "someId", + * tagId: "someTag", * members: state.response.body.rows * .filter((u) => u.allow_other_emails) * .map((u) => u.email), @@ -141,10 +137,8 @@ export function tagMembers(params, callback = s => s) { */ export function startBatch(params, callback = s => s) { return state => { - // const { apiKey, server } = state.configuration; const [resolvedParams] = expandReferences(state, params); const { operations } = resolvedParams; - // client.setConfig({ apiKey, server }); return state.client.batches .start({ operations: [...operations] }) @@ -161,12 +155,10 @@ export function startBatch(params, callback = s => s) { */ export function listBatches(params, callback = s => s) { return state => { - // const { apiKey, server } = state.configuration; - // client.setConfig({ apiKey, server }); const [resolvedParams] = expandReferences(state, params); return state.client.batches - .list() + .list(resolvedParams) .then(response => handleResponse(response, state, callback)); }; } @@ -190,55 +182,43 @@ export function listMembers(params, callback = s => s) { } /** - * Get information about all avaliable segments for a specific list + * addMember to a list * @function * @param {object} params - a listId, and options * @param {function} [callback] - Optional callback to handle the response * @returns {Operation} */ -export function listSegments(params, callback = s => s) { +export function addMember(params, callback = s => s) { return state => { const [resolvedParams] = expandReferences(state, params); - const { listId, ...otherParams } = resolvedParams; + const { listId, member } = resolvedParams; return state.client.lists - .listSegments(listId, otherParams) + .addListMember(listId, ...member) .then(response => handleResponse(response, state, callback)); }; } /** - * Get information about members in saved segment. + * updateMember * @function - * @param {object} params - a listId,segmentId and options + * @param {object} params - a listId,subscriberHash and member * @param {function} [callback] - Optional callback to handle the response * @returns {Operation} */ -export function getSegmentMembers(params, callback = s => s) { +export function updateMember( + params = { listId, subscriberHash, member }, + callback = s => s +) { return state => { + const requiredParams = ['listId', 'subscriberHash']; const [resolvedParams] = expandReferences(state, params); + assertKeys(resolvedParams, requiredParams); - const { listId, segmentId, ...otherParams } = resolvedParams; - return state.client.lists - .getSegmentMembersList(listId, segmentId, otherParams) - .then(response => handleResponse(response, state, callback)); - }; -} - -/** - * addMember to a list - * @function - * @param {object} params - a listId, and options - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} - */ -export function addMember(params, callback = s => s) { - return state => { - const [resolvedParams] = expandReferences(state, params); + const { listId, subscriberHash, member } = resolvedParams; - const { listId, member } = resolvedParams; return state.client.lists - .addListMember(listId, ...member) + .updateListMember(listId, subscriberHash, member) .then(response => handleResponse(response, state, callback)); }; } @@ -304,7 +284,7 @@ export function deleteMember(params, callback = s => s) { * @param {function} [callback] - Optional callback to handle the response * @returns {Operation} */ -export function getAllLists(query, callback = s => s) { +export function listAudiences(query, callback = s => s) { return state => { const [resolvedQuery] = expandReferences(state, query); @@ -315,19 +295,19 @@ export function getAllLists(query, callback = s => s) { } /** - * Search for tags on a list by name + * Get information about a specific list in your Mailchimp account. + * Results include list members who have signed up but haven't confirmed their subscription yet and unsubscribed or cleaned. * @function - * @param {object} query - Query parameters + * @param {object} query - listId and query parameters * @param {function} [callback] - Optional callback to handle the response * @returns {Operation} */ -export function searchTag(query, callback = s => s) { +export function listAudienceInfo(query, callback = s => s) { return state => { const [resolvedQuery] = expandReferences(state, query); - const { listId, name } = resolvedQuery; - + const { listId, ...queries } = resolvedQuery; return state.client.lists - .tagSearch(listId, { name: name }) + .getList(listId, queries) .then(response => handleResponse(response, state, callback)); }; } From 32a165a936887215e962a57690fdc106ce256e55 Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Tue, 1 Aug 2023 17:45:44 +0300 Subject: [PATCH 8/9] update changelog --- .changeset/smooth-countries-move.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.changeset/smooth-countries-move.md b/.changeset/smooth-countries-move.md index 463625fd2..7b242ab8a 100644 --- a/.changeset/smooth-countries-move.md +++ b/.changeset/smooth-countries-move.md @@ -4,12 +4,10 @@ Add new functions -- listMembers() -- listSegments() -- getSegmentMembers() - addMember() -- updateMemberTags() -- archiveMembers() +- listMembers() - deleteMember() -- getAllList() -- searchTag() +- listAudiences() +- archiveMembers() +- updateMemberTags() +- listAudienceInfo() From 0db1204e8485c39efbe0d75275323e767316d3e6 Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Tue, 1 Aug 2023 17:47:27 +0300 Subject: [PATCH 9/9] update changelog --- .changeset/smooth-countries-move.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/smooth-countries-move.md b/.changeset/smooth-countries-move.md index 7b242ab8a..d94a631ad 100644 --- a/.changeset/smooth-countries-move.md +++ b/.changeset/smooth-countries-move.md @@ -8,6 +8,6 @@ Add new functions - listMembers() - deleteMember() - listAudiences() -- archiveMembers() +- archiveMember() - updateMemberTags() - listAudienceInfo()