Skip to content

Instantly share code, notes, and snippets.

@evgeniynet
Created January 25, 2018 07:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evgeniynet/32bbf38074caa3ea3860febd3e673e9a to your computer and use it in GitHub Desktop.
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
<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>
&nbsp;&nbsp;&nbsp;
<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 &amp;&amp; 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