Added referrer attribution data to member api

refs https://github.com/TryGhost/Team/issues/1961

- includes referrer source and medium information in member api
This commit is contained in:
Rishabh 2022-09-23 20:49:51 +05:30 committed by Rishabh Garg
parent 6fffe5468d
commit 6c85c75b86
9 changed files with 254 additions and 45 deletions

View File

@ -55,6 +55,22 @@ const clickEventMapper = (json, frame) => {
};
};
function serializeAttribution(attribution) {
if (!attribution) {
return attribution;
}
return {
id: attribution?.id,
type: attribution?.type,
url: attribution?.url,
title: attribution?.title,
referrer_source: attribution?.referrerSource,
referrer_medium: attribution?.referrerMedium,
referrer_url: attribution.referrerUrl
};
}
const activityFeedMapper = (event, frame) => {
if (event.type === 'comment_event') {
return commentEventMapper(event, frame);
@ -62,6 +78,9 @@ const activityFeedMapper = (event, frame) => {
if (event.type === 'click_event') {
return clickEventMapper(event, frame);
}
if (event.data?.attribution) {
event.data.attribution = serializeAttribution(event.data.attribution);
}
return event;
};

View File

@ -96,6 +96,22 @@ function exportCSV(data) {
return unparse(data.data);
}
function serializeAttribution(attribution) {
if (!attribution) {
return attribution;
}
return {
id: attribution?.id,
type: attribution?.type,
url: attribution?.url,
title: attribution?.title,
referrer_source: attribution?.referrerSource,
referrer_medium: attribution?.referrerMedium,
referrer_url: attribution.referrerUrl
};
}
/**
* @param {import('bookshelf').Model} member
* @param {object} options
@ -129,7 +145,7 @@ function serializeMember(member, options) {
email_recipients: json.email_recipients,
status: json.status,
last_seen_at: json.last_seen_at,
attribution: json.attribution
attribution: serializeAttribution(json.attribution)
};
if (json.products) {
@ -141,15 +157,16 @@ function serializeMember(member, options) {
if (!subscription.price) {
continue;
}
if (!subscription.price.tier && subscription.price.product) {
subscription.price.tier = subscription.price.product;
if (!subscription.price.tier.tier_id) {
subscription.price.tier.tier_id = subscription.price.tier.product_id;
}
delete subscription.price.tier.product_id;
}
subscription.attribution = serializeAttribution(subscription.attribution);
delete subscription.price.product;
}

View File

@ -6,6 +6,9 @@ Object {
Object {
"attribution": Object {
"id": "618ba1ffbe2896088840a6e9",
"referrer_medium": null,
"referrer_source": null,
"referrer_url": null,
"title": "This is a static page",
"type": "page",
"url": "http://127.0.0.1:2369/static-page-test/",
@ -39,7 +42,7 @@ exports[`Members API - member attribution Can read member attributed to a page 2
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "1955",
"content-length": "2021",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -53,6 +56,9 @@ Object {
Object {
"attribution": Object {
"id": "618ba1ffbe2896088840a6df",
"referrer_medium": null,
"referrer_source": null,
"referrer_url": null,
"title": "HTML Ipsum",
"type": "post",
"url": "http://127.0.0.1:2369/html-ipsum/",
@ -86,7 +92,7 @@ exports[`Members API - member attribution Can read member attributed to a post 2
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "1938",
"content-length": "2004",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -100,6 +106,9 @@ Object {
Object {
"attribution": Object {
"id": "618ba1febe2896088840a6db",
"referrer_medium": null,
"referrer_source": null,
"referrer_url": null,
"title": "kitchen sink",
"type": "tag",
"url": "http://127.0.0.1:2369/tag/kitchen-sink/",
@ -133,7 +142,7 @@ exports[`Members API - member attribution Can read member attributed to a tag 2:
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "1944",
"content-length": "2010",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -147,6 +156,9 @@ Object {
Object {
"attribution": Object {
"id": "1",
"referrer_medium": null,
"referrer_source": null,
"referrer_url": null,
"title": "Joe Bloggs",
"type": "author",
"url": "http://127.0.0.1:2369/author/joe-bloggs/",
@ -180,7 +192,7 @@ exports[`Members API - member attribution Can read member attributed to an autho
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "1926",
"content-length": "1992",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -194,6 +206,9 @@ Object {
Object {
"attribution": Object {
"id": null,
"referrer_medium": null,
"referrer_source": null,
"referrer_url": null,
"title": "/a-static-page/",
"type": "url",
"url": "http://127.0.0.1:2369/a-static-page/",
@ -227,7 +242,7 @@ exports[`Members API - member attribution Can read member attributed to an url 2
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "1922",
"content-length": "1988",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -266,7 +281,7 @@ exports[`Members API - member attribution Returns sign up attributions in activi
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "8874",
"content-length": "9204",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -612,6 +627,9 @@ Object {
Object {
"attribution": Object {
"id": "618ba1ffbe2896088840a6df",
"referrer_medium": "Social",
"referrer_source": "Twitter",
"referrer_url": "https://twitter.com",
"title": "HTML Ipsum",
"type": "post",
"url": "http://127.0.0.1:2369/html-ipsum/",
@ -685,7 +703,7 @@ exports[`Members API Can add a subscription 2: [headers] 1`] = `
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "2283",
"content-length": "2375",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -699,6 +717,9 @@ Object {
Object {
"attribution": Object {
"id": "618ba1ffbe2896088840a6df",
"referrer_medium": "Social",
"referrer_source": "Twitter",
"referrer_url": "https://twitter.com",
"title": "HTML Ipsum",
"type": "post",
"url": "http://127.0.0.1:2369/html-ipsum/",
@ -772,7 +793,7 @@ exports[`Members API Can add a subscription 4: [headers] 1`] = `
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "2283",
"content-length": "2375",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -2219,6 +2240,44 @@ Object {
}
`;
exports[`Members API Can filter by signup attribution 2: [body] 1`] = `
Object {
"members": Array [
Object {
"avatar_image": null,
"comped": false,
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
"email": "member1@test.com",
"email_count": 0,
"email_open_rate": null,
"email_opened_count": 0,
"geolocation": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"labels": Any<Array>,
"last_seen_at": null,
"name": "Mr Egg",
"newsletters": Any<Array>,
"note": null,
"status": "free",
"subscribed": true,
"subscriptions": Any<Array>,
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
"uuid": StringMatching /\\[a-f0-9\\]\\{8\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{12\\}/,
},
],
"meta": Object {
"pagination": Object {
"limit": 15,
"next": null,
"page": 1,
"pages": 1,
"prev": null,
"total": 1,
},
},
}
`;
exports[`Members API Can filter by signup attribution 2: [headers] 1`] = `
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
@ -2269,6 +2328,18 @@ Object {
}
`;
exports[`Members API Can filter by signup attribution 3: [headers] 1`] = `
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "1379",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
"x-powered-by": "Express",
}
`;
exports[`Members API Can filter by signup attribution 4: [headers] 1`] = `
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
@ -3183,6 +3254,9 @@ Object {
Object {
"attribution": Object {
"id": "618ba1ffbe2896088840a6df",
"referrer_medium": "Social",
"referrer_source": "Twitter",
"referrer_url": "https://twitter.com",
"title": "HTML Ipsum",
"type": "post",
"url": "http://127.0.0.1:2369/html-ipsum/",
@ -3216,7 +3290,7 @@ exports[`Members API Can read 2: [headers] 1`] = `
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "1427",
"content-length": "1519",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -3230,6 +3304,9 @@ Object {
Object {
"attribution": Object {
"id": "618ba1ffbe2896088840a6df",
"referrer_medium": "Social",
"referrer_source": "Twitter",
"referrer_url": "https://twitter.com",
"title": "HTML Ipsum",
"type": "post",
"url": "http://127.0.0.1:2369/html-ipsum/",
@ -3264,7 +3341,7 @@ exports[`Members API Can read and include email_recipients 2: [headers] 1`] = `
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "1449",
"content-length": "1541",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -3278,6 +3355,9 @@ Object {
Object {
"attribution": Object {
"id": "618ba1ffbe2896088840a6df",
"referrer_medium": "Social",
"referrer_source": "Twitter",
"referrer_url": "https://twitter.com",
"title": "HTML Ipsum",
"type": "post",
"url": "http://127.0.0.1:2369/html-ipsum/",
@ -3311,7 +3391,7 @@ exports[`Members API Can read and include tiers 2: [headers] 1`] = `
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "1427",
"content-length": "1519",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",

View File

@ -192,7 +192,10 @@ describe('Members API - member attribution', function () {
attribution: memberAttributionService.attributionBuilder.build({
id,
url: '/out-of-date/',
type: 'post'
type: 'post',
refSource: null,
refMedium: null,
refUrl: null
})
});
@ -212,7 +215,10 @@ describe('Members API - member attribution', function () {
id: post.id,
url: absoluteUrl,
type: 'post',
title: post.get('title')
title: post.get('title'),
referrer_source: null,
referrer_medium: null,
referrer_url: null
});
signupAttributions.push(body.members[0].attribution);
});
@ -228,7 +234,10 @@ describe('Members API - member attribution', function () {
attribution: memberAttributionService.attributionBuilder.build({
id,
url: '/out-of-date/',
type: 'page'
type: 'page',
refSource: null,
refMedium: null,
refUrl: null
})
});
@ -248,7 +257,10 @@ describe('Members API - member attribution', function () {
id: post.id,
url: absoluteUrl,
type: 'page',
title: post.get('title')
title: post.get('title'),
referrer_source: null,
referrer_medium: null,
referrer_url: null
});
signupAttributions.push(body.members[0].attribution);
});
@ -264,7 +276,10 @@ describe('Members API - member attribution', function () {
attribution: memberAttributionService.attributionBuilder.build({
id,
url: '/out-of-date/',
type: 'tag'
type: 'tag',
refSource: null,
refMedium: null,
refUrl: null
})
});
@ -284,7 +299,10 @@ describe('Members API - member attribution', function () {
id: tag.id,
url: absoluteUrl,
type: 'tag',
title: tag.get('name')
title: tag.get('name'),
referrer_source: null,
referrer_medium: null,
referrer_url: null
});
signupAttributions.push(body.members[0].attribution);
});
@ -300,7 +318,10 @@ describe('Members API - member attribution', function () {
attribution: memberAttributionService.attributionBuilder.build({
id,
url: '/out-of-date/',
type: 'author'
type: 'author',
refSource: null,
refMedium: null,
refUrl: null
})
});
@ -320,7 +341,10 @@ describe('Members API - member attribution', function () {
id: author.id,
url: absoluteUrl,
type: 'author',
title: author.get('name')
title: author.get('name'),
referrer_source: null,
referrer_medium: null,
referrer_url: null
});
signupAttributions.push(body.members[0].attribution);
});
@ -333,7 +357,10 @@ describe('Members API - member attribution', function () {
attribution: memberAttributionService.attributionBuilder.build({
id: null,
url: '/a-static-page/',
type: 'url'
type: 'url',
refSource: null,
refMedium: null,
refUrl: null
})
});
@ -353,7 +380,10 @@ describe('Members API - member attribution', function () {
id: null,
url: absoluteUrl,
type: 'url',
title: '/a-static-page/'
title: '/a-static-page/',
referrer_source: null,
referrer_medium: null,
referrer_url: null
});
signupAttributions.push(body.members[0].attribution);
});

View File

@ -6,6 +6,9 @@ Object {
Object {
"attribution": Object {
"id": "1",
"referrer_medium": null,
"referrer_source": null,
"referrer_url": null,
"title": "Joe Bloggs",
"type": "author",
"url": "http://127.0.0.1:2369/author/joe-bloggs/",
@ -39,7 +42,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent with
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "2795",
"content-length": "2927",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -53,6 +56,9 @@ Object {
Object {
"attribution": Object {
"id": null,
"referrer_medium": null,
"referrer_source": null,
"referrer_url": null,
"title": "/removed-blog-post/",
"type": "url",
"url": "http://127.0.0.1:2369/removed-blog-post/",
@ -86,7 +92,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent with
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "2809",
"content-length": "2941",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -142,6 +148,9 @@ Object {
Object {
"attribution": Object {
"id": "618ba1ffbe2896088840a6e9",
"referrer_medium": null,
"referrer_source": null,
"referrer_url": null,
"title": "This is a static page",
"type": "page",
"url": "http://127.0.0.1:2369/static-page-test/",
@ -175,7 +184,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent with
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "2857",
"content-length": "2989",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -189,6 +198,9 @@ Object {
Object {
"attribution": Object {
"id": "618ba1ffbe2896088840a6df",
"referrer_medium": null,
"referrer_source": null,
"referrer_url": null,
"title": "HTML Ipsum",
"type": "post",
"url": "http://127.0.0.1:2369/html-ipsum/",
@ -222,7 +234,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent with
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "2823",
"content-length": "2955",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -236,6 +248,9 @@ Object {
Object {
"attribution": Object {
"id": "618ba1febe2896088840a6db",
"referrer_medium": null,
"referrer_source": null,
"referrer_url": null,
"title": "kitchen sink",
"type": "tag",
"url": "http://127.0.0.1:2369/tag/kitchen-sink/",
@ -269,7 +284,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent with
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "2837",
"content-length": "2969",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -283,6 +298,9 @@ Object {
Object {
"attribution": Object {
"id": null,
"referrer_medium": null,
"referrer_source": null,
"referrer_url": null,
"title": "homepage",
"type": "url",
"url": "http://127.0.0.1:2369/",
@ -316,7 +334,7 @@ exports[`Members API Member attribution Creates a SubscriptionCreatedEvent with
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "2751",
"content-length": "2883",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",
@ -421,7 +439,7 @@ exports[`Members API Member attribution Returns subscription created attribution
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "14106",
"content-length": "14502",
"content-type": "application/json; charset=utf-8",
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Origin, Accept-Encoding",

View File

@ -1836,7 +1836,10 @@ describe('Members API', function () {
id: null,
url: absoluteUrl,
type: 'url',
title: 'homepage'
title: 'homepage',
referrer_source: null,
referrer_medium: null,
referrer_url: null
});
});
@ -1856,7 +1859,10 @@ describe('Members API', function () {
id: post.id,
url: absoluteUrl,
type: 'post',
title: post.get('title')
title: post.get('title'),
referrer_source: null,
referrer_medium: null,
referrer_url: null
});
});
@ -1873,7 +1879,10 @@ describe('Members API', function () {
id: null,
url: absoluteUrl,
type: 'url',
title: '/removed-blog-post/'
title: '/removed-blog-post/',
referrer_source: null,
referrer_medium: null,
referrer_url: null
});
});
@ -1893,7 +1902,10 @@ describe('Members API', function () {
id: post.id,
url: absoluteUrl,
type: 'page',
title: post.get('title')
title: post.get('title'),
referrer_source: null,
referrer_medium: null,
referrer_url: null
});
});
@ -1913,7 +1925,10 @@ describe('Members API', function () {
id: tag.id,
url: absoluteUrl,
type: 'tag',
title: tag.get('name')
title: tag.get('name'),
referrer_source: null,
referrer_medium: null,
referrer_url: null
});
});
@ -1933,7 +1948,10 @@ describe('Members API', function () {
id: author.id,
url: absoluteUrl,
type: 'author',
title: author.get('name')
title: author.get('name'),
referrer_source: null,
referrer_medium: null,
referrer_url: null
});
});

View File

@ -4,6 +4,9 @@
* @prop {string|null} url (absolute URL)
* @prop {'page'|'post'|'author'|'tag'|'url'} type
* @prop {string|null} title
* @prop {string|null} referrerSource
* @prop {string|null} referrerMedium
* @prop {string|null} referrerUrl
*/
class Attribution {
@ -17,7 +20,7 @@ class Attribution {
* @param {'page'|'post'|'author'|'tag'|'url'} [data.type]
* @param {string|null} [data.refSource]
* @param {string|null} [data.refMedium]
* @param {URL|null} [data.refUrl]
* @param {string|null} [data.refUrl]
*/
constructor({
id, url, type, refSource, refMedium, refUrl
@ -50,7 +53,10 @@ class Attribution {
id: null,
type: 'url',
url: this.#urlTranslator.relativeToAbsolute(this.url),
title: this.#urlTranslator.getUrlTitle(this.url)
title: this.#urlTranslator.getUrlTitle(this.url),
referrerSource: this.refSource,
referrerMedium: this.refMedium,
referrerUrl: this.refUrl
};
}
@ -60,7 +66,10 @@ class Attribution {
id: model.id,
type: this.type,
url: updatedUrl,
title: model.get('title') ?? model.get('name') ?? this.#urlTranslator.getUrlTitle(this.url)
title: model.get('title') ?? model.get('name') ?? this.#urlTranslator.getUrlTitle(this.url),
referrerSource: this.refSource,
referrerMedium: this.refMedium,
referrerUrl: this.refUrl
};
}

View File

@ -69,7 +69,10 @@ class MemberAttributionService {
const _attribution = this.attributionBuilder.build({
id: eventModel.get('attribution_id'),
url: eventModel.get('attribution_url'),
type: eventModel.get('attribution_type')
type: eventModel.get('attribution_type'),
refSource: eventModel.get('referrer_source'),
refMedium: eventModel.get('referrer_medium'),
refUrl: eventModel.get('referrer_url')
});
if (_attribution.type !== 'url') {
@ -102,7 +105,10 @@ class MemberAttributionService {
const attribution = this.attributionBuilder.build({
id: memberCreatedEvent.get('attribution_id'),
url: memberCreatedEvent.get('attribution_url'),
type: memberCreatedEvent.get('attribution_type')
type: memberCreatedEvent.get('attribution_type'),
refSource: memberCreatedEvent.get('referrer_source'),
refMedium: memberCreatedEvent.get('referrer_medium'),
refUrl: memberCreatedEvent.get('referrer_url')
});
return await attribution.fetchResource();
}
@ -120,7 +126,10 @@ class MemberAttributionService {
const attribution = this.attributionBuilder.build({
id: subscriptionCreatedEvent.get('attribution_id'),
url: subscriptionCreatedEvent.get('attribution_url'),
type: subscriptionCreatedEvent.get('attribution_type')
type: subscriptionCreatedEvent.get('attribution_type'),
refSource: subscriptionCreatedEvent.get('referrer_source'),
refMedium: subscriptionCreatedEvent.get('referrer_medium'),
refUrl: subscriptionCreatedEvent.get('referrer_url')
});
return await attribution.fetchResource();
}

View File

@ -54,7 +54,10 @@ describe('MemberAttributionService', function () {
id: null,
type: 'url',
url: '/my/url/',
title: 'added'
title: 'added',
refMedium: null,
refSource: null,
refUrl: null
});
});
@ -83,6 +86,9 @@ describe('MemberAttributionService', function () {
if (name === 'attribution_url') {
return '/my/url/';
}
if (name.startsWith('referrer')) {
return null;
}
return 'test_user_id';
},
related(name) {
@ -98,7 +104,10 @@ describe('MemberAttributionService', function () {
id: 'test_user_id',
type: 'user',
url: '/my/url/',
title: 'added'
title: 'added',
refMedium: null,
refSource: null,
refUrl: null
});
});
});