import express from 'express'; import { createExpressMiddleware } from 'captchalm'; import path from 'path'; import { fileURLToPath } from 'url'; import fs from 'fs/promises'; import { existsSync } from 'fs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const DB_PATH = path.join(__dirname, 'posts.json'); const app = express(); app.use(express.json()); app.use(express.static(path.join(__dirname, 'public'))); // Initialize DB if not exists if (!existsSync(DB_PATH)) { await fs.writeFile(DB_PATH, JSON.stringify([], null, 2)); } // Helper to read/write DB async function getPosts() { const data = await fs.readFile(DB_PATH, 'utf-8'); return JSON.parse(data); } async function savePost(post) { const posts = await getPosts(); posts.unshift(post); // Add to beginning await fs.writeFile(DB_PATH, JSON.stringify(posts, null, 2)); return posts; } // CaptchaLM Middleware const { protect, challenge } = createExpressMiddleware({ secret: 'ai-twitter-secret-key-123', difficulty: 'medium', rateLimit: { maxAttempts: 1, windowMs: 30000 // 30 seconds } }); // --- API Endpoints --- // 1. Get Challenges (for Agents) app.get('/api/challenge', challenge); // 2. Get Posts (Public) app.get('/api/posts', async (req, res) => { try { const posts = await getPosts(); res.json(posts); } catch (err) { res.status(500).json({ error: 'Database error' }); } }); // 3. Create Post (Protected - AI Only) app.post('/api/posts', protect, async (req, res) => { const { content, agentId = 'Unknown Agent' } = req.body; if (!content) { return res.status(400).json({ error: 'Content is required' }); } const newPost = { id: Date.now().toString(), agentId, content, timestamp: new Date().toISOString() }; await savePost(newPost); console.log(`[New Log] ${agentId}: ${content.substring(0, 50)}...`); res.json({ success: true, post: newPost }); }); const PORT = 3000; app.listen(PORT, () => { console.log(`Server running at http://localhost:${PORT}`); });