Mini Programs that can't handle files are like offices without filing cabinets — technically functional, but painfully limited. Whether it's user-uploaded images, generated reports, or conversation attachments, your OpenClaw-powered Mini Program needs a solid file storage strategy.
Let's build one.
WeChat Mini Programs have strict limitations:
Your OpenClaw backend on Tencent Cloud Lighthouse becomes the persistent storage layer that the Mini Program itself can't provide.
Mini Program → Upload API → Lighthouse Storage → OpenClaw Processing
↓
File Metadata DB
↓
Mini Program ← Download API ← Lighthouse Storage
On your Lighthouse instance:
// /opt/clawdbot/api/file-storage.js
const express = require('express');
const multer = require('multer');
const path = require('path');
const crypto = require('crypto');
const fs = require('fs');
const app = express();
const STORAGE_DIR = '/opt/clawdbot/data/files';
// Configure upload handling
const storage = multer.diskStorage({
destination: STORAGE_DIR,
filename: (req, file, cb) => {
const hash = crypto.randomBytes(16).toString('hex');
const ext = path.extname(file.originalname);
cb(null, `${hash}${ext}`);
}
});
const upload = multer({
storage,
limits: { fileSize: 10 * 1024 * 1024 }, // 10MB
fileFilter: (req, file, cb) => {
const allowed = ['.jpg', '.jpeg', '.png', '.pdf', '.doc', '.docx', '.xlsx'];
const ext = path.extname(file.originalname).toLowerCase();
cb(null, allowed.includes(ext));
}
});
// Upload endpoint
app.post('/api/files/upload', upload.single('file'), (req, res) => {
if (!req.file) {
return res.status(400).json({ error: 'No file uploaded or invalid type' });
}
const fileRecord = {
id: path.parse(req.file.filename).name,
original_name: req.file.originalname,
size: req.file.size,
mime_type: req.file.mimetype,
uploaded_at: new Date().toISOString(),
user_id: req.headers['x-user-id']
};
// Save metadata
saveFileMetadata(fileRecord);
res.json({
file_id: fileRecord.id,
download_url: `/api/files/${fileRecord.id}`,
size: fileRecord.size
});
});
// Download endpoint
app.get('/api/files/:fileId', (req, res) => {
const metadata = getFileMetadata(req.params.fileId);
if (!metadata) {
return res.status(404).json({ error: 'File not found' });
}
const filePath = path.join(STORAGE_DIR, `${req.params.fileId}${path.extname(metadata.original_name)}`);
res.download(filePath, metadata.original_name);
});
app.listen(3001, () => console.log('File storage API running on :3001'));
// pages/upload/upload.js
Page({
chooseAndUpload() {
wx.chooseMessageFile({
count: 1,
type: 'file',
success: (res) => {
const file = res.tempFiles[0];
wx.uploadFile({
url: 'https://YOUR_LIGHTHOUSE_IP/api/files/upload',
filePath: file.path,
name: 'file',
header: {
'x-user-id': wx.getStorageSync('userId')
},
success: (uploadRes) => {
const data = JSON.parse(uploadRes.data);
wx.showToast({ title: 'Upload complete!' });
// Now send the file reference to OpenClaw for processing
this.processWithAI(data.file_id, file.name);
},
fail: () => {
wx.showToast({ title: 'Upload failed', icon: 'none' });
}
});
}
});
},
async processWithAI(fileId, fileName) {
const res = await wx.request({
url: 'https://YOUR_LIGHTHOUSE_IP/api/chat',
method: 'POST',
data: {
message: `Please analyze the uploaded file: ${fileName}`,
attachments: [{ file_id: fileId }]
}
});
// Handle AI response about the file
}
});
Keep your disk healthy with automated cleanup:
#!/bin/bash
# /opt/clawdbot/storage-cleanup.sh
STORAGE_DIR="/opt/clawdbot/data/files"
MAX_AGE_DAYS=30
echo "=== Storage Cleanup ==="
echo "Before: $(du -sh $STORAGE_DIR | awk '{print $1}')"
# Remove files older than 30 days
find $STORAGE_DIR -type f -mtime +$MAX_AGE_DAYS -delete
echo "After: $(du -sh $STORAGE_DIR | awk '{print $1}')"
echo "Cleaned files older than $MAX_AGE_DAYS days"
Schedule it weekly:
echo "0 3 * * 0 /opt/clawdbot/storage-cleanup.sh >> /var/log/clawdbot/cleanup.log 2>&1" | crontab -
Get your file storage backend running:
Files are data. Data needs backups:
# Daily backup of uploaded files
tar czf /opt/clawdbot/backups/files-$(date +%Y%m%d).tar.gz /opt/clawdbot/data/files/
# Keep 14 days of backups
find /opt/clawdbot/backups/ -name "files-*.tar.gz" -mtime +14 -delete
chmod 640 on uploaded files# Set secure permissions on the storage directory
chmod 750 /opt/clawdbot/data/files
chown clawdbot:clawdbot /opt/clawdbot/data/files
#!/bin/bash
echo "=== Storage Health ==="
echo "Total files: $(find /opt/clawdbot/data/files -type f | wc -l)"
echo "Total size: $(du -sh /opt/clawdbot/data/files | awk '{print $1}')"
echo "Disk free: $(df -h /opt/clawdbot/data/files | tail -1 | awk '{print $4}')"
echo "Largest files:"
find /opt/clawdbot/data/files -type f -exec du -h {} + | sort -rh | head -5
File storage turns your Mini Program from a chat interface into a full-featured application platform. Documents, images, reports — all managed through your OpenClaw backend.
Files in. Intelligence out.