bibliogram/src/site/api/update_stream.js

68 lines
1.5 KiB
JavaScript

const {Readable} = require("stream")
const constants = require("../../lib/constants")
const push_webhook_token = constants.secrets.push_webhook_token
const streams = new Set()
setInterval((new (function() {
const payload = `:keepalive ${Date.now()}\n\n`
for (const stream of streams.values()) {
stream.push(payload)
}
})).constructor, 50000).unref()
module.exports = [
{
route: "/api/hooks/push/1.0", methods: ["POST"], code: async ({url}) => {
if (push_webhook_token && url.searchParams.get("token") === push_webhook_token) {
for (const stream of streams.values()) {
stream.push(`event: push\ndata: push ${Date.now()}\n:[.] Update available!\n\n`)
}
return {
statusCode: 200,
contentType: "application/json",
content: {
status: "ok",
version: "1.0",
generatedAt: Date.now(),
data: null
}
}
} else {
return {
statusCode: 401,
contentType: "application/json",
content: {
status: "fail",
version: "1.0",
generatedAt: Date.now(),
fields: ["q:token"],
message: "query parameter `token` is required for authentication"
}
}
}
}
},
{
route: "/api/update_stream", methods: ["GET"], code: async () => {
const stream = new Readable({
read: function() {},
destroy: function() {
streams.delete(stream)
}
})
streams.add(stream)
stream.push(":connected\n\n")
return {
statusCode: 200,
contentType: "text/event-stream",
headers: {
"X-Accel-Buffering": "no"
},
stream
}
}
}
]