Summary
This post will walk through the steps necessary to generate a custom report job on InContact's platform via API. I'll show examples in Node.js (asynchronous) and Python (synchronous).
Overview of Steps
Get Token
Node.js
getToken() {
console.log('getToken()');
const url = 'https://api.incontact.com/InContactAuthorizationServer/Token';
const body = {
'grant_type' : 'password',
'username' : this.username,
'password' : this.password
};
return fetch(url, {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Content-Type' : 'application/json',
'Authorization' : 'basic ' + this.authCode
},
cache: 'no-store',
mode: 'cors'
})
.then(response => {
if (response.ok) {
return response.json();
}
else {
const msg = 'response status: ' + response.status;
throw new Error(msg);
}
})
.then(json => {
if (json && json.access_token && json.resource_server_base_uri) {
return json;
}
else {
const msg = 'missing token and/or uri';
throw new Error(msg);
}
})
.catch(err => {
console.error('getToken() - ' + err.message);
throw err;
});
}
Python
def getToken(self):
print('getToken()')
url = 'https://api.incontact.com/InContactAuthorizationServer/Token'
header = {'Authorization' : b'basic ' + self.authCode, 'Content-Type': 'application/json'}
body = {'grant_type' : 'password', 'username' : self.username, 'password' : self.password}
resp = requests.post(url, headers=header, json=body)
resp.raise_for_status()
return resp.json()
Start Report Job
Node.js
startReportJob(reportId, reportURL, token) {
const url = reportURL + reportId;
console.log('startReportJob() - url: ' + url);
const body = {
'fileType': 'CSV',
'includeHeaders': 'true',
'appendDate': 'true',
'deleteAfter': '7',
'overwrite': 'true'
};
return fetch(url, {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Content-Type' : 'application/json',
'Authorization' : 'bearer ' + token
},
cache: 'no-store',
mode: 'cors'
})
.then(response => {
if (response.ok) {
return response.json();
}
else {
const msg = 'response status: ' + response.status;
throw new Error(msg);
}
})
.then(json => {
return json.jobId;
})
.catch(err => {
console.error('startReportJob() - ' + err.message);
throw err;
});
}
Python
def startReportJob(self, reportId, reportURL, token):
url = reportURL + reportId
print('startReportJob() - url: ' + url);
body = {
'fileType': 'CSV',
'includeHeaders': 'true',
'appendDate': 'true',
'deleteAfter': '7',
'overwrite': 'true'
}
header = { 'Content-Type' : 'application/json', 'Authorization' : 'bearer ' + token}
resp = requests.post(url, headers=header, json=body)
resp.raise_for_status()
return resp.json()['jobId']
Get File URL
Node.js
getFileURL(jobId, reportURL, token, numTries=10) {
console.log('getFileURL() - jobId: ' + jobId + ' numTries: ' + numTries);
const that = this;
const url = reportURL + jobId;
return fetch(url, {
method: 'GET',
headers: {
'Content-Type' : 'application/x-www-form-urlencoded',
'Authorization' : 'bearer ' + token
},
cache: 'no-store',
mode: 'cors'
})
.then(response => {
if (response.ok) {
return response.json();
}
else {
const msg = 'response status: ' + response.status;
throw new Error(msg);
}
})
.then(json => {
if (json.jobResult.resultFileURL) {
return json.jobResult.resultFileURL;
}
else {
if (numTries > 0) { //loop (recursive) up to the numTries parameter
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(that.getFileURL(jobId, reportURL, token, numTries-1));
}, 60000); //retry once per minute
});
}
else {
throw new Error('Maximum retries reached');
}
}
})
.catch(err => {
console.error('getFileURL() - ' + err.message);
throw err;
});
}
Python
def getFileURL(self, jobId, reportURL, token):
url = reportURL + jobId
header = { 'Content-Type' : 'application/x-www-form-urlencoded', 'Authorization' : 'bearer ' + token }
resp = requests.get(url, headers=header)
fileURL = resp.json()['jobResult']['resultFileURL']
numTries = 10
while (not fileURL and numTries > 0):
print('getFileURL() - jobId: ' + jobId + ' numTries: ' + str(numTries))
time.sleep(60)
resp = requests.get(url, headers=header)
fileURL = resp.json()['jobResult']['resultFileURL']
numTries -= 1
return fileURL
Download Report
Node.js
downloadReport(url, token) {
console.log('downLoadReport() - url: ' + url);
return fetch(url, {
method: 'GET',
headers: {'Authorization' : 'bearer ' + token},
cache: 'no-store',
mode: 'cors'
})
.then(response => {
if (response.ok) {
return response.json();
}
else {
const msg = 'response status: ' + response.status;
throw new Error(msg);
}
})
.then(json => {
return json.files.file;
})
.catch(err => {
console.error('downloadReport() - ' + err.message);
throw err;
})
Python
def downloadReport(self, url, token):
print('downLoadReport() - url: ' + url)
header = { 'Content-Type' : 'application/x-www-form-urlencoded', 'Authorization' : 'bearer ' + token }
resp = requests.get(url, headers=header)
return resp.json()['files']['file']
Output
Node.js
getReport() - reportId: 4477 getToken() startReportJob() - url: https://api-c7.incontact.com/inContactAPI/services/v13.0/report-jobs/4477 getFileURL() - jobId: 825795 numTries: 10 getFileURL() - jobId: 825795 numTries: 9 getFileURL() - jobId: 825795 numTries: 8 getFileURL() - jobId: 825795 numTries: 7 downLoadReport() - url: https://api-C7.incontact.com/inContactAPI/services/V15.0/files?fileName=CustomReports%5cApiReports%5cService+Levels_20190203T054855.csv Job Complete
Python
getReport() - reportId: 4477 getToken() startReportJob() - url: https://api-c7.incontact.com/inContactAPI/services/v13.0/report-jobs/4477 getFileURL() - jobId: 825797 numTries: 10 getFileURL() - jobId: 825797 numTries: 9 getFileURL() - jobId: 825797 numTries: 8 downLoadReport() - url: https://api-C7.incontact.com/inContactAPI/services/V15.0/files?fileName=CustomReports%5cApiReports%5cService+Levels_20190203T055156.csv Job Complete
Source
Full source w/comments - https://github.com/joeywhelan/reportdemo
Copyright ©1993-2024 Joey E Whelan, All rights reserved.
