Dropbox and TrueFace.ai Facial Recognition Security System [TUTORIAL]

Alex Walling
The Era of APIs
Published in
8 min readAug 29, 2017

Office security is always a concern that needs to be properly addressed, especially for tech companies. But there aren’t a lot of great solutions out there. Key cards are easy to lose. Fobs can be lost or stolen as well. Enter the power of APIs!

This past week, I built an office security system using facial recognition. A facial recognition office security system means one less thing to bring with you every day! I also added a Dropbox integration so anyone on the team could easily add new hires to the system.

I present to you the Dropbox and TrueFace.ai Facial Recognition Security System. Let’s get started building yours!

Step 1: Connect to the Dropbox API

For this tutorial, you’ll use the Dropbox API for file management of a facial recognition security system.

Do the following to get the credentials to connect the Dropbox API:

1a. Create an account on Dropbox if you don’t already have one

1b. Create an application on the Developer App Console

1c. Grab your API secret, API Key and generated access token.

Then, add all three of these as variables to your program.

Pro Tip: If you set these up as environment variables, you don’t have to worry about accidentally sharing your API keys to the world when you upload your project to GitHub.

Step 2: Add Dropbox Webhooks to Your Application

The best part about using RapidAPI Webhooks to connect to Dropbox is that you receive the webhook events through a direct SSL socket from RapidAPI. This means that you can now test your webhook integration on localhost, while also automatically gaining added speed and security. You can learn more about RapidAPI Webhooks in our docs.

Unlike other API webhooks, Dropbox provides very little hard data with the webhook event. Instead, the webhook’s primary purpose is to alert your program that something has changed. Then, it is your job to use other API calls to determine what exactly has changed. This means that the code for the webhook is very simple. All you need to do is listen for the webhook and then, when the webhooks occurs, check if an image upload has been made.

rapid.listen('Dropbox', 'webhookEvent', { 
'token': process.env.RAPIDAPI_TOKEN
})
.on('join', () => {

})
.on('message', (message) => {
checkForUpload();
})
.on('error', (error) => {
console.log(error);
})
.on('close', (reason) => {

});

This code may seem simple, and it is, but the beauty of it is that we can now handle checking if an image only when we know a Dropbox webhook event has occured.

Step 3: Check if an Image Has Been Uploaded

Now that you know a webhook event has occurred, you will need to confirm that a file has been uploaded to a Dropbox folder. Let’s use a folder called /office-employee-image-upload-folder to upload all of the employee images to.

With the folder you’ve created, you will need to track when files are changed. The way Dropbox allows you to do this is by using a cursor. A cursor is a string that is used to keep track of your current folder state. When a cursor is saved, it can then be used to retrieve delta entries that have been recorded since the cursor was originally saved. To save the cursor when your program is first started, call the getFolderContents function:

rapid.call('Dropbox', 'getFolderContents', { 
'accessToken': process.env.RAPIDAPI_TOKEN,
'folderPath': '/office-employee-image-upload-folder'
}).on('success', (payload)=>{
cursor = payload[0].cursor;
files = payload[0].entries;
}).on('error', (payload)=>{
console.log(payload);
});

With the cursor of the folder saved, you will need another function that uses the cursor to check if delta entries have been recorded. I’m going to call this function checkForUpload, which will be called anytime a webhook event occurs.

Within your checkForUpload function, call paginateFolderContents. This function, when given a cursor, will return delta entries that have been recorded. The information returned will allow you to go through all of the newly uploaded files. Use these newly uploaded files to check if the employee is already in the system and handle their images accordingly. I’ve opted to use an array to keep track of the employees currently in the system. Based on if they’re in the system already, you will either create a new enrollment or update an existing enrollment. You can look at the logic in my code below:

function checkForUpload(){
rapid.call('Dropbox', 'paginateFolderContents', {
'accessToken': process.env.RAPIDAPI_TOKEN,
'cursor': cursor
}).on('success', (payload)=>{
files = payload[0].entries;
if(files.length > 0){
for(let i = 0; i < files.length; i++){
if(files[i]['.tag'] == 'file'){
path = files[i].path_lower
filename = path.replace(/^.*[\\\/]/, '');
// file name -> employee name
ind = filename.indexOf('-');
name = filename.substring(0, ind);
if(!employee_names.includes(name)){
console.log("ENROLL");
downloadFile(path).then(res => {
let id = enroll_employee(filename, name);
}).catch(res => {
console.log(res);
});
} else {
downloadFile(path).then(res => {
let employee_id = employee_ids[employee_names.indexOf(name)];
update_employee(filename, employee_id);
}).catch(res => {
console.log(res);
});
}
}
}
}

}).on('error', (payload)=>{
/*YOUR CODE GOES HERE*/
});
}

One thing you might be wondering is, what if there are files in the folder before you ever start your program? This is a great edge case of your program! To handle this instance, instead of calling paginateFolderContents, when you call getFolderContents at the start of your program, you use the same logic to process the images that were already uploaded. This logic allows you to go through all of the files already in the Dropbox folder and create the enrollments for each employee. This functionality is especially important. If your program crashes, you can just restart the program and you won’t have to re-upload images for each employee.

Step 4: Download the Dropbox Images

In order to use the images with TrueFace.ai, you need to first download the files. There might be a more efficient way to pipe the image data directly to the TrueFace.ai API call, but for now this is how I was able to get it working. If you have a good way of taking the image information from Dropbox and directly call the TrueFace.ai API without downloading, comment your solution down below!

To download the files, copy the downloadFile code snippet from RapidAPI along with downloading the fs npm package:

function downloadFile(path_to_file){
return new Promise((resolve, reject) => {
rapid.call('Dropbox', 'downloadFile', {
'accessToken': process.env.RAPIDAPI_TOKEN,
'filePath': path_to_file
}).on('success', (payload)=>{
let filename = path_to_file.replace(/^.*[\\\/]/, '');
let file = fs.createWriteStream(filename);
let request = https.get(payload.file, function(response) {
response.pipe(file);
});
getCursor();
file.on('finish', function() {
resolve('success');
});
}).on('error', (payload)=>{
reject(‘it didn’t work’);
});
});
}

Step 5: Connect to the TrueFace.ai API

Now that you have set up the file management system, the next step is to add TrueFace.ai. I’ve decided to use TrueFace.ai as the facial recognition API because if has a feature called Spoof Detection. This feature helps make the recognition more secure, and you can learn more about it in step 7!

To get started withTrueFace.ai, first select a pricing plan.

TrueFace.ai Pricing Page

The BASIC plan allows you to make 5,000 TrueFace.ai API calls a month for free. However, you will be charged an overage for any calls that you make over this quota. RapidAPI will email you when you have reached 85% and 100% of your quota. Should you need to make more that 5,000 calls you can select the PRO or ULTRA plans, but for building and testing your application, we recommend the BASIC plan.

Step 6: Create and Update Employee Enrollments

When an image is uploaded, you have two options to process it:

  1. If it is the first time an image has been uploaded for an employee, you will need to create a new enrollment for them.
  2. If an employee has already had an image uploaded, you’ll just need to update their existing enrollment.

Scenario 1: Create new employee enrollment
The first scenario, of creating an employee enrollment, is achieved by using the Enroll function. This is what the code looks like:

function enroll_employee(img_path, employee_name){
console.log('ENROLLING: ' + employee_name);
console.log('IMG PATH: ' + img_path);
let employee_id;
unirest.post("https://trueface.p.mashape.com/enroll")
.header("X-Mashape-Key", process.env.MASHAPE_TOKEN_2)
.attach("img0", fs.createReadStream(img_path))
.field("name", employee_name)
.end(function (result) {
console.log(result.status, result.headers, result.body);
employee_id = result.body.data.enrollment_id;
if(result.body.data.enrollment_id == 'enrollment processed successfully'){
employee_names.push(employee_name);
employee_ids.push(employee_id);
}
});
}

Scenario 2: Update an existing enrollment
When an image of an existing employee is uploaded, just use the Update Enrollment to update the employee’s enrollment like so:

function update_employee(img_path, employee_id){
console.log('UPDATING: ' + employee_id);
console.log('IMG PATH: ' + img_path);
unirest.put("https://trueface.p.mashape.com/enroll")
.header("X-Mashape-Key", process.env.MASHAPE_TOKEN_2)
.field("enrollment_id", employee_id)
.attach("img0", fs.createReadStream(img_path))
.end(function (result) {
console.log(result.status, result.headers, result.body);
});
}

Step 7: Update the Collection of Employees

To create a security system that is able to identify a face, you will need to have a collection of employee enrollments. To do this, you’ll need to create a collection when your program is started by calling the Create Collection function:

unirest.post("https://trueface.p.mashape.com/collection")
.header("X-Mashape-Key", process.env.MASHAPE_TOKEN_2)
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Accept", "application/json")
.send("name=Office Employees")
.end(function (result) {
console.log(result.status, result.headers, result.body);
collection = result.headers.data.collection;
});

Any time an employee is added or updated, you’ll also need to update the collection to include them in your Office Employee collection. Create a function called update_collection, that is passed the collection_id along with the enrollment_id of the employee you want to add or update. Your update_collection function will make use of the TrueFace.ai Update Collection function.

function update_collection(collection_id, enrollment_id){
unirest.put("https://trueface.p.mashape.com/collection")
.header("X-Mashape-Key", process.env.MASHAPE_TOKEN_2)
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Accept", "application/json")
.send("collection_id="+collection_id)
.send("enrollment_id="+enrollment_id)
.end(function (result) {
console.log(result.status, result.headers, result.body);
});
}

Step 8: Identify Employees & Spoof Detection

The only thing left to do from here is to get the hardware and connect it with this program. When the hardware has seen a person and taken a picture, you can call an identify function with a path to the picture taken. Here’s the code on how to do that:

function identify(path_to_file){
unirest.post("https://trueface.p.mashape.com/spdetect")
.header("X-Mashape-Key", "kkLAE9tdKfmshARl9UVANBrYk4RKp1xDfWFjsnimWVdTYzp6HS")
.header("Content-Type", "multipart/form-data")
.attach("img", fs.createReadStream(path_to_file))
.end(function (result) {
console.log(result.status, result.headers, result.body);
if(result.headers.data.class == 'real'){
unirest.post("https://trueface.p.mashape.com/identify")
.header("X-Mashape-Key", "kkLAE9tdKfmshARl9UVANBrYk4RKp1xDfWFjsnimWVdTYzp6HS")
.field("collection_id", collection)
.attach("img", fs.createReadStream(path_to_file))
.end(function (result) {
console.log(result.status, result.headers, result.body);
console.log(result.headers.data.name);
return true;
});
} else {
return false;
}
});
}

The identify function you created uses both the Spoof Detection function and the Identify function from TrueFace.ai.

You might be wondering, what is a spoof? A spoof is when someone is trying to use a picture of an employee to break into the office. This is the feature of TrueFace.ai that helps make it more secure to use. With TrueFace.ai, holding up a picture of an employee won’t be accepted for entry to the building.

What is spoof detection?

After determining if the face is a spoof or not, then you can check if it is part of the office employee collection. If this person is part of the collection, then you return true and the security system hardware will open the door.

Conclusion

Through the power of APIs, you now have a security system which doesn’t require key cards or a fob! All you have to make sure you bring with you to work is your face to scan into the building.

If you’re interested in learning more about security solutions with APIs, we’ve got some great security APIs on the marketplace like Eversign, Common Passwords, and other facial recognition APIs!

Comment down below what you thought of the Dropbox and TrueFace.ai APIs being used together for a security system.

--

--

Alex Walling
The Era of APIs

Current: Field CTO RapidAPI. Former: Head of Sales Engineering & Developer Relations RapidAPI, Founder of HackCU. Part-time adventurer, full-time hooligan