Create mediaUpload.ts

This commit is contained in:
RogerHsu7 2026-01-30 10:39:44 +08:00 committed by GitHub
parent 01e2e9264c
commit 76ec00aa3b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -0,0 +1,69 @@
// Draft implementation for Gateway media upload (Fastify-style)
// Adjust to the actual server framework (Fastify/Express) used by clawdbot gateway.
import path from 'node:path'
import fs from 'node:fs/promises'
import { randomUUID } from 'node:crypto'
// Pseudo helpers replace with gateway's real config/log/auth utilities
const CONFIG = {
uploads: {
maxItemBytes: 25 * 1024 * 1024,
accept: [ 'image/', 'application/pdf', 'text/plain', 'application/zip' ],
},
mediaDir: path.resolve(process.env.CLAWDBOT_MEDIA_DIR || path.join(process.env.HOME || process.cwd(), '.clawdbot', 'media', 'inbound')),
}
function ensureDir(p: string) {
return fs.mkdir(p, { recursive: true })
}
function inferExt(mime: string, name?: string) {
const fromName = name && path.extname(name)
if (fromName) return fromName
if (mime.startsWith('image/')) return '.png'
if (mime === 'application/pdf') return '.pdf'
return ''
}
function allowed(mime: string) {
return CONFIG.uploads.accept.some(a => a.endsWith('/*') ? mime.startsWith(a.slice(0, -1)) : mime === a)
}
export async function registerMediaUploadRoute(fastify: any) {
await ensureDir(CONFIG.mediaDir)
fastify.register(import('@fastify/multipart'), { limits: { fileSize: CONFIG.uploads.maxItemBytes } })
fastify.post('/api/media/upload', async (req: any, reply: any) => {
const mp = await req.parts()
const files: any[] = []
for await (const part of mp) {
if (part.type !== 'file') continue
const { filename, mimetype } = part
if (!allowed(mimetype)) {
await part.file?.resume()
return reply.code(415).send({ error: 'unsupported_type', mimetype })
}
const id = randomUUID()
const ext = inferExt(mimetype, filename)
const outPath = path.join(CONFIG.mediaDir, `${id}${ext}`)
const chunks: Buffer[] = []
let size = 0
for await (const chunk of part.file) {
size += chunk.length
if (size > CONFIG.uploads.maxItemBytes) {
return reply.code(413).send({ error: 'file_too_large' })
}
chunks.push(chunk)
}
const buf = Buffer.concat(chunks)
await fs.writeFile(outPath, buf)
const mediaPath = `MEDIA:${outPath}`
files.push({ path: mediaPath, mime: mimetype, name: filename, size })
}
return reply.send({ files })
})
}