UNPKG

suchtube

Version:

YouTube search as a service, with Slack and Discord integration and CLI

120 lines (100 loc) 3.33 kB
import express from 'express' import bodyParser from 'body-parser' import { search } from './search.js' import { parseArguments } from './arguments-parser.js' import pkg from '../package.json' with { type: 'json' } const { version } = pkg const app = express() app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: true })) export const start = async () => { const port = process.env.PORT || 3333 const server = app.listen(port, () => { console.log( `\nSuchTube server v${version} listening on port ${server.address().port} in ${app.settings.env} mode\n`) }) } app.get('/', async (req, res) => { res.redirect('/search') }) app.all('/search.:format?', async (req, res) => { const format = req.params.format || 'html' let originalQuery = '' if ((format == "slack") && (req.method == 'POST')) { originalQuery = req.body.text || '' } else if ((format == "discord") && (req.method == 'POST')) { // Discord sends interaction data with options array const options = req.body.data?.options || [] const queryOption = options.find(opt => opt.name === 'query') originalQuery = queryOption?.value || '' } else { originalQuery = req.query.q || '' } const args = parseArguments(originalQuery) const query = args._.join(" ") console.log(`[LOG] format: ${format} | query: ${originalQuery}\n`) const result = await search(query, args) let video, videos, videoLink, videoTitle // Handle --all option: result could be an array or single video if (args.all && Array.isArray(result)) { videos = result video = result[0] // Use first video for HTML, Slack and Discord } else { video = result videos = result ? [result] : [] } if (video) { videoLink = video.link videoTitle = video.title } else { videoLink = 'Not found 乁(ツ)ㄏ' videoTitle = videoLink } if (format == 'slack') { res.send({ response_type: 'in_channel', text: videoLink }) } else if (format == 'discord') { res.send({ type: 4, // CHANNEL_MESSAGE_WITH_SOURCE data: { content: videoLink } }) } else if (format == 'text') { // For text format with --all, return all video links if (args.all && videos.length > 1) { res.send(videos.map(v => v.link).join('\n')) } else { res.send(videoLink) } } else if (format == 'json') { // For JSON format with --all, return all videos if (args.all && videos.length > 1) { res.send(videos) } else { res.send(video) } } else if (format == 'html') { let html = `<html><body style="background-color: #ccc; padding: 2em; font-family: sans-serif;"> <h1>SuchTube v${version}</h1> <form action="/search"><input name="q" value="${originalQuery}" style="width: 400px; height: 40px;"></form>` if (query != "") html += `<h2>${videoTitle}</h2>` if (video) { html += `<small>${video.publishedAt} -- ${video.channelTitle}</small> <p>${video.description}</p> <p><a href="${videoLink}" target="_blank">${videoLink}</a></p>` if (video.linkEmbed){ html += `<iframe src="${video.linkEmbed}" width="640" height="360" frameborder="0"></iframe>` } } html += '</body></html>' res.send(html) } })