8
9const stripe = new Stripe(Deno.env.get(getEnvVarName("STRIPE_SECRET_KEY")) as string, {
10 apiVersion: "2024-06-20",
11});
12
51 // const paymentIntent: Stripe.PaymentIntent = await stripe.paymentIntents.retrieve(session.client_reference_id);
52
53 const response = await fetch(`https://api.stripe.com/v1/payment_intents/${session.client_reference_id}`, {
54 method: "GET",
55 headers: {
4
5/**
6 * Plays a bell sound notification using the Web Audio API
7 * @returns A Promise that resolves when the sound has started playing
8 */
13 const AudioContext = window.AudioContext || (window as any).webkitAudioContext;
14 if (!AudioContext) {
15 console.warn("Web Audio API not supported in this browser");
16 resolve();
17 return;
65
66/**
67 * Plays a simple notification sound using the Web Audio API
68 * This is a simpler, shorter bell sound
69 * @returns A Promise that resolves when the sound has started playing
75 const AudioContext = window.AudioContext || (window as any).webkitAudioContext;
76 if (!AudioContext) {
77 console.warn("Web Audio API not supported in this browser");
78 resolve();
79 return;
50 } = await c.req.json();
51
52 const apiKey = Deno.env.get("ANTHROPIC_API_KEY");
53
54 if (await hasInsufficientCredits({ bearerToken })) {
66
67 const rowid = await startTrackingUsage({
68 our_api_token: true,
69 bearerToken,
70 branch_id: branchId,
74 });
75
76 const anthropic = createAnthropic({ apiKey });
77 let tracedModel = anthropic(model);
78
79 if (Deno.env.get("POSTHOG_PROJECT_API_KEY")) {
80 const phClient = new PostHog(Deno.env.get("POSTHOG_PROJECT_API_KEY"), {
81 host: "https://us.i.posthog.com",
82 });
20 finish_reason?: string;
21 num_images?: number;
22 our_api_token: boolean;
23}
24
45 finish_reason TEXT,
46 num_images INTEGER,
47 our_api_token INTEGER NOT NULL,
48 finish_timestamp INTEGER
49 )`,
17 finish_reason: string | null;
18 num_images: number | null;
19 our_api_token: number;
20}
21
69 <th>Finish</th>
70 <th>Images</th>
71 <th>Our API</th>
72 </tr>
73 </thead>
88 <td>${row.finish_reason || '-'}</td>
89 <td>${formatNumber(row.num_images)}</td>
90 <td>${formatBoolean(row.our_api_token)}</td>
91 </tr>
92 `).join("")}
17Townie is fully open-source and itself runs on Val Town. Pull requests welcome!
18
19To get Townie running in your Val Town account, click the **Remix** button and then add your ANTHROPIC_API_KEY. You can leave all the other environment variables blank.
20
21Authentication in Townie is handled via Val Town Oauth. However, we have not yet opened up our OAuth to anyone else, which currently makes it very awkward to use your own Townie. Here is a temporary workaround:
1# Usage Dashboard
2
3A dashboard for monitoring API usage and inference calls.
4
5## Features
20 index.ts # Main entry point and routing
21 auth.ts # Authentication logic
22 /api/
23 index.ts # API request handler
24 requests.ts # API endpoints for requests data
25 inference-calls.ts # API endpoints for inference calls
26 user-summary.ts # API endpoints for user summary data
27 /views/
28 layout.ts # Common layout template
54 - Links back to the associated request
55
56### API Endpoints
57
58- `/api/requests` - Get paginated requests
59- `/api/requests?usage_id=123` - Get a specific request
60- `/api/inference-calls` - Get paginated inference calls
61- `/api/inference-calls?usage_id=123` - Get inference calls for a specific request
62- `/api/user-summary` - Get user summary data
63
64## Debugging
157 branch_id,
158 model,
159 our_api_token,
160 num_images,
161 tablePrefix = "",
165 branch_id: string;
166 model: string;
167 our_api_token: boolean;
168 num_images: number;
169 tablePrefix?: string;
178 branch_id,
179 model,
180 our_api_token,
181 num_images
182 ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
189 branch_id,
190 model,
191 our_api_token ? 1 : 0,
192 num_images,
193 ],
38 branch_id,
39 model,
40 our_api_token,
41 num_images
42 ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
14const stripe = stripeSecretKey
15 ? new Stripe(stripeSecretKey, {
16 apiVersion: "2024-04-10",
17 })
18 : null;
57 // user_id: user.id,
58 // username: user.username,
59 // purchase_source: source || "api", // e.g., "insufficient_credits", "settings_page"
60 // },
61 // description: `Townie credits purchase - $${amount} for ${user.username}`,
62 // api_key: stripeSecretKey,
63 // });
64
69 "metadata[user_id]": user.id,
70 "metadata[username]": user.username,
71 "metadata[purchase_source]": source || "api",
72 description: `Townie credits purchase - $${amount} for ${user.username}`,
73 });
74
75 const response = await fetch("https://api.stripe.com/v1/payment_intents", {
76 method: "POST",
77 headers: {
84 const paymentIntent = await response.json();
85 if (!response.ok) {
86 throw new Error(`Stripe API error: ${paymentIntent.error?.message || "Unknown error"}`);
87 }
88