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.