board backups to R2

This commit is contained in:
Jeff-Emmett 2025-01-28 16:42:58 +01:00
parent c2abfcd3e3
commit acc12363be
3 changed files with 67 additions and 1 deletions

View File

@ -4,6 +4,7 @@
export interface Environment {
TLDRAW_BUCKET: R2Bucket
BOARD_BACKUPS_BUCKET: R2Bucket
TLDRAW_DURABLE_OBJECT: DurableObjectNamespace
DAILY_API_KEY: string;
DAILY_DOMAIN: string;

View File

@ -180,5 +180,61 @@ const router = AutoRouter<IRequest, [env: Environment, ctx: ExecutionContext]>({
}
})
async function backupAllBoards(env: Environment) {
try {
// List all room files from TLDRAW_BUCKET
const roomsList = await env.TLDRAW_BUCKET.list({ prefix: 'rooms/' })
const date = new Date().toISOString().split('T')[0]
// Process each room
for (const room of roomsList.objects) {
try {
// Get the room data
const roomData = await env.TLDRAW_BUCKET.get(room.key)
if (!roomData) continue
// Get the data as text since it's already stringified JSON
const jsonData = await roomData.text()
// Create backup key with date only
const backupKey = `${date}/${room.key}`
// Store in backup bucket as JSON
await env.BOARD_BACKUPS_BUCKET.put(backupKey, jsonData)
console.log(`Backed up ${room.key} to ${backupKey}`)
} catch (error) {
console.error(`Failed to backup room ${room.key}:`, error)
}
}
// Clean up old backups (keep last 30 days)
const thirtyDaysAgo = new Date()
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30)
const oldBackups = await env.BOARD_BACKUPS_BUCKET.list({
prefix: thirtyDaysAgo.toISOString().split('T')[0]
})
for (const backup of oldBackups.objects) {
await env.BOARD_BACKUPS_BUCKET.delete(backup.key)
}
return { success: true, message: 'Backup completed successfully' }
} catch (error) {
console.error('Backup failed:', error)
return { success: false, message: (error as Error).message }
}
}
router
.get("/backup", async (_, env) => {
const result = await backupAllBoards(env)
return new Response(JSON.stringify(result), {
headers: { 'Content-Type': 'application/json' }
})
})
// export our router for cloudflare
export default router

View File

@ -27,6 +27,15 @@ binding = 'TLDRAW_BUCKET'
bucket_name = 'jeffemmett-canvas'
preview_bucket_name = 'jeffemmett-canvas-preview'
[[r2_buckets]]
binding = 'BOARD_BACKUPS_BUCKET'
bucket_name = 'board-backups'
preview_bucket_name = 'board-backups-preview'
[observability]
enabled = true
head_sampling_rate = 1
head_sampling_rate = 1
[triggers]
crons = ["0 0 * * *"] # Run at midnight UTC every day
# crons = ["*/10 * * * *"] # Run every 10 minutes