Skip to content

Instantly share code, notes, and snippets.

@winniecluk
Created October 26, 2017 18:56
Show Gist options
  • Select an option

  • Save winniecluk/f131dae18c4db39cbeada0e63d2e3009 to your computer and use it in GitHub Desktop.

Select an option

Save winniecluk/f131dae18c4db39cbeada0e63d2e3009 to your computer and use it in GitHub Desktop.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const ROOT_URL = 'https://kipuapi.kipuworks.com';
const ACCEPT_HEADER_VALUE = 'application/vnd.kipusystems+json; version=1';
const request = require('request');
const crypto = require('crypto');
const querystring = require('querystring');
const BOUNDARY = '741e90d31eff';
const APP_IDENTIFIER = 'Salesforce.com';
// var Readable = require('stream');
var streamifier = require('streamifier');
var FormData = require('form-data');
var http = require('http');
let resourceMap = {
"patients": {
method: "POST",
params: [],
route: "/api/patients",
idRequired: false
},
"occupancy": {
method: "GET",
params: ["phi_level"],
route: "/api/patients/occupancy?app_id=",
idRequired: false
},
"census": {
method: "GET",
params: ["phi_level"],
route: "/api/patients/census?app_id=",
idRequired: false
},
"admissions": {
method: "GET",
params: ["phi_level"],
route: "/api/patients/census?app_id=",
idRequired: false
},
"patient": {
method: "GET",
params: ["phi_level", "patient_master_id"],
route: "/api/patients/:ID?app_id=" ,
idRequired: true
},
"utilization": {
method: "GET",
params: ["phi_level", "patient_master_id"],
route: "/api/patients/:ID/ur?app_id=" ,
idRequired: true
}
}
function createReq(configObj){
let md5Digest = crypto.createHash('md5').update(JSON.stringify(configObj.body)).digest('binary');
let contentStr = Buffer.from(md5Digest, 'binary').toString('base64', 0, 24);
let dateStr = new Date().toUTCString();
var canonicalStr = '';
if (configObj.method != 'GET') canonicalStr += 'application/json';
canonicalStr += ','+contentStr+','+configObj.uri+','+dateStr;
let signature = crypto.createHmac('sha1', configObj.credentials.secretKey).update(canonicalStr).digest('base64');
let reqObj = {
url: ROOT_URL + configObj.uri,
headers: {
'Accept': ACCEPT_HEADER_VALUE,
'Authorization': 'APIAuth '+configObj.credentials.accessId+':'+signature,
'Content-MD5': contentStr,
'Date': dateStr
}
}
if (configObj.method === 'POST'){
reqObj.body = JSON.stringify(configObj.body);
reqObj.method = 'POST';
reqObj.headers['Content-type'] = 'application/json';
} else {
reqObj.method = 'GET';
}
return reqObj;
}
function createMultiPost(configObj){
// should have already validated earlier
let dataObj = configObj.body.document.data;
let attachmentsArr = configObj.body.document['attachment_attributes'];
var postBody = '';
console.log('this is dataObj ');
console.log(dataObj);
console.log('these are the attachments');
console.log(attachmentsArr);
for (var field in dataObj){
if (Array.isArray(dataObj[field])){
for (let i = 0; i < dataObj[field].length; i++){
for (var attribute in dataObj[field][i]){
postBody += '--'+BOUNDARY+'\r\n';
postBody += 'Content-Disposition: form-data; ';
postBody += 'name="document[data][' + field +'][' + i + ']['+attribute+']\r\n';
postBody += '\r\n';
postBody += dataObj[field][i][attribute];
postBody += '\r\n';
}
}
} else {
postBody += '--'+BOUNDARY+'\r\n';
postBody += 'Content-Disposition: form-data; ';
postBody += 'name="document[data][' + field +']"'+'\r\n';
postBody += '\r\n';
postBody += dataObj[field];
postBody += '\r\n';
}
}
postBody += '--'+BOUNDARY+'\r\n';
postBody += 'Content-Disposition: form-data; ';
postBody += 'name="document[recipient_id]"'+'\r\n';
postBody += '\r\n';
if (configObj.credentials.recipientId){
postBody += configObj.credentials.recipientId;
} else {
postBody += configObj.credentials.accessId;
}
postBody += '\r\n';
postBody += '--'+BOUNDARY+'\r\n';
postBody += 'Content-Disposition: form-data; ';
postBody += 'name="document[sending_app_name]"'+'\r\n';
postBody += '\r\n';
postBody += APP_IDENTIFIER;
postBody += '\r\n';
for (let i = 0; i < attachmentsArr.length; i++){
postBody += '--'+BOUNDARY+'\r\n';
postBody += 'Content-Disposition: form-data; ';
postBody += 'name="document[attachments_attributes]['+ i +'][attachment]'+'"; ';
postBody += 'filename="'+ attachmentsArr[i]['filename'] + '"\r\n';
// postBody += 'Content-type: ' + 'text/html' +' \r\n';
postBody += 'Content-type: ' + 'application/pdf' +' \r\n';
postBody += '\r\n';
var b = Buffer.from(attachmentsArr[i].attachment, 'base64');
// var bArr = [b];
// var buf = Buffer.concat(bArr);
// postBody += escape(b.toString());
postBody += b;
// if (i === attachmentsArr.length - 1){
// postBody += '\r\n--'+BOUNDARY+'--\r\n';
// } else {
postBody += '\r\n';
// }
} // closes attachmentArr loop
postBody += '--'+BOUNDARY+'--\r\n';
let md5Digest = crypto.createHash('md5').update(postBody).digest('binary');
let contentStr = Buffer.from(md5Digest, 'binary').toString('base64', 0, 24);
let dateStr = new Date().toUTCString();
// boundary
var canonicalStr = 'multipart/form-data, boundary='+BOUNDARY+',';
canonicalStr += contentStr+','+configObj.uri+','+dateStr;
let signature = crypto.createHmac('sha1', configObj.credentials.secretKey).update(canonicalStr).digest('base64');
console.log('THIS IS POSTBODY IN CREATE MULTIPART');
console.log(postBody);
// url: ROOT_URL + configObj.uri,
let reqObj = {
url: ROOT_URL + configObj.uri,
method: 'POST',
headers: {
'Content-type': 'multipart/form-data, boundary='+BOUNDARY,
'Accept': ACCEPT_HEADER_VALUE,
'Authorization': 'APIAuth '+configObj.credentials.accessId+':'+signature,
'Date': new Date().toUTCString(),
'Content-MD5': contentStr
},
body: postBody
};
// let options = {
// host: 'cc570bfc.ngrok.io',
// port: 3000,
// path: '/firebase',
// method: 'POST',
// headers: {
// 'Content-type': 'multipart/form-data, boundary='+BOUNDARY,
// 'Accept': ACCEPT_HEADER_VALUE,
// 'Authorization': 'APIAuth '+configObj.credentials.accessId+':'+signature,
// 'Date': new Date().toUTCString(),
// 'Content-MD5': contentStr
// },
// body: postBody
// };
// console.log('THIS IS REQOBJ INSIDE CREATE MULTIPART');
// console.log(reqObj);
// form.submit(reqObj, function(err, response){
// if (err){
// console.log('we have an error');
// console.log(err);
// } else {
// console.log('this is the response');
// console.log(response);
// }
// })
return reqObj;
}
function validate(req, res){
var scope = {};
if (req.query.hasOwnProperty('sfid')
&& req.query.hasOwnProperty('method')
&& req.query.hasOwnProperty('resource')
&& resourceMap[req.query.resource]
&& req.query.method.toUpperCase() === resourceMap[req.query.resource].method
){
scope.sfId = req.query.sfid;
scope.method = req.query.method.toUpperCase();
scope.resource = req.query.resource;
} else {
res.send('Missing required parameters or invalid arguments.');
}
if (resourceMap[scope.resource].idRequired){
if (req.query.patientId){
scope.patientId = req.query.patientid;
} else {
res.send('Missing patient ID.');
}
}
if (scope.method === 'POST'){
if (req.query.hasOwnProperty('multipart')
&& (req.query.multipart.toLowerCase() === 'true'
|| req.query.multipart.toLowerCase() === 'false')
){
scope.multipart = req.query.multipart;
} else {
res.send('Missing required parameters or invalid arguments.');
}
if (req.body
&& req.body.document.data
&& req.body.document['attachment_attributes']
){
scope.body = req.body;
} else {
res.send('Missing body of request.');
}
}
let queryParams = resourceMap[scope.resource].params;
for (let i = 0; i < queryParams.length; i++){
if (!req.query[queryParams[i]]){
res.send('Missing required parameters for this request.');
}
}
return scope;
}
function createURI(scope, req, res){
var uri = resourceMap[scope.resource].route;
if (scope.method != 'POST'){
if (scope.credentials.appId){
uri += scope.credentials.appId;
} else if (scope.credentials.accessId){
uri += scope.credentials.accessId;
} else {
res.send('Credentials missing in database.');
}
// if idRequired == true
if (resourceMap[scope.resource].idRequired){
uri = uri.replace(/:ID/, patientId)
}
let queryParams = resourceMap[scope.resource].params;
for (let i = 0; i < queryParams.length; i++){
uri += '&' + queryParams[i] +'=' + req.query[queryParams[i]]
}
}
console.log('this is the URI: ' + uri);
return uri;
}
exports.handleRequests = functions.https.onRequest((req, res) => {
var scope = validate(req, res);
console.log('this is the scope');
console.log(scope);
admin.database().ref('orgIds/' + scope.sfId).once('value').then(snapshot => {
let data = snapshot.val();
if (data) {
return {
accessId: data.accessId,
appId: data.appId,
recipientId: data.recipientId,
secretKey: data.secretKey
}
} else {
res.send('Salesforce ID not found in database.');
}
}).then(credentials => {
scope.credentials = credentials;
var uri = createURI(scope, req, res);
return uri;
}).then(uri => {
scope.uri = uri;
var reqObj;
if (scope.method === 'GET'){
scope.body = '';
reqObj = createReq(scope);
} else if (scope.method === 'POST'){
reqObj = scope.multipart ? createMultiPost(scope) : createReq(scope);
// if (scope.multipart){
// reqObj = createMultiPost(scope);
// } else {
// reqObj = createReq(scope);
// }
};
return reqObj;
}).then(reqObj => {
// const req = http.request(reqObj, (resp) =>{
// console.log(`STATUS: ${res.statusCode}`);
// console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
// res.setEncoding('utf8');
// res.on('data', (chunk) => {
// console.log(`BODY: ${chunk}`);
// });
// res.on('end', () => {
// console.log('No more data in response.');
// });
// });
//
// req.on('error', (e) => {
// console.error(`problem with request: ${e.message}`);
// });
//
// req.write(postBody);
// req.end();
console.log('this is reqObj being sent');
console.log(reqObj);
request(reqObj, function(error, response, body){
if (error){
console.log(error);
res.send(error);
} else if (!error && response.statusCode === 200){
console.log('THINGS ARE 200');
console.log(body);
res.send(body);
} else if (!error && response.statusCode === 201){
console.log('THINGS ARE 201');
console.log(body);
res.send(body);
} else {
console.log('THIS IS THE RESPONSE FROM KIPU');
console.log(response);
console.log(body);
res.send(response);
}
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment