Skip to content

Instantly share code, notes, and snippets.

@mfrancois3k
Forked from louiskueh/API-functions.js
Created February 20, 2022 01:49
Show Gist options
  • Save mfrancois3k/2ffe3af25e58450e8db26ca256159438 to your computer and use it in GitHub Desktop.
Save mfrancois3k/2ffe3af25e58450e8db26ca256159438 to your computer and use it in GitHub Desktop.
BlackBaud API exploration
var helper = {
processCodings: function (codingArray) {
// ID = 6, description: Fund
var fund;
// ID = 4, description : "Program Area "
var programArea;
for (var i = 0; i < codingArray.length; i++) {
var obj = codingArray[i]
//ID = 6, description: Fund
if (obj.codeTable.id === 6 && obj.codeTable.description === "Fund") {
fund = this.loopAllLevels(obj);
}
// ID = 4, description : "Program Area "
else if (obj.codeTable.id === 4 && obj.codeTable.description === "Program Area") {
programArea = this.loopAllLevels(obj);
}
}
return JSON.stringify({ fund: fund, programArea: programArea })
},
loopAllLevels(codeTable) {
var result = "";
for (var i = 1; i <= 5; i++) {
var variableLoop = i.toString()
var item = codeTable["level" + variableLoop]
if (item.id === 0 && item.code === null && item.description === null) {
break;
} else {
item.code = item.code ? item.code : ""
result = result + "[" + item.code + "]" + " " + item.description + " / "
}
}
result =result.slice(0,-3)
return result
}
};
module.exports = helper
import React from "react";
import classNames from "classnames";
import withStyles from "material-ui/styles/withStyles";
import Header from "components/Header/Header.jsx";
import Parallax from "components/Parallax/Parallax.jsx";
import componentsStyle from "assets/jss/material-kit-react/views/componentsStyle.jsx";
import SectionDisplayResult from "./Sections/SectionDisplayResult";
import SectionOpenFile from "./Sections/SectionOpenFile";
class Components extends React.Component {
constructor(props) {
super(props)
this.state = {
file: [],
fileSubmitted: false
}
}
handlefile = (file,fileSubmitValue) => {
this.setState({file:file,fileSubmitted: fileSubmitValue});
}
render() {
const { classes, ...rest } = this.props;
return (
<div>
<Header
brand="Buzzacott"
fixed
changeColorOnScroll={{
height: 400,
color: "white"
}}
{...rest}
/>
<div className={classes.small}>
<Parallax image={require("assets/img/buzzacott.jpg")} >
</Parallax>
</div>
<div className={classNames(classes.main, classes.mainRaised)}>
{this.state.fileSubmitted ? <SectionDisplayResult file={this.state.file} submitted={this.state.fileSubmitted}/>
: <SectionOpenFile onFinishSubmit={this.handlefile} /> }
{/* <SectionDisplayResult file={this.state.file} submitted={this.state.fileSubmitted} /> */}
</div>
</div>
);
}
}
export default withStyles(componentsStyle)(Components);
var helper = {
print: function (textArray) {
for (var i in textArray) {
console.log(textArray[i] + '\n')
}
},
checkFirstLine: function (line) {
var firstString = line.split(" ")
if (firstString[0] !== "CHECKS") return false;
else if (firstString[1] !== "EXPORT") return false;
else {
return true;
}
},
checkLastLine: function (line) {
var lastString = line.split(" ")
if (lastString[0] !== "END") return false;
else if (lastString[1] !== "OF") return false;
else {
return true;
}
},
checkValid: function (textArray) {
return ( this.checkFirstLine(textArray[0]) && this.checkLastLine(textArray[textArray.length - 1]))
},
getDate: function (textArray) {
var re = /(\d{2})\/(\d{2})\/(\d{4})/
var firstLine = textArray[0];
firstLine = firstLine.match(re)[0]
var arr = firstLine.split('/');
var temp = arr[1]
arr[1] = arr[0]
arr[0] = temp
return arr[0] +"/" +arr[1] +"/"+ arr[2];
},
getTime: function (textArray) {
var re = /(\d{2}):(\d{2}):(\d{2})/
var firstLine = textArray[0];
return firstLine.match(re)[0]
},
getNumber: function (textArray) {
var re = /(\t)(\d*?)(\t)/
var lastLine = textArray[textArray.length - 1]
return lastLine.match(re)[0].slice(1, -1)
},
getAmount: function (textArray) {
var re = /(\d*)(\.)(\d{2})/
var lastLine = textArray[textArray.length - 1]
return lastLine.match(re)[0].replace("\t", "")
},
getRecords: function (textArray) {
var temp = textArray;
if (temp.length > 2) {
temp =temp.slice(1, -1)
}
return temp;
},
getIthItem: function (record, i) {
var items = record.split(/[\s\t]+/)
i = i -1;
if (i < items.length) {
return items[i]
}
else {
return false;
}
}
};
module.exports = helper
import React from "react";
import withStyles from "material-ui/styles/withStyles";
import displayResultStyle from "assets/jss/material-kit-react/views/componentsSections/displayResultStyle.jsx";
import Button from "components/CustomButtons/Button.jsx";
import 'react-notifications/lib/notifications.css';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import GridContainer from "components/Grid/GridContainer.jsx";
import GridItem from "components/Grid/GridItem.jsx";
// import { Input } from "material-ui";
import { TextField } from 'material-ui';
var functions = require('Functions/functions.js');
//File is the text array seperated by \n
class SectionDisplayResult extends React.Component {
constructor(props) {
super(props)
this.state = {
Received: [],
input: "",
ids: [],
text: []
};
this.callAPI = this.callAPI.bind(this)
this.testAPI = this.testAPI.bind(this)
}
componentWillMount() {
console.log("component mounted")
var input = this.props.file
// var input = "CHECKS EXPORT FILE\t06/19/2018\t10:36:24\r\n604\t632\tTime to say goodbye\t5059\t0\t12/01/2018\t5000.00\t\tThe Old Time Show\t Helen Hughes \t\t\t\t\t\t\t\t\t\t\r\n605\t633\tTime to say goodbye\t5059\t0\t12/01/2018\t5000.00\t\tThe Old Time Show\t Helen Hughes \t\t\t\t\t\t\t\t\t\t\r\nEND OF FILE\t1\t5000.00"
// input = input.split("\n")
this.setState({ text: input })
this.getIds(input)
}
getSummary() {
console.log("Summary called")
var text = this.state.text
var date = functions.getDate(text)
var time = functions.getTime(text)
var numRecords = functions.getNumber(text)
var amount = functions.getAmount(text)
return <div><h1>This A/P file was created on <b>{date}</b>, <b>{time}</b></h1> <h2>There are <b>{numRecords}</b> record(s) with a total amount of <b>£{amount}</b></h2></div>
}
componentDidMount() {
NotificationManager.success('Please view the summary below', "A/P file successfully processed", 6000);
}
fetchEndPoint(endPoint, req) {
var self = this;
console.log(req)
fetch(endPoint, req).then(data => {
data.json().then(function(record){
var tempArray = []
for (var i = 0 ; i < record.length; i ++) {
var data = JSON.parse(record[i])
console.log(data)
var obj = "fund: " + data.fund + ", Program Area: " + data.programArea + "\n"
tempArray.push(obj)
}
console.log("Temp array: " + tempArray)
self.setState({ Received: tempArray })
})
}
)
}
getIds(input) {
var records = functions.getRecords(input)
var arrayID = []
for (var i = 0; i < records.length; i++) {
arrayID.push(functions.getIthItem(records[i], 2))
}
console.log(arrayID)
this.setState({ ids: arrayID })
}
callAPI() {
var jsonObj = {
"method": "post",
"mode": 'cors',
"headers": {
"Content-Type": "application/json"
},
"body": JSON.stringify(
{
endPoint: "request/getRequestsById",
ids: this.state.ids
}
)
}
console.log("IDS sent: " + this.state.ids)
this.fetchEndPoint('/API', jsonObj)
}
testAPI() {
var self = this;
fetch("/test").then(data => {
data.text().then(function (data) {
self.setState({ Received: data })
console.log("Received text: " + self.state.Received)
})
}
)
}
updateInputValue(evt) {
this.setState({
input: evt.target.value
});
}
displayIds() {
const listItems = this.state.ids.map((id) =>
<li key={id}>{id}</li>
)
return (<div><h2>Request IDs:</h2><ul>{listItems}</ul></div>)
}
displayReceived(){
if(this.state.Received){
const listItems = this.state.Received.map((id) =>
<li key={id}>{id}</li>
)
return (<div><h2>Request IDs:</h2><ul>{listItems}</ul></div>)
}
}
render() {
return (
<div>
<div>
{this.getSummary()}
</div>
<div>{this.displayIds()}</div>
<GridContainer>
<GridItem xs={12} sm={4} md={4} lg={3}>
<TextField label="Enter ID" helperText="Click Connect to API when finished" onChange={evt => this.updateInputValue(evt)} />
</GridItem>
<Button color="success" onClick={this.callAPI} round>Connect to API</Button>
<Button color="success" onClick={this.testAPI} round>Test Server</Button>
</GridContainer>
<div>{this.state.Received.length >0 ? this.displayReceived() : null }</div>
{/* <div>Data: {this.state.Received}</div> */}
<div>Input: {this.state.input}</div>
<NotificationContainer />
</div>
);
}
}
export default withStyles(displayResultStyle)(SectionDisplayResult);
import React from "react";
import withStyles from "material-ui/styles/withStyles";
import basicsStyle from "assets/jss/material-kit-react/views/componentsSections/basicsStyle.jsx";
import Files from 'react-files'
import Button from "components/CustomButtons/Button.jsx";
import 'react-notifications/lib/notifications.css';
import { NotificationContainer, NotificationManager } from 'react-notifications';
var functions = require('Functions/functions.js');
class SectionOpenFile extends React.Component {
constructor(props) {
super(props)
this.state = {
files: [],
submitted:false
}
}
onFilesChange = (files) => {
this.setState({
files
}, () => {
console.log(this.state.files)
})
}
onFilesError = (error, file) => {
console.log('error code ' + error.code + ': ' + error.message)
if (error.code === 1) {
NotificationManager.error('Please make sure the file format is text', error.message, 6000);
}
else {
NotificationManager.error('Error code ' + error.code, error.message, 6000);
}
}
filesRemoveOne = (file) => {
this.refs.files.removeFile(file)
}
filesRemoveAll = () => {
this.refs.files.removeFiles()
}
filesUpload = () => {
var read = new FileReader();
var textArray
var submit
var self = this;
read.readAsBinaryString(this.state.files[0]);
read.onloadend = function (){
textArray = read.result.split("\n")
if (functions.checkValid(textArray)){
submit = true;
}
else {
NotificationManager.error('Please ensure it is an A/P file directly exported from Gifts Online', "There was something wrong with the file", 10000);
submit = false;
}
self.passtoParent(textArray,submit)
}
}
passtoParent(textArray,submitted){
this.props.onFinishSubmit(textArray,submitted)
console.log("Passed props with text array:" + textArray)
console.log("And submitted: " + submitted)
}
render() {
const { classes} = this.props;
return (
<div>
<div>
<NotificationContainer />
</div>
<div className={classes.files}>
<h1>Please upload an A/P file (.txt)</h1>
<Files
ref='files'
className='files-dropzone-list'
style={{ height: '100px' }}
onChange={this.onFilesChange}
onError={this.onFilesError}
accepts={['.txt']}
multiple
maxFiles={1}
maxFileSize={10000000}
minFileSize={0}
clickable
>
Drop files here or click to upload
</Files>
<Button color="danger" onClick={this.filesRemoveAll} round>Remove File</Button>
<Button color="success" onClick={this.filesUpload} round>Submit</Button>
{
this.state.files.length > 0
? <div className='files-list'>
<ul>{this.state.files.map((file) =>
<li className='files-list-item' key={file.id}>
<div className='files-list-item-preview'>
{file.preview.type === 'image'
? <img className='files-list-item-preview-image' alt=""src={file.preview.url} />
: <div className='files-list-item-preview-extension'>{file.extension}</div>}
</div>
<div className='files-list-item-content'>
<div className='files-list-item-content-item files-list-item-content-item-1'>{file.name}</div>
<div className='files-list-item-content-item files-list-item-content-item-2'>{file.sizeReadable}</div>
</div>
<div
id={file.id}
className='files-list-item-remove'
onClick={this.filesRemoveOne.bind(this, file)}
/>
</li>
)}</ul>
</div>
: null
}
</div>
</div>
);
}
}
export default withStyles(basicsStyle)(SectionOpenFile);
const express = require('express')
const app = express()
const port = 3001
var request = require('request');
var keys = require('./keys');
var bodyParser = require('body-parser')
var helper = require('./API-functions.js')
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json())
app.get('/', (request, response) => {
response.send('Hello from Express!')
})
app.get('/test', (request, res) => {
res.send("Server Test works")
})
app.post('/API', (req, res) => {
console.log("Inside API")
var userId = keys.getuserID()
var privateKey = keys.getprivateKey()
// Abort if any of these weren't provided
if (!userId) {
console.log('User ID not provided.');
res.send('User ID not provided.')
return;
}
if (!privateKey) {
console.log('Private key not provided.');
res.send('Private key not provided.')
return;
}
var endPoint = req.body.endPoint
var ids = req.body.ids
var proxyUrl = "http://webdefence.global.blackspider.com:8081"
var proxiedRequest = request.defaults({ 'proxy': proxyUrl })
proxiedRequest.post(
'https://uk.api.microedge.com/auth/token/me-auth',
{ json: { userId: userId, privateKey: privateKey } },
function (error, response, body) {
if (!error && response.statusCode === 200 && body.authenticated) {
var token = body.token;
var options = {
url: 'https://uk.api.microedge.com/goapi/' + endPoint,
method: 'POST',
headers: { 'Authorization': 'bearer ' + token },
json: true,
body: { ids: ids}
};
// use the auth JWT to call the contact endpoint
proxiedRequest(options, function (contactError, response, contactBody) {
if (response.statusCode === 200) {
//Loop for request
var requestsArray = response.body.requests
console.log("Request array:" + requestsArray)
var resultArray = []
for (var i = 0 ; i < requestsArray.length; i++){
var codings = requestsArray[i].codings
var codingResult = helper.processCodings(codings)
resultArray.push(codingResult)
}
console.log(resultArray)
res.send(JSON.stringify(resultArray))
} else {
console.log(response.statusCode)
console.log('There was an error retrieving the contact:');
res.send('There was an error retrieving the contact:')
// console.log(response);
// res.send(response)
}
});
}
}
);
})
app.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err)
}
console.log(`server is listening on ${port}`)
})
// proxiedRequest(options, function (contactError, contactResponse, contactBody) {
// if (contactResponse.statusCode == 200) {
// var contact = contactResponse.body.contact;
// if (contact) {
// console.log('Name of contact: ' + contact.firstName + ' ' + contact.lastName);
// res.send('Name of contact: ' + contact.firstName + ' ' + contact.lastName)
// } else {
// console.log('Contact not found');
// res.send('Contact not found')
// }
// } else {
// console.log('There was an error retrieving the contact:');
// res.send('There was an error retrieving the contact:')
// console.log(contactResponse);
// res.send(contactResponse)
// }
// });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment