From c78b5ecf7cc3ba4827618cb4919cfa44993b61e1 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Mon, 20 Aug 2018 14:13:22 -0500 Subject: [PATCH] Analytics: More / improved tracking (#10608) * WIP(analytics): add / improve tracking * fix(groups): revert attempt at tracking on group model * fix(analytics): track questing based on user data * each buy-operation now has a getItemType method - typo getItemKey - removed unneeded overrides --- .../script/ops/buy/abstractBuyOperation.js | 22 ++++++++++++++----- website/common/script/ops/buy/buyArmoire.js | 6 ----- website/common/script/ops/buy/buyGem.js | 12 +++++----- .../common/script/ops/buy/buyHealthPotion.js | 6 ----- website/common/script/ops/buy/buyQuest.js | 4 ++++ website/common/script/ops/buy/buyQuestGem.js | 4 ++++ website/common/script/ops/buy/buySpell.js | 4 ++++ website/common/script/ops/buy/purchase.js | 2 +- website/server/controllers/api-v3/groups.js | 10 +++++++++ website/server/controllers/api-v3/tasks.js | 2 ++ website/server/libs/cron.js | 10 +++++++++ 11 files changed, 57 insertions(+), 25 deletions(-) diff --git a/website/common/script/ops/buy/abstractBuyOperation.js b/website/common/script/ops/buy/abstractBuyOperation.js index 78256d21c3..85b9588f0a 100644 --- a/website/common/script/ops/buy/abstractBuyOperation.js +++ b/website/common/script/ops/buy/abstractBuyOperation.js @@ -38,10 +38,22 @@ export class AbstractBuyOperation { * @param item * @returns {String} */ - getIemKey (item) { + getItemKey (item) { return item.key; } + /** + * Returns the item type + * @param item + * @returns {String} + */ + getItemType (item) { + if (!item.type) + throw new NotImplementedError('item doesn\'t have a type property'); + + return item.type; + } + /** * Shortcut to get the translated string without passing `req.language` * @param {String} key - translation key @@ -141,8 +153,8 @@ export class AbstractGoldItemOperation extends AbstractBuyOperation { analyticsData () { return { - itemKey: this.getIemKey(this.item), - itemType: 'Market', + itemKey: this.getItemKey(this.item), + itemType: this.getItemType(this.item), acquireMethod: 'Gold', goldCost: this.getItemValue(this.item), }; @@ -175,8 +187,8 @@ export class AbstractGemItemOperation extends AbstractBuyOperation { analyticsData () { return { - itemKey: this.getIemKey(this.item), - itemType: 'Market', + itemKey: this.getItemKey(this.item), + itemType: this.getItemType(this.item), acquireMethod: 'Gems', gemCost: this.getItemValue(this.item) * 4, }; diff --git a/website/common/script/ops/buy/buyArmoire.js b/website/common/script/ops/buy/buyArmoire.js index 4d091a2c12..82c7868e3a 100644 --- a/website/common/script/ops/buy/buyArmoire.js +++ b/website/common/script/ops/buy/buyArmoire.js @@ -135,10 +135,4 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { }, }; } - - analyticsData () { - let data = super.analyticsData(); - data.itemKey = 'Armoire'; - return data; - } } diff --git a/website/common/script/ops/buy/buyGem.js b/website/common/script/ops/buy/buyGem.js index 9655537d42..b2ea03046e 100644 --- a/website/common/script/ops/buy/buyGem.js +++ b/website/common/script/ops/buy/buyGem.js @@ -21,10 +21,14 @@ export class BuyGemOperation extends AbstractGoldItemOperation { return planGemLimits.convRate; } - getIemKey () { + getItemKey () { return 'gem'; } + getItemType () { + return 'gems'; + } + extractAndValidateParams (user, req) { let key = this.key = get(req, 'params.key'); if (!key) throw new BadRequest(this.i18n('missingKeyParam')); @@ -72,10 +76,4 @@ export class BuyGemOperation extends AbstractGoldItemOperation { analyticsLabel () { return 'purchase gems'; } - - analyticsData () { - let data = super.analyticsData(); - data.itemKey = 'gem'; - return data; - } } diff --git a/website/common/script/ops/buy/buyHealthPotion.js b/website/common/script/ops/buy/buyHealthPotion.js index cad055a97c..e3d6c1062a 100644 --- a/website/common/script/ops/buy/buyHealthPotion.js +++ b/website/common/script/ops/buy/buyHealthPotion.js @@ -46,10 +46,4 @@ export class BuyHealthPotionOperation extends AbstractGoldItemOperation { message, ]; } - - analyticsData () { - let data = super.analyticsData(); - data.itemKey = 'Potion'; - return data; - } } diff --git a/website/common/script/ops/buy/buyQuest.js b/website/common/script/ops/buy/buyQuest.js index acc0b88940..92e5e92dcf 100644 --- a/website/common/script/ops/buy/buyQuest.js +++ b/website/common/script/ops/buy/buyQuest.js @@ -33,6 +33,10 @@ export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation { return item.goldValue; } + getItemType () { + return 'quest'; + } + extractAndValidateParams (user, req) { let key = this.key = get(req, 'params.key'); if (!key) throw new BadRequest(errorMessage('missingKeyParam')); diff --git a/website/common/script/ops/buy/buyQuestGem.js b/website/common/script/ops/buy/buyQuestGem.js index d3dae03502..90cf0190e8 100644 --- a/website/common/script/ops/buy/buyQuestGem.js +++ b/website/common/script/ops/buy/buyQuestGem.js @@ -26,6 +26,10 @@ export class BuyQuestWithGemOperation extends AbstractGemItemOperation { return item.value / 4; } + getItemType () { + return 'quest'; + } + extractAndValidateParams (user, req) { let key = this.key = get(req, 'params.key'); if (!key) throw new BadRequest(errorMessage('missingKeyParam')); diff --git a/website/common/script/ops/buy/buySpell.js b/website/common/script/ops/buy/buySpell.js index 2a26d0defb..46e73a5d81 100644 --- a/website/common/script/ops/buy/buySpell.js +++ b/website/common/script/ops/buy/buySpell.js @@ -18,6 +18,10 @@ export class BuySpellOperation extends AbstractGoldItemOperation { return this.key; } + getItemType () { + return 'spell'; + } + multiplePurchaseAllowed () { return true; } diff --git a/website/common/script/ops/buy/purchase.js b/website/common/script/ops/buy/purchase.js index 4904b74fe3..bd07248590 100644 --- a/website/common/script/ops/buy/purchase.js +++ b/website/common/script/ops/buy/purchase.js @@ -107,7 +107,7 @@ module.exports = function purchase (user, req = {}, analytics) { analytics.track('acquire item', { uuid: user._id, itemKey: key, - itemType: 'Market', + itemType: type, acquireMethod: 'Gems', gemCost: price * 4, quantityPurchased: quantity, diff --git a/website/server/controllers/api-v3/groups.js b/website/server/controllers/api-v3/groups.js index 16d586a5ca..0870890953 100644 --- a/website/server/controllers/api-v3/groups.js +++ b/website/server/controllers/api-v3/groups.js @@ -1213,6 +1213,16 @@ api.inviteToGroup = { results.push(...emailResults); } + let analyticsObject = { + uuid: user._id, + hitType: 'event', + category: 'behavior', + groupType: group.type, + headers: req.headers, + }; + + res.analytics.track('group invite', analyticsObject); + res.respond(200, results); }, }; diff --git a/website/server/controllers/api-v3/tasks.js b/website/server/controllers/api-v3/tasks.js index a7707e9772..39a12edf55 100644 --- a/website/server/controllers/api-v3/tasks.js +++ b/website/server/controllers/api-v3/tasks.js @@ -175,6 +175,7 @@ api.createUserTasks = { hitType: 'event', category: 'behavior', taskType: task.type, + headers: req.headers, }); } @@ -702,6 +703,7 @@ api.scoreTask = { category: 'behavior', taskType: task.type, direction, + headers: req.headers, }); } }, diff --git a/website/server/libs/cron.js b/website/server/libs/cron.js index e83a92f6b9..3091987637 100644 --- a/website/server/libs/cron.js +++ b/website/server/libs/cron.js @@ -186,6 +186,16 @@ function trackCronAnalytics (analytics, user, _progress, options) { headers: options.headers, loginIncentives: user.loginIncentives, }); + + if (user.party && user.party.quest && !user.party.quest.RSVPNeeded && !user.party.quest.completed && user.party.quest.key && !user.preferences.sleep) { + analytics.track('quest participation', { + category: 'behavior', + uuid: user._id, + user, + questName: user.party.quest.key, + headers: options.headers, + }); + } } function awardLoginIncentives (user) {