Implementing Contact Me
November 21, 2024
I’m reachable!
I recently added a contact me to my website. This involves two separate pieces of functionality, a way to get in touch via email, and a way to book time with me. Here’s how I implemented these features.
Functionality
I started with figuring out what functionality I wanted.
For get in touch, I wanted an easy way for people to email me. I didn’t want to implement the simple href='mailto'
because I find that an annoying experience. So I decided I wanted an in page form.
For book time with me, I wanted just a simple calendar that I could customize slightly, and that I could adjust availability times.
Email me
This is a gatsby site, and has no server, so what do I have that can handle the form? If I was still on Netlify, they have a form handler, but I am not. I switched from Netlify to Cloudflare.
Website changes
I implemented the contact me form, and tried to style it similarly to the rest of the site. I also added reasonable maxLength, and used html email field for validation. I then added some new error pages, and a success page, all because this is the first interactive part of my site.
First decision - Cloudflare worker
I decided to implement a cloudflare worker to receive the form information from my gatsby side. This part was fun. I had to figure out wrangler, and built an initial working solution using their docs. It was very MVP at this point but worked well enough to test full functionality.
I made certain to add a very simple rate limit functionality, and also synced up the worker to the error pages that I have on the site. This way the user is informed if something goes wrong, whether it’s rate limit, server error or they may be doing something to mis-use the site.
First pass solution
Originally I thought I wanted to send an actual email to myself. In the cloudflare worker, I must use some functionality to send an email to a new email address I created. I created a new email address for my domain on MXroute since I am already using MXroute.
But… Email seems to always be difficult. I ended up using Twilio sendgrid for email sending, since I already had a twilio account for some text message work I did previously. It properly send out the email. But, I never got it into my MXroute account. Why? MXroute blocks a bunch of sendgrid servers because they are known for spam. MXroute is very protective of their service, so I have no complaints about this behavior. But, I needed a different solution.
Second and final solution
Why did I want an email to myself? How about if I just store the information in a table and then use some other mechanism to let me know a new contact form was received?
I researched quite a few online table services. I was looking for generous free tier, ease of use, and market acceptance. There were quite a few really good options, but I settled on Airtable because I figured some experience with this well known product could only benefit me. I defined my Airtable table, and got a table address and access token so I could write new rows to the table. And, they have an awesome Automation triggering service, so I could notify myself, ironically via email, when there is a new entry to the table.
Time to test! And… the first test failed. I had forgotten all those secrets I needed the Cloudflare worker to know, mostly about the Airtable connection. Once I updated the worker to have those secrets, I had a full working solution.
Summary of contact me
Form data -> cloudflare worker -> Airtable -> Automation to email to me
Book time with me
This solution was easier. I went with zcal because I know someone who uses them, and their free tier seemed like enough. I embedded the calendar in my site, and was able to customize it with my photo. I can also customize my availability, meeting length, booking message, link to google calendar, etc. When a new booking is created, I get notified by zcal.
It’s done!
I know there are many ways to implement this, some easier than others. This was a fun addition to my website, with some minor technical challenge and decision making.