feat(analytics): initial Habitica-owned solution
This commit is contained in:
committed by
Kalista Payne
parent
746fcfff49
commit
e6ffd69148
@@ -3,10 +3,8 @@ import isFunction from 'lodash/isFunction';
|
||||
import min from 'lodash/min';
|
||||
import reduce from 'lodash/reduce';
|
||||
import filter from 'lodash/filter';
|
||||
import pick from 'lodash/pick';
|
||||
import pickBy from 'lodash/pickBy';
|
||||
import size from 'lodash/size';
|
||||
import moment from 'moment';
|
||||
import content from '../content/index';
|
||||
import i18n from '../i18n';
|
||||
import { daysSince } from '../cron';
|
||||
@@ -28,7 +26,7 @@ function trueRandom () {
|
||||
return Math.random();
|
||||
}
|
||||
|
||||
export default function randomDrop (user, options, req = {}, analytics) {
|
||||
export default function randomDrop (user, options, req = {}) {
|
||||
let acceptableDrops;
|
||||
let drop;
|
||||
let dropMultiplier;
|
||||
@@ -157,15 +155,5 @@ export default function randomDrop (user, options, req = {}, analytics) {
|
||||
user._tmp.drop = drop;
|
||||
user.items.lastDrop.date = Number(new Date());
|
||||
user.items.lastDrop.count += 1;
|
||||
|
||||
if (analytics && moment().diff(user.auth.timestamps.created, 'days') < 7) {
|
||||
analytics.track('dropped item', {
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
itemKey: drop.key,
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import pick from 'lodash/pick';
|
||||
|
||||
export function hasCompletedOnboarding (user) {
|
||||
return (
|
||||
user.achievements.createdTask === true
|
||||
@@ -16,18 +14,9 @@ export function onOnboardingComplete (user) {
|
||||
}
|
||||
|
||||
// Add notification and awards (server)
|
||||
export function checkOnboardingStatus (user, req, analytics) {
|
||||
export function checkOnboardingStatus (user) {
|
||||
if (hasCompletedOnboarding(user) && user.addNotification) {
|
||||
user.addNotification('ONBOARDING_COMPLETE');
|
||||
if (analytics) {
|
||||
analytics.track('onboarding complete', {
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
hitType: 'event',
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
onOnboardingComplete(user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/* eslint-disable max-classes-per-file */
|
||||
import get from 'lodash/get';
|
||||
import merge from 'lodash/merge';
|
||||
import pick from 'lodash/pick';
|
||||
import i18n from '../../i18n';
|
||||
import {
|
||||
NotAuthorized,
|
||||
@@ -15,12 +13,10 @@ export class AbstractBuyOperation {
|
||||
/**
|
||||
* @param {User} user - the User-Object
|
||||
* @param {Request} req - the Request-Object
|
||||
* @param {analytics} analytics
|
||||
*/
|
||||
constructor (user, req, analytics) {
|
||||
constructor (user, req) {
|
||||
this.user = user;
|
||||
this.req = req || {};
|
||||
this.analytics = analytics;
|
||||
|
||||
const quantity = get(req, 'quantity');
|
||||
|
||||
@@ -87,10 +83,6 @@ export class AbstractBuyOperation {
|
||||
throw new NotImplementedError('executeChanges');
|
||||
}
|
||||
|
||||
analyticsData () { // eslint-disable-line class-methods-use-this
|
||||
throw new NotImplementedError('sendToAnalytics');
|
||||
}
|
||||
|
||||
async purchase () {
|
||||
if (!this.multiplePurchaseAllowed() && this.quantity > 1) {
|
||||
throw new NotAuthorized(this.i18n('messageNotAbleToBuyInBulk'));
|
||||
@@ -98,34 +90,10 @@ export class AbstractBuyOperation {
|
||||
|
||||
this.extractAndValidateParams(this.user, this.req);
|
||||
|
||||
const resultObj = await this.executeChanges(this.user, this.item, this.req, this.analytics);
|
||||
|
||||
if (this.analytics) {
|
||||
this.sendToAnalytics(this.analyticsData());
|
||||
}
|
||||
const resultObj = await this.executeChanges(this.user, this.item, this.req);
|
||||
|
||||
return resultObj;
|
||||
}
|
||||
|
||||
analyticsLabel () { // eslint-disable-line class-methods-use-this
|
||||
return 'buy';
|
||||
}
|
||||
|
||||
sendToAnalytics (additionalData = {}) {
|
||||
// spread-operator produces an "unexpected token" error
|
||||
const analyticsData = merge(additionalData, {
|
||||
user: pick(this.user, ['preferences', 'registeredThrough']),
|
||||
uuid: this.user._id,
|
||||
category: 'behavior',
|
||||
headers: this.req.headers,
|
||||
});
|
||||
|
||||
if (this.multiplePurchaseAllowed()) {
|
||||
analyticsData.quantityPurchased = this.quantity;
|
||||
}
|
||||
|
||||
this.analytics.track(this.analyticsLabel(), analyticsData);
|
||||
}
|
||||
}
|
||||
|
||||
export class AbstractGoldItemOperation extends AbstractBuyOperation {
|
||||
@@ -149,15 +117,6 @@ export class AbstractGoldItemOperation extends AbstractBuyOperation {
|
||||
|
||||
user.stats.gp -= itemValue * this.quantity;
|
||||
}
|
||||
|
||||
analyticsData () {
|
||||
return {
|
||||
itemKey: this.getItemKey(this.item),
|
||||
itemType: this.getItemType(this.item),
|
||||
currency: 'Gold',
|
||||
goldCost: this.getItemValue(this.item),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class AbstractGemItemOperation extends AbstractBuyOperation {
|
||||
@@ -179,15 +138,6 @@ export class AbstractGemItemOperation extends AbstractBuyOperation {
|
||||
|
||||
await updateUserBalance(user, -(itemValue * this.quantity), 'spend', item.key, item.text());
|
||||
}
|
||||
|
||||
analyticsData () {
|
||||
return {
|
||||
itemKey: this.getItemKey(this.item),
|
||||
itemType: this.getItemType(this.item),
|
||||
currency: 'Gems',
|
||||
gemCost: this.getItemValue(this.item) * 4,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class AbstractHourglassItemOperation extends AbstractBuyOperation {
|
||||
@@ -202,11 +152,4 @@ export class AbstractHourglassItemOperation extends AbstractBuyOperation {
|
||||
async subtractCurrency (user, item) { // eslint-disable-line class-methods-use-this
|
||||
await updateUserHourglasses(user, -1, 'spend', item.key);
|
||||
}
|
||||
|
||||
analyticsData () {
|
||||
return {
|
||||
itemKey: this.item.key,
|
||||
currency: 'Hourglass',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import { BuyHourglassMountOperation } from './buyMount';
|
||||
export default async function buy (
|
||||
user,
|
||||
req = {},
|
||||
analytics,
|
||||
options = { quantity: 1, hourglass: false },
|
||||
) {
|
||||
const key = get(req, 'params.key');
|
||||
@@ -42,35 +41,35 @@ export default async function buy (
|
||||
|
||||
switch (type) {
|
||||
case 'armoire': {
|
||||
const buyOp = new BuyArmoireOperation(user, req, analytics);
|
||||
const buyOp = new BuyArmoireOperation(user, req);
|
||||
|
||||
buyRes = await buyOp.purchase();
|
||||
break;
|
||||
}
|
||||
case 'backgrounds':
|
||||
if (!hourglass) throw new BadRequest(errorMessage('useUnlockForCosmetics'));
|
||||
buyRes = await hourglassPurchase(user, req, analytics);
|
||||
buyRes = await hourglassPurchase(user, req);
|
||||
break;
|
||||
case 'mystery':
|
||||
buyRes = await buyMysterySet(user, req, analytics);
|
||||
buyRes = await buyMysterySet(user, req);
|
||||
break;
|
||||
case 'potion': {
|
||||
const buyOp = new BuyHealthPotionOperation(user, req, analytics);
|
||||
const buyOp = new BuyHealthPotionOperation(user, req);
|
||||
|
||||
buyRes = await buyOp.purchase();
|
||||
break;
|
||||
}
|
||||
case 'gems': {
|
||||
const buyOp = new BuyGemOperation(user, req, analytics);
|
||||
const buyOp = new BuyGemOperation(user, req);
|
||||
|
||||
buyRes = await buyOp.purchase();
|
||||
break;
|
||||
}
|
||||
case 'quests': {
|
||||
if (hourglass) {
|
||||
buyRes = await hourglassPurchase(user, req, analytics, quantity);
|
||||
buyRes = await hourglassPurchase(user, req, quantity);
|
||||
} else {
|
||||
const buyOp = new BuyQuestWithGemOperation(user, req, analytics);
|
||||
const buyOp = new BuyQuestWithGemOperation(user, req);
|
||||
|
||||
buyRes = await buyOp.purchase();
|
||||
}
|
||||
@@ -81,36 +80,36 @@ export default async function buy (
|
||||
case 'food':
|
||||
case 'gear':
|
||||
case 'bundles':
|
||||
buyRes = await purchaseOp(user, req, analytics);
|
||||
buyRes = await purchaseOp(user, req);
|
||||
break;
|
||||
case 'mounts': {
|
||||
const buyOp = new BuyHourglassMountOperation(user, req, analytics);
|
||||
const buyOp = new BuyHourglassMountOperation(user, req);
|
||||
|
||||
buyRes = await buyOp.purchase();
|
||||
break;
|
||||
}
|
||||
case 'pets':
|
||||
if (key === 'Gryphatrice-Jubilant') {
|
||||
const buyOp = new BuyPetWithGemOperation(user, req, analytics);
|
||||
const buyOp = new BuyPetWithGemOperation(user, req);
|
||||
buyRes = await buyOp.purchase();
|
||||
} else {
|
||||
buyRes = hourglassPurchase(user, req, analytics);
|
||||
buyRes = hourglassPurchase(user, req);
|
||||
}
|
||||
break;
|
||||
case 'quest': {
|
||||
const buyOp = new BuyQuestWithGoldOperation(user, req, analytics);
|
||||
const buyOp = new BuyQuestWithGoldOperation(user, req);
|
||||
|
||||
buyRes = await buyOp.purchase();
|
||||
break;
|
||||
}
|
||||
case 'special': {
|
||||
const buyOp = new BuySpellOperation(user, req, analytics);
|
||||
const buyOp = new BuySpellOperation(user, req);
|
||||
|
||||
buyRes = await buyOp.purchase();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
const buyOp = new BuyMarketGearOperation(user, req, analytics);
|
||||
const buyOp = new BuyMarketGearOperation(user, req);
|
||||
|
||||
buyRes = await buyOp.purchase();
|
||||
break;
|
||||
|
||||
@@ -69,19 +69,6 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { // eslint-d
|
||||
];
|
||||
}
|
||||
|
||||
_trackDropAnalytics (user, key) {
|
||||
this.analytics.track(
|
||||
'Enchanted Armoire',
|
||||
{
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
itemKey: key,
|
||||
category: 'behavior',
|
||||
headers: this.req.headers,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
_gearResult (user, eligibleEquipment) {
|
||||
const emptied = eligibleEquipment.length === 1;
|
||||
eligibleEquipment.sort();
|
||||
@@ -105,10 +92,6 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { // eslint-d
|
||||
|
||||
removeItemByPath(user, `gear.flat.${drop.key}`);
|
||||
|
||||
if (this.analytics) {
|
||||
this._trackDropAnalytics(user, drop.key);
|
||||
}
|
||||
|
||||
const armoireResp = {
|
||||
type: 'gear',
|
||||
dropKey: drop.key,
|
||||
@@ -134,9 +117,6 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { // eslint-d
|
||||
user.items.food[drop.key] += 1;
|
||||
if (user.markModified) user.markModified('items.food');
|
||||
|
||||
if (this.analytics) {
|
||||
this._trackDropAnalytics(user, drop.key);
|
||||
}
|
||||
return {
|
||||
message: this.i18n('armoireFood', {
|
||||
image: `<span class="Pet_Food_${drop.key} pull-left"></span>`,
|
||||
|
||||
@@ -70,8 +70,4 @@ export class BuyGemOperation extends AbstractGoldItemOperation { // eslint-disab
|
||||
this.i18n('plusGem', { count: this.quantity }),
|
||||
];
|
||||
}
|
||||
|
||||
analyticsLabel () { // eslint-disable-line class-methods-use-this
|
||||
return 'purchase gems';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ export class BuyMarketGearOperation extends AbstractGoldItemOperation { // eslin
|
||||
}
|
||||
}
|
||||
|
||||
executeChanges (user, item, req, analytics) {
|
||||
executeChanges (user, item, req) {
|
||||
let message;
|
||||
|
||||
if (user.preferences.autoEquip) {
|
||||
@@ -70,7 +70,7 @@ export class BuyMarketGearOperation extends AbstractGoldItemOperation { // eslin
|
||||
|
||||
if (!user.achievements.purchasedEquipment && user.addAchievement) {
|
||||
user.addAchievement('purchasedEquipment');
|
||||
checkOnboardingStatus(user, req, analytics);
|
||||
checkOnboardingStatus(user, req);
|
||||
}
|
||||
|
||||
removePinnedGearAddPossibleNewOnes(user, `gear.flat.${item.key}`, item.key);
|
||||
|
||||
@@ -49,10 +49,4 @@ export class BuyHourglassMountOperation extends AbstractHourglassItemOperation {
|
||||
message,
|
||||
];
|
||||
}
|
||||
|
||||
analyticsData () {
|
||||
const data = super.analyticsData();
|
||||
data.itemType = 'mounts';
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import get from 'lodash/get';
|
||||
import each from 'lodash/each';
|
||||
import pick from 'lodash/pick';
|
||||
import i18n from '../../i18n';
|
||||
import content from '../../content/index';
|
||||
import {
|
||||
@@ -13,7 +12,7 @@ import updateUserHourglasses from '../updateUserHourglasses';
|
||||
import { removeItemByPath } from '../pinnedGearUtils';
|
||||
import getItemInfo from '../../libs/getItemInfo';
|
||||
|
||||
export default async function buyMysterySet (user, req = {}, analytics) {
|
||||
export default async function buyMysterySet (user, req = {}) {
|
||||
const key = get(req, 'params.key');
|
||||
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
|
||||
|
||||
@@ -35,18 +34,6 @@ export default async function buyMysterySet (user, req = {}, analytics) {
|
||||
const itemInfo = getItemInfo(user, 'mystery_set', mysterySet);
|
||||
removeItemByPath(user, itemInfo.path);
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('buy', {
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
itemKey: mysterySet.key,
|
||||
itemType: 'Subscriber Gear',
|
||||
currency: 'Hourglass',
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
|
||||
// Here we need to trigger vue reactivity through reassign object
|
||||
user.items.gear.owned = {
|
||||
...user.items.gear.owned,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import get from 'lodash/get';
|
||||
import includes from 'lodash/includes';
|
||||
import keys from 'lodash/keys';
|
||||
import pick from 'lodash/pick';
|
||||
import i18n from '../../i18n';
|
||||
import content from '../../content/index';
|
||||
import {
|
||||
@@ -13,7 +12,7 @@ import getItemInfo from '../../libs/getItemInfo';
|
||||
import { removeItemByPath } from '../pinnedGearUtils';
|
||||
import updateUserHourglasses from '../updateUserHourglasses';
|
||||
|
||||
export default async function purchaseHourglass (user, req = {}, analytics, quantity = 1) {
|
||||
export default async function purchaseHourglass (user, req = {}, quantity = 1) {
|
||||
const key = get(req, 'params.key');
|
||||
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
|
||||
|
||||
@@ -94,18 +93,6 @@ export default async function purchaseHourglass (user, req = {}, analytics, quan
|
||||
}
|
||||
}
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('buy', {
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
itemKey: key,
|
||||
itemType: type,
|
||||
currency: 'Hourglass',
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
{ items: user.items, purchasedPlanConsecutive: user.purchased.plan.consecutive },
|
||||
i18n.t('hourglassPurchase', req.language),
|
||||
|
||||
@@ -76,7 +76,7 @@ async function purchaseItem (user, item, price, type, key) {
|
||||
|
||||
const acceptedTypes = ['eggs', 'hatchingPotions', 'food', 'gear', 'bundles'];
|
||||
const singlePurchaseTypes = ['gear'];
|
||||
export default async function purchase (user, req = {}, analytics) {
|
||||
export default async function purchase (user, req = {}) {
|
||||
const type = get(req.params, 'type');
|
||||
const key = get(req.params, 'key');
|
||||
|
||||
@@ -130,19 +130,6 @@ export default async function purchase (user, req = {}, analytics) {
|
||||
await purchaseItem(user, item, price, type, key);
|
||||
}
|
||||
/* eslint-enable no-await-in-loop */
|
||||
if (analytics) {
|
||||
analytics.track('buy', {
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
itemKey: key,
|
||||
itemType: type,
|
||||
currency: 'Gems',
|
||||
gemCost: price * 4,
|
||||
quantityPurchased: quantity,
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
pick(user, splitWhitespace('items balance')),
|
||||
|
||||
@@ -34,19 +34,18 @@ async function resetClass (user, req = {}) {
|
||||
return balanceRemoved;
|
||||
}
|
||||
|
||||
export default async function changeClass (user, req = {}, analytics) {
|
||||
export default async function changeClass (user, req = {}) {
|
||||
const klass = get(req, 'query.class');
|
||||
let balanceRemoved = 0;
|
||||
// user.flags.classSelected is set to false after the user paid the 3 gems
|
||||
if (user.stats.lvl < 10) {
|
||||
throw new NotAuthorized(i18n.t('lvl10ChangeClass', req.language));
|
||||
} else if (!klass) {
|
||||
// if no class is specified, reset points and set user.flags.classSelected to false.
|
||||
// User will have paid 3 gems and will be prompted to select class.
|
||||
balanceRemoved = await resetClass(user, req);
|
||||
await resetClass(user, req);
|
||||
} else if (klass === 'warrior' || klass === 'rogue' || klass === 'wizard' || klass === 'healer') {
|
||||
if (user.flags.classSelected) {
|
||||
balanceRemoved = await resetClass(user, req);
|
||||
await resetClass(user, req);
|
||||
}
|
||||
|
||||
user.stats.class = klass;
|
||||
@@ -67,17 +66,6 @@ export default async function changeClass (user, req = {}, analytics) {
|
||||
if (user.markModified) user.markModified('items.gear.owned');
|
||||
|
||||
removePinnedItemsByOwnedGear(user);
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('change class', {
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
class: klass,
|
||||
currency: balanceRemoved === 0 ? 'Free' : 'Gems',
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// if invalid class is specified, throw an error.
|
||||
throw new BadRequest(i18n.t('invalidClass', req.language));
|
||||
|
||||
@@ -2,9 +2,7 @@ import forEach from 'lodash/forEach';
|
||||
import findIndex from 'lodash/findIndex';
|
||||
import get from 'lodash/get';
|
||||
import keys from 'lodash/keys';
|
||||
import pick from 'lodash/pick';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
import moment from 'moment';
|
||||
import i18n from '../i18n';
|
||||
import content from '../content/index';
|
||||
import {
|
||||
@@ -36,7 +34,7 @@ function evolve (user, pet, req) {
|
||||
}, req.language);
|
||||
}
|
||||
|
||||
export default function feed (user, req = {}, analytics) {
|
||||
export default function feed (user, req = {}) {
|
||||
let pet = get(req, 'params.pet');
|
||||
const foodK = get(req, 'params.food');
|
||||
let amount = Number(get(req.query, 'amount', 1));
|
||||
@@ -116,7 +114,7 @@ export default function feed (user, req = {}, analytics) {
|
||||
|
||||
if (!user.achievements.fedPet && user.addAchievement) {
|
||||
user.addAchievement('fedPet');
|
||||
checkOnboardingStatus(user, req, analytics);
|
||||
checkOnboardingStatus(user, req);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,17 +139,6 @@ export default function feed (user, req = {}, analytics) {
|
||||
}
|
||||
});
|
||||
|
||||
if (analytics && moment().diff(user.auth.timestamps.created, 'days') < 7) {
|
||||
analytics.track('pet feed', {
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
foodKey: food.key,
|
||||
petKey: pet.key,
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
user.items.pets[pet.key],
|
||||
message,
|
||||
|
||||
@@ -2,9 +2,7 @@ import findIndex from 'lodash/findIndex';
|
||||
import forEach from 'lodash/forEach';
|
||||
import get from 'lodash/get';
|
||||
import keys from 'lodash/keys';
|
||||
import pick from 'lodash/pick';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
import moment from 'moment';
|
||||
import i18n from '../i18n';
|
||||
import content from '../content/index';
|
||||
import {
|
||||
@@ -15,7 +13,7 @@ import {
|
||||
import { errorMessage } from '../libs/errorMessage';
|
||||
import { checkOnboardingStatus } from '../libs/onboarding';
|
||||
|
||||
export default function hatch (user, req = {}, analytics) {
|
||||
export default function hatch (user, req = {}) {
|
||||
const egg = get(req, 'params.egg');
|
||||
const hatchingPotion = get(req, 'params.hatchingPotion');
|
||||
|
||||
@@ -57,7 +55,7 @@ export default function hatch (user, req = {}, analytics) {
|
||||
|
||||
if (!user.achievements.hatchedPet && user.addAchievement) {
|
||||
user.addAchievement('hatchedPet');
|
||||
checkOnboardingStatus(user, req, analytics);
|
||||
checkOnboardingStatus(user, req);
|
||||
}
|
||||
|
||||
if (content.dropEggs[egg]) {
|
||||
@@ -152,16 +150,6 @@ export default function hatch (user, req = {}, analytics) {
|
||||
});
|
||||
}
|
||||
|
||||
if (analytics && moment().diff(user.auth.timestamps.created, 'days') < 7) {
|
||||
analytics.track('pet hatch', {
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
petKey: pet,
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
user.items,
|
||||
i18n.t('messageHatched', req.language),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import each from 'lodash/each';
|
||||
import pick from 'lodash/pick';
|
||||
import i18n from '../i18n';
|
||||
import { capByLevel } from '../statHelpers';
|
||||
import {
|
||||
@@ -13,31 +12,15 @@ import updateUserBalance from './updateUserBalance';
|
||||
|
||||
const USERSTATSLIST = ['per', 'int', 'con', 'str', 'points', 'gp', 'exp', 'mp'];
|
||||
|
||||
export default async function rebirth (user, tasks = [], req = {}, analytics) {
|
||||
export default async function rebirth (user, tasks = [], req = {}) {
|
||||
const notFree = !isFreeRebirth(user);
|
||||
|
||||
if (user.balance < 1.5 && notFree) {
|
||||
throw new NotAuthorized(i18n.t('notEnoughGems', req.language));
|
||||
}
|
||||
|
||||
const analyticsData = {
|
||||
uuid: user._id,
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
category: 'behavior',
|
||||
};
|
||||
|
||||
if (notFree) {
|
||||
await updateUserBalance(user, -1.5, 'rebirth');
|
||||
analyticsData.currency = 'Gems';
|
||||
analyticsData.gemCost = 6;
|
||||
} else {
|
||||
analyticsData.currency = 'Free';
|
||||
analyticsData.gemCost = 0;
|
||||
}
|
||||
|
||||
if (analytics) {
|
||||
analyticsData.headers = req.headers;
|
||||
analytics.track('Rebirth', analyticsData);
|
||||
}
|
||||
|
||||
const lvl = capByLevel(user.stats.lvl);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import pick from 'lodash/pick';
|
||||
import content from '../content/index';
|
||||
import { mountMasterProgress } from '../count';
|
||||
import i18n from '../i18n';
|
||||
@@ -7,7 +6,7 @@ import {
|
||||
} from '../libs/errors';
|
||||
import updateUserBalance from './updateUserBalance';
|
||||
|
||||
export default async function releaseMounts (user, req = {}, analytics) {
|
||||
export default async function releaseMounts (user, req = {}) {
|
||||
if (user.balance < 1) {
|
||||
throw new NotAuthorized(i18n.t('notEnoughGems', req.language));
|
||||
}
|
||||
@@ -42,17 +41,6 @@ export default async function releaseMounts (user, req = {}, analytics) {
|
||||
user.achievements.mountMasterCount += 1;
|
||||
}
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('release mounts', {
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
currency: 'Gems',
|
||||
gemCost: 4,
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
user.items.mounts,
|
||||
i18n.t('mountsReleased'),
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import pick from 'lodash/pick';
|
||||
import content from '../content/index';
|
||||
import { beastMasterProgress } from '../count';
|
||||
import i18n from '../i18n';
|
||||
@@ -7,7 +6,7 @@ import {
|
||||
} from '../libs/errors';
|
||||
import updateUserBalance from './updateUserBalance';
|
||||
|
||||
export default function releasePets (user, req = {}, analytics) {
|
||||
export default function releasePets (user, req = {}) {
|
||||
if (user.balance < 1) {
|
||||
throw new NotAuthorized(i18n.t('notEnoughGems', req.language));
|
||||
}
|
||||
@@ -42,17 +41,6 @@ export default function releasePets (user, req = {}, analytics) {
|
||||
user.achievements.beastMasterCount += 1;
|
||||
}
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('release pets', {
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
currency: 'Gems',
|
||||
gemCost: 4,
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
user.items.pets,
|
||||
i18n.t('petsReleased'),
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import each from 'lodash/each';
|
||||
import pick from 'lodash/pick';
|
||||
import i18n from '../i18n';
|
||||
import {
|
||||
NotAuthorized,
|
||||
} from '../libs/errors';
|
||||
import updateUserBalance from './updateUserBalance';
|
||||
|
||||
export default async function reroll (user, tasks = [], req = {}, analytics) {
|
||||
export default async function reroll (user, tasks = [], req = {}) {
|
||||
if (user.balance < 1) {
|
||||
throw new NotAuthorized(i18n.t('notEnoughGems', req.language));
|
||||
}
|
||||
@@ -22,17 +21,6 @@ export default async function reroll (user, tasks = [], req = {}, analytics) {
|
||||
}
|
||||
});
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('Fortify Potion', {
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
currency: 'Gems',
|
||||
gemCost: 4,
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
{ user, tasks },
|
||||
i18n.t('fortifyComplete'),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import merge from 'lodash/merge';
|
||||
import pick from 'lodash/pick';
|
||||
import reduce from 'lodash/reduce';
|
||||
import each from 'lodash/each';
|
||||
import i18n from '../i18n';
|
||||
@@ -13,7 +12,7 @@ import predictableRandom from '../fns/predictableRandom';
|
||||
import { removePinnedGearByClass, addPinnedGearByClass, addPinnedGear } from './pinnedGearUtils';
|
||||
import getItemInfo from '../libs/getItemInfo';
|
||||
|
||||
export default function revive (user, req = {}, analytics) {
|
||||
export default function revive (user, req = {}) {
|
||||
if (user.stats.hp > 0) {
|
||||
throw new NotAuthorized(i18n.t('cannotRevive', req.language));
|
||||
}
|
||||
@@ -110,16 +109,6 @@ export default function revive (user, req = {}, analytics) {
|
||||
message = i18n.t('messageLostItem', { itemText: item.text(req.language) }, req.language);
|
||||
}
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('Death', {
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
lostItem,
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
user.items,
|
||||
message,
|
||||
|
||||
@@ -225,7 +225,7 @@ function _updateLastHistoryEntry (lastHistoryEntry, task, direction, times) {
|
||||
}
|
||||
}
|
||||
|
||||
export default function scoreTask (options = {}, req = {}, analytics) {
|
||||
export default function scoreTask (options = {}, req = {}) {
|
||||
const {
|
||||
user, task, direction, times = 1, cron = false,
|
||||
} = options;
|
||||
@@ -425,7 +425,7 @@ export default function scoreTask (options = {}, req = {}, analytics) {
|
||||
|
||||
if (!user.achievements.completedTask && cron === false && direction === 'up' && user.addAchievement) {
|
||||
user.addAchievement('completedTask');
|
||||
checkOnboardingStatus(user, req, analytics);
|
||||
checkOnboardingStatus(user, req);
|
||||
}
|
||||
|
||||
return delta;
|
||||
|
||||
@@ -1,17 +1,4 @@
|
||||
import pick from 'lodash/pick';
|
||||
|
||||
export function sleep (user, req = {}, analytics) {
|
||||
export function sleep (user) {
|
||||
user.preferences.sleep = !user.preferences.sleep;
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('sleep', {
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
status: user.preferences.sleep,
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
|
||||
return [user.preferences.sleep];
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import get from 'lodash/get';
|
||||
import pick from 'lodash/pick';
|
||||
import setWith from 'lodash/setWith';
|
||||
import i18n from '../i18n';
|
||||
import { NotAuthorized, BadRequest } from '../libs/errors';
|
||||
@@ -208,7 +207,7 @@ function buildResponse ({ purchased, preference, items }, ownsAlready, language)
|
||||
// If item is already purchased -> equip it
|
||||
// Otherwise unlock it
|
||||
// @TODO refactor and take as parameter the set name, for single items use the buy ops
|
||||
export default async function unlock (user, req = {}, analytics) {
|
||||
export default async function unlock (user, req = {}) {
|
||||
const path = get(req.query, 'path');
|
||||
|
||||
if (!path) {
|
||||
@@ -319,19 +318,6 @@ export default async function unlock (user, req = {}, analytics) {
|
||||
|
||||
if (!unlockedAlready) {
|
||||
await updateUserBalance(user, -cost, 'spend', path);
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('buy', {
|
||||
user: pick(user, ['preferences', 'registeredThrough']),
|
||||
uuid: user._id,
|
||||
itemKey: path,
|
||||
itemType: 'customization',
|
||||
currency: 'Gems',
|
||||
gemCost: cost / 0.25,
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return buildResponse(user, unlockedAlready, req.language);
|
||||
|
||||
Reference in New Issue
Block a user