mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-06 22:40:14 -05:00
Added bulkEmail.batchSize
option to configure batch size
refs https://github.com/TryGhost/Ghost/issues/15725 This pull request adds a new configuration option for the Mailgun email provider that allows the user to set the maximum number of recipients per email batch via a new config option `bulkEmail.batchSize`
This commit is contained in:
parent
0a6b3d6b99
commit
9601285c3d
6 changed files with 62 additions and 22 deletions
|
@ -228,5 +228,8 @@
|
|||
"members": [0, 100, 1000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000],
|
||||
"minDaysSinceImported": 7,
|
||||
"minDaysSinceLastEmail": 14
|
||||
}
|
||||
},
|
||||
"bulkEmail": {
|
||||
"batchSize": 1000
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ const sinon = require('sinon');
|
|||
const assert = require('assert/strict');
|
||||
const jobManager = require('../../../../core/server/services/jobs/job-service');
|
||||
const _ = require('lodash');
|
||||
const {MailgunEmailProvider} = require('@tryghost/email-service');
|
||||
const escapeRegExp = require('lodash/escapeRegExp');
|
||||
const configUtils = require('../../../utils/configUtils');
|
||||
const {settingsCache} = require('../../../../core/server/services/settings-helpers');
|
||||
|
@ -259,7 +258,7 @@ describe('Batch sending tests', function () {
|
|||
let ghostServer;
|
||||
|
||||
beforeEach(function () {
|
||||
MailgunEmailProvider.BATCH_SIZE = 100;
|
||||
configUtils.set('bulkEmail:batchSize', 100);
|
||||
stubbedSend = sinon.fake.resolves({
|
||||
id: 'stubbed-email-id'
|
||||
});
|
||||
|
@ -548,7 +547,7 @@ describe('Batch sending tests', function () {
|
|||
});
|
||||
|
||||
it('Splits up in batches according to email provider batch size', async function () {
|
||||
MailgunEmailProvider.BATCH_SIZE = 1;
|
||||
configUtils.set('bulkEmail:batchSize', 1);
|
||||
await testEmailBatches({
|
||||
mobiledoc: mobileDocExample
|
||||
}, null, [
|
||||
|
@ -561,7 +560,7 @@ describe('Batch sending tests', function () {
|
|||
});
|
||||
|
||||
it('Splits up in batches according to email provider batch size with paid and free segments', async function () {
|
||||
MailgunEmailProvider.BATCH_SIZE = 1;
|
||||
configUtils.set('bulkEmail:batchSize', 1);
|
||||
await testEmailBatches({
|
||||
mobiledoc: mobileDocWithPaidMemberOnly
|
||||
}, null, [
|
||||
|
@ -577,7 +576,7 @@ describe('Batch sending tests', function () {
|
|||
});
|
||||
|
||||
it('One failed batch marks the email as failed and allows for a retry', async function () {
|
||||
MailgunEmailProvider.BATCH_SIZE = 1;
|
||||
configUtils.set('bulkEmail:batchSize', 1);
|
||||
let counter = 0;
|
||||
stubbedSend = async function () {
|
||||
counter += 1;
|
||||
|
|
|
@ -30,8 +30,6 @@ class MailgunEmailProvider {
|
|||
#mailgunClient;
|
||||
#errorHandler;
|
||||
|
||||
static BATCH_SIZE = 1000;
|
||||
|
||||
/**
|
||||
* @param {object} dependencies
|
||||
* @param {import('@tryghost/mailgun-client/lib/MailgunClient')} dependencies.mailgunClient - mailgun client to send emails
|
||||
|
@ -172,7 +170,7 @@ class MailgunEmailProvider {
|
|||
}
|
||||
|
||||
getMaximumRecipients() {
|
||||
return MailgunEmailProvider.BATCH_SIZE;
|
||||
return this.#mailgunClient.getBatchSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -225,8 +225,20 @@ describe('Mailgun Email Provider', function () {
|
|||
});
|
||||
|
||||
describe('getMaximumRecipients', function () {
|
||||
let mailgunClient;
|
||||
let getBatchSizeStub;
|
||||
|
||||
it('returns 1000', function () {
|
||||
const provider = new MailgunEmailProvider({});
|
||||
getBatchSizeStub = sinon.stub().returns(1000);
|
||||
|
||||
mailgunClient = {
|
||||
getBatchSize: getBatchSizeStub
|
||||
};
|
||||
|
||||
const provider = new MailgunEmailProvider({
|
||||
mailgunClient,
|
||||
errorHandler: () => {}
|
||||
});
|
||||
assert.equal(provider.getMaximumRecipients(), 1000);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@ module.exports = class MailgunClient {
|
|||
#config;
|
||||
#settings;
|
||||
|
||||
static BATCH_SIZE = 1000;
|
||||
static DEFAULT_BATCH_SIZE = 1000;
|
||||
|
||||
constructor({config, settings}) {
|
||||
this.#config = config;
|
||||
|
@ -38,9 +38,10 @@ module.exports = class MailgunClient {
|
|||
return null;
|
||||
}
|
||||
|
||||
if (Object.keys(recipientData).length > MailgunClient.BATCH_SIZE) {
|
||||
const batchSize = this.getBatchSize();
|
||||
if (Object.keys(recipientData).length > batchSize) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: `Mailgun only supports sending to ${MailgunClient.BATCH_SIZE} recipients at a time`
|
||||
message: `Mailgun only supports sending to ${batchSize} recipients at a time`
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -305,4 +306,13 @@ module.exports = class MailgunClient {
|
|||
const instance = this.getInstance();
|
||||
return !!instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns configured batch size
|
||||
*
|
||||
* @returns {number}
|
||||
*/
|
||||
getBatchSize() {
|
||||
return this.#config.get('bulkEmail')?.batchSize ?? this.DEFAULT_BATCH_SIZE;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -43,8 +43,19 @@ describe('MailgunClient', function () {
|
|||
sinon.restore();
|
||||
});
|
||||
|
||||
it('exports a number for BATCH_SIZE', function () {
|
||||
assert(typeof MailgunClient.BATCH_SIZE === 'number');
|
||||
it('exports a number for configurable batch size', function () {
|
||||
const configStub = sinon.stub(config, 'get');
|
||||
configStub.withArgs('bulkEmail').returns({
|
||||
mailgun: {
|
||||
apiKey: 'apiKey',
|
||||
domain: 'domain.com',
|
||||
baseUrl: 'https://api.mailgun.net/v3'
|
||||
},
|
||||
batchSize: 1000
|
||||
});
|
||||
|
||||
const mailgunClient = new MailgunClient({config, settings});
|
||||
assert(typeof mailgunClient.getBatchSize() === 'number');
|
||||
});
|
||||
|
||||
it('can connect via config', function () {
|
||||
|
@ -54,7 +65,8 @@ describe('MailgunClient', function () {
|
|||
apiKey: 'apiKey',
|
||||
domain: 'domain.com',
|
||||
baseUrl: 'https://api.mailgun.net/v3'
|
||||
}
|
||||
},
|
||||
batchSize: 1000
|
||||
});
|
||||
|
||||
const mailgunClient = new MailgunClient({config, settings});
|
||||
|
@ -116,7 +128,8 @@ describe('MailgunClient', function () {
|
|||
apiKey: 'apiKey',
|
||||
domain: 'configdomain.com',
|
||||
baseUrl: 'https://api.mailgun.net'
|
||||
}
|
||||
},
|
||||
batchSize: 1000
|
||||
});
|
||||
|
||||
const settingsStub = sinon.stub(settings, 'get');
|
||||
|
@ -170,7 +183,8 @@ describe('MailgunClient', function () {
|
|||
apiKey: 'apiKey',
|
||||
domain: 'domain.com',
|
||||
baseUrl: 'https://api.mailgun.net/v3'
|
||||
}
|
||||
},
|
||||
batchSize: 1000
|
||||
});
|
||||
|
||||
const firstPageMock = nock('https://api.mailgun.net')
|
||||
|
@ -214,7 +228,8 @@ describe('MailgunClient', function () {
|
|||
apiKey: 'apiKey',
|
||||
domain: 'domain.com',
|
||||
baseUrl: 'https://api.mailgun.net/v3'
|
||||
}
|
||||
},
|
||||
batchSize: 1000
|
||||
});
|
||||
|
||||
const firstPageMock = nock('https://api.mailgun.net')
|
||||
|
@ -259,7 +274,8 @@ describe('MailgunClient', function () {
|
|||
apiKey: 'apiKey',
|
||||
domain: 'domain.com',
|
||||
baseUrl: 'https://api.mailgun.net/v3'
|
||||
}
|
||||
},
|
||||
batchSize: 1000
|
||||
});
|
||||
|
||||
const firstPageMock = nock('https://api.mailgun.net')
|
||||
|
@ -304,7 +320,8 @@ describe('MailgunClient', function () {
|
|||
apiKey: 'apiKey',
|
||||
domain: 'domain.com',
|
||||
baseUrl: 'https://api.mailgun.net/v3'
|
||||
}
|
||||
},
|
||||
batchSize: 1000
|
||||
});
|
||||
|
||||
const firstPageMock = nock('https://api.mailgun.net')
|
||||
|
@ -349,7 +366,8 @@ describe('MailgunClient', function () {
|
|||
apiKey: 'apiKey',
|
||||
domain: 'domain.com',
|
||||
baseUrl: 'https://api.eu.mailgun.net/v3'
|
||||
}
|
||||
},
|
||||
batchSize: 1000
|
||||
});
|
||||
|
||||
const firstPageMock = nock('https://api.eu.mailgun.net')
|
||||
|
|
Loading…
Reference in a new issue