FIX: use oEmbed for Instagram onebox.

FIX: use oEmbed for Instagram onebox.

diff --git a/lib/onebox/engine/instagram_onebox.rb b/lib/onebox/engine/instagram_onebox.rb
index f847736..ae35765 100644
--- a/lib/onebox/engine/instagram_onebox.rb
+++ b/lib/onebox/engine/instagram_onebox.rb
@@ -1,7 +1,5 @@
 # frozen_string_literal: true
 
-require 'htmlentities'
-
 module Onebox
   module Engine
     class InstagramOnebox
@@ -9,25 +7,43 @@ module Onebox
       include StandardEmbed
       include LayoutSupport
 
-      matches_regexp(/^https?:\/\/(?:www\.)?(?:instagram\.com|instagr\.am)\/?(?:.*)\/p\//)
+      matches_regexp(/^https?:\/\/(?:www\.)?(?:instagram\.com|instagr\.am)\/?(?:.*)\/p\/[a-zA-Z\d_-]+/)
       always_https
 
-      def data
-        og = get_opengraph
-        title = og.title.split(":")[0].strip.gsub(" on Instagram", "")
-
-        json_data = html_doc.xpath('//script[contains(text(),"window._sharedData")]').text.to_s
-        title = "[Album] #{title}" if json_data =~ /"edge_sidecar_to_children"/
+      def clean_url
+        url.scan(/^https?:\/\/(?:www\.)?(?:instagram\.com|instagr\.am)\/?(?:.*)\/p\/[a-zA-Z\d_-]+/).flatten.first
+      end
 
-        result = { link: og.url,
-                   title: Onebox::Helpers.truncate(title, 80),
-                   description: og.description(250)
+      def data
+        oembed = get_oembed
+        permalink = clean_url.gsub("/#{oembed.author_name}/", "/")
+        description = oembed.title
+        type = if description =~ /^Photos by/
+          "album"
+        elsif description =~ /^Video by/
+          "video"
+        else
+          "photo"
+        end
+        title = if type == "album"
+          "[Album] @#{oembed.author_name}"
+        else
+          "@#{oembed.author_name}"
+        end
+
+        result = { link: permalink,
+                   title: title,
+                   image: "#{permalink}/media/?size=l",
+                   description: Onebox::Helpers.truncate(description, 250)
                   }
+        result[:video_link] = permalink if type == "video"
+        result
+      end
 
-        result[:image] = og.image if !og.image.nil?
-        result[:video_link] = og.url if !og.video_secure_url.nil?
+      protected
 
-        result
+      def get_oembed_url
+        oembed_url = "https://api.instagram.com/oembed/?url=#{clean_url}"
       end
     end
   end
diff --git a/spec/fixtures/instagram.response b/spec/fixtures/instagram.response
index 6c3d4e7..2f0f432 100644
--- a/spec/fixtures/instagram.response
+++ b/spec/fixtures/instagram.response
@@ -1,345 +1,17 @@
-<!DOCTYPE html>
-<html lang="en" class="no-js not-logged-in client-root">
-    <head>
-        <meta charset="utf-8">
-        <meta http-equiv="X-UA-Compatible" content="IE=edge">
-
-        <title>
-National Geographic on Instagram: “Photo @ladzinski / Adorableness aside, companionship from pets is proven to lower blood pressure and increase oxytocin, a hormone that…”
-</title>
-
-
-        <meta name="robots" content="noimageindex, noarchive">
-        <meta name="apple-mobile-web-app-status-bar-style" content="default">
-        <meta name="mobile-web-app-capable" content="yes">
-        <meta name="theme-color" content="#ffffff">
-        <meta id="viewport" name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, viewport-fit=cover">
-        <link rel="manifest" href="/data/manifest.json">
-
-        <link rel="preload" href="/static/bundles/metro/ConsumerUICommons.css/376c16df040f.css" as="style" type="text/css" crossorigin="anonymous" />
-<link rel="preload" href="/static/bundles/metro/ConsumerAsyncCommons.css/b89a1ccfaa6e.css" as="style" type="text/css" crossorigin="anonymous" />
-<link rel="preload" href="/static/bundles/metro/Consumer.css/aa65d84a486c.css" as="style" type="text/css" crossorigin="anonymous" />
-<link rel="preload" href="/static/bundles/metro/PostPageContainer.css/e8e152153a56.css" as="style" type="text/css" crossorigin="anonymous" />
-<link rel="preload" href="/static/bundles/metro/Vendor.js/5a56d51ae30f.js" as="script" type="text/javascript" crossorigin="anonymous" />
-<link rel="preload" href="/static/bundles/metro/en_US.js/75c323f42cee.js" as="script" type="text/javascript" crossorigin="anonymous" />
-<link rel="preload" href="/static/bundles/metro/ConsumerLibCommons.js/c278d02f018f.js" as="script" type="text/javascript" crossorigin="anonymous" />
-<link rel="preload" href="/static/bundles/metro/ConsumerUICommons.js/adadc46dad46.js" as="script" type="text/javascript" crossorigin="anonymous" />
-<link rel="preload" href="/static/bundles/metro/ConsumerAsyncCommons.js/05fde2fa93ee.js" as="script" type="text/javascript" crossorigin="anonymous" />
-<link rel="preload" href="/static/bundles/metro/Consumer.js/342978c8bbac.js" as="script" type="text/javascript" crossorigin="anonymous" />
-<link rel="preload" href="/static/bundles/metro/PostPageContainer.js/d76471f2ff47.js" as="script" type="text/javascript" crossorigin="anonymous" />
-
-
-
-        <script type="text/javascript">
-        (function() {
-  var docElement = document.documentElement;
-  var classRE = new RegExp('(^|\\s)no-js(\\s|$)');
-  var className = docElement.className;
-  docElement.className = className.replace(classRE, '$1js$2');
-})();
-</script>
-        <script type="text/javascript">
-(function() {
-  if ('PerformanceObserver' in window && 'PerformancePaintTiming' in window) {
-    window.__bufferedPerformance = [];
-    var ob = new PerformanceObserver(function(e) {
-      window.__bufferedPerformance.push.apply(window.__bufferedPerformance,e.getEntries());
-    });
-    ob.observe({entryTypes:['paint']});
-  }
-
-  window.__bufferedErrors = [];
-  window.onerror = function(message, url, line, column, error) {
-    window.__bufferedErrors.push({
-      message: message,
-      url: url,
-      line: line,
-      column: column,
-      error: error
-    });
-    return false;
-  };
-  window.__initialData = {
-    pending: true,
-    waiting: []
-  };
-  function asyncFetchSharedData(extra) {
-    var sharedDataReq = new XMLHttpRequest();
-    sharedDataReq.onreadystatechange = function() {
-          if (sharedDataReq.readyState === 4) {
-            if(sharedDataReq.status === 200){
-              var sharedData = JSON.parse(sharedDataReq.responseText);
-              window.__initialDataLoaded(sharedData, extra);
-            }
-          }
-        }
-    sharedDataReq.open('GET', '/data/shared_data/', true);
-    sharedDataReq.send(null);
-  }
-  function notifyLoaded(item, data) {
-    item.pending = false;
-    item.data = data;
-    for (var i = 0;i < item.waiting.length; ++i) {
-      item.waiting[i].resolve(item.data);
-    }
-    item.waiting = [];
-  }
-  function notifyError(item, msg) {
-    item.pending = false;
-    item.error = new Error(msg);
-    for (var i = 0;i < item.waiting.length; ++i) {
-      item.waiting[i].reject(item.error);
-    }
-    item.waiting = [];
-  }
-  window.__initialDataLoaded = function(initialData, extraData) {
-    if (extraData) {
-      for (var key in extraData) {
-        initialData[key] = extraData[key];
-      }
-    }
-    notifyLoaded(window.__initialData, initialData);
-  };
-  window.__initialDataError = function(msg) {
-    notifyError(window.__initialData, msg);
-  };
-  window.__additionalData = {};
-  window.__pendingAdditionalData = function(paths) {
-    for (var i = 0;i < paths.length; ++i) {
-      window.__additionalData[paths[i]] = {
-        pending: true,
-        waiting: []
-      };
-    }
-  };
-  window.__additionalDataLoaded = function(path, data) {
-    if (path in window.__additionalData) {
-      notifyLoaded(window.__additionalData[path], data);
-    } else {
-      console.error('Unexpected additional data loaded "' + path + '"');
-    }
-  };
-  window.__additionalDataError = function(path, msg) {
-    if (path in window.__additionalData) {
-      notifyError(window.__additionalData[path], msg);
-    } else {

[... diff too long, it was truncated ...]

GitHub sha: ee82c858

1 Like

Instagram oEmbed Documentation: https://developers.facebook.com/docs/instagram/embedding/

1 Like