48 lines
1.5 KiB
TypeScript
48 lines
1.5 KiB
TypeScript
|
|
import http from 'node:http'
|
||
|
|
import { searchKeywords } from './threads-keyword-search'
|
||
|
|
|
||
|
|
const port = Number(process.env.PORT ?? process.env.HAIXUN_NODE_TOOL_PORT ?? 9101)
|
||
|
|
|
||
|
|
type SearchInput = {
|
||
|
|
storage_state?: string
|
||
|
|
query?: string
|
||
|
|
limit?: number
|
||
|
|
}
|
||
|
|
|
||
|
|
async function readJson(req: http.IncomingMessage): Promise<SearchInput> {
|
||
|
|
const chunks: Buffer[] = []
|
||
|
|
for await (const chunk of req) {
|
||
|
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))
|
||
|
|
}
|
||
|
|
if (chunks.length === 0) return {}
|
||
|
|
return JSON.parse(Buffer.concat(chunks).toString('utf8')) as SearchInput
|
||
|
|
}
|
||
|
|
|
||
|
|
function writeJson(res: http.ServerResponse, status: number, body: unknown) {
|
||
|
|
res.writeHead(status, { 'content-type': 'application/json; charset=utf-8' })
|
||
|
|
res.end(JSON.stringify(body))
|
||
|
|
}
|
||
|
|
|
||
|
|
const server = http.createServer(async (req, res) => {
|
||
|
|
try {
|
||
|
|
if (req.method === 'GET' && req.url === '/health') {
|
||
|
|
writeJson(res, 200, { ok: true })
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if (req.method !== 'POST' || req.url !== '/search') {
|
||
|
|
writeJson(res, 404, { error: 'not found' })
|
||
|
|
return
|
||
|
|
}
|
||
|
|
const input = await readJson(req)
|
||
|
|
const posts = await searchKeywords(input.storage_state ?? '', input.query ?? '', input.limit ?? 12)
|
||
|
|
writeJson(res, 200, { posts })
|
||
|
|
} catch (error) {
|
||
|
|
const message = error instanceof Error ? error.message : String(error)
|
||
|
|
writeJson(res, 500, { error: message })
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
server.listen(port, '0.0.0.0', () => {
|
||
|
|
console.log(`[keyword-search-tool] listening on :${port}`)
|
||
|
|
})
|