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

[W.I.P.] Ubi integration #7144

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
18 changes: 1 addition & 17 deletions _layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -255,28 +255,12 @@ <h2>Related articles</h2>
</script>
{% endif %}
<script src="{{ '/assets/js/timeme.min.js' | relative_url }}"></script>
<script type="text/javascript">
// Initialize library and start tracking time
TimeMe.initialize({
currentPageName: window.location.pathname,
idleTimeoutInSeconds: 5 // seconds
});
</script>
<script type="module" src="{{ '/assets/js/ubi.js' | relative_url }}"></script>
<script type="text/javascript">
// Initialize library and start tracking time
TimeMe.initialize({
currentPageName: window.location.pathname,
idleTimeoutInSeconds: 5 // seconds
});
TimeMe.startTimer(window.location.pathname);
</script>

{% if site.search_enabled == false and site.use_custom_search == true %}
<script type="module" defer src="{{ '/assets/js/search.js' | relative_url }}"></script>
{% endif %}
<script src="{{ '/assets/js/copy-button.js' | relative_url }}"></script>
<script src="{{ '/assets/js/nav-scroll.js' | relative_url }}"></script>
<script src="{{ '/assets/js/listener.js' | relative_url }}"></script>
<script type="module" src="{{ '/assets/js/listener.js' | relative_url }}"></script>
</body>
</html>
20 changes: 19 additions & 1 deletion assets/js/listener.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as UBI from "./ubi.js";

const yesButton = document.getElementById('yes');
const noButton = document.getElementById('no');
const numCharsLabel = document.getElementById('num-chars');
Expand Down Expand Up @@ -48,7 +50,7 @@ function updateTextArea() {
}

// calculate the number of characters remaining
counter = 350 - commentTextArea.value.length;
const counter = 350 - commentTextArea.value.length;
numCharsLabel.innerText = counter + " characters left";
}

Expand All @@ -68,6 +70,22 @@ function sendFeedback() {

if (helpful === 'none' && comment === 'none') return;

try{
let e = new UBI.UbiEvent('user_feedback', {
message: `Relevance: ${helpful}, Comment: ${comment}`,
event_attributes:{
url:location.pathname,
helpful:helpful,
comment:comment
}
});
e.message_type = 'USER';
UBI.logEvent(e);

} catch(e){
console.warn(`UBI Error: ${e}`)
}

// split the comment into 100-char parts because of GA limitation on custom dimensions
const commentLines = ["", "", "", ""];
for (let i = 0; i <= (comment.length - 1)/100; i++) {
Expand Down
144 changes: 92 additions & 52 deletions assets/js/ubi.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

function guiid() {
RasonJ marked this conversation as resolved.
Show resolved Hide resolved
let id = '123456-insecure';
try {
Expand Down Expand Up @@ -28,11 +29,10 @@ export function hash(str, seed=42) {


/**
* In place of true authentication, this makes a hash out of the user's IP address and browser
* for tracking individual user behavior
* user_id = hash( user ip ) + '::' + hash( userAgent )
* In place of true authentication, this makes a hash out of the user's cookie,
* which at the moment is _ga...
*
* NOTE: if this function is called, but user_id starts with 'USER-',
* NOTE: if this function is called, but user_id starts with 'U-',
* the function below did not complete successfully,
* and userError() was called instead
* @returns
Expand All @@ -41,68 +41,47 @@ export async function initialize(){
let i = 1;

try {


if(!sessionStorage.hasOwnProperty('session_id')) {
sessionStorage.setItem('session_id', guiid());
sessionStorage.setItem('session_id', 'S-' + guiid());
}

if(sessionStorage.hasOwnProperty('user_id')){
console.log('Already initialized UBI');
return;
}

var rq = new XMLHttpRequest;

rq.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
if(this.response != null) {

//make a new user id: user ip + '::' + hash( userAgent )
let client_id = '';
if( window.navigator != null && window.navigator.userAgent != null){
client_id = window.navigator.userAgent;
} else {
client_id = guiid();
}
let user_id = hash( this.response.ip ) + '::' + hash( client_id );
sessionStorage.setItem('user_id', user_id);
console.log('user_id: ' + user_id);

}
}
};

rq.onerror = function(){
// currently, the only cookie is gtag's client_id et al.
if(document.cookie && document.cookie.length > 0){
setUserId(hash(document.cookie));
return;
} else {
//back up user_id method
userError();
if(this.error != null && this.error != ''){
console.error('ERROR Retrieving user info: ' + this.error);
}
else
console.error('UNSPECIFIED ERROR Retrieving user info');
}

rq.open("GET", "https://api64.ipify.org?format=json", true);
rq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
rq.responseType = "json";
rq.send();

} catch(error){
console.log(error)
}
}

/**
* back up method to make a user individual
* Back up method to make a user individual
* Note that this is basically the same as a session id since it would
* generate each time a user lands on the site
* @returns
*/
function userError(){
let user_id = 'USER-' + guiid();
sessionStorage.setItem('user_id', user_id);
let user_id = guiid();
setUserId(user_id);
return user_id;
}


export function genQueryId(){
const qid = 'QUERY-' + guiid();
const qid = 'Q-' + guiid();
sessionStorage.setItem('query_id', qid);
return qid;
}
Expand All @@ -113,7 +92,7 @@ export function getQueryId(){
/**
* Save explicitly, if conditions are right
*/
export function saveQueryId(query_id){
export function setQueryId(query_id){
sessionStorage.setItem('query_id', query_id);
}

Expand All @@ -124,7 +103,7 @@ export function clearCache() {

export function cacheQueryResults(results){
let qid = genQueryId();
saveQueryId(qid);
setQueryId(qid);

if(results.length > 0){
let search_results = {};
Expand All @@ -142,6 +121,10 @@ export function cacheQueryResults(results){
return [qid, []];
}

export function setUserId(user_id){
sessionStorage.setItem('user_id', 'U-' + user_id);
}

export function getUserId(){
if(sessionStorage.hasOwnProperty('user_id')){
return sessionStorage.getItem('user_id');
Expand All @@ -164,23 +147,48 @@ export function getPageId(){
return location.pathname;
}

function getTrail(){
let trail = sessionStorage.getItem('trail');
if(trail == null)
return '';
return trail;
}

function setTrail(){
let trail = getTrail();
if(trail && trail.length > 0){
if(!trail.startsWith(window.location.pathname)){
trail += ` › ${window.location.pathname}`;
}
} else {
trail = window.location.pathname;
}
sessionStorage.setItem('trail', trail);

return trail;
}

RasonJ marked this conversation as resolved.
Show resolved Hide resolved
window.addEventListener("DOMContentLoaded", function (e) {
try{
initialize();
TimeMe.currentPageName = this.window.location.href;
TimeMe.initialize({
currentPageName: window.location.href,
idleTimeoutInSeconds: 5
});
setTrail();
TimeMe.startTimer(window.location.pathname);
} catch(e){

} catch(error){
console.warn(error);
}
});

window.addEventListener("beforeunload", function (e) {
try{
TimeMe.stopTimer(window.location.pathname);
logDwellTime('page_exit', window.location.pathname,
TimeMe.getTimeOnPageInSeconds(window.location.pathname));
} catch(e){

TimeMe.getTimeOnPageInSeconds(window.location.pathname));
} catch(error){
console.warn(error);
}
});

Expand Down Expand Up @@ -235,7 +243,11 @@ export class UbiPosition{
this.ordinal = ordinal;
this.x = x;
this.y = y;
this.trail = trail;
if(trail)
this.trail = trail;
else {
console.log(document.referrer);
}
}
}

Expand All @@ -252,10 +264,37 @@ export class UbiEventAttributes {
if(attributes != null){
Object.assign(this, attributes);
}
if(object != null && object != {}){
if(object != null && Object.keys(object).length > 0){
this.object = object;
}
this.position = position;
if(position != null && Object.keys(position).length > 0){
this.position = position;
}
this.setDefaultValues();
}

setDefaultValues(){
try{
if(!this.hasOwnProperty('dwell_seconds') && typeof TimeMe !== 'undefined'){
this.dwell_seconds = TimeMe.getTimeOnPageInSeconds(window.location.pathname);
}

if(!this.hasOwnProperty('browser')){
this.browser = window.navigator.userAgent;
}

if(!this.hasOwnProperty('position') || this.position == null){
const trail = getTrail();
if(trail.length > 0){
this.position = new UbiPosition({trail:trail});
}
}

// TODO: set IP
}
catch(error){

}
}
}

Expand Down Expand Up @@ -284,7 +323,8 @@ export class UbiEvent {
* @returns
*/
static replacer(key, value){
if(value == null) {
if(value == null ||
(value.constructor == Object && Object.keys(value).length === 0)) {
return undefined;
}
return value;
Expand Down
Loading