A FastAPI backend for a personal planner application with calendar integration capabilities.
Open PowerShell and verify Python is installed:
python --versionYou should see something like Python 3.12.x or
Python 3.11.x
Navigate to your project folder and install the required packages:
cd path\to\plannerNew
python -m pip install -r requirements.txtStart the FastAPI server:
python -m uvicorn main:app --reloadYou should see:
INFO: Uvicorn running on http://127.0.0.1:8000
The API will be available at http://localhost:8000
The /upsert-event endpoint prevents duplicate events by
matching existing events and updating them instead of creating
duplicates.
Step 1: Create "Gym 14–16"
curl -X POST "http://localhost:8000/upsert-event" \
-H "Content-Type: application/json" \
-d '{
"title": "Gym",
"start_time": "2024-01-15T14:00:00+00:00",
"end_time": "2024-01-15T16:00:00+00:00"
}'Step 2: Update to "Gym 14–15" (should update, not duplicate)
curl -X POST "http://localhost:8000/upsert-event" \
-H "Content-Type: application/json" \
-d '{
"title": "Gym",
"start_time": "2024-01-15T14:00:00+00:00",
"end_time": "2024-01-15T15:00:00+00:00"
}'The second call will update the existing event (change end time from 16:00 to 15:00) instead of creating a duplicate event.
The endpoint matches events using:
planner_uid in
extendedProperties.private or descriptionMatching parameters:
match_window_minutes (default: 180) - Time window for
matching eventsallow_title_fuzzy_match (default: true) - Enable
title-based matchingInteractive API documentation is available at:
http://localhost:8000/docshttp://localhost:8000/redocinstalled client with client_id,
client_secret, and the standard Google OAuth endpoints.
Keep this file out of git.Option A: Using Local Development
credentials.json in the
project roottoken.json will be createdrefresh_token value from
token.jsonOption B: Using OAuth Playground
refresh_token from the responseIn your Railway project, go to Variables and add:
production.Procfile and
deploy"GOOGLE_OAUTH_CLIENT_JSON environment variable is required"
ENV=production is setGOOGLE_OAUTH_CLIENT_JSON contains valid JSON
(check for proper escaping)"GOOGLE_REFRESH_TOKEN environment variable is required"
"Failed to refresh token"
For local development, the app uses credentials.json and
token.json files:
credentials.json in the project root (not
committed to git)token.json will be automatically created and used for
subsequent runsNote: Do NOT set ENV=production when
running locally, or the app will expect environment variables instead of
local files.
The API includes a Telegram webhook endpoint at
POST /telegram/webhook for receiving bot updates.
Set these environment variables (for Railway, add them in the Variables section):
After deploying to Railway (or running locally with a public URL), set the webhook URL via the Telegram Bot API:
curl -X POST "https://api.telegram.org/bot<your_bot_token>/setWebhook" \
-d "url=https://<your_railway_url>/telegram/webhook?secret=<your_webhook_secret>"Substitute the three angle-bracketed placeholders with your own
values. <your_webhook_secret> must match the
TELEGRAM_WEBHOOK_SECRET env var.
/start to your bot in Telegram