• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
kvey

kvey

oatmeal

Public
Like
oatmeal
Home
Code
12
.env.example
.vtignore
AGENTS.md
README.md
api-routes.ts
database.ts
middleware.ts
routes.ts
services.ts
ui-routes.ts
utils.ts
H
val.ts
Branches
1
Pull requests
Remixes
History
Environment variables
3
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
Code
/
Search
val.ts
https://kvey--bc2a0158c72411f09f1d42dde27851f2.web.val.run
README.md

Oatmeal for Val Town

Meeting recording automation platform built for Val Town.

Features

  • πŸ€– 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

Deploy to Val Town

  1. Copy val.ts to Val Town

    • Go to https://val.town
    • Create new HTTP Val
    • Paste contents of val.ts
  2. 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
    
  3. 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}`);
  4. Test

    curl -H "Authorization: Token YOUR_TOKEN" \ https://yourname-yourval.web.val.run/api/recordings

Run Locally with Deno

# 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

Web UI

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.

API Endpoints

All endpoints require Authorization: Token <uuid> header (except webhooks and web UI routes).

Recordings (API)

  • GET /api/recordings - List recordings (paginated, 50 per page)
  • POST /api/recordings/update - Update recording title

Recordings (Actions)

  • POST /recordings/upload - Create desktop SDK upload (returns upload_token for video upload)
  • POST /recordings/send_bot - Send bot to meeting
  • POST /recordings/:id/refresh_status - Refresh recording status
  • POST /recordings/:id/create_clip - Create clip from recording

Calendar

  • GET /api/calendars/preferences - Get calendar automation preferences
  • POST /api/calendars/preferences - Update calendar automation preferences
  • GET /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 settings
  • POST /api/calendars/events/sync_status - Get sync status for multiple events

Users

  • POST /api/heartbeat - Update heartbeat timestamp

Webhooks

  • 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)

API Examples

Send Bot to Meeting

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" }'

Create Desktop SDK Upload

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", ... }

List Recordings

curl -H "Authorization: Token YOUR_TOKEN" \ http://localhost:8000/api/recordings

Send Webhook (for testing)

# 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).

Database

Val Town's built-in SQLite:

  • users - User accounts
  • recordings - Meeting recordings
  • clips - Video clips
  • calendar_events - Calendar data
  • calendar_preferences - Automation rules
  • webhook_logs - Incoming webhook requests (with headers and body as JSON)

Schema auto-initializes on startup.

Environment Variables

Required:

  • RECALLAI_API_KEY
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_STORAGE_BUCKET_NAME
  • JWT_SECRET

Optional:

  • RECALLAI_API_BASE
  • ZOOM_CLIENT_ID
  • ZOOM_CLIENT_SECRET
  • GOOGLE_CLIENT_ID
  • GOOGLE_CLIENT_SECRET
  • CHORUS_API_KEY
  • PORT (local only, default: 8000)

Files

  • val.ts - Complete application
  • AGENTS.md - AI assistant instructions
  • .env.example - Environment template
  • README.md - This file

Support

  • Val Town: https://val.town
  • Recall.ai: https://docs.recall.ai
HTTP
  • val.ts
    kvey--bc…f2.web.val.run
Code
.env.example.vtignoreAGENTS.mdREADME.mdapi-routes.tsdatabase.tsmiddleware.tsroutes.tsservices.tsui-routes.tsutils.ts
H
val.ts
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
Β© 2025 Val Town, Inc.