Skip to content

Instantly share code, notes, and snippets.

@llSourcell
Last active September 27, 2015 05:39
Show Gist options
  • Select an option

  • Save llSourcell/08c34ba5e5967c5069fe to your computer and use it in GitHub Desktop.

Select an option

Save llSourcell/08c34ba5e5967c5069fe to your computer and use it in GitHub Desktop.

#Question 1

#####Overview The following is the index.js file for question 1. The instructions said to create a node.js script to generate a textfile of access_tokens for Jenny, and a bash script to read the access_tokens from the text file, outputting the item ID's associated with New Age Banking. Interestingly, the instructions provided a javascript function to deserialize the access tokens so I'm not sure if bash script was a typo and it meant to say node script? Regardless, I thought it would be equally efficient to do it all in one script, so below is a node.js script that does the following steps

  1. Pulls the clients and items from the sraval-interview.plaid.com server

  2. Sorts through them to match the clients with their respective items.

  3. Serializes each set once its found a client-item match and stores it in the match array

  4. Once all the matches have been found, it writes every access_token in the match array to a textfile called array.txt.

  5. Once array.txt has been written, it will read every line in array.txt and deserialize each access_token to check to see if the client_id matches New Age Banking's client id. If a match is found, it prints it out to the console.

#####Future Optimizations The script works and outputs the intended result, but it could be faster. We're storing all the clients and items in memory, but perhaps a predicated query could be faster and we could bring the local runtime complexity down from what it currently is for matching (O(mn) where m is the number of clients and n is the number of items). The instructions said to take 1-2 hours per question so I will leave it as is for now, but can optimize if needed. Also, tests! The instructions didn't explicitly say to write tests but I did see a test.js script at the bottom. I can write tests if needed.

#####Index.js

var express = require('express');
var router = express.Router();
var request = require("request");
var Db = require('mongodb').Db,
    MongoClient = require('mongodb').MongoClient,
    Server = require('mongodb').Server,
    ReplSetServers = require('mongodb').ReplSetServers,
    ObjectID = require('mongodb').ObjectID,
    Binary = require('mongodb').Binary,
    GridStore = require('mongodb').GridStore,
    Code = require('mongodb').Code,
    fs = require('fs'),
    assert = require('assert');


/* GET home page. */
router.get('/', function(req, res) {
  res.render('index', { title: 'Plaid Test App' });
});

//at the /test endpoint
router.get('/test', function(req, res){
   var db = new Db('platform-interview', new Server("sraval-interview.plaid.com", 27017,
    {auto_reconnect: false, poolSize: 4}), {w:0, native_parser: false});

   // Establish connection to db
   db.open(function(err, db) {
     assert.equal(null, err);

       // Authenticate
       db.authenticate('platform-interviewee', 'plaid', function(err, result) {
         assert.equal(true, result);
		 
		 //Get items
		 db.collection('items', function(err,itemCollection) {
			 itemCollection.find().toArray(function(err,items) {

			    //Get clients
			     db.collection('clients', function(err, clientCollection) {
	 	 		  	    clientCollection.find().toArray(function(err, clients) {
							var access_token_array = findMatches(clients,items)
							//write file
							writeFile(access_token_array)
							//read file
							readFile()
	 				        res.send(clients)
	 			    });
			    });
			 });
		 });
	 });
  });
});


function findMatches(clients, items) {
	var access_token_array = new Array();
	for(var x = 0; x < items.length; x++) {
		for(var y = 0; y < clients.length; y++) {
			if(new String(clients[y]._id).valueOf() == new String(items[x]._client).valueOf()) {
			    var access_token = serialize(clients[y]._id, items[x]._id, items[x].institution_type);
				access_token_array.push(access_token);
			}
		}
	}
	return access_token_array
}

function serialize(client_id, item_id, institution_type) {
  return new Buffer(
    client_id + ',' + item_id + ',' + institution_type,
    'utf8'
  ).toString('base64');
};


function writeFile(access_token_array) {
	//write file
	var file = fs.createWriteStream('array.txt');
	file.on('error', function(err) { /* error handling */ });
	access_token_array.forEach(function(v) { file.write(v+ '\n'); });
	file.end();
}

function readFile() {
	//read file
	var input = fs.createReadStream('array.txt');
	readLines(input, func);
}


function deserialize(string) {
  return new Buffer(string, 'base64').toString('utf8');
};

function readLines(input, func) {
  var remaining = '';

  input.on('data', function(data) {
    remaining += data;
    var index = remaining.indexOf('\n');
    while (index > -1) {
      var line = remaining.substring(0, index);
      remaining = remaining.substring(index + 1);
      func(line);
      index = remaining.indexOf('\n');
    }
  });

  input.on('end', function() {
    if (remaining.length > 0) {
      func(remaining);
    }
  });
}

//55f7076079cebe83d0b3cffd is the client id of New Age Banking
function func(data) {
	var deserialized = deserialize(data)
	var arr = deserialized.split(',');
	var client_id = String(arr[0])
	var myString = "55f7076079cebe83d0b3d002"
     console.log('')
	if(client_id.localeCompare(myString) == 0) {
    	  console.log('Item ID associated with New Age Banking: ' + arr[1]);
	}
		
}



module.exports = router;

#Question 2

#####Request one:

Hi Support,

I'm trying to get up-and-running with the API. I'm using the Go library but have been getting a weird HTTP 402 response code that I don't understand. Everything looks right to me and I've read through the docs.

Here's my code:
client := plaid.NewClient("test_id", "test_secret", plaid.Tartan)

// POST /auth
postRes, mfaRes, err := client.AuthAddUser("plaid_test", "plaid_good", "", "amex", nil)
if err != nil {
    fmt.Println(err)
} else if mfaRes != nil {
    fmt.Println("MFA received");
} else {
    fmt.Println(postRes.Accounts)
}

What am I doing wrong??

My Reply:

Hey there!

I'm really sorry to hear that you were having trouble using our Go library. Upon closer inspection, this line seems to be the source of the error.

	postRes, mfaRes, err := client.AuthAddUser("plaid_test", "plaid_good", "", "amex", nil)

This function is using the /auth endpoint to add a user to your Plaid client. The bank type parameter is amex (American Express) and the error code is essentially saying that the product isn't available for this institution. What this means is that /auth as a product is not yet available for 'amex'. You can see the products that are available for amex by checking out this link

https://tartan.plaid.com/institutions/5301a9d704977c52b60000db

According to the products field in the link, amex currently has 2 products enabled; connect and balance. The balance endpoint helps you check the balance of your account.

https://plaid.com/docs/#balance

The /connect endpoint acts as an alternative to the /auth endpoint and works with 'amex'.

https://plaid.com/docs/#add-user

To implement this change simply replace the problem line I mentioned with this line and use the same parameters.

    postRes, mfaRes, err := client.ConnectAddUser("plaid_test", "plaid_good", "", "amex", nil)

That's it! I hope that helps! If you have any other questions, definitely let me know and I'll be happy to help.

Best,

Siraj

#####Request two:

The docs seem to be wrong. I'm trying to add a auth user with the example the docs provide:
curl -G https://api.plaid.com/auth -d client_id=test_id -d secret=test_secret -d type=chase -d username=plaid_test -d password=plaid_good
but I'm getting a code 1000 error. Is there a problem with the API or are the docs just wrong?

My Reply:

Hi,

Thanks for your email and I'm sorry to hear you were having trouble with our docs. The code 1000 error means that you need to add an access_token to the API call. In the production environment, you get the access_token as a response once you add an auth user

https://plaid.com/docs/#add-auth-user

In sandbox mode, as is the case in your code snippet, you can just add the access token like so

curl G https://api.plaid.com/auth -d client_id=test_id -d secret=test_secret -d type=chase -d username=plaid_test -d password=plaid_good access_token=test_chase

The access token should take the form test_'institution' where institution is the type set in the type parameter.

That should do it! Feel free to get back to me with any other questions you might have.

Cheers,

Siraj

#Question 3

I tested the node.js sample app on my own machine and it worked in my browser. I accessed it via 'localhost:8000' and all of the sandbox authentication inputs passed. The question says that Bob has run the program but can't see it in the browser. It also seems to say that http://[YOUR SERVER]-interview.plaid.com resolves to his machine and I could access the program by going to that URL. My best bet is that this is a networking issue relating to the script's APP_PORT.

var server = app.listen(APP_PORT, function () {
  console.log('plaid-link-demo server listening on port ' + String(APP_PORT));
});

I would bet that there is a firewall on his machine that prevents access to the APP_PORT set whenever he booted the app. The solution would be that the port needs to be opened.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment