Support » Fixing WordPress » New Instagram API for OEmbed

  • Hello,

    I was struggling the last hour with integrating an embed instagram link to my blog pos. While debugging the WP core code, I discovered that WordPress is relying on a recently deprecated API for Instagram. Three days ago, Facebook shut down the Instagram API running at https://api.instagram.com/oembed. See: https://developers.facebook.com/docs/instagram/oembed/

    Currently, one can reproduce it by trying out the Instagram Gutenberg block with a valid link. In the logs, one may notice the response from the respective WordPress AJAX endpoint:
    {"code":"oembed_invalid_url","message":"Not Found","data":{"status":404}}

    So in wp-includes/class-wp-oembed.php:75 you need to replace ‘https://api.instagram.com/oembed’ with ‘https://graph.facebook.com/v8.0/instagram_oembed’. Further, the API now requires an access token to be defined, so this whole logic might fail since the user needs to define his app id & client secret somewhere in the admin interface.

    Until this is fixed in the WordPress core, one can use my code to replace the endpoint and collect the access token manually:

    
    add_filter('oembed_providers', 'fr_replace_deprecated_instagram_api', 10, 1);
    function fr_replace_deprecated_instagram_api($providers) {
      unset($providers['#https?://(www\.)?instagr(\.am|am\.com)/(p|tv)/.*#i']);
      $providers['#https?://(www\.)?instagr(\.am|am\.com)/(p|tv)/.*#i'] = array('https://graph.facebook.com/v8.0/instagram_oembed', true);
      return $providers;
    }
    
    // You need to create a developer account for Facebook's API and grant permission for the "OEmbed" App.
    define('FR_FACEBOOK_APP_ID', 'APP_ID');
    define('FR_FACEBOOK_CLIENT_SECRET', 'CLIENT_SECRET');
    define('FR_FACEBOOK_TOKEN_URI', 'https://graph.facebook.com/oauth/access_token?client_id=' . FR_FACEBOOK_APP_ID . '&client_secret=' . FR_FACEBOOK_CLIENT_SECRET . '&grant_type=client_credentials');
    
    add_filter('oembed_fetch_url', 'fr_add_facebook_access_token', 10, 3);
    function fr_add_facebook_access_token($provider, $url, $args) {
      if (strpos($provider, 'instagram_oembed') !== -1) {
        $response = @file_get_contents(FR_FACEBOOK_TOKEN_URI);
        if (!$response) {
          trigger_error("Couldn't retrieve an access token for Instagram OEmbed API by Facebook. Check your App ID, Client Secret & the permissions in the Facebook Developer Dashboard.", E_USER_WARNING);
          return $provider;
        }
        $response = json_decode($response);
        $access_token = $response->access_token;
        $provider .= '&access_token=' . $access_token;
      }
      return $provider;
    }
    

    Additionally, the docs state that only ‘https://www.instagram.com/p/{media-shortcode}/’ and ‘https://www.instagram.com/tv/{media-shortcode}/’ are supported while the WP code also accepts ‘instagr.am’ instead of ‘instagram.com’. I just tested it: ‘instagr.am’ works fine, the Facebook docs are just not complete regarding this fact 🙂

    Greetings,
    Thomas

    • This topic was modified 11 months, 4 weeks ago by chaoste.
Viewing 5 replies - 1 through 5 (of 5 total)
  • The embeds for Instagram and Facebook are scheduled to be removed from WordPress in 5.5.2, which is coming next week (I think). It just takes awhile for things to happen…
    https://core.trac.wordpress.org/ticket/50861

    Hello @chaoste
    Your code is really amazing, its solve Instagram embed problem on my site! Have you got a similar code to solve the Facebook embeds problems?

    It would be amazing!
    Thanks

    Thread Starter chaoste

    (@chaoste)

    Hi @victorrest,

    In general, I’d suggest you to look out for a separate plugin with its own embed widgets (e.g. https://wordpress.org/plugins/embedalbum-pro/).

    If you really want to fix the endpoints (even though it will be removed completely this week), you might have a look into the new endpoints by Facebook for OEmbed:
    https://developers.facebook.com/docs/plugins/oembed/

    Example for FB posts:

    
    add_filter('oembed_providers', 'fr_replace_deprecated_fb_post_api', 10, 1);
    function fr_replace_deprecated_fb_post_api($providers) {
      unset($providers['#https?://www\.facebook\.com/.*/posts/.*#i']);
      $providers['#https?://www\.facebook\.com/.*/posts/.*#i'] = array('https://graph.facebook.com/v8.0/oembed_post', true);
      return $providers;
    }
    

    The filter for acquiring the access token just needs to consider this API, too:

    
    add_filter('oembed_fetch_url', 'fr_add_facebook_access_token', 10, 3);
    function fr_add_facebook_access_token($provider, $url, $args) {
      if (strpos($provider, 'instagram_oembed') !== -1 || strpos($provider, 'oembed_post')) {
        $response = @file_get_contents(FR_FACEBOOK_TOKEN_URI);
        if (!$response) {
          trigger_error("Couldn't retrieve an access token for Facebooks OEmbed API. Check your App ID, Client Secret & the permissions in the Facebook Developer Dashboard.", E_USER_WARNING);
          return $provider;
        }
        $response = json_decode($response);
        $access_token = $response->access_token;
        $provider .= '&access_token=' . $access_token;
      }
      return $provider;
    }
    

    @joyously Thanks for pointing out. Sadly, this means my work is useless :/

    Greetings,
    Thomas

    Thanks @chaoste, it’s work! Amazing 🙂

Viewing 5 replies - 1 through 5 (of 5 total)
  • The topic ‘New Instagram API for OEmbed’ is closed to new replies.