I now need to setup user authentication so that I can have a mechanism to create a usage limit per user. I also decided I wanted to implement a site wide monthly limit to ensure I do not exceed a predefined budget for costs to call the OpenAI API. It is fairly inexpensive but it is not a good idea to leave a site open to the public (or bots) to spam it with requests with no upper bound. Here is how I went about it.
Step 1: Usage Control Limit
My first task was to set clear usage limits. I aimed for 5,000 calls per month total across all users and per user limits of 25 calls/month & 5 calls/day —reasonable enough without the need for user fees.
Step 2: Meet Clerk
Clerk was my choice for user authentication. It offered all the essentials: user sign-up, sign-in, and even social platform logins like Google and Facebook. A practical and free solution. Similar to setting up OpenAI, I have to first create an account with Clerk and create keys to use it. It also has support for creating a dev and production environment setup in the free tier and several other basic configurations for the experience. The main thing I needed was reading/writing user metadata into the user object. The client-side javascript library they provided for Gatsby appears to have what I need to do the job.
Step 3: Coding the Basics
To integrate Clerk into the webapp I first had to install gatsby-plugin-clerk. After that it was as simple as this render jsx code to get the buttons into my sidebar component.
Step 4: Keeping Track of the User's Usage
Here's the real meat of the operation. With guidance from ChatGPT, I developed code snippets to monitor API calls on a daily and monthly basis. I stored the daily and monthly usage counter on the Clerk user object like this:
Step 5: The Monthly Total Use Check
I set an overall monthly limit of 5,000 API calls for the entire site. I chose MongoDB Atlas as the tech to use to keep track of this given this part couldn't (and shouldn't) use Clerk user data. MongoDB Atlas is a managed service version of Mongo that allowed me to not have to setup GCP compute or storage infrastructure to run Mongo. I am 100% sure GCP has other NoSQL solutions, but I was most comfortable with Mongo so this is the direction i decided to take. I may refactor later to use a GCP native capability just for fun.
This limit check makes the most sense to be done from the GO code on the server-side as a part of the generate-story api call that i created. This would keep a detailed record of every API call. I used the CountDocuments query that MongoDB provides with a filter of a dateCreated range within the current month. Here is that code and it's a straightforward fast query to check usage has exceed my set limit.
There is also a function for inserting a new record after the call but I did not share that here.
And that's the lowdown on how I tackled user authentication and use limits. Pretty fun on as well.