-
-
Save mfrancois3k/2ffe3af25e58450e8db26ca256159438 to your computer and use it in GitHub Desktop.
BlackBaud API exploration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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