Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: onboard sfmc with record event to support mirror mode #3719

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 91 additions & 13 deletions src/v0/destinations/sfmc/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,29 +283,106 @@
throw new ConfigurationError(`Event type '${category.type}' not supported`);
};

const addResponseBuilder = ({
traits,
destinationExternalId,
identifierType,
subDomain,
externalKey,
token,
}) => {
const response = defaultRequestConfig();
response.method = defaultPutRequestConfig.requestMethod;
response.endpoint = `https://${subDomain}.${ENDPOINTS.INSERT_CONTACTS}${externalKey}/rows/${identifierType}:${destinationExternalId}`;
response.headers = {
'Content-Type': JSON_MIME_TYPE,
Authorization: `Bearer ${token}`,
};
response.body.JSON = {
values: {
...traits,
},
};
return response;
};

const retlResponseBuilder = async (message, destination, metadata) => {
const { clientId, clientSecret, subDomain, externalKey } = destination.Config;
const token = await accessTokenCache.get(metadata.destinationId, () =>
getToken(clientId, clientSecret, subDomain, metadata),
);

const { destinationExternalId, objectType, identifierType } = getDestinationExternalIDInfoForRetl(
message,
'SFMC',
);

// This part will handle the mirror mode
const { type, action } = message;
if (type === 'record') {
if (action === 'insert') {
return addResponseBuilder({
traits: message.fields,

Check failure on line 325 in src/v0/destinations/sfmc/transform.js

View workflow job for this annotation

GitHub Actions / Check for formatting & lint errors

Use destructured variables over properties

Check failure on line 325 in src/v0/destinations/sfmc/transform.js

View workflow job for this annotation

GitHub Actions / Code Coverage

Use destructured variables over properties
destinationExternalId: message.fields[identifierType],

Check failure on line 326 in src/v0/destinations/sfmc/transform.js

View workflow job for this annotation

GitHub Actions / Check for formatting & lint errors

Use destructured variables over properties

Check failure on line 326 in src/v0/destinations/sfmc/transform.js

View workflow job for this annotation

GitHub Actions / Code Coverage

Use destructured variables over properties
identifierType,
subDomain,
externalKey,
token,
});
} else if (action === 'delete') {

Check failure on line 332 in src/v0/destinations/sfmc/transform.js

View workflow job for this annotation

GitHub Actions / Check for formatting & lint errors

Move this "if" to a new line or add the missing "else"

Check failure on line 332 in src/v0/destinations/sfmc/transform.js

View workflow job for this annotation

GitHub Actions / Code Coverage

Move this "if" to a new line or add the missing "else"
let data = `<s:Envelope\n
xmlns:s="http://www.w3.org/2003/05/soap-envelope"\n
xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing"\n
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">\n
<s:Header>\n
<fueloauth>ACCESS_TOKEN</fueloauth>\n
</s:Header>\n
<s:Body\n
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n
xmlns:xsd="http://www.w3.org/2001/XMLSchema">\n
<DeleteRequest
xmlns="http://exacttarget.com/wsdl/partnerAPI">\n
<Objects xsi:type="DataExtensionObject">\n
<CustomerKey>CUSTOMER_KEY</CustomerKey>\n
<Keys>\n
<Key>\n
<Name>FIELD_NAME</Name>\n
<Value>FIELD_VALUE</Value>\n
</Key>\n
</Keys>\n
</Objects>\n
</DeleteRequest>\n
</s:Body>\n
</s:Envelope>`;
data = data.replace('ACCESS_TOKEN', token);
data = data.replace('CUSTOMER_KEY', externalKey);
data = data.replace('FIELD_NAME', destinationExternalId);
data = data.replace('FIELD_VALUE', message.fields[identifierType]);

Check failure on line 360 in src/v0/destinations/sfmc/transform.js

View workflow job for this annotation

GitHub Actions / Check for formatting & lint errors

Use destructured variables over properties

Check failure on line 360 in src/v0/destinations/sfmc/transform.js

View workflow job for this annotation

GitHub Actions / Code Coverage

Use destructured variables over properties
const response = defaultRequestConfig();
response.method = defaultPostRequestConfig.requestMethod;
response.endpoint = `https://${subDomain}.soap.marketingcloudapis.com/Service.asmx`;
response.headers = {
soapaction: 'Delete',
'Content-Type': 'text/xml; charset="UTF-8"',
};
response.body.XML = {
payload: data,
};
return response;
}
}

// This part will handle the upsert mode

if (objectType?.toLowerCase() === 'data extension') {
const response = defaultRequestConfig();
response.method = defaultPutRequestConfig.requestMethod;
response.endpoint = `https://${subDomain}.${ENDPOINTS.INSERT_CONTACTS}${externalKey}/rows/${identifierType}:${destinationExternalId}`;
response.headers = {
'Content-Type': JSON_MIME_TYPE,
Authorization: `Bearer ${token}`,
};
response.body.JSON = {
values: {
...message.traits,
},
};
return response;
return addResponseBuilder({
traits: message.traits,

Check failure on line 379 in src/v0/destinations/sfmc/transform.js

View workflow job for this annotation

GitHub Actions / Check for formatting & lint errors

Use destructured variables over properties

Check failure on line 379 in src/v0/destinations/sfmc/transform.js

View workflow job for this annotation

GitHub Actions / Code Coverage

Use destructured variables over properties
destinationExternalId,
identifierType,
subDomain,
externalKey,
token,
});
}
throw new PlatformError('Unsupported object type for rETL use case');
};
Expand Down Expand Up @@ -344,6 +421,7 @@

const processRouterDest = async (inputs, reqMetadata) => {
const respList = await simpleProcessRouterDest(inputs, process, reqMetadata);
console.log(JSON.stringify(respList));

Check warning on line 424 in src/v0/destinations/sfmc/transform.js

View workflow job for this annotation

GitHub Actions / Check for formatting & lint errors

Unexpected console statement

Check warning on line 424 in src/v0/destinations/sfmc/transform.js

View workflow job for this annotation

GitHub Actions / Code Coverage

Unexpected console statement
return respList;
};

Expand Down
Loading