Created
January 25, 2018 07:21
-
-
Save evgeniynet/32bbf38074caa3ea3860febd3e673e9a to your computer and use it in GitHub Desktop.
How to Use Hubspot’s API like a Pro & Generate Hubspot Custom Reports - SherpaDesk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html lang="en" manifest="manifest.appcache"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | |
<link rel="stylesheet" type="text/css" href="style.css"> | |
<script src="SalsaCalendar.min.js"></script> | |
<link rel="stylesheet" href="SalsaCalendar.min.css"> | |
<link rel="shortcut icon" href="https://s4w.cdn.skype.com/0-238-0/images/favicon.ico" id="favicon"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<style> | |
.chart { | |
display: none; | |
table-layout: fixed; | |
width: 90%; | |
max-width: 700px; | |
height: 150px; | |
margin: 0 auto; | |
background-image: linear-gradient(bottom, #6dccf7 2%, transparent 2%); | |
background-size: 100% 50px; | |
background-position: left top; | |
} | |
.chart li { | |
text-align: center; | |
position: relative; | |
display: table-cell; | |
vertical-align: bottom; | |
height: 150px; | |
} | |
.chart span { | |
margin: 0 1em; | |
display: block; | |
background: #6dccf7; | |
animation: draw 1s ease-in-out; | |
} | |
.chart span:before { | |
position: absolute; | |
left: 0; | |
right: 0; | |
top: 100%; | |
padding: 5px 1em 0; | |
display: block; | |
text-align: center; | |
content: attr(title); | |
word-wrap: break-word; | |
} | |
@keyframes draw { | |
0% { | |
height: 0; | |
} | |
} | |
</style> | |
<title>Hubspot Customer update</title> | |
</head> | |
<body> | |
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript --> | |
<header> | |
<div class="container"> | |
<img src="https://support.sherpadesk.com/images/icons/Metro/mountain.png" alt="label-mountain"> | |
<div class="line"></div> | |
<h3>SherpaDesk v1.6</h3> | |
</div> | |
</header> | |
<div id="navigation"> | |
<div class="container"> | |
<h1>Hubspot Customer update</h1> | |
<p> | |
Dates: | |
<input type="text" id="checkin" class="salsa-calendar-input" autocomplete="off" name="arrival" value="" /> to | |
<input type="text" id="checkout" class="salsa-calendar-input" autocomplete="off" name="departure" value="" /> | |
<span id="nights-no"> | |
( | |
<span class="counter"></span> | |
<span class="singular" style="display:none;">day</span> | |
<span class="plural" style="display:none;">days</span> | |
) | |
</span> | |
| |
<a href="javascript:void(0);" onclick="document.getElementById('checkin').value =''">Clear Dates (to use index)</a> | |
</p> | |
<div id="fountainG"> | |
</br> | |
</br> | |
<div id="fountainG_1" class="fountainG"></div> | |
<div id="fountainG_2" class="fountainG"></div> | |
<div id="fountainG_3" class="fountainG"></div> | |
<div id="fountainG_4" class="fountainG"></div> | |
<div id="fountainG_5" class="fountainG"></div> | |
<div id="fountainG_6" class="fountainG"></div> | |
<div id="fountainG_7" class="fountainG"></div> | |
<div id="fountainG_8" class="fountainG"></div> | |
</div> | |
</div> | |
</div> | |
<div class="navBar"> | |
<div class="container search-box"> | |
<div class="lupa"> | |
<svg class="search-icon" viewBox="0 0 24 24"> | |
<path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path> | |
<path d="M0 0h24v24H0z" fill="none"></path> | |
</svg> | |
</div> | |
<input id="myName" name="searchstring" onkeydown="if (event.keyCode == 13 && this.value) search()" value="" placeholder="enter next index or Email" class="Search"> | |
</div> | |
<div class="right"> | |
<input type="checkbox" id="UpdateU"> Update | |
<input id="submit" onclick="this.focus(); search()" value="Proceed" class="Buttons"> | |
<button onclick="stopnow();" class="Buttons">Stop</button> | |
<a href="javascript:void(0);" onclick="removeall();" >Clear</a> | |
<button onclick="javascript:exportToExcel();" class="Buttons">Download XLS</button> | |
</div> | |
</div> | |
<ul class="chart" id=chart> | |
<li><div id=nsubscriber></div> | |
<span id=ssubscriber style="height:0%" title="Subscriber"></span> | |
</li> | |
<li> | |
<div id=nmarketingqualifiedlead></div> | |
<span id=smarketingqualifiedlead style="height:0%" title="Marketing Lead"></span> | |
</li> | |
<li> | |
<div id=nsalesqualifiedlead></div> | |
<span id=ssalesqualifiedlead style="height:0%" title="Sales Lead"></span> | |
</li> | |
<li> | |
<div id=nlead></div> | |
<span id=slead style="height:0%" title="Lead"></span> | |
</li> | |
<li> | |
<div id=nopportunity></div> | |
<span id=sopportunity style="height:0%" title="Oportunity"></span> | |
</li> | |
<li> | |
<div id=ncustomer></div> | |
<span id=scustomer style="height:0%" title="Customer"></span> | |
</li> | |
</ul> | |
<br> | |
<br> | |
<br> | |
<table id="apps"><tbody><tr class="headerTable"><th>Index</th><th>Email</th><th>Added At</th><th>Hubspot Stage</th><th>Registered in App</th><th>Updated</th><th></th></tr></tbody></table> | |
<script> | |
var calendar_from = new SalsaCalendar({ | |
inputId: 'checkin', | |
lang: 'en', | |
range: { | |
max: 'today' | |
}, | |
calendarPosition: 'right', | |
fixed: false, | |
connectCalendar: true, | |
}); | |
var calendar_to = new SalsaCalendar({ | |
inputId: 'checkout', | |
lang: 'en', | |
range: { | |
max: 'today' | |
}, | |
calendarPosition: 'right', | |
fixed: false | |
}); | |
var t1 = new SalsaCalendar.Connector({ | |
from: calendar_from, | |
to: calendar_to, | |
//maximumInterval: 21, | |
minimumInterval: 0 | |
}); | |
var t2 = new SalsaCalendar.NightsCalculator({ | |
from: calendar_from, | |
to: calendar_to, | |
nightsNo: 'nights-no' | |
}); | |
var dt = new Date(new Date()-864E5*7); | |
calendar_from.input.setDate(dt); | |
calendar_from.setCurrentDate(dt); | |
//calendar_to.input.setDate(new Date()); | |
var update, table, chart, loop, id, start, end, timeoffset = 0; | |
var stages = {customer: 0,opportunity:0,lead:0,subscriber:0,marketingqualifiedlead:0,salesqualifiedlead:0}; | |
var stop = false; | |
//your company api | |
var SITE = "https://api.mycompany.com/"; //"http://localhost:81/" | |
var HUBSPOT_SITE = "https://api.hubapi.com/"; | |
function checkall(){} | |
function stopnow(){ | |
stop = true; | |
document.getElementById("fountainG").style.display = "none"; | |
setStat(); | |
stages = {customer: 0,opportunity:0,lead:0,subscriber:0,marketingqualifiedlead:0,salesqualifiedlead:0}; | |
} | |
//var notfound_users = ""; | |
String.prototype.addp = function(param, value) { | |
if (!value || !param) | |
return this; | |
var pos = this.indexOf(param + '='); | |
//if parameter exists | |
if (pos != -1) | |
return this.slice(0, pos + param.length) + '=' + value; | |
var ch = this.indexOf('?') > 0 ? '&' : '?'; | |
return this + ch + param + '=' + value; | |
}; | |
function getParameterByName(name) { | |
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.href); | |
return match && decodeURIComponent(match[1].replace(/\+/g, ' ')); | |
} | |
window.addEventListener("load", function () { | |
table = document.getElementById("apps"); | |
chart = document.getElementById("chart"); | |
var id = getParameterByName("id") || ""; | |
var update = getParameterByName("update") || ""; | |
if (id) | |
search(id+''); | |
if (update) | |
{ | |
document.getElementById("UpdateU").checked = true; | |
search(); | |
} | |
//document.getElementById("checkin").value = ""; | |
}); | |
function setStat(){ | |
for (const key of Object.keys(stages)) { | |
document.getElementById("n"+key).innerText = stages[key]; | |
document.getElementById("s"+key).style.height = (stages[key]*2)+"%"; | |
console.log(key, stages[key]); | |
} | |
chart.style.display = "table"; | |
} | |
function removeall(){ | |
chart.style.display = "none"; | |
stages = {customer: 0,opportunity:0,lead:0,subscriber:0,marketingqualifiedlead:0,salesqualifiedlead:0}; | |
timeoffset = 0; | |
loop = 0; | |
table.innerHTML = '<tbody><tr class="headerTable"><th>Index</th><th>Email</th><th>Added At</th><th>Hubspot Stage</th><th>Registered in App</th><th>Updated</th><th></th></tr></tbody>'; | |
return false; | |
} | |
function search(id) { | |
var text = document.getElementById("myName").value || id || "0"; | |
var date = document.getElementById("checkin").value || ""; | |
id = 0; | |
if (text && ~text.indexOf("@")) | |
{ | |
getUserData(text); | |
return; | |
} | |
stop = false; | |
update = document.getElementById("UpdateU").checked; | |
loop = parseInt(text); | |
loop = loop || 0; | |
if (date) | |
{ | |
searchByDate(loop); | |
return; | |
} | |
var xy = function x (){ | |
if(stop == false){ | |
getUserData(loop); | |
//console.log(loop); | |
setTimeout(function(){xy()},100); | |
} else { | |
console.log('loop exited! - '+loop); | |
document.getElementById("myName").value = loop; | |
return true; | |
} | |
} | |
xy(); | |
} | |
function getUserData(index) { | |
var XHR = new XMLHttpRequest(); | |
// Define what happens on successful data submission | |
XHR.addEventListener("load", function(event) { | |
showResult(event.target.responseText, index); | |
}); | |
// Define what happens in case of error | |
XHR.addEventListener("error", function(event) { | |
alert('Oups! Something goes wrong.'); | |
stopnow(); | |
}); | |
// Set up our request | |
XHR.open("GET", HUBSPOT_SITE + "contacts/v1/lists/53/contacts/all?&formSubmissionMode=all&hapikey=XXXXXXa&property=lifecyclestage&propertyMode=value_only&count=1&vidOffset="+index, false); | |
// The data sent is what the user provided in the form | |
XHR.send(); | |
} | |
function searchByDate(index) { | |
start = calendar_from.current_date.getTime(); | |
end = (new Date(calendar_to.current_date.getTime() + 86399990)).getTime(); | |
if (calendar_to.current_date.getTime() < (new Date()).getTime()) | |
document.getElementById("fountainG").style.display = "block"; | |
stop = false; | |
update = document.getElementById("UpdateU").checked; | |
timeoffset = timeoffset || 0; | |
loop = loop || 0; | |
var xy = function x (){ | |
if(stop == false){ | |
getUserDataByDate(loop, timeoffset, start, end); | |
//console.log(loop); | |
setTimeout(function(){xy()},100); | |
} else { | |
console.log('loop2 exited! - '+loop); | |
document.getElementById("myName").value = loop; | |
return true; | |
} | |
} | |
xy(); | |
} | |
function getUserDataByDate(index, current_timeoffset, start_time, end_time) { | |
var XHR = new XMLHttpRequest(); | |
// Define what happens on successful data submission | |
XHR.addEventListener("load", function(event) { | |
var resp = event.target.responseText; | |
/*var time = ""; | |
if (resp) | |
time = resp.substring(resp.indexOf("time-offset")+13,resp.length-1); | |
console.log("time", time); | |
if (time && Number(time) <= end_time) | |
{ | |
document.getElementById("fountainG").style.display = "none"; | |
} | |
else | |
document.getElementById("fountainG").style.display = "block"; | |
*/ | |
showResult(event.target.responseText, index); | |
}); | |
// Define what happens in case of error | |
XHR.addEventListener("error", function(event) { | |
alert('Oups! Something goes wrong.'); | |
stopnow(); | |
}); | |
var add = ""; | |
if (index) | |
add += "&vidOffset="+index; | |
if (current_timeoffset) | |
add +="&timeOffset="+current_timeoffset; | |
// Set up our request | |
XHR.open("GET", HUBSPOT_SITE + "contacts/v1/lists/all/contacts/recent?formSubmissionMode=all&hapikey=XXXXXXX&property=lifecyclestage&propertyMode=value_only&count=1"+add, false); | |
// The data sent is what the user provided in the form | |
XHR.send(); | |
} | |
(function() { | |
//https://crossorigin.me/ | |
var cors_api_host = 'cors-anywhere.herokuapp.com'; | |
var cors_api_url = 'https://' + cors_api_host + '/'; | |
var slice = [].slice; | |
var origin = window.location.protocol + '//' + window.location.host; | |
var open = XMLHttpRequest.prototype.open; | |
XMLHttpRequest.prototype.open = function() { | |
var args = slice.call(arguments); | |
var targetOrigin = /^https?:\/\/([^\/]+)/i.exec(args[1]); | |
if (targetOrigin && targetOrigin[0].toLowerCase() !== origin && | |
targetOrigin[1] !== cors_api_host) { | |
args[1] = cors_api_url + args[1]; | |
} | |
return open.apply(this, args); | |
}; | |
})(); | |
function getSherpaData(index, email, oldstatus) { | |
var XHR = new XMLHttpRequest(); | |
// Define what happens on successful data submission | |
XHR.addEventListener("load", function(event) { | |
var status = event.target.responseText; | |
if (update) | |
{ | |
if (status == "ex-customer" || status == "expired") | |
{ | |
updateUserData(index, email, "ex_customer", "expired org", ""); | |
} | |
else if (status != "false" && status != oldstatus) | |
{ | |
updateUserData(index, email, "lifecyclestage", status, oldstatus); | |
} | |
//else if (status == "false" && (oldstatus == "customer" || oldstatus == "lead")) | |
//{ | |
// updateUserData(index, email, "lifecyclestage", "subscriber", oldstatus); | |
//} | |
} | |
status = status == "false" ? "subscriber" : status; | |
document.getElementById("c"+index).innerHTML = status && status[0].toUpperCase() + status.slice(1); | |
}); | |
// Define what happens in case of error | |
XHR.addEventListener("error", function(event) { | |
alert('Oups! Something goes wrong.'); | |
stopnow(); | |
}); | |
// Set up our request | |
XHR.open("GET", SITE + "data?format=json&name="+email); | |
// The data sent is what the user provided in the form | |
XHR.send(); | |
} | |
function updateUserData(index, email, name, value, oldstatus) { | |
var XHR = new XMLHttpRequest(); | |
// Define what happens on successful data submission | |
XHR.addEventListener("load", function(event) { | |
//console.log(event.target.responseText); | |
document.getElementById("u"+index).innerHTML = event.target.responseText; | |
}); | |
// Define what happens in case of error | |
XHR.addEventListener("error", function(event) { | |
alert('Oups! Something goes wrong.'); | |
stopnow(); | |
}); | |
// Set up our request | |
XHR.open('POST', HUBSPOT_SITE + "https://api.hubapi.com/contacts/v1/contact/email/"+email+"/profile?hapikey=XXXXXX"); | |
var formData ={"properties":[{"property":"lifecyclestage","value":"\" + value + "\""}]}; | |
// execute results | |
XHR.send(formData); | |
} | |
function showResult(test, index) { | |
index = index || 0; | |
if (!test){ | |
alert('Oups! No results found'); | |
return; | |
} | |
var dataObj = JSON.parse(test); | |
//console.log(dictionaryData); | |
if (dataObj != null){ | |
loop = dataObj["vid-offset"]; | |
if (dataObj.contacts.length){ | |
var email = dataObj.contacts[0]["identity-profiles"][0].identities.filter(i => i.type == "EMAIL")[0].value; | |
var stage = dataObj.contacts[0].properties.lifecyclestage.value; | |
var date = new Date(dataObj.contacts[0]["addedAt"]).toLocaleDateString() | |
var timeOffset = dataObj["time-offset"]; | |
if (timeOffset) | |
timeoffset = timeOffset; | |
stop = !dataObj["has-more"]; | |
if (stop) | |
{ | |
if (timeOffset) | |
{ | |
timeoffset = 0; | |
loop = 0; | |
} | |
stopnow(); | |
} | |
var url = dataObj.contacts[0]["profile-url"]; | |
//console.log(email); | |
if (email && ~email.indexOf("@")) { | |
if (!timeOffset || (timeOffset && timeOffset <= end && timeOffset >= start)) | |
{ | |
stages[stage.toLowerCase()]++; | |
AddNoSkypeRow(index, email, stage, url, date); | |
getSherpaData(index,email,stage); | |
} | |
if (timeOffset && timeOffset < start) | |
stopnow(); | |
} | |
} | |
} | |
} | |
function AddNoSkypeRow(index, email, stage, url, date) | |
{ | |
var tr = null; | |
if (!timeoffset) | |
tr = table.insertRow(1); //document.createElement("tr"); | |
else | |
tr = document.createElement("tr"); | |
var td = document.createElement("td"); | |
var txt = document.createTextNode(index); | |
td.appendChild(txt); | |
tr.appendChild(td); | |
txt = document.createTextNode(email); | |
td = document.createElement("td"); | |
td.appendChild(txt); | |
tr.appendChild(td); | |
txt = document.createTextNode(date); | |
td = document.createElement("td"); | |
td.appendChild(txt); | |
tr.appendChild(td); | |
//txt = document.createTextNode(stage); | |
td = document.createElement("td"); | |
//td.appendChild(txt); | |
td.innerHTML = '<a target=blank href="'+url+'"">'+stage+'</a>'; | |
tr.appendChild(td); | |
txt = document.createTextNode(""); | |
td = document.createElement("td"); | |
td.id = "c"+index; | |
td.appendChild(txt); | |
tr.appendChild(td); | |
txt = document.createTextNode("---"); | |
td = document.createElement("td"); | |
td.id = "u"+index; | |
td.appendChild(txt); | |
tr.appendChild(td); | |
if (timeoffset) | |
table.appendChild(tr); | |
} | |
function exportToExcel(){ | |
var htmls = ""; | |
var uri = 'data:application/vnd.ms-excel;base64,'; | |
var template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>'; | |
var base64 = function(s) { | |
return window.btoa(unescape(encodeURIComponent(s))) | |
}; | |
var format = function(s, c) { | |
return s.replace(/{(\w+)}/g, function(m, p) { | |
return c[p]; | |
}) | |
}; | |
htmls = table.innerHTML; | |
var ctx = { | |
worksheet : 'Worksheet', | |
table : htmls | |
} | |
var link = document.createElement("a"); | |
link.download = "export.xls"; | |
link.href = uri + base64(format(template, ctx)); | |
link.click(); | |
} | |
</script> | |
</body></html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment