I'm not a believer in astrology in the slightest, but I've long been fascinated by it as a coder. When I was a kid just learning to code for the first time, a friend of the family was a professional astrologer, writing the horoscopes for a well known weekly women's magazine in the UK. Contrary to popular belief, he didn't just make them up, but actually carefully calculated the current celestial map using ephemeris software, which he then interpreted. I was fascinated with the charts that he'd noisily print off on the his dot matrix printer. Fast forward to today and this intersection of highly specific calculations and fantastical storytelling seems like a perfect candidate for a custom GPT using the OpenAI GPT API. In this post I'm going to show how to build an ephemeris API, and a custom GPT that uses it for a custom action. I'll also show how to use instructions to give responses in the proper astrological style.
If you have ChatGPT Plus, you can try the end result in ChatGPT. See the finished code for the API in GitHub.
To perform their readings, astrologers use an ephemeris to show the locations of all of the celestial bodies visible in the sky at a certain time and place. These used to be huge tables of pre-calculated coordinates, but even in the 1980s they were computerised. Today they can be easily calculated with any of many libraries. We can create an Action to provide this data to the GPT.
I'm going to create a Netlify Edge Function for this, because I like the API and it can give quick responses close to the OpenAI server. I'm using the Moshier ephemeris library because it doesn't need pregenerated data and performs all of the calculations locally. Netlify Edge Functions are based on Deno, so we can load it directly from a URL import using esm.sh:
// netlify/edge-functions/ephemeris.ts
import Ephemeris from "https://esm.sh/gh/0xStarcat/Moshier-Ephemeris-JS/src/Ephemeris.js";
export default async function handler(request: Request) {
// do stuff
}
export const config = {
path: "/ephemeris",
};
To get the ephemeris results, we need the location, date and time, so we'll these in the request. The ephemeris library needs the date and time parts to be passed in individually, so we'll parse the datetime string and then extract these values. If the user doesn't pass in the date then we will default to now.
export default async function handler(req: Request) {
const url = new URL(req.url);
const datetimeString = url.searchParams.get("datetime");
const latitude = parseFloat(url.searchParams.get("latitude")!);
const longitude = parseFloat(url.searchParams.get("longitude")!);
if (isNaN(latitude) || isNaN(longitude)) {
return new Response("Invalid parameters", { status: 400 });
}
const datetime = datetimeString ? new Date(datetimeString) : new Date();
const year = datetime.getUTCFullYear();
const month = datetime.getUTCMonth();
const day = datetime.getUTCDate();
const hours = datetime.getUTCHours();
const minutes = datetime.getUTCMinutes();
By default, the ephemeris library returns values for all of the celestial bodies that it knows about, but we can let ChatGPT choose the ones it's interested in, while defaulting to returning all of them:
const ALL_BODIES = [
"mercury",
"venus",
"mars",
"jupiter",
"saturn",
"uranus",
"neptune",
"pluto",
"sun",
"moon",
"chiron",
];
export default async function handler(req: Request) {
const url = new URL(req.url);
let celestialBodies = url.searchParams.get("bodies")?.split(",");
if (!celestialBodies || celestialBodies.length === 0) {
celestialBodies = ALL_BODIES;
}
Now we have all of the details we need, we can pass these to the library and return the results:
const ephemeris = new Ephemeris({
year,
month,
day,
hours,
minutes,
latitude,
longitude,
calculateShadows: false,
});
const results: Record<string, unknown> = {};
for (const body of celestialBodies) {
if (ephemeris[body]) {
results[body] = ephemeris[body].position;
} else {
results[body] = "Celestial body not found";
}
}
return Response.json(results);
This gives us the data we need, and returns it. See the full code here.
Creating a repo with just that file is enough to deploy to Netlify, but I've added a static index.html
file too, as well as a privacy policy because we'll need that later. Thanks ChatGPT for both. You can deploy your own copy by clicking this:
We're almost ready to start creating the custom GPT. To register an API as an action for a GPT, we need an OpenAPI spec for it. These are really verbose an annoying to write, so I usually just ask ChatGPT to do it for me. There's no need to go into detail typing the full response - ChatGPT can work it out for itself. You can see what we generated here. I've deployed it as part of the site, but that's not needed. Remember to change the URL to that of your own site!
Now we're ready to go. Let's create a GPT. Go to https://chat.openai.com/gpts/editor to start. You can find it linked from "Explore" in the ChatGPT sidebar.
The editor is quite simple to use, because it does most things for you via the chat interface. However, we should start by defining the Action. Click on "Configure", then scroll down to the bottomn, enable "Code Interpreter", the click "Create new action".
You then need to define your schema. If you deployed it earlier then you can just choose "import from URL". Otherwise paste it in. You might get an error message - if so, just share it with the ChatGPT session where you created the schema and it should fix it for you.
If you get no errors, then you can click on "Test" to try it out.
Now we get to the fun bit. Go back to the "Create" tab and just tell it what you want. You should include all sorts of detail, including the tone for the responses and how exactly to use the APIs.
ChatGPT will then use this to customise the GPT. That prompt gave these results:
You can try this out, and adjust the details as you wish. You can ask for a profile pic. As long as you included the privacy policy when creating the action, you can then publish your GPT. Enjoy! Try it out here
Top comments (3)
HI Mark, this is most awesome free resource. Then I went to see how it was working with astro gpt you have created and it is not giving accurate planetary positions. I practice astrology for a long time and I have used it for few birth charts that are well know to me. Would there be an easy way to fix this cause and I will pay for your work on this. Please let me know, as I need to get my astrology gpt going very soon. Just for the case I dont see your reply here, contact me via stella_star@live.com. Thanks, and all the best
I love
Do you have an extra ChatGPT plus account?