Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for custom dimensions and metrics #278

Open
3 of 14 tasks
leandroz opened this issue Aug 22, 2018 · 13 comments · May be fixed by #287
Open
3 of 14 tasks

Add support for custom dimensions and metrics #278

leandroz opened this issue Aug 22, 2018 · 13 comments · May be fixed by #287

Comments

@leandroz
Copy link

This is a...

  • 🪲 Bug Report
  • 🚀 Feature Request
  • 📜 Documentation Request

Which target(s) are you using?

  • Google Analytics
  • Google Analytics (gtag)
  • React Native Google Analytics
  • Google Tag Manager
  • React Native Google Tag Manager
  • Amplitude
  • Segment
  • Other/Third Party: ...(please specify here)

🚀 📜 What's missing from Redux Beacon that you'd like to add?

Custom dimensions and metrics are a powerful way to send custom data to Google Analytics. Web developers can use custom dimensions and metrics to segment and measure differences between logged in and logged out users, authors of pages, levels in games, or any other business data you have on a page.
https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets

So basic idea is to add support for this, the problem I see is that we don't know in advance the field key, as it would be anything between dimension1 and dimension20, and the same for metrics. (The number of custom dimensions and metrics varies between plans I believe)

One option would be to pass a dimensions object with numbers as keys, and then build the parameters from there. I will be happy to send a PR once agreed on the design.

Examples:

ga('send', 'pageview', {
  'dimension15':  'My Custom Dimension'
});

ga('send', 'event', 'category', 'action', {
  'metric18': 8000
});

Can you help out?

  • 🌟 I am a legend and can get started on a pull request right away given the go-ahead.
  • ⭐ I am a superstar and would like to help out given some guidance.
  • 😞 I won't be able to help out on this one.
@julienma
Copy link

julienma commented Aug 22, 2018

Hijacking the thread — I'm interested in passing some custom dimensions / metrics, but also passing other google analytics parameters (what they call "fields").

E.g. to force a session to start, you can pass an additional parameters object:

// Starts a new session.
ga('send', 'pageview', {'sessionControl': 'start'});

I can't find any reference to this in the Google Analytics target docs, so I assume that neither custom dimensions/metrics nor session control is implemented, right?

@ttmarek
Copy link
Contributor

ttmarek commented Aug 23, 2018

I can't find any reference to this in the Google Analytics target docs, so I assume that neither custom dimensions/metrics nor session control is implemented, right?

Right!

@julienma @leandroz let's fix that!

So, as a place to start, we do support custom dimensions on the React Native Google Analytics target. Here's the API we went with: https://rangle.gitbook.io/redux-beacon/index/react-native-google-analytics#screenview. We don't need to go with the same API for this target.

We're using ga('set', 'page', page); as described here to set the page view. I'm not sure if calling ga('send', 'pageview', [customDimensions | fields]); right after would trigger a second page hit in GA.

But, first, before we get into the implementation, let's land on a new API for trackPageView. Now we have:

import { trackPageView } from '@redux-beacon/google-analytics';const pageView = trackPageView((action, prevState, nextState) => {
 return {
   page: /* fill me in */,
   title: /* (optional) */,
   location: /* (optional) */,
 };
}, /* (optional) tracker name */ );

In an ideal world how would you like this to look, assuming support for custom dimensions and fields?

@julienma
Copy link

julienma commented Aug 24, 2018

Ha, excellent @ttmarek! I was just looking at the React Native target, as I saw it supports custom dimensions :)

I'd mostly use this with events, so am using a trackEvent example:

import { trackEvent } from '@redux-beacon/google-analytics';const myEvent = trackEvent((action, prevState, nextState) => {
 return {
   category: /* fill me in */,
   action: /* fill me in */,
   label: /* (optional) */,
   value: /* (optional) */,
   customFields: { /* (optional) */
     [/* dimension index */]: /* dimension value */,
   },
 };
}, /* (optional) tracker name */ );

Note that I'm proposing to use a customFields object instead of customDimensions, so it can be used for any GA fields. I think this would work, as ga.send() accepts a fieldsObject parameter which can contain any documented field.

This make it more flexible, and answers both use case from this issue (custom dimensions / metrics + session control):

   // ...
   customFields: {
     'dimension5': 'custom dimension data', // custom dimension
     'metric12': 'custom metric data', // custom metric
     'sessionControl': 'start', // force start a session
     'anonymizeIp': true,
     // etc.
   },

Actually, customFields should probably be named fieldsObject, so it's coherent with GA's wording.


A couple of other things I'd like (I should probably create another issue?):

1. A way to set a clientIdon the GA tracker.

This has to be done when creating the GA tracker, not when sending a hit, so it should probably be set up with the target.

However, to make it generic, I'd use a trackerOptions object instead of just a clientId parameter, this way any other "Create Only Fields" can be set:

import { GoogleAnalyticsTracker } from 'react-native-google-analytics-bridge';
import GoogleAnalytics from '@redux-beacon/react-native-google-analytics';const trackingId = 'UA-12345678-1';
const trackerOptions = {
  clientId: '123-ABC-XYZ-789',
};
const ga = GoogleAnalytics(trackingId, trackerOptions, GoogleAnalyticsTracker);const gaMiddleware = createMiddleware(eventsMap, ga);

(And same comment: trackerOptions should probably be named fieldsObject)

2. A global opt-out setting.

This would disable all tracking when enabled, without having to write a bunch of conditionals all over the place.

Could be something like this?

import { optOutFromTracking } from '@redux-beacon/google-analytics';// somewhere in an action
export function disableTracking(bool) {
  optOutFromTracking(bool);

  return {
    type: types.DISABLE_TRACKING,
    bool,
  };
}

Idea taken from https://github.com/75lb/usage-stats#usagestatsdisable-%EF%B8%8E.

@leandroz
Copy link
Author

An additional fieldsObject makes sense for me, it's good to use the same terminology to avoid confusion.

@ttmarek
Copy link
Contributor

ttmarek commented Aug 27, 2018

I love all of this.

  1. I'm on board with adding a fieldsObject special property. It makes sense to follow GA's naming here to avoid confusion.

  2. About setting clientId on the tracker, how do you feel about going with something like this:

import GoogleAnalytics from '@redux-beacon/google-analytics';

// Create or import an events map.
// See "getting started" pages for instructions.

const gaOptions = {
  clientId?: string,
};

const ga = GoogleAnalytics(gaOptions);

const gaMiddleware = createMiddleware(eventsMap, ga);
const gaMetaReducer = createMetaReducer(eventsMap, ga);
  1. The global opt-out setting is a little different. I have to think about this.

@julienma
Copy link

@ttmarek

  1. 👍

  2. 👍

  3. It's clearly a different topic anyway.

@xpander001
Copy link

This is great. I came just to write exactly the same feature request!

@julienma
Copy link

julienma commented Sep 1, 2018

@ttmarek I can't promise anything, but if I could set some time aside to help with this, where do you suggest I start? Copy/pasting the things related to custom dimensions from the React Native target?

@ttmarek ttmarek linked a pull request Sep 20, 2018 that will close this issue
2 tasks
@ttmarek
Copy link
Contributor

ttmarek commented Sep 20, 2018

@leandroz @julienma @xpander001 Sorry for the delay on this, I've had some projects at home that have been keeping me busy on my evenings/weekends.

I have a pull request that add's support for custom dimensions via the fieldsObject here: #287

I was hoping one or more of you could help me out by trying out the new changes and seeing if it works and meets your needs.

You can install the changes under the next dist tag:

npm install @redux-beacon/google-analytics@next

@julienma
Copy link

Thanks @ttmarek.
I switched to the Amplitude target since then (not because of this PR, just because I can't get the heck out of GA). I'll still try to have a look next week.

@kevinsperrine
Copy link

@ttmarek What are your preferences on submitting contributions here? I need to use the session start stop feature described here (https://github.com/idehub/react-native-google-analytics-bridge#hitpayload) on the react-native-google-analytics-bridge and am happy to add it in a PR, but don't know how you to want to handle the parameter differences that'll need to happen in the event-helpers and google-analytics files.

@ttmarek
Copy link
Contributor

ttmarek commented Oct 30, 2018

Hey @kevinsperrine.

What are your preferences on submitting contributions here

No real preferences. Just come up with your dream API for the new additions and we can chat about them. Ideally the API would more or less align with the existing patterns we have so we don't have to disrupt too many users.

@OKNoah
Copy link

OKNoah commented Oct 31, 2018

Sorry if I'm out of the loop, but this merged PR which is linked to in the docs seems to say you can can add custom variables by setting a particular hit type, and adding by adds the customDimensionDict key:

const pageView = action => ({
    hitType: 'pageviewCustomDimensions',
    page: action.payload,
    customDimensionDict: {
      '1': 'premium',
      '5': 'foo'
    }
  })

However, I have tried this and it does not seem to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants