Last active
September 27, 2017 22:24
-
-
Save davideicardi/db0a92fd133fe29644808c6c172f575e to your computer and use it in GitHub Desktop.
oEmbed creator webtask
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use latest'; | |
import express from 'express'; | |
import { fromExpress } from 'webtask-tools'; | |
import bodyParser from 'body-parser'; | |
import request from 'request'; | |
import cheerio from 'cheerio'; | |
import escapeHtml from 'escape-html'; | |
const app = express(); | |
app.use(bodyParser.json()); | |
app.get('/', (req, res) => { | |
const renderUrl = req.query.render; | |
if (renderUrl) { | |
oEmbed(renderUrl, (err, data) => { | |
if (err) { | |
return res.status(500).send(err.message); | |
} | |
home(res, data); | |
}); | |
} else { | |
home(res); | |
} | |
}); | |
app.get('/*', (req, res) => { | |
const url = getUrlToEmbed(req); | |
oEmbed(url, (err, data) => { | |
if (err) { | |
return res.status(500).send(err.message); | |
} | |
res.json(data); | |
}); | |
}); | |
module.exports = fromExpress(app); | |
function home(res, oEmbedPreview) { | |
const HTML = renderView({ | |
title: 'oEmbed creator', | |
body: renderHome(oEmbedPreview) | |
}); | |
res.set('Content-Type', 'text/html'); | |
res.status(200).send(HTML); | |
} | |
function oEmbed(url, cb) { | |
discoverOEmbed(url, (err, oEmbedUrl) => { | |
if (err) { | |
return res.status(500).send(err.message); | |
} | |
getOEmbedData(oEmbedUrl, (err, data) => { | |
if (err) { | |
return res.status(500).send(err.message); | |
} | |
cb(undefined, data); | |
}); | |
}); | |
} | |
function getOEmbedData(url, cb) { | |
request.get({url, json:true}, (error, response, body) => { | |
if (error) { | |
return cb(error); | |
} | |
if (response && response.statusCode >= 300) { | |
return cb(new Error(`Invalid response ${response.statusCode}`)); | |
} | |
cb(undefined, body); | |
}); | |
} | |
function discoverOEmbed(url, cb) { | |
request.get({url}, (error, response, body) => { | |
if (error) { | |
return cb(error); | |
} | |
if (response && response.statusCode >= 300) { | |
return cb(new Error(`Invalid response ${response.statusCode}`)); | |
} | |
const $ = cheerio.load(body); | |
const oEmbedLink = $('link[type="application/json+oembed"]'); | |
const oEmbedUrl = oEmbedLink.attr('href'); | |
if (!oEmbedUrl) { // oEmbed auto discovery failed | |
// TODO Here I can try to understand how to oembed based on the url | |
// something similar to https://iframely.com/ | |
return cb(new Error("oEmbed discovery link not found")); | |
} | |
cb(undefined, oEmbedUrl); | |
}); | |
} | |
function getUrlToEmbed(req) { | |
const url = req.originalUrl; | |
const slashIndex = url.indexOf('/', 1); | |
return url.substr(slashIndex + 1); | |
} | |
function renderHome(oEmbedData) { | |
return ` | |
<h1>oEmbed creator</h1> | |
<form method="GET"> | |
<label>Url</label> | |
<input name="render" value="https://www.flickr.com/photos/bees/2341623661/" /> | |
<button type="submit">Render</button> | |
</form> | |
<p>Examples:</p> | |
<ul> | |
<li>https://www.flickr.com/photos/bees/2341623661/</li> | |
<li>https://www.youtube.com/watch?v=8SbUC-UaAxE</li> | |
</ul> | |
<div> | |
<a href="https://oembed.com/" target="blank">More info on oEmbed</a> | |
</div> | |
<pre>${escapeHtml(JSON.stringify(oEmbedData || {}, null, '\t'))}</pre> | |
<div> | |
${(oEmbedData && oEmbedData.html) || ""} | |
</div> | |
`; | |
} | |
function renderView(locals) { | |
return ` | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>${locals.title}</title> | |
</head> | |
<body> | |
${locals.body} | |
</body> | |
</html> | |
`; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment