Meeting recording automation platform built for Val Town.
- π€ Send bots to meetings via Recall.ai
- π Calendar automation with custom rules
- πΉ Recording management with transcripts
- π Chorus.ai export integration
- πͺ Webhook handling for real-time updates
-
Copy
val.tsto Val Town- Go to https://val.town
- Create new HTTP Val
- Paste contents of
val.ts
-
Set Environment Variables (in Val Town UI)
RECALLAI_API_KEY=your_key AWS_ACCESS_KEY_ID=your_key AWS_SECRET_ACCESS_KEY=your_secret AWS_STORAGE_BUCKET_NAME=your_bucket JWT_SECRET=your_random_secret -
Create First User (new script Val)
import { sqlite } from "https://esm.town/v/std/sqlite"; const userId = crypto.randomUUID(); const apiToken = crypto.randomUUID(); const now = Date.now(); await sqlite.execute({ sql: `INSERT INTO users (id, email, first_name, last_name, api_token, created_at, updated_at, is_active) VALUES (?, ?, ?, ?, ?, ?, ?, 1)`, args: [userId, "admin@example.com", "Admin", "User", apiToken, now, now], }); console.log(`API Token: ${apiToken}`); -
Test
curl -H "Authorization: Token YOUR_TOKEN" \ https://yourname-yourval.web.val.run/api/recordings
# Copy environment template (optional - works without .env) cp .env.example .env # Edit .env with your credentials (optional) nano .env # Run the server deno run --allow-net --allow-read --allow-env --allow-write val.ts # Server runs on http://localhost:8000 # Creates local.db file for SQLite database # Automatically creates a default user and prints the API token
Note: When running locally, a default user with a random API token is automatically created on first startup. The token is displayed in the console output. You can also:
- Visit
http://localhost:8000/in your browser to register/login via the web UI - Get your API token from the dashboard after logging in
Visit the root URL in your browser to access the web interface:
- Login/Register: Create an account or log in with existing credentials
- Dashboard: View your API token after logging in
- Copy Token: Use the displayed token for API authentication
- Webhook Logs: View all incoming webhook requests at
/webhooks(requires login)- See headers, body, method, and timestamp for each webhook
- Paginated view (50 per page) in reverse chronological order
- Expandable details with formatted JSON
The web UI provides an easy way to manage your account, retrieve your API token, and monitor webhook activity without using curl or the console.
All endpoints require Authorization: Token <uuid> header (except webhooks and web UI routes).
GET /api/recordings- List recordings (paginated, 50 per page)POST /api/recordings/update- Update recording title
POST /recordings/upload- Create desktop SDK upload (returns upload_token for video upload)POST /recordings/send_bot- Send bot to meetingPOST /recordings/:id/refresh_status- Refresh recording statusPOST /recordings/:id/create_clip- Create clip from recording
GET /api/calendars/preferences- Get calendar automation preferencesPOST /api/calendars/preferences- Update calendar automation preferencesGET /api/calendars/events- List calendar events (with tab filter)GET /api/desktop-calendars/events- List calendar events for desktop (14-day window)POST /api/calendars/events/update- Update calendar event settingsPOST /api/calendars/events/sync_status- Get sync status for multiple events
POST /api/heartbeat- Update heartbeat timestamp
POST /webhooks/recall- Recall.ai webhook handler (no auth required, logged to database)POST /webhooks/*- Generic webhook handler (accepts any path, logs to database)GET /webhooks/*- Generic GET webhook handler (logs query params)GET /webhooks- View webhook logs UI (requires login)
curl -X POST http://localhost:8000/recordings/send_bot \ -H "Authorization: Token YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "meeting_url": "https://zoom.us/j/123456789", "title": "Customer Call" }'
curl -X POST http://localhost:8000/recordings/upload \ -H "Authorization: Token YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "My Recording", "recording_config": {} }'
Response includes upload_token for uploading video data to Recall.ai:
{ "id": "upload-id", "recording_id": "recording-id", "upload_token": "token-for-upload", ... }
curl -H "Authorization: Token YOUR_TOKEN" \ http://localhost:8000/api/recordings
# POST webhook curl -X POST http://localhost:8000/webhooks/test \ -H "Content-Type: application/json" \ -d '{"event": "test", "data": {"foo": "bar"}}' # GET webhook curl "http://localhost:8000/webhooks/test?event=test&foo=bar"
Then view the logged webhooks at http://localhost:8000/webhooks (after logging in).
Val Town's built-in SQLite:
users- User accountsrecordings- Meeting recordingsclips- Video clipscalendar_events- Calendar datacalendar_preferences- Automation ruleswebhook_logs- Incoming webhook requests (with headers and body as JSON)
Schema auto-initializes on startup.
Required:
RECALLAI_API_KEYAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_STORAGE_BUCKET_NAMEJWT_SECRET
Optional:
RECALLAI_API_BASEZOOM_CLIENT_IDZOOM_CLIENT_SECRETGOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETCHORUS_API_KEYPORT(local only, default: 8000)
val.ts- Complete applicationAGENTS.md- AI assistant instructions.env.example- Environment templateREADME.md- This file
- Val Town: https://val.town
- Recall.ai: https://docs.recall.ai