hello-realtimeindex.html1 match
4<meta charset="utf-8" />
5<meta name="viewport" content="width=device-width, initial-scale=1" />
6<title>OpenAI Realtime API Voice Agent</title>
7<style>
8:root {
cogs-v-clippies-2index.ts13 matches
36});
3738// API Routes
3940// Create new game
41app.post("/api/games", async c => {
42const body = await c.req.json() as CreateGameRequest;
43
6768// Get game info
69app.get("/api/games/:gameId", async c => {
70const gameId = c.req.param("gameId").toUpperCase();
71
8384// Join game
85app.post("/api/games/:gameId/join", async c => {
86const gameId = c.req.param("gameId").toUpperCase();
87const body = await c.req.json() as JoinGameRequest;
119120// Get game for management
121app.get("/api/games/:gameId/manage/:mgmtId", async c => {
122const gameId = c.req.param("gameId").toUpperCase();
123const mgmtId = c.req.param("mgmtId");
134135// Update game settings
136app.put("/api/games/:gameId/manage/:mgmtId", async c => {
137const gameId = c.req.param("gameId").toUpperCase();
138const mgmtId = c.req.param("mgmtId");
150151// Create piece type
152app.post("/api/games/:gameId/manage/:mgmtId/pieces", async c => {
153const gameId = c.req.param("gameId").toUpperCase();
154const mgmtId = c.req.param("mgmtId");
166167// Clone game
168app.post("/api/games/:gameId/clone", async c => {
169const gameId = c.req.param("gameId").toUpperCase();
170
207208// Get player data
209app.get("/api/games/:gameId/players/:username", async c => {
210const gameId = c.req.param("gameId").toUpperCase();
211const username = c.req.param("username");
228229// Create player piece
230app.post("/api/games/:gameId/players/:username/pieces", async c => {
231const gameId = c.req.param("gameId").toUpperCase();
232const username = c.req.param("username");
249250// Update player piece instructions
251app.put("/api/games/:gameId/players/:username/pieces/:pieceId", async c => {
252const gameId = c.req.param("gameId").toUpperCase();
253const username = c.req.param("username");
271272// Take turn (trigger LLM moves)
273app.post("/api/games/:gameId/turn", async c => {
274const gameId = c.req.param("gameId").toUpperCase();
275const body = await c.req.json() as TurnRequest;
326327// Server-sent events for turn updates
328app.get("/api/games/:gameId/events", async c => {
329const gameId = c.req.param("gameId").toUpperCase();
330
cogs-v-clippies-2PlayPage.tsx5 matches
73const loadPlayerData = async () => {
74try {
75const response = await fetch(`/api/games/${gameId}/players/${username}`);
76
77if (!response.ok) {
99100const setupSSE = () => {
101const eventSource = new EventSource(`/api/games/${gameId}/events`);
102eventSourceRef.current = eventSource;
103171};
172173const response = await fetch(`/api/games/${gameId}/players/${username}/pieces`, {
174method: 'POST',
175headers: { 'Content-Type': 'application/json' },
202};
203204const response = await fetch(`/api/games/${gameId}/players/${username}/pieces/${pieceId}`, {
205method: 'PUT',
206headers: { 'Content-Type': 'application/json' },
258};
259260const response = await fetch(`/api/games/${gameId}/turn`, {
261method: 'POST',
262headers: { 'Content-Type': 'application/json' },
cogs-v-clippies-2ManagePage.tsx4 matches
31const loadGameData = async () => {
32try {
33const response = await fetch(`/api/games/${gameId}/manage/${mgmtId}`);
34
35if (!response.ok) {
6667try {
68const response = await fetch(`/api/games/${gameId}/manage/${mgmtId}`, {
69method: 'PUT',
70headers: { 'Content-Type': 'application/json' },
111};
112113const response = await fetch(`/api/games/${gameId}/manage/${mgmtId}/pieces`, {
114method: 'POST',
115headers: { 'Content-Type': 'application/json' },
153154try {
155const response = await fetch(`/api/games/${gameId}/clone`, {
156method: 'POST'
157});
cogs-v-clippies-2JoinPage.tsx2 matches
22const loadGame = async () => {
23try {
24const response = await fetch(`/api/games/${gameId}`);
25
26if (!response.ok) {
51const request: JoinGameRequest = { username };
5253const response = await fetch(`/api/games/${gameId}/join`, {
54method: 'POST',
55headers: { 'Content-Type': 'application/json' },
26};
2728const response = await fetch('/api/games', {
29method: 'POST',
30headers: { 'Content-Type': 'application/json' },
cogs-v-clippies-2openai.ts1 match
70
71} catch (error) {
72console.error("OpenAI API error:", error);
73throw new Error(`Failed to generate move: ${error.message}`);
74}
cogs-v-clippies-2types.ts1 match
52}
5354// API request/response types
55export interface CreateGameRequest {
56name: string;
cogs-v-clippies-2README.md1 match
11- **queries.ts**: Database query functions
12- **llm/**: LLM integration
13- **openai.ts**: OpenAI API calls for piece moves
1415### Frontend (`/frontend/`)
denoCrudTaskREADME.md25 matches
1# RankWatch API
23A powerful keyword ranking monitoring API built with Val Town. Track your SEO rankings with precision and reliability.
45## 🚀 Features
25- **Unlimited**: Unlimited keywords/projects, daily updates
2627## 📚 API Documentation
2829### Swagger UI
30Access interactive documentation at: `GET /docs`
3132### OpenAPI Specification
33Get the OpenAPI spec at: `GET /docs/openapi.json`
3435### Alternative Documentation
42- **Framework**: Hono for HTTP routing
43- **Database**: SQLite (Turso-powered)
44- **External API**: Serper.dev for Google search data
45- **Email**: Val Town std/email (Resend integration ready)
4647### Key Components
48- `main.ts` - Main application entry point
49- `authApi.ts` - Authentication endpoints
50- `projectsApi.ts` - Project management
51- `keywordsApi.ts` - Keyword management with bulk operations
52- `rankingsApi.ts` - Ranking data and analysis
53- `searchApi.ts` - Global search functionality
54- `exportApi.ts` - CSV export endpoints
55- `swaggerApi.ts` - API documentation
56- `serperClient.ts` - Serper.dev integration
57- `cronDaily.ts` - Daily ranking checks (unlimited users)
66JWT_SECRET=your-secure-jwt-secret-key
6768# Serper.dev API Key (get from https://serper.dev)
69SERPER_API_KEY=your-serper-api-key
7071# Resend API Key (for email notifications)
72RESEND_API_KEY=your-resend-api-key
7374# Optional: Custom base URL
82831. **Create Vals**: Create separate Vals for each main component:
84- Main API: `main.ts`
85- Weekly Cron: `cronWeekly.ts`
86- Daily Cron: `cronDaily.ts`
92- Daily: Every day 6 AM UTC
9394## 🔧 API Endpoints
9596### Authentication
161162### Support Tables
163- `rate_limits` - API rate limiting
164- `usage_limits` - Plan usage tracking
165192```typescript
193resend: {
194apiKey: Deno.env.get("RESEND_API_KEY"),
195fromEmail: "noreply@rankwatch.dev",
196}
2011. **Clone the project** to your Val Town workspace
2022. **Set environment variables** in Val Town settings
2033. **Deploy main API** using `main.ts`
2044. **Setup cron jobs** for automated ranking checks
2055. **Test endpoints** using Swagger UI at `/docs`
220221### Automated Testing
222The API includes health checks:
223- `GET /health` - Service health
224- `GET /status` - API status and features
225- `GET /docs/health` - Documentation health
226228229### Health Endpoints
230- `GET /` - API welcome/info
231- `GET /health` - Database connectivity check
232- `GET /status` - Feature and limits overview