Business cards, those little cards with your contact information. I remember when I got my first box, I felt like a complete office professional! Giving and receiving them was a stringent ritual. I even had business card holders and organizers. But that was a long time ago. Do people still use those?!?
Well, apparently they still do. Yesterday, I got a big stack from my wife from her Singapore trip and she asked if I can encode the data into a spreadsheet. So me being me, instead of spending some time encoding, I spent a bit more time coding.
Writing a business card reader can be tedious. You need to have do optical character recognition (OCR) then identify text patterns for names, title, phones, emails, etc and extract them. But thankfully, technology and especially AI has come a long way and we can use widely available AI engines such as OpenAI’s to make the job easier… unbelievably easier.
In this post, we’ll go through the whole thing from start to finish.
Part 1. Setting Up Your OpenAI Account
The first thing you need to do, if you haven’t already, is to set up your OpenAI account.
Step 1. Sign up with OpenAI https://platform.openai.com/signup
Step 2. Set up payment
The OpenAI API is not free and to utilize the API, you need credits. Unlike before, OpenAI is no longer giving free trial credits. So you need to set up a payment method to buy credits. Go to Settings->Billing->Payment methods->Add payment Method and add your credit card.
Step 3. Buy credits
From Billing, choose Overview->Add to credit balance.
Don’t worry, $10 dollar can go a long way in helping you learn the OpenAI API.
Part 2: Creating Your API key
You will need an API key for your code to access the API. You can create one for each project. Or you can use one for all your projects.
Step 1. Create your API key
Go to Dashboard->API keys->Create new secret key
Step 2. Save your key
Put it somewhere safe and accessible or add to your .bashrc or .zshrc file.
export OPENAI_API_KEY="your_api_key_here"
Step 3. Export the key
If you’ve saved it on .bashrc
$ source .bashrc
or if you’ve saved it on .zshrc
% source .zshrc
or just run the export command from your shell prompt.
$ export OPENAI_API_KEY="your_api_key_here"
Part 3: The Data
They often say GIGO: garbage in, garbage out. So for best results, the data you’re going to feed your AI needs to be good. I got the stack of business cards and scanned them one by one using Microsoft Lens. You can, of course, use your favorite scanning app. What’s important is you got good lighting and a steady hand. Put all the files in one folder, e.g. images.
Part 4: The Code
Now for the fun part. The idea is pretty simple:
1. Get the folder containing the business card image files.
2. Go through each file in the folder
2.1. Check if the file is an image and if so send to ChatGPT with the prompt "identify the contact's name, title, email address, mobile/phone number, company name, industry, and website and output in a comma-delimited string" You can tweak the prompt to get the results you want
2.2. Append the result from ChatGPT to a CSV file named contacts.csv
For simplicity, I’ll assume you already have node and npm set up. If not, you can find the info here and here.
Step 1. Create a new directory
$ mkdir business-card-scanner $ cd business-card-scanner
Step 2. Initialize a new node.js project
$ npm init -y
Step 3. Install required packages
$ npm install openai fs path
Step 4. Write the code, I called mine processCards.js. Or you can get it on GitHub.
// Import required packages
const OpenAI = require("openai");
const fs = require("fs").promises;
const path = require("path");
// Instantiate OpenAI with API secret key
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
// Check if file is an image
function isImageFile(filePath) {
const ext = path.extname(filePath).toLowerCase();
return ['.jpg', '.jpeg', '.png', '.gif'].includes(ext); // Adjust extensions as needed
}
// Send to ChatGPT
async function processImageFile(filePath) {
try {
// Read the image content as base64 encoded string
const imageBuffer = await fs.readFile(filePath);
const base64Image = Buffer.from(imageBuffer).toString("base64");
// Send the base64 encoded image content to ChatGPT
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{
role: "user",
content: [
{
type: "text",
text: "identify the contact's name, title, email address, phone number, company name, industry, and website and output in a comma-delimited string" },
{
type: "image_url",
image_url:
{
url: "data:image/jpeg;base64,"+base64Image
}
}
],
},
],
});
// console.log(response.choices[0]);
content = response.choices[0].message.content;
console.log(content);
return content;
} catch (error) {
console.error("Error processing image:", error);
}
}
// Append the result from ChatGPT to a CSV file
async function appendToFile(filePath, content) {
try {
await fs.appendFile(filePath, content, 'utf8');
console.log('Content appended successfully!');
} catch (err) {
console.error('Error appending content:', err);
}
}
// Go through each file in the folder
async function processFolder(folderPath) {
try {
const files = await fs.readdir(folderPath);
for (const file of files) {
const filePath = path.join(folderPath, file);
if (isImageFile(filePath)) {
const extractedData = await processImageFile(filePath);
await appendToFile('contacts.csv', extractedData + '\n');
console.log('Processed:', filePath);
} else {
console.warn('Skipping non-image file:', filePath);
}
}
} catch (error) {
console.error('Error processing folder:', error);
}
}
// Get the folder containing the business card image files.
const folderPath = process.argv[2];
if (!folderPath) {
console.error("Please provide a folder path as an argument.");
process.exit(1);
}
processFolder(folderPath);
Step 5. Run the code
Run the code from your shell prompt:
$ node processCards images
If everything works out right, you should have a contacts.csv file that contains the business card information you want to get.
This is just a simple use of the OpenAI API. There are certainly more complex tasks you can do with the API and with AI in general and I hope this post helped you get started exploring.
Thank you for reading!