6import urlSigning from "./url-signing.ts";
7await migrateDB();
8async function foo(req: Request): Promise<Response> {
9const url = new URL(req.url);
10const ts = await urlSigning.verify(url.pathname.slice(1));
76};
7778function Header() {
79return (
80<div
100}
101102function formatTimestamp(timestamp: number): string {
103return new Date(timestamp).toLocaleString();
104}
105106function parseMessageData(data: string, eventType: string): any {
107try {
108return JSON.parse(data);
112}
113114function ToolTimestamp({ timestamp }: { timestamp: number }) {
115return (
116<div style={styles.toolTimestamp}>
120}
121122function SlackMessage({ message }: { message: any }) {
123const parsedData = parseMessageData(message.data, message.event_type);
124143}
144145function ClaudeMessage({ message }: { message: any }) {
146const parsedData = parseMessageData(message.data, message.event_type);
147const cleanMessage = parsedData.raw
170}
171172function Timestamp(
173{ timestamp, style = {} }: { timestamp: number; style?: any },
174) {
194}
195196function ToolCall({ message }: { message: any }) {
197return (
198<div style={styles.centerMessageContainer}>
213}
214215function ToolResult({ message }: { message: any }) {
216return (
217<div style={styles.centerMessageContainer}>
234}
235236function UnknownEvent({ message }: { message: any }) {
237return (
238<div style={styles.centerMessageContainer}>
254}
255256function MessagesContainer({ children }: { children: any }) {
257return (
258<div
267}
268269function MessageBubble({ message }: { message: any }) {
270switch (message.event_type) {
271case "slack_message":
282}
283284function Footer({ conversationData }: { conversationData: any }) {
285return (
286<div
320};
321322function renderError(e: unknown) {
323const error = e instanceof Error ? e : new Error(String(e));
324
23}).catch(() => {});
2425export async function reply(
26event: GenericMessageEvent,
27messages: Anthropic.MessageParam[],
43});
4445const function_calls = response.content.filter(
46(block) => block.type === "tool_use",
47);
6667// If were no more tool calls, we're done, return
68if (!function_calls.length) return;
6970// Append the assistant message once per step
7273// Run every tool call the model requested
74for (const call of function_calls) {
75if (call.type !== "tool_use") continue;
76
exampleindex.http.tsx1 match
1export default async function (req) {
2return new Response("Hello there. This is live-updating, and live-deployed.");
3}
9* @returns A promise that resolves when all files have been uploaded.
10*/
11export async function uploadDir(dir: string) {
12const uploadPromises: Promise<void>[] = [];
1332* @param dir The directory to save the files in.
33*/
34export async function downloadDir(dir: string) {
35const response = await client.files.list.$get();
36const { files } = await response.json();
8* @returns A promise that resolves to the path of the blob.
9*/
10export async function setBlobContent(path: string, content: string | ArrayBuffer): Promise<string> {
11const key = env.STORAGE_PREFIX + path;
12await blob.set(key, content);
20* @returns A promise that resolves to the content of the blob as a string.
21*/
22export async function getBlobContent(path: string): Promise<string> {
23const key = env.STORAGE_PREFIX + path;
24return await blob.get(key).then((resp) => resp.text());
30* @returns {Promise<string[]>} A promise that resolves to an array of blob keys, with the storage prefix removed.
31*/
32export async function listBlobs(): Promise<string[]> {
33const files = await blob.list(env.STORAGE_PREFIX);
34return files.map(({ key }) => key.replace(env.STORAGE_PREFIX, ""));
41* @returns A promise that resolves when the blob is successfully deleted.
42*/
43export async function deleteBlob(path: string): Promise<void> {
44const key = env.STORAGE_PREFIX + path;
45await blob.delete(key);
52* representing the keys of the deleted blobs, with the storage prefix removed.
53*/
54export async function deleteAllBlobs(): Promise<string[]> {
55const allFiles = await blob.list(env.STORAGE_PREFIX);
5672* @returns A promise that resolves to true if the blob exists, false otherwise.
73*/
74export async function blobExists(path: string): Promise<boolean> {
75const key = env.STORAGE_PREFIX + path;
76try {
test-appnew-file-774.js1 match
1// Learn more: https://docs.val.town/vals/http/
2export default async function (req: Request): Promise<Response> {
3return Response.json({ ok: true })
4}
9};
1011function parseModuleUrl(url: string) {
12// Match the pattern: /p/{username}/{name}@{version}-{branch}/events/db.ts
13const regex = /\/p\/[^\/]+\/([^@]+)@\d+-([^\/]+)\//;
24}
2526export async function migrateDB() {
27await sqlite.batch([
28`
39}
4041export async function getAll({ ts }: {
42ts?: string;
43}) {
54}
5556export async function writeSlackMessage({ event }: {
57event: AppMentionEvent | GenericMessageEvent;
58}) {
70}
7172export async function writeClaudeMessage({ channel, ts, msg }: {
73channel: string;
74ts: string;
88}
8990export async function writeToolCall({ channel, ts, data }: {
91channel: string;
92ts: string;
106}
107108export async function writeToolResult({ channel, ts, result }: {
109channel: string;
110ts: string;
5import { writeSlackMessage } from "../util/db.ts";
67export async function handleSlackEvent(event: SlackEvent) {
8if (
9event.type === "message" && !event.subtype && !event.bot_id &&
slackboturl-signing.ts2 matches
23// Sign a value
4async function sign(value: string) {
5const encoder = new TextEncoder();
6const key = await crypto.subtle.importKey(
2627// Verify a signed value
28async function verify(signedValue: string) {
29const lastDotIndex = signedValue.lastIndexOf(".");
30if (lastDotIndex === -1) return null;
my-first-val04_email.ts1 match
2// Click "Run", copy and paste the email address and send an email to it.
3// This example will log the email details received.
4export default async function emailHandler(email: Email){
5console.log("Email received!", email.from, email.subject, email.text);
6for (const file of email.attachments) {