Have opinions about JavaScript? We want to hear them. Take the 2018 JavaScript Ecosystem Survey »

yoem

1.4.1 • Public • Published

yoem

NPM Circle CI Coverage Status

Oembed URL expansion route for Express apps.


This library can be used to expand URLs according to the Oembed specification, either by using a service's official oembed endpoint or by using available tags on the webpage in question.

This is yet another open source re-implementation of two services that Car Throttle uses to handle link-expansion in various locations across the platform, most commonly in link posts like this and video posts like this.

Not to be mistaken for wrender, an open-source re-implementation of Car Throttle's image delivery service.

The recommended usage is part of a larger Express-based application, therefore rate-limiting, authentication, logging and other such luxeries are not implemented here. Provided is an example server for live-testing & non-production environments.

const express = require('express');
const yoem = require('yoem');
 
const app = express();
app.use('/embed', yoem());
 
app.listen(3000);
# Using httpie - https://httpie.org/ 
$ http GET http://localhost:3010/embed?url=https://www.youtube.com/watch\?v\=610rMnK9HCo
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 632
Content-Type: application/json; charset=utf-8
Date: Thu, 20 Apr 2017 17:56:34 GMT
ETag: W/"278-E/jT6YNWofKzDmsTjLnGOgb3hws"
X-Powered-By: Express
 
{
  "type""video",
  "version""1.0",
  "url""https://www.youtube.com/watch?v=610rMnK9HCo",
  "title""Car Guys VS Non-Car Guys",
  "thumbnail_url""https://i.ytimg.com/vi/610rMnK9HCo/hqdefault.jpg",
  "provider_name""YouTube",
  "width": 480,
  "provider_url""https://www.youtube.com/",
  "height": 270,
  "thumbnail_height": 360,
  "author_url""https://www.youtube.com/user/CarThrottle",
  "thumbnail_width": 480,
  "author_name""Car Throttle",
  "html""<iframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/610rMnK9HCo?feature=oembed\" frameborder=\"0\" allowfullscreen></iframe>",
  "driver""YouTube",
  "harvested_date""Thu, 20 Apr 2017 17:56:34 GMT"
}

Installation

$ npm install --save yoem

Usage

const yoem = require('yoem');
 
const options = {
  // Optionally specify route-level headers, which will be included with every request
  // These can be overridden by service-level headers and request-level headers
  headers: {
    'user-agent': 'Some-Important-Microservice',
  },
 
  // Optionally specify a route-level timeout, which can be overridden at the service level
  // Uses the ms syntax
  timeout: '10s',
 
  // Optionally provide a list of URLs to blacklist
  // Uses micromatch syntax
  blacklist: [
    '*.wikia.com',
  ],
 
  // Optionally pass a proxy URL to route requests through
  // You can either use this option or handle proxies yourself with something like
  //   https://www.npmjs.com/package/global-tunnel
  proxy: 'http://user:pass@proxy.someimportantcompany.com:42318',
 
  // You can specify a fixed list of services that you wish to support,
  // Either from the list of pre-defined ones or by specifying your own:
  services: [
    yoem.services.facebook_posts,
    yoem.services.facebook_videos,
    yoem.services.twitter,
    yoem.services.youtube,
 
    {
      // See below for detailed examples of writing your own services
      name: 'SomeImportantService',
      matches: [ 'someimportantcompany.com/*' ],
      url: 'https://someimportantcompany.com/oembed.json?url={{ url }}',
    },
  ],
 
  // Realistically, you'll probably want to use the default collection of services,
  // and just add your own, which you can do like so:
  services: yoem.services.defaults.concat([
    {
      // See below for detailed examples of writing your own services
      name: 'SomeImportantService',
      matches: [ 'someimportantcompany.com/*' ],
      url: 'https://someimportantcompany.com/oembed.json?url={{ url }}',
    },
  ]),
 
  // Optionally you can choose to override the fallback function, which is
  // called when no service matches a URL. Examples of overriding this
  // would be to only support specific services, and not pull information
  // from the target URL.
  fallback(opts, callback) {
    /**
     * Opts contains all the information Yoem uses to make requests:
     *   url (string): The original URL
     *   url_parsed (object): The url after running through url.parse(), saves you having to do it yourself!
     *   headers (object): A merged object of headers, based on global-level, service-level & request-level headers
     *   proxy (string|undefined): The optional proxy URL
     *   timeout: (int): The timeout (either request-level, service-level or global-level) after passing through ms()
     *   blacklist (array|undefined): An array of hostnames to blacklist against, which you should respect!
     *   service (object): The service object that has been matched against this URL
     *
     * Callback expects:
     *   err (Error): An error object to be returned
     *   result (object): The Oembed response object, conforming to the Oembed specification
     *
     * For this example, fallback() returns an error, which means only services with pre-defined Oembed URLs will be
     * matched, and no scraping will be performed, which could be a desirable outcome.
     */
    callback(new Error(`No oembed service matches ${opts.url}`));
  },
};
 
app.use('/embed', yoem(options));

Services

All services listed on oembed.com are supported (since they are programmatically imported on a regular basis), as well as a few others detailed at src/services.

And of course you can write your own:

{
  services: yoem.services.defaults.concat([
 
    {
      // Specify a name for your service - this is included in the response for sanity checking
      name: 'SomeImportantService',
      // Specify an array of URLs that your service accepts - using micromatch syntax
      matches: [ 'someimportantcompany.com/*' ],
      // Specify a URL that will be hit to collect data - remembering to include the URL too!
      url: 'https://someimportantcompany.com/oembed.json?url={{ url }}',
 
      // Optionally include additional params for your URL, in this case an API key is provided
      params: { api_key: 'f4f4b2d07339fd1aaf10a1d63d45ef6f' },
      // Don't forget to include these params in the URL, otherwise what's the point?
      url: 'https://someimportantcompany.com/oembed.json?url={{ url }}&key={{ api_key }}',
 
      // Optionally specify additional headers for this service
      // These override route-level headers, but not request-level headers
      headers: {
        'X-Awesome-Client': 'glip-glops',
      },
 
      // Optionally specify a service-level timeout, which can be overrides at the route-level timeout
      // Uses the ms syntax
      timeout: '20s',
    },
 
  ]),
}

Questions

Keywords

install

npm i yoem

Downloadsweekly downloads

30

version

1.4.1

license

MIT

homepage

github.com

repository

Gitgithub

last publish

collaborators

  • avatar
Report a vulnerability