canvas-lms/lib/google_analytics_dimensions.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

89 lines
3.2 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
track user roles & masquerades in Google Analytics fixes KNO-355 flag = none this is an attempt at making it possible to segment the stats available on GA by metrics relevant to product... the goal is to be able to tell which flows are popular among students versus those among teachers, for example we now supply every pageview hit with 3 types of additional information: 1. enrollments (student? teacher? observer?) 2. admin status (admin? site admin?) 3. masquerading? this information is tracked in "custom dimensions"[1] and the submission is still anonymous; we're not tracking userId . . . . . \ TEST PLAN / ---- ---- - create yourself a google analytics account, because if not now, when? this is your chance - inside GA, create "Custom Dimensions" for each of the dimensions[2] implemented in this patch: 1. Enrollments 2. Admin 3. Masquerading - use a Rails console to set your tracker id: Setting.set('google_analytics_key', TRACKER_ID) - now browse around Canvas and keep an eye on the GA dashboard; you should see points tracked after some time (could take up to an hour really...) with the dimensions populated [1]: https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs [2]: from User#user_roles - https://gerrit.instructure.com/plugins/gitiles/canvas-lms/+/refs/heads/master/app/models/user.rb#2877 Change-Id: I1d797e6c500d3d60da36da3b50339bab649e57de Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/230360 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Rob Orton <rob@instructure.com> QA-Review: Rob Orton <rob@instructure.com> Product-Review: Rob Orton <rob@instructure.com>
2020-03-18 14:54:00 +08:00
#
# Copyright (C) 2020 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
module GoogleAnalyticsDimensions
# Prepare some contextual data to supplement a pageview hit when submitting to
# GA to provide the analyst with more context surrounding the request:
#
# {
# "enrollments": BoolMask.<student, teacher, observer>,
# "admin": BoolMask.<admin, site_admin>,
# "masquerading": Bool
# }
#
# Bool is a "0" or "1" value (encoded as strings) while "BoolMask" is a stream
# of bools encoded also as a string. For example:
#
# {
# "enrollments": "010", # a teacher
# "admin": "11", # an admin and a site admin
# "masquerading": "0" # nope
# }
#
# Encoding flags in such a way gives us the flexibility to represent future
# values while also giving the analyst more freedom in reporting (GA supports
# regex filtering.)
def self.calculate(domain_root_account:, user:, real_user:)
user_roles = user ? user.roles(domain_root_account) : []
{
admin: _encode_admin_status(roles: user_roles),
enrollments: _encode_enrollments(roles: user_roles),
masquerading: _encode_masquerading_status(user: user, real_user: real_user),
tell GA what kind of account it is fixes KNO-392 flag = none the org type that was introduced in g/236404 and g/236535 is now submitted to GA pageviews as a new dimension (4). These are the current org types and their account counts, which you can get from Salesforce: - Corporate (1206) - Further Education (359) - Government (29) - Higher Ed (2468) - K12 (3807) - Other (15) - RTO/Training (86) - RTO (1) - Internal Use Only (1) - Regional Training Provider (1) - Training Org (1) | | TEST PLAN | - make sure you have GA enabled if you don't already: Setting.set('google_analytics_key', 'foo') - visit any page, then look for the GA snippet[1] and verify that "dimension4" is set to null - now mark your account as "K12": Account.default.external_integration_keys.create!( key_type: 'salesforce_org_type', key_value: 'K12' ) - reload the page and verify that "dimension4" is set to "K12" in the GA snippet - unmark the account and verify the dimension is back to null: Account.default.external_integration_keys.where( key_type: 'salesforce_org_type' ).destroy_all [1]: do "view source" in browser then jump to the term "window.ga", or you can use this query in the console and inspect the element: Array.prototype.find.call( document.head.querySelectorAll('script'), x => x.innerHTML.match(/window.ga/) ) Change-Id: I505bf1ee2a8347a21d691e2fa4ef04cb07c9a48e Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/238656 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Davis Hyer <dhyer@instructure.com> QA-Review: Davis Hyer <dhyer@instructure.com> Product-Review: Davis Hyer <dhyer@instructure.com>
2020-05-29 01:43:19 +08:00
org_type: _encode_org_type(account: domain_root_account),
user_id: _compute_non_compromising_user_id(user: user),
track user roles & masquerades in Google Analytics fixes KNO-355 flag = none this is an attempt at making it possible to segment the stats available on GA by metrics relevant to product... the goal is to be able to tell which flows are popular among students versus those among teachers, for example we now supply every pageview hit with 3 types of additional information: 1. enrollments (student? teacher? observer?) 2. admin status (admin? site admin?) 3. masquerading? this information is tracked in "custom dimensions"[1] and the submission is still anonymous; we're not tracking userId . . . . . \ TEST PLAN / ---- ---- - create yourself a google analytics account, because if not now, when? this is your chance - inside GA, create "Custom Dimensions" for each of the dimensions[2] implemented in this patch: 1. Enrollments 2. Admin 3. Masquerading - use a Rails console to set your tracker id: Setting.set('google_analytics_key', TRACKER_ID) - now browse around Canvas and keep an eye on the GA dashboard; you should see points tracked after some time (could take up to an hour really...) with the dimensions populated [1]: https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs [2]: from User#user_roles - https://gerrit.instructure.com/plugins/gitiles/canvas-lms/+/refs/heads/master/app/models/user.rb#2877 Change-Id: I1d797e6c500d3d60da36da3b50339bab649e57de Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/230360 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Rob Orton <rob@instructure.com> QA-Review: Rob Orton <rob@instructure.com> Product-Review: Rob Orton <rob@instructure.com>
2020-03-18 14:54:00 +08:00
}
end
# we only need some identifier that GA can utilize to track users across
# different devices but we don't want it to know who the users are (e.g. their
# canvas id)
#
# see https://support.google.com/analytics/answer/2992042?hl=en
# see https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id
def self._compute_non_compromising_user_id(user:)
user ? Canvas::Security.hmac_sha512(user.id.to_s)[0, 32] : nil
end
track user roles & masquerades in Google Analytics fixes KNO-355 flag = none this is an attempt at making it possible to segment the stats available on GA by metrics relevant to product... the goal is to be able to tell which flows are popular among students versus those among teachers, for example we now supply every pageview hit with 3 types of additional information: 1. enrollments (student? teacher? observer?) 2. admin status (admin? site admin?) 3. masquerading? this information is tracked in "custom dimensions"[1] and the submission is still anonymous; we're not tracking userId . . . . . \ TEST PLAN / ---- ---- - create yourself a google analytics account, because if not now, when? this is your chance - inside GA, create "Custom Dimensions" for each of the dimensions[2] implemented in this patch: 1. Enrollments 2. Admin 3. Masquerading - use a Rails console to set your tracker id: Setting.set('google_analytics_key', TRACKER_ID) - now browse around Canvas and keep an eye on the GA dashboard; you should see points tracked after some time (could take up to an hour really...) with the dimensions populated [1]: https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs [2]: from User#user_roles - https://gerrit.instructure.com/plugins/gitiles/canvas-lms/+/refs/heads/master/app/models/user.rb#2877 Change-Id: I1d797e6c500d3d60da36da3b50339bab649e57de Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/230360 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Rob Orton <rob@instructure.com> QA-Review: Rob Orton <rob@instructure.com> Product-Review: Rob Orton <rob@instructure.com>
2020-03-18 14:54:00 +08:00
def self._encode_admin_status(roles:)
# again, look at User#user_roles for the definition
%w[admin root_admin].map do |enrollment_type|
roles.include?(enrollment_type) ? "1" : "0"
end.join
track user roles & masquerades in Google Analytics fixes KNO-355 flag = none this is an attempt at making it possible to segment the stats available on GA by metrics relevant to product... the goal is to be able to tell which flows are popular among students versus those among teachers, for example we now supply every pageview hit with 3 types of additional information: 1. enrollments (student? teacher? observer?) 2. admin status (admin? site admin?) 3. masquerading? this information is tracked in "custom dimensions"[1] and the submission is still anonymous; we're not tracking userId . . . . . \ TEST PLAN / ---- ---- - create yourself a google analytics account, because if not now, when? this is your chance - inside GA, create "Custom Dimensions" for each of the dimensions[2] implemented in this patch: 1. Enrollments 2. Admin 3. Masquerading - use a Rails console to set your tracker id: Setting.set('google_analytics_key', TRACKER_ID) - now browse around Canvas and keep an eye on the GA dashboard; you should see points tracked after some time (could take up to an hour really...) with the dimensions populated [1]: https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs [2]: from User#user_roles - https://gerrit.instructure.com/plugins/gitiles/canvas-lms/+/refs/heads/master/app/models/user.rb#2877 Change-Id: I1d797e6c500d3d60da36da3b50339bab649e57de Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/230360 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Rob Orton <rob@instructure.com> QA-Review: Rob Orton <rob@instructure.com> Product-Review: Rob Orton <rob@instructure.com>
2020-03-18 14:54:00 +08:00
end
def self._encode_enrollments(roles:)
# keep in mind that some of these roles may be rolled up from different
# enrollment types, see User#user_roles for the meat
%w[student teacher observer].map do |enrollment_type|
roles.include?(enrollment_type) ? "1" : "0"
end.join
track user roles & masquerades in Google Analytics fixes KNO-355 flag = none this is an attempt at making it possible to segment the stats available on GA by metrics relevant to product... the goal is to be able to tell which flows are popular among students versus those among teachers, for example we now supply every pageview hit with 3 types of additional information: 1. enrollments (student? teacher? observer?) 2. admin status (admin? site admin?) 3. masquerading? this information is tracked in "custom dimensions"[1] and the submission is still anonymous; we're not tracking userId . . . . . \ TEST PLAN / ---- ---- - create yourself a google analytics account, because if not now, when? this is your chance - inside GA, create "Custom Dimensions" for each of the dimensions[2] implemented in this patch: 1. Enrollments 2. Admin 3. Masquerading - use a Rails console to set your tracker id: Setting.set('google_analytics_key', TRACKER_ID) - now browse around Canvas and keep an eye on the GA dashboard; you should see points tracked after some time (could take up to an hour really...) with the dimensions populated [1]: https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs [2]: from User#user_roles - https://gerrit.instructure.com/plugins/gitiles/canvas-lms/+/refs/heads/master/app/models/user.rb#2877 Change-Id: I1d797e6c500d3d60da36da3b50339bab649e57de Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/230360 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Rob Orton <rob@instructure.com> QA-Review: Rob Orton <rob@instructure.com> Product-Review: Rob Orton <rob@instructure.com>
2020-03-18 14:54:00 +08:00
end
tell GA what kind of account it is fixes KNO-392 flag = none the org type that was introduced in g/236404 and g/236535 is now submitted to GA pageviews as a new dimension (4). These are the current org types and their account counts, which you can get from Salesforce: - Corporate (1206) - Further Education (359) - Government (29) - Higher Ed (2468) - K12 (3807) - Other (15) - RTO/Training (86) - RTO (1) - Internal Use Only (1) - Regional Training Provider (1) - Training Org (1) | | TEST PLAN | - make sure you have GA enabled if you don't already: Setting.set('google_analytics_key', 'foo') - visit any page, then look for the GA snippet[1] and verify that "dimension4" is set to null - now mark your account as "K12": Account.default.external_integration_keys.create!( key_type: 'salesforce_org_type', key_value: 'K12' ) - reload the page and verify that "dimension4" is set to "K12" in the GA snippet - unmark the account and verify the dimension is back to null: Account.default.external_integration_keys.where( key_type: 'salesforce_org_type' ).destroy_all [1]: do "view source" in browser then jump to the term "window.ga", or you can use this query in the console and inspect the element: Array.prototype.find.call( document.head.querySelectorAll('script'), x => x.innerHTML.match(/window.ga/) ) Change-Id: I505bf1ee2a8347a21d691e2fa4ef04cb07c9a48e Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/238656 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Davis Hyer <dhyer@instructure.com> QA-Review: Davis Hyer <dhyer@instructure.com> Product-Review: Davis Hyer <dhyer@instructure.com>
2020-05-29 01:43:19 +08:00
def self._encode_org_type(account:)
account&.external_integration_keys&.find_by(
key_type: "salesforce_org_type"
)&.key_value
end
track user roles & masquerades in Google Analytics fixes KNO-355 flag = none this is an attempt at making it possible to segment the stats available on GA by metrics relevant to product... the goal is to be able to tell which flows are popular among students versus those among teachers, for example we now supply every pageview hit with 3 types of additional information: 1. enrollments (student? teacher? observer?) 2. admin status (admin? site admin?) 3. masquerading? this information is tracked in "custom dimensions"[1] and the submission is still anonymous; we're not tracking userId . . . . . \ TEST PLAN / ---- ---- - create yourself a google analytics account, because if not now, when? this is your chance - inside GA, create "Custom Dimensions" for each of the dimensions[2] implemented in this patch: 1. Enrollments 2. Admin 3. Masquerading - use a Rails console to set your tracker id: Setting.set('google_analytics_key', TRACKER_ID) - now browse around Canvas and keep an eye on the GA dashboard; you should see points tracked after some time (could take up to an hour really...) with the dimensions populated [1]: https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs [2]: from User#user_roles - https://gerrit.instructure.com/plugins/gitiles/canvas-lms/+/refs/heads/master/app/models/user.rb#2877 Change-Id: I1d797e6c500d3d60da36da3b50339bab649e57de Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/230360 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Rob Orton <rob@instructure.com> QA-Review: Rob Orton <rob@instructure.com> Product-Review: Rob Orton <rob@instructure.com>
2020-03-18 14:54:00 +08:00
def self._encode_masquerading_status(user:, real_user:)
real_user && real_user != user ? "1" : "0"
end
end