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.