@wepublish/api
Version:
API core for we.publish.
192 lines • 8.11 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MailchimpMailProvider = void 0;
const tslib_1 = require("tslib");
const crypto_1 = tslib_1.__importDefault(require("crypto"));
const mailchimp_transactional_1 = tslib_1.__importDefault(require("@mailchimp/mailchimp_transactional"));
const client_1 = require("@prisma/client");
const mail_provider_interface_1 = require("./mail-provider.interface");
const base_mail_provider_1 = require("./base-mail-provider");
function mapMandrillEventToMailLogState(event) {
switch (event) {
case 'send':
return client_1.MailLogState.delivered;
case 'deferral':
return client_1.MailLogState.deferred;
case 'hard_bounce':
case 'soft_bounce':
return client_1.MailLogState.bounced;
case 'reject':
return client_1.MailLogState.rejected;
default:
return null;
}
}
/*
* Mandrill template engine does not support nested objects
*/
function flattenObjForMandrill(ob) {
const nestedObject = {};
for (const i in ob) {
const nestedObj = ob[i];
if (Array.isArray(nestedObj)) {
for (const j in nestedObj) {
if (nestedObj[j] && typeof nestedObj[j] === 'object') {
const returnedNestedObject = flattenObjForMandrill(nestedObj[j]);
for (const k in returnedNestedObject) {
nestedObject[`${i}_${j}_${k}`] = returnedNestedObject[k];
}
}
else {
nestedObject[`${i}_${j}`] = nestedObj[j];
}
}
}
else if (nestedObj && typeof nestedObj === 'object') {
const returnedNestedObject = flattenObjForMandrill(nestedObj);
for (const j in returnedNestedObject) {
nestedObject[`${i}_${j}`] = returnedNestedObject[j];
}
}
else {
// eventho it should be string according to Mandrill typings
// it accepts booleans, numbers etc.
nestedObject[i] = nestedObj;
}
}
return nestedObject;
}
class MailchimpMailProvider extends base_mail_provider_1.BaseMailProvider {
constructor(props) {
super(props);
this.webhookEndpointSecret = props.webhookEndpointSecret;
this.mailchimpClient = (0, mailchimp_transactional_1.default)(props.apiKey);
}
verifyWebhookSignature({ signature, url, params }) {
const keys = Object.keys(params).sort();
const longString = keys.reduce((sig, key) => {
return sig + key + params[key];
}, url || '');
const generatedSignature = crypto_1.default
.createHmac('sha1', this.webhookEndpointSecret)
.update(longString)
.digest('base64');
return signature === generatedSignature;
}
webhookForSendMail({ req }) {
var _a, _b;
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (req.method !== 'POST') {
return [];
}
if (typeof req.headers['x-mandrill-signature'] !== 'string') {
throw new Error('Webhook Header is missing signature');
}
if (!this.verifyWebhookSignature({
signature: req.headers['x-mandrill-signature'],
url: `https://${req.headers.host}${req.originalUrl}`,
params: req.body
})) {
throw new Error('Webhook signature failed');
}
const mandrillEvents = JSON.parse(req.body.mandrill_events);
const mailLogStatuses = [];
for (const mandrillEvent of mandrillEvents) {
const state = mapMandrillEventToMailLogState(mandrillEvent.event);
const mailLogID = (_b = (_a = mandrillEvent === null || mandrillEvent === void 0 ? void 0 : mandrillEvent.msg) === null || _a === void 0 ? void 0 : _a.metadata) === null || _b === void 0 ? void 0 : _b.mail_log_id;
if (state !== null && mailLogID !== undefined) {
mailLogStatuses.push({
state,
mailLogID,
mailData: JSON.stringify(mandrillEvent)
});
}
}
return mailLogStatuses;
});
}
sendMail(props) {
var _a, _b, _c;
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (props.template) {
const templateContent = [];
const flattenedObject = flattenObjForMandrill((_a = props.templateData) !== null && _a !== void 0 ? _a : {});
for (const [key, value] of Object.entries(flattenedObject)) {
templateContent.push({
name: key,
content: value
});
}
const response = yield this.mailchimpClient.messages.sendTemplate({
template_name: props.template,
template_content: [],
message: {
text: props.message,
subject: props.subject,
from_email: this.fromAddress,
to: [
{
email: props.recipient,
type: 'to'
}
],
merge_vars: [
{
rcpt: props.recipient,
vars: templateContent
}
]
}
});
if (this.responseIsError(response)) {
throw new mail_provider_interface_1.MailProviderError((_b = response.response) === null || _b === void 0 ? void 0 : _b.data.message);
}
return;
}
const response = yield this.mailchimpClient.messages.send({
message: {
html: props.messageHtml,
text: props.message,
subject: props.subject,
from_email: this.fromAddress,
to: [
{
email: props.recipient,
type: 'to'
}
]
}
});
if (this.responseIsError(response)) {
throw new mail_provider_interface_1.MailProviderError((_c = response.response) === null || _c === void 0 ? void 0 : _c.data.message);
}
});
}
// beware: Mailchimp templates are still created and stored in Mandrill: https://mandrillapp.com/templates
getTemplates() {
var _a;
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const response = yield this.mailchimpClient.templates.list();
if (this.responseIsError(response)) {
throw new mail_provider_interface_1.MailProviderError((_a = response.response) === null || _a === void 0 ? void 0 : _a.data.message);
}
const templates = response.map(mailTemplateResponse => {
return {
name: mailTemplateResponse.name,
uniqueIdentifier: mailTemplateResponse.slug,
createdAt: new Date(mailTemplateResponse.created_at),
updatedAt: new Date(mailTemplateResponse.updated_at)
};
});
return templates;
});
}
getTemplateUrl(template) {
return `https://mandrillapp.com/templates/code?id=${template.externalMailTemplateId}`;
}
responseIsError(response) {
return 'isAxiosError' in response;
}
}
exports.MailchimpMailProvider = MailchimpMailProvider;
//# sourceMappingURL=mailchimp-mail-provider.js.map