Skip to content

Free and easy DIY digital business card

Recently, I wanted to order a new business card for myself and while Googling I came across dozens of startups that produce digital business cards. After checking out several offers, I realized that the most important thing these companies lack is reliability. If you give someone a physical business card, you can be sure that they will know your information for a long time (unless they lose it 🀫). There’s no guarantee that these startups will still be around in 5 or 10 years, or that they won’t raise their fees. That is why I created the serverless-business-card.

I saw a video on YouTube about how to make your business card smart with a simple NFC sticker. The problem is that while you can program a vCard into a sticker, iOS devices don’t support them yet. The only way to get an iPhone to read an NFC vCard is to host the vCard file on the web. Then it hit me. 🀯 Why not host the vCard on AWS using only free tier resources. 😎

The obvious solution was Lambda and Lambda Function URLs since they are completely free. Plus, you can be sure that AWS will still be around in 5 or 10 years, so your digital business card will still be running.
Also, it’s very easy to update your information if something changes, you don’t have to buy a new one. Which is good for the environment too! πŸ‘ 🌎

During development I ran into issues that required creating extra policies to make it work. Since I wanted to make it as simple as possible for everyone to use it I created a CloudFormation template that creates all the resources for you.
And when you no longer need it, CloudFormation can delete all the used resources. But why would you do that when it’s completely free. πŸ€‘πŸ€‘πŸ€‘

The code is written in Node.js 18.x and produces a v. 3.0 vCard. You might ask why not v. 4.0 and the answer is simple. Apple doesn’t support it and I wanted to make it as compatible as possible.
The other problem I faced is that according to the vCard specifications you can link an image URL as your photo, but Apple devices don’t support that either. The photo should be Base64 encoded in your vCard.
That is why CloudFormation creates an S3 bucket where you can store your photo (avatar.jpeg) and the Lambda function will convert it to Base64 and include it in your card.

Not just Apple, AWS has some weird things too. For example, when you create a FunctionURL for your Lambda function, this URL is not defined in your Lambda environment variable. To get the FunctionURL, you need to grant the GetFunctionUrlConfig role to read your function URL. Since a vCard allows you to define the source of the vCard where you can always get the latest version, I had to create a policy and attach it to the Lambda role to include the FunctionURL in the vCard.

The other issue I faced is that while you can include your Lambda code in CloudFormation, it creates an index.js file instead of an index.mjs which is required for Node.js 18.x. There is a solution to include the code in an S3 bucket and CloudFormation will retrieve the code from there, but then you are stuck with the region where your S3 bucket is. So I created two CloudFormation templates. πŸ˜€
If you want the easiest installation and don’t want to change your region, use the default template. This will run in US East (N. Virginia). If you want to host your business card in another region, use the template-with-code.yaml instead, but you will need to rename index.js to index.mjs for the code to work.

All the source code is available on GitHub under the Apache 2.0 license. See the GitHub page for detailed installation information.
Use template.yaml if you don’t want the simplest installation.
If you want to specify the region in which the resources are created, use the template-with-code.yaml stack instead and rename the index.js source file to index.mjs.

I hope this little code is as useful as it was fun to write it. πŸ‘¨β€πŸ’»

Published inTutorial
0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments