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

colel

rust-nyc-talk-submissions

https://github.com/colelawrence/rust-nyc-talk-submissions
Public
Like
rust-nyc-talk-submissions
Home
Code
15
.context
4
.github
1
.pi
1
backend
8
docs
3
frontend
3
shared
1
.gitignore
.vtignore
AGENTS.md
BRAND_STYLE_GUIDE.md
README.md
biome.json
deno.json
main.tsx
Environment variables
7
Branches
2
Pull requests
Remixes
1
History
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
/
.context
/
concepts
/
integrations-platform.md
Code
/
.context
/
concepts
/
integrations-platform.md
Search
…
Viewing readonly version of main branch: v157
View latest version
integrations-platform.md

Rust NYC Integrations Platform: "Connect"

Status: PR-Ready Concept
Author: Integration Design Task
Date: 2026-02-06


Executive Summary

Connect is a first-party integrations platform for the Rust NYC Talk Submission System. It provides a unified, secure interface for external tools to access talk data, receive real-time notifications, and export schedulesβ€”enabling organizers to build custom workflows without modifying the core system.


1. Core Primitives

1.1 API Keys

FieldDescription
key_idPublic identifier (prefix: rnc_)
key_hashbcrypt hash of secret portion
nameHuman-readable label
scopesPermission array: ["submissions:read", "webhooks:manage", "exports:create"]
created_byDiscord user ID of creator
expires_atOptional expiration timestamp
last_used_atAudit timestamp

Key format: rnc_live_<24-char-random> (production) / rnc_test_<24-char-random> (test mode)

Schema addition (backend/index.ts, new table):

CREATE TABLE IF NOT EXISTS api_keys_1 ( id INTEGER PRIMARY KEY AUTOINCREMENT, key_id TEXT UNIQUE NOT NULL, key_hash TEXT NOT NULL, name TEXT NOT NULL, scopes TEXT NOT NULL, -- JSON array created_by TEXT NOT NULL, expires_at DATETIME, last_used_at DATETIME, created_at DATETIME DEFAULT CURRENT_TIMESTAMP );

1.2 Webhooks

FieldDescription
idAuto-increment ID
urlHTTPS endpoint (must be TLS)
eventsArray: ["submission.created", "submission.updated", "talk.scheduled"]
secretHMAC-SHA256 signing secret
api_key_idOwning API key
activeBoolean toggle
failure_countConsecutive failures (disable at 10)

Webhook payload structure:

{ "event": "submission.created", "timestamp": "2026-02-06T13:57:40Z", "data": { /* TalkSubmission object */ }, "signature": "sha256=..." }

Schema addition:

CREATE TABLE IF NOT EXISTS webhooks_1 ( id INTEGER PRIMARY KEY AUTOINCREMENT, url TEXT NOT NULL, events TEXT NOT NULL, -- JSON array secret TEXT NOT NULL, api_key_id INTEGER REFERENCES api_keys_1(id), active BOOLEAN DEFAULT true, failure_count INTEGER DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP );

2. API Endpoints

All endpoints require Authorization: Bearer rnc_live_... header.

2.1 Read Operations

EndpointScopeDescription
GET /api/v1/submissionssubmissions:readList all submissions with pagination
GET /api/v1/submissions/:idsubmissions:readGet single submission
GET /api/v1/schedulesubmissions:readGet scheduled talks with dates

2.2 Export Operations

EndpointScopeFormat
GET /api/v1/exports/submissions.csvexports:createCSV download
GET /api/v1/exports/submissions.jsonexports:createJSON array
GET /api/v1/exports/schedule.icsexports:createiCalendar feed

CSV columns: id,speaker_name,talk_context,is_on_behalf,submitter_name,discord_channel_id,created_at,scheduled_date

2.3 Webhook Management

EndpointScopeDescription
POST /api/v1/webhookswebhooks:manageRegister new webhook
GET /api/v1/webhookswebhooks:manageList webhooks
DELETE /api/v1/webhooks/:idwebhooks:manageRemove webhook
POST /api/v1/webhooks/:id/testwebhooks:manageSend test event

3. Example Integrations

3.1 Notion Database Sync

// Zapier/Make webhook handler app.post("/api/webhooks/notion-sync", async (c) => { const payload = await c.req.json(); if (payload.event === "submission.created") { await notionClient.pages.create({ parent: { database_id: NOTION_DB_ID }, properties: { "Speaker": { title: [{ text: { content: payload.data.speaker_name }}] }, "Context": { rich_text: [{ text: { content: payload.data.talk_context }}] }, "Discord": { url: payload.data.discord_invite_link }, "Status": { select: { name: "New" } } } }); } });

3.2 Google Sheets Export

# Cron job or manual trigger curl -H "Authorization: Bearer rnc_live_..." \ "https://rustnyc-talks.val.run/api/v1/exports/submissions.csv" \ | google-sheets-append --spreadsheet-id=... --sheet="Submissions"

3.3 Calendar Integration

<!-- Subscribe to iCal feed --> <a href="webcal://rustnyc-talks.val.run/api/v1/exports/schedule.ics?key=rnc_live_..."> Add to Calendar </a>

3.4 Slack Notification Bot

// Webhook endpoint receives events async function handleWebhook(event: WebhookPayload) { if (event.event === "talk.scheduled") { await slack.chat.postMessage({ channel: "#rust-nyc-talks", text: `πŸ“… "${event.data.speaker_name}" scheduled for ${event.data.scheduled_date}!`, unfurl_links: false }); } }

4. Security Model

4.1 Authentication

  1. API Key validation: Extract from Authorization: Bearer header
  2. Hash verification: Compare bcrypt hash against stored key_hash
  3. Expiration check: Reject if expires_at < NOW()
  4. Scope enforcement: Check required scope for endpoint

4.2 Webhook Security

  1. TLS only: Reject non-HTTPS URLs at registration
  2. HMAC signing: X-Signature: sha256=HMAC(secret, rawBody)
  3. Timestamp header: X-Timestamp for replay protection (5-min window)
  4. Auto-disable: Deactivate webhook after 10 consecutive failures

4.3 Rate Limiting

ScopeLimit
Per API key100 req/min
Webhook deliveries10 req/sec per endpoint
Export endpoints10 req/hour

4.4 Audit Logging

CREATE TABLE IF NOT EXISTS api_audit_log_1 ( id INTEGER PRIMARY KEY AUTOINCREMENT, api_key_id INTEGER, endpoint TEXT NOT NULL, method TEXT NOT NULL, status_code INTEGER, ip_address TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP );

5. Success Metrics

MetricTarget (90 days)Measurement
API keys created10+COUNT in api_keys_1
Webhooks registered5+COUNT in webhooks_1
Export downloads/week20+Audit log COUNT
Webhook delivery success rate>99%Failures / Total
P95 API latency<200msTiming middleware
Integration partners mentioned2+Manual tracking

6. Implementation Phases

Phase 1: Foundation (Week 1)

  • API key table + CRUD endpoints
  • Auth middleware (backend/middleware/auth.ts)
  • Basic GET /api/v1/submissions with API key auth

Phase 2: Exports (Week 2)

  • CSV export endpoint
  • JSON export endpoint
  • iCalendar feed (requires scheduled_date column)

Phase 3: Webhooks (Week 3)

  • Webhook registration endpoints
  • Event dispatch on submission create (backend/index.ts:70-90)
  • Retry logic with exponential backoff
  • Signature verification guide

Phase 4: Polish (Week 4)

  • Rate limiting middleware
  • Audit logging
  • Developer documentation page
  • API key management UI (organizer-only)

7. Type Additions

File: shared/types.ts (add after line 24)

// --- Integrations Platform Types --- export type ApiKeyScope = "submissions:read" | "webhooks:manage" | "exports:create"; export interface ApiKey { id: number; key_id: string; // e.g., "rnc_live_abc123..." name: string; scopes: ApiKeyScope[]; created_by: string; expires_at?: string; last_used_at?: string; created_at: string; } export type WebhookEvent = "submission.created" | "submission.updated" | "talk.scheduled"; export interface Webhook { id: number; url: string; events: WebhookEvent[]; api_key_id: number; active: boolean; failure_count: number; created_at: string; } export interface WebhookPayload<T = TalkSubmission> { event: WebhookEvent; timestamp: string; data: T; signature: string; } export interface ExportOptions { format: "csv" | "json" | "ics"; since?: string; // ISO date filter status?: "pending" | "scheduled" | "all"; }

8. Mock Press Release Outline

Title

Rust NYC Launches "Connect" β€” Open API for Community Tool Integrations

Subhead

Organizers can now sync talks to Notion, export to Sheets, and receive real-time Slack notifications

Lead Paragraph

  • Rust NYC announces Connect, an API platform enabling organizers and community members to integrate talk submissions with their existing tools
  • Available today with CSV/JSON exports, iCalendar feeds, and webhooks

Key Features (bullets)

  • πŸ”‘ Secure API keys with granular scopes
  • πŸ“€ One-click CSV/JSON exports for spreadsheets
  • πŸ“… Subscribe to iCal feed in Google/Apple Calendar
  • πŸ”” Webhooks for real-time notifications to Slack, Discord, custom bots
  • πŸ”’ HMAC-signed payloads, TLS-only, automatic rate limiting

Quote (Organizer)

"We used to manually copy submissions into Notion every week. Now they appear automatically within seconds."

Availability

  • API documentation: https://rustnyc-talks.val.run/docs/api
  • API keys: Request via Discord #organizers channel
  • No cost for community use

Call to Action

Join Rust NYC Discord to request an API key and start building integrations today.


Remaining Work

  1. Schema migration: Add scheduled_date column to talk_submissions_3 (required for calendar feed)
  2. Organizer auth: Decide how organizers authenticate to create API keys (Discord OAuth or shared admin key)
  3. Documentation site: Static /docs/api page with OpenAPI spec or Markdown
  4. Webhook queue: Consider async job queue for reliability (Val Town cron for retries?)
  5. Key rotation UI: Endpoint to revoke and regenerate keys without data loss
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
Β© 2026 Val Town, Inc.