-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapi.js
140 lines (118 loc) · 3.5 KB
/
api.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import fs from 'fs';
import express from 'express';
import { WebSocket } from 'ws';
import config from './config.js';
import http from 'http';
import https from 'https';
const { protocol, ip, port, ssl } = config.server;
const RELAY_URLS = config.relays;
const app = express();
app.use(express.json());
const NOTES_FILE = "./notes.json";
const loadNotes = () => {
try {
const data = fs.readFileSync(NOTES_FILE, "utf8");
return JSON.parse(data);
} catch (e) {
console.error("Error reading notes file:", e);
return [];
}
};
const saveNotes = (notes) => {
try {
fs.writeFileSync(NOTES_FILE, JSON.stringify(notes, null, 2));
} catch (e) {
console.error("Error writing to notes file:", e);
}
};
const validateEventFormat = (event) => {
const requiredFields = ["id", "pubkey", "created_at", "kind", "tags", "content", "sig"];
for (const field of requiredFields) {
if (!event[field]) {
throw new Error(`Missing required field: ${field}`);
}
}
};
const broadcastToRelays = async (event) => {
const parsedEvent = JSON.parse(event);
const eventPayload = {
id: parsedEvent.id,
pubkey: parsedEvent.pubkey,
created_at: parsedEvent.created_at,
kind: parsedEvent.kind,
tags: parsedEvent.tags,
content: parsedEvent.content,
sig: parsedEvent.sig,
};
for (const relayUrl of RELAY_URLS) {
try {
const ws = new WebSocket(relayUrl);
ws.on('open', () => {
const message = JSON.stringify(["EVENT", eventPayload]);
ws.send(message);
console.log(`Event broadcasted to relay: ${relayUrl}`);
ws.close();
});
ws.on('error', (err) => {
console.error(`Error connecting to relay ${relayUrl}:`, err);
});
} catch (e) {
console.error(`Failed to broadcast to relay ${relayUrl}:`, e);
}
}
};
app.post("/api/notes", (req, res) => {
try {
const { broadcast_id, planned_date, event } = req.body;
if (!broadcast_id || !planned_date || !event) {
return res.status(400).send("Missing required fields.");
}
const parsedEvent = JSON.parse(event);
validateEventFormat(parsedEvent);
const notes = loadNotes();
notes.push({ broadcast_id, planned_date, event });
saveNotes(notes);
console.log(`Received note: ${broadcast_id} scheduled for ${planned_date}`);
res.status(200).send("Note saved successfully.");
} catch (e) {
console.error("Error saving note:", e.message);
res.status(500).send(`Error saving note: ${e.message}`);
}
});
setInterval(() => {
const notes = loadNotes();
const now = new Date();
const remainingNotes = notes.filter((note) => {
const plannedDate = new Date(note.planned_date);
if (plannedDate <= now) {
broadcastToRelays(note.event);
return false;
}
return true;
});
if (remainingNotes.length !== notes.length) {
saveNotes(remainingNotes);
console.log(`Broadcasted ${notes.length - remainingNotes.length} notes.`);
}
}, 30000);
let server;
if (protocol === "https") {
try {
const sslOptions = {
key: fs.readFileSync(ssl.key),
cert: fs.readFileSync(ssl.cert),
};
server = https.createServer(sslOptions, app);
server.listen(port, ip, () => {
console.log(`HTTPS Server running at https://${ip}:${port}`);
});
} catch (e) {
console.error("Failed to start HTTPS server:", e);
process.exit(1);
}
} else {
server = http.createServer(app);
server.listen(port, ip, () => {
console.log(`HTTP Server running at http://${ip}:${port}`);
});
}