VAPI Todo System
AI Voice agentic solution integrated with VAPI
Technical Architecture
Overview
VAPI is currently the leading Voice AI agent solution for developers in the market.
This project leverages VAPI to enable users to manage to-do tasks, reminders, and calendar events through natural voice interactions.
Callers can create, update, and delete their tasks, reminders, and events simply by speaking.
All data is stored in a PostgreSQL database and seamlessly integrated with the user’s Google Calendar and Gmail via the Google Calendar API,
ensuring real-time synchronization across platforms.
Core Technologies
- • Flask (Python web framework)
- • SQLAlchemy with shared database instance
- • Pydantic models for request/response validation
- • markdown2 for documentation rendering
- • Blueprint architecture for modular design
Key Features
- • Todo list management
- • Reminder system
- • Calendar event management
- • Google Calendar integration
- • Voice API integration
- • RESTful API endpoints
Module Structure
Shared Components
shared/ ├── google_calendar.py # Google Calendar integration service ├── helpers.py # Shared utility functions └── schemas.py # Pydantic validation schemas
VAPI Todo Components
vapi_todo/ ├── __init__.py # Package initialization, exports blueprint ├── models.py # SQLAlchemy database models ├── routes.py # Flask routes and blueprint definition └── README_vapi.md # Documentation
Data Layer (models.py)
Todo Model
- • id: Primary key
- • title: Task title (indexed)
- • description: Optional task details
- • completed: Boolean status
- • google_calendar_event_id
Reminder Model
- • id: Primary key
- • reminder_text: Reminder content
- • importance: Priority level
- • google_calendar_event_id
CalendarEvent Model
- • id: Primary key
- • title: Event title (indexed)
- • description: Event details
- • event_from: Start datetime
- • event_to: End datetime
- • google_calendar_event_id
API Endpoints
Todo Management
POST /create_todo
POST /get_todos
POST /complete_todo
POST /delete_todo
Reminder Management
POST /add_reminder
POST /get_reminders
POST /delete_reminder
Calendar Management
POST /add_calendar_entry
POST /get_calendar_entries
POST /delete_calendar_entry
Response Format
All API responses follow a consistent structure:
{
"results": [
{
"toolCallId": "string",
"result": "success" | object | array
}
]
}
Google Calendar Integration
The VAPI Todo system integrates with Google Calendar to automatically sync calendar events, todos, and reminders with the user's Google Calendar account.
Authentication
- • OAuth2 authentication with Google Calendar API
- • Requires credentials.json from Google Cloud Console
- • Token-based authentication with automatic refresh
- • Supports desktop application authentication flow
Features
- • Automatic event creation in Google Calendar
- • Real-time synchronization with database
- • Event updates and deletions
- • Timezone-aware datetime handling
Implementation Details
Service Location: shared/google_calendar.py
Main Class: GoogleCalendarService
Global Access: get_calendar_service()
API Methods
- •
create_event()
- Create new calendar event - •
update_event()
- Update existing event - •
delete_event()
- Delete calendar event - •
get_event()
- Retrieve event details
Code Examples
Database Models (models.py)
from extensions import db
from datetime import datetime
class VapiTodo(db.Model):
__tablename__ = 'vapi_todos'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(255), index=True)
description = db.Column(db.Text)
completed = db.Column(db.Boolean, default=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
google_calendar_event_id = db.Column(db.String(255))
class VapiReminder(db.Model):
__tablename__ = 'vapi_reminders'
id = db.Column(db.Integer, primary_key=True)
reminder_text = db.Column(db.String(500))
importance = db.Column(db.String(50))
created_at = db.Column(db.DateTime, default=datetime.utcnow)
google_calendar_event_id = db.Column(db.String(255))
API Routes (routes.py)
from flask import Blueprint, request, jsonify
from shared.helpers import get_validated_tool_call
from .models import VapiTodo, VapiReminder
from shared.schemas import TodoResponse, ReminderResponse
from shared.google_calendar import get_calendar_service
vapi_flask_bp = Blueprint('vapi_todo', __name__, url_prefix='/vapi_todo')
@vapi_flask_bp.route('/create_todo', methods=['POST'])
def create_todo():
tool_call = get_validated_tool_call('createTodo')
args = tool_call.function.arguments
title = args.get('title', '')
description = args.get('description', '')
# Create todo in database
todo = VapiTodo(title=title, description=description)
db.session.add(todo)
db.session.commit()
db.session.refresh(todo)
# Sync with Google Calendar
try:
calendar_service = get_calendar_service()
google_event_id = calendar_service.create_event(
title=f"TODO: {title}",
description=description or "Task from VAPI Todo System"
)
if google_event_id:
todo.google_calendar_event_id = google_event_id
db.session.commit()
except Exception as e:
print(f"Failed to sync with Google Calendar: {e}")
return jsonify({'results': [{'toolCallId': tool_call.id, 'result': 'success'}]})
Shared Components
Helpers (shared/helpers.py)
from flask import request, abort
from pydantic import ValidationError as PydanticValidationError
from .schemas import ToolRequest, ToolCall
def get_validated_tool_call(expected_function_name: str) -> ToolCall:
"""
Validates the incoming JSON request against the ToolRequest schema
and returns the specific tool call matching the expected function name.
"""
json_data = request.get_json()
if not json_data:
abort(400, description="Invalid JSON payload.")
try:
# Validate the entire request structure
tool_req = ToolRequest(**json_data)
except PydanticValidationError as e:
abort(400, description=f"Invalid request format: {e.errors()}")
# Find the specific tool call we are looking for
for tool_call in tool_req.message.toolCalls:
if tool_call.function.name == expected_function_name:
# If arguments are a string, parse them into a dict
if isinstance(tool_call.function.arguments, str):
tool_call.function.arguments = request.json_loads(tool_call.function.arguments)
return tool_call
abort(400, description=f"Tool call with function name '{expected_function_name}' not found.")
Schemas (shared/schemas.py)
import datetime as dt
from typing import Union, Dict, Any
from pydantic import BaseModel, ValidationError as PydanticValidationError
# --- Common Schemas for Tool Calling ---
class ToolCallFunction(BaseModel):
name: str
arguments: Union[str, Dict[str, Any]]
class ToolCall(BaseModel):
id: str
function: ToolCallFunction
class Message(BaseModel):
toolCalls: list[ToolCall]
class ToolRequest(BaseModel):
"""A generic request model for any tool-calling service."""
message: Message
# --- Common Response Schemas ---
class TodoResponse(BaseModel):
id: int
title: str
description: Union[str, None]
completed: bool
model_config = {'from_attributes': True}
class ReminderResponse(BaseModel):
id: int
reminder_text: str
importance: str
model_config = {'from_attributes': True}
class CalendarEventResponse(BaseModel):
id: int
title: str
description: Union[str, None]
event_from: dt.datetime
event_to: dt.datetime
model_config = {'from_attributes': True}
Google Calendar Integration
from shared.google_calendar import get_calendar_service
from datetime import datetime, timedelta
# Create calendar service
calendar_service = get_calendar_service()
# Create event in Google Calendar
google_event_id = calendar_service.create_event(
title=f"Todo: {todo.title}",
description=todo.description or "Task from VAPI Todo System",
start_time=datetime.now(),
end_time=datetime.now() + timedelta(hours=1)
)
# Store Google Calendar event ID
if google_event_id:
todo.google_calendar_event_id = google_event_id
db.session.commit()
VAPI Integration Guide
VAPI Configuration & Deployment
1. VAPI.AI Setup
Start by creating an account if you do not have an account and logging in.
2. Create Tool
Once logged in, go to your dashboard and click on "Create Tool" in Tools/Build of the left panel.
3. Tool Functions
Todo Functions
- • createTodo
- • getTodos
- • completeTodo
- • deleteTodo
Reminder Functions
- • addReminder
- • getReminder
- • deleteReminder
Calendar Functions
- • addCalendarEntry
- • getCalendarEntries
- • deleteCalendarEntry
4. Create Assistant
Model Configuration
- • Provider: OpenAI or preferred
- • Model: GPT 4o Cluster
- • First Message: Customize as needed
Voice & Transcriber
- • Voice Provider: OpenAI
- • Transcriber: Deepgram
- • Language: English
- • Tools: Select created functions
5. Publish
Once creating an assistant and tools, click "published" to make it live.
API Functions Implementation
The Flask API responds to VAPI tool calls with validated requests:
tool_call = _get_validated_tool_call('createTodo')
# Make sure that attribute 'createTodo' name should exactly match
# to 'Create Tool' name in step 3.
Database Requirements
Postgres DB need to be created and db.Model need to be set for each table.
Testing AI Voice Scheduler
Make a call and say "to do list with time and date" to AI assistant
Make a call and ask what "to do lists" exist currently and ask to remind the tasks
Make a call and say that some tasks were completed
Make a call and say that some tasks were deleted
Check whether all test cases have been updated to Database tables
Test Results & Validation
1. Create Todo Functionality
Database Validation

ToDo Task created successfully in todos table
GMail Pop-up

Call Transcript

Voice interaction transcript for todo creation
Voice Recording
Voice call recording for todo creation
2. Add Reminders Functionality
Database Validation

Reminder database entry created
GMail Pop-up

3. Add Calendar Events Functionality
Database Validation

Calendar event database entry
Google Calendar Sync 1

Google Calendar integration
Google Calendar Sync 2

Additional calendar sync view
4. Complete Todo Functionality
Database Validation

Task completion status in database
Call Transcript

Voice interaction for task completion
Voice Recording
Voice call recording for task completion
5. Delete Calendar Event Functionality
Database Validation

Calendar event deletion from database
Call Transcript

Voice interaction for calendar deletion
Google Calendar Sync

One Event deletion from Google Calendar
Voice Recording
Voice call recording for calendar deletion