diff --git a/ghost/link-tracking/.eslintrc.js b/ghost/link-tracking/.eslintrc.js new file mode 100644 index 0000000000..c9c1bcb522 --- /dev/null +++ b/ghost/link-tracking/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: ['ghost'], + extends: [ + 'plugin:ghost/node' + ] +}; diff --git a/ghost/link-tracking/README.md b/ghost/link-tracking/README.md new file mode 100644 index 0000000000..65887256af --- /dev/null +++ b/ghost/link-tracking/README.md @@ -0,0 +1,21 @@ +# Link Tracking + + +## Usage + + +## Develop + +This is a monorepo package. + +Follow the instructions for the top-level repo. +1. `git clone` this repo & `cd` into it as usual +2. Run `yarn` to install top-level dependencies. + + + +## Test + +- `yarn lint` run just eslint +- `yarn test` run lint and tests + diff --git a/ghost/link-tracking/index.js b/ghost/link-tracking/index.js new file mode 100644 index 0000000000..10a765e4ca --- /dev/null +++ b/ghost/link-tracking/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/link-tracking'); diff --git a/ghost/link-tracking/lib/link-tracking.js b/ghost/link-tracking/lib/link-tracking.js new file mode 100644 index 0000000000..0d0b2861b6 --- /dev/null +++ b/ghost/link-tracking/lib/link-tracking.js @@ -0,0 +1,43 @@ +const DomainEvents = require('@tryghost/domain-events'); +const {RedirectEvent} = require('@tryghost/link-redirects'); + +class LinkClickTrackingService { + #initialised = false; + + async init() { + if (this.#initialised) { + return; + } + this.subscribe(); + this.#initialised = true; + } + + /** + * @param {import('@tryghost/link-redirects/LinkRedirect')} redirect + * @param {string} id + * @return {Promise} + */ + async addTrackingToRedirect(redirect, id){ + const trackingUrl = new URL(redirect.from); + trackingUrl.searchParams.set('m', id); + return trackingUrl; + } + + subscribe() { + DomainEvents.subscribe(RedirectEvent, (event) => { + const id = event.data.url.searchParams.get('m'); + if (typeof id !== 'string') { + return; + } + + const clickEvent = { + member_id: id, + link_id: event.data.link.link_id + }; + // eslint-disable-next-line no-console + console.log('Finna store a click event', clickEvent); + }); + } +} + +module.exports = LinkClickTrackingService; diff --git a/ghost/link-tracking/package.json b/ghost/link-tracking/package.json new file mode 100644 index 0000000000..d927a2ad25 --- /dev/null +++ b/ghost/link-tracking/package.json @@ -0,0 +1,30 @@ +{ + "name": "@tryghost/link-tracking", + "version": "0.0.0", + "repository": "https://github.com/TryGhost/Ghost/tree/main/packages/link-tracking", + "author": "Ghost Foundation", + "private": true, + "main": "index.js", + "scripts": { + "dev": "echo \"Implement me!\"", + "test:unit": "NODE_ENV=testing c8 --all --reporter text --reporter cobertura mocha './test/**/*.test.js'", + "test": "yarn test:unit", + "lint:code": "eslint *.js lib/ --ext .js --cache", + "lint": "yarn lint:code && yarn lint:test", + "lint:test": "eslint -c test/.eslintrc.js test/ --ext .js --cache" + }, + "files": [ + "index.js", + "lib" + ], + "devDependencies": { + "c8": "7.12.0", + "mocha": "10.0.0", + "should": "13.2.3", + "sinon": "14.0.0" + }, + "dependencies": { + "@tryghost/domain-events": "^0.1.14", + "@tryghost/link-redirects": "0.0.0" + } +} diff --git a/ghost/link-tracking/test/.eslintrc.js b/ghost/link-tracking/test/.eslintrc.js new file mode 100644 index 0000000000..829b601eb0 --- /dev/null +++ b/ghost/link-tracking/test/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: ['ghost'], + extends: [ + 'plugin:ghost/test' + ] +}; diff --git a/ghost/link-tracking/test/LinkTrackingService.test.js b/ghost/link-tracking/test/LinkTrackingService.test.js new file mode 100644 index 0000000000..9e3585f749 --- /dev/null +++ b/ghost/link-tracking/test/LinkTrackingService.test.js @@ -0,0 +1,5 @@ +describe('LinkTrackingService', function () { + it('exists', function () { + require('../'); + }); +}); diff --git a/yarn.lock b/yarn.lock index 5dcbaf4a39..ae7e6d0005 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3325,6 +3325,11 @@ "@tryghost/root-utils" "^0.3.16" debug "^4.3.1" +"@tryghost/domain-events@^0.1.14": + version "0.1.14" + resolved "https://registry.yarnpkg.com/@tryghost/domain-events/-/domain-events-0.1.14.tgz#a0206b21981d8e3337dfc0ed56df182d6e7188b3" + integrity sha512-SoJMvrwBXFDciQwjobpuZae0AQ/pVB+RgSj+QEuKNqg6V6CAhNlLrI1rAhkHtXkuKaLDDzH8tKWQEeeApXdBng== + "@tryghost/elasticsearch@^3.0.3": version "3.0.3" resolved "https://registry.yarnpkg.com/@tryghost/elasticsearch/-/elasticsearch-3.0.3.tgz#6651298989f38bbe30777ab122d56a43f719d2c2"