diff --git a/ghost/admin/app/templates/settings/staff/user.hbs b/ghost/admin/app/templates/settings/staff/user.hbs
index c79cddf435..585b6a4ee9 100644
--- a/ghost/admin/app/templates/settings/staff/user.hbs
+++ b/ghost/admin/app/templates/settings/staff/user.hbs
@@ -327,6 +327,27 @@
{{/if}}
{{/if}}
{{/if}}
+ {{#if (feature 'webmentions')}}
+
+
+
+
When you receive a new webmention
+
+
+
+
+
+ {{/if}}
{{/if}}
diff --git a/ghost/admin/mirage/factories/user.js b/ghost/admin/mirage/factories/user.js
index d99fe93f2c..76c49c0b4e 100644
--- a/ghost/admin/mirage/factories/user.js
+++ b/ghost/admin/mirage/factories/user.js
@@ -19,7 +19,6 @@ export default Factory.extend({
updatedAt: '2015-11-02T16:12:05.000Z',
updatedBy: '1',
website: 'http://example.com',
-
posts() { return []; },
roles() { return []; }
});
diff --git a/ghost/admin/tests/acceptance/staff-test.js b/ghost/admin/tests/acceptance/staff-test.js
index 9a02eeb400..a618c5004f 100644
--- a/ghost/admin/tests/acceptance/staff-test.js
+++ b/ghost/admin/tests/acceptance/staff-test.js
@@ -14,6 +14,7 @@ import {
focus,
triggerEvent
} from '@ember/test-helpers';
+import {enableLabsFlag} from '../helpers/labs-flag';
import {enableMembers} from '../helpers/members';
import {enableStripe} from '../helpers/stripe';
import {expect} from 'chai';
@@ -79,6 +80,7 @@ describe('Acceptance: Staff', function () {
adminRole = this.server.schema.roles.find(1);
enableMembers(this.server);
enableStripe(this.server);
+ enableLabsFlag(this.server, 'webmentions');
admin = this.server.create('user', {email: 'admin@example.com', roles: [adminRole]});
@@ -869,17 +871,20 @@ describe('Acceptance: Staff', function () {
expect(find('[data-test-checkbox="free-signup-notifications"]')).to.not.be.checked;
expect(find('[data-test-checkbox="paid-started-notifications"]')).to.not.be.checked;
expect(find('[data-test-checkbox="paid-canceled-notifications"]')).to.not.be.checked;
+ expect(find('[data-test-checkbox="mention-notifications"]')).to.not.be.checked;
await click('[data-test-label="free-signup-notifications"]');
await click('[data-test-label="paid-started-notifications"]');
await click('[data-test-label="paid-canceled-notifications"]');
-
+ await click('[data-test-label="mention-notifications"]');
await click('[data-test-save-button]');
- await visit(`/settings/staff/${admin.slug}`);
+ await visit(`/settings/staff/${admin.slug}`);
+
expect(find('[data-test-checkbox="free-signup-notifications"]')).to.be.checked;
expect(find('[data-test-checkbox="paid-started-notifications"]')).to.be.checked;
expect(find('[data-test-checkbox="paid-canceled-notifications"]')).to.be.checked;
+ expect(find('[data-test-checkbox="mention-notifications"]')).to.be.checked;
});
});
diff --git a/ghost/core/core/server/models/user.js b/ghost/core/core/server/models/user.js
index 1f3230ea88..da3c767ad1 100644
--- a/ghost/core/core/server/models/user.js
+++ b/ghost/core/core/server/models/user.js
@@ -505,6 +505,8 @@ User = ghostBookshelf.Model.extend({
filter += '+paid_subscription_started_notification:true';
} else if (type === 'paid-canceled') {
filter += '+paid_subscription_canceled_notification:true';
+ } else if (type === 'mention-received') {
+ filter += '+mention_notifications:true';
}
const updatedOptions = _.merge({}, options, {filter, withRelated: ['roles']});
return this.findAll(updatedOptions).then((users) => {
diff --git a/ghost/core/core/shared/labs.js b/ghost/core/core/shared/labs.js
index cb09d52e72..80cf42153c 100644
--- a/ghost/core/core/shared/labs.js
+++ b/ghost/core/core/shared/labs.js
@@ -35,7 +35,6 @@ const ALPHA_FEATURES = [
'urlCache',
'beforeAfterCard',
'lexicalEditor',
- 'webmentionEmail',
'outboundLinkTagging',
'milestoneEmails'
];
diff --git a/ghost/core/test/e2e-api/webmentions/webmentions.test.js b/ghost/core/test/e2e-api/webmentions/webmentions.test.js
index fb5653df6d..3d6f5dbfb9 100644
--- a/ghost/core/test/e2e-api/webmentions/webmentions.test.js
+++ b/ghost/core/test/e2e-api/webmentions/webmentions.test.js
@@ -19,7 +19,7 @@ describe('Webmentions (receiving)', function () {
agent = await agentProvider.getWebmentionsAPIAgent();
await fixtureManager.init('posts');
nock.disableNetConnect();
- mockManager.mockLabsEnabled('webmentionEmail');
+ mockManager.mockLabsEnabled('webmentions');
});
after(function () {
@@ -136,7 +136,7 @@ describe('Webmentions (receiving)', function () {
await processWebmentionJob;
await DomainEvents.allSettled();
- const users = await models.User.findAll();
+ const users = await models.User.getEmailAlertUsers('mention-received');
users.forEach(async (user) => {
await mockManager.assert.sentEmail({
subject: 'You\'ve been mentioned!',
@@ -147,7 +147,7 @@ describe('Webmentions (receiving)', function () {
});
it('does not send notification with flag disabled', async function () {
- mockManager.mockLabsDisabled('webmentionEmail');
+ mockManager.mockLabsDisabled('webmentions');
const processWebmentionJob = jobsService.awaitCompletion('processWebmention');
const targetUrl = new URL('integrations/', urlUtils.getSiteUrl());
const sourceUrl = new URL('http://testpage.com/external-article-123-email-test/');
diff --git a/ghost/staff-service/lib/emails.js b/ghost/staff-service/lib/emails.js
index eda8bff677..45864d079b 100644
--- a/ghost/staff-service/lib/emails.js
+++ b/ghost/staff-service/lib/emails.js
@@ -143,9 +143,24 @@ class StaffServiceEmails {
}
async notifyMentionReceived({mention}) {
- const users = await this.models.User.findAll(); // sending to all staff users for now
+ const users = await this.models.User.getEmailAlertUsers('mention-received');
+ let resource = null;
+ if (mention.resourceId) {
+ try {
+ const postModel = await this.models.Post.findOne({id: mention.resourceId.toString()});
+ if (postModel) {
+ resource = {
+ id: postModel.id,
+ name: postModel.get('title'),
+ type: 'post'
+ };
+ }
+ } catch (err) {
+ this.logging.error(err);
+ }
+ }
for (const user of users) {
- const to = user.toJSON().email;
+ const to = user.email;
const subject = `💌 New mention from: ${mention.sourceSiteTitle}`;
const templateData = {
@@ -155,13 +170,14 @@ class StaffServiceEmails {
sourceSiteTitle: mention.sourceSiteTitle,
sourceFavicon: mention.sourceFavicon,
sourceAuthor: mention.sourceAuthor,
+ resource,
siteTitle: this.settingsCache.get('title'),
siteUrl: this.urlUtils.getSiteUrl(),
siteDomain: this.siteDomain,
accentColor: this.settingsCache.get('accent_color'),
fromEmail: this.fromEmailAddress,
toEmail: to,
- staffUrl: this.urlUtils.urlJoin(this.urlUtils.urlFor('admin', true), '#', `/settings/staff/${user.toJSON().slug}`)
+ staffUrl: this.urlUtils.urlJoin(this.urlUtils.urlFor('admin', true), '#', `/settings/staff/${user.slug}`)
};
const {html, text} = await this.renderEmailTemplate('new-mention-received', templateData);
diff --git a/ghost/staff-service/lib/staff-service.js b/ghost/staff-service/lib/staff-service.js
index b713d29834..0b6fe42b72 100644
--- a/ghost/staff-service/lib/staff-service.js
+++ b/ghost/staff-service/lib/staff-service.js
@@ -77,7 +77,7 @@ class StaffService {
/** @private */
async handleEvent(type, event) {
- if (type === MentionCreatedEvent && event.data.mention && this.labs.isSet('webmentionEmail')) {
+ if (type === MentionCreatedEvent && event.data.mention && this.labs.isSet('webmentions')) {
await this.emails.notifyMentionReceived(event.data);
}
if (!['api', 'member'].includes(event.data.source)) {
diff --git a/ghost/staff-service/test/staff-service.test.js b/ghost/staff-service/test/staff-service.test.js
index 51c49542b8..f2ab18a81a 100644
--- a/ghost/staff-service/test/staff-service.test.js
+++ b/ghost/staff-service/test/staff-service.test.js
@@ -269,7 +269,7 @@ describe('StaffService', function () {
urlUtils,
settingsHelpers,
labs: {
- isSet: () => 'webmentionEmail'
+ isSet: () => 'webmentions'
}
});
});