Search code examples
javascriptgoogle-chrometwittergoogle-chrome-extensioninstagram-api

Adding Instagram into Tweetdeck


I finally got fed up with Tweetdeck and the inability for it to load images from Instagram. So i've decided to solve the problem using a Chrome Extension. It's quite a difficult thing to do since Tweetdeck has very strict content security policies. However I have found a work around.

Using the Instagram embedding code we can extract the ID of the image and form a new image based on the ID. This is a link to a 301 redirect to the actual image. However when I try and run this on Tweetdeck a random transparent .png appears. Which forces this error:

Refused to load the image 'http://images.instagram.com/transparent.gif' because it violates the following Content Security Policy directive: "img-src https: data:".

I can't seem to find where this png is coming from, it's not being loaded by my app, nor instagram. It is breaking everything else and causing the 301 redirect to be cancelled.

Any help would be greatly appreciated.

Manifest

{
  "manifest_version": 2,
  "name": "Instagram for TweetDeck",
  "description": "This extension will show thumbnails for instagram on TweetDeck",
  "version": "1.0",
  "content_security_policy": "script-src 'self'; object-src 'self'; img-src http: https: data:",
  "content_scripts": [
     {
       "matches": ["https://tweetdeck.twitter.com/"],
       "js": ["instagram_tweetdeck.js"]
     }
  ]
}

JS File

var func = function () {

var Instagram = function () {
    this.links = [];
};

Instagram.prototype.add = function (url, element) {

    if (this.links.indexOf(url) !== -1) {
        // already done this link
        return;
    }
    this.links.push(url);

    var id = url.substr(url.indexOf('/p/')).replace('/p/', '').replace('/', '');

    obj = document.createElement('img');
    obj.src = 'https://instagram.com/p/' + id + '/media/?size=m';
    obj.width = "230";
    obj.style.marginTop = "10px";
    element.parentNode.insertBefore(obj, element);
};


var instagram = new Instagram();

var poll = function () {
    var nodes = document.getElementsByTagName('a');
    for (var i = 0; i < nodes.length; i++) {
        if (nodes[i].innerHTML.indexOf('instagram.com') !== -1) {
            instagram.add(nodes[i].innerHTML, nodes[i]);
        }
    }
};

setInterval(poll, 500);
};

var script = document.createElement("script");
script.textContent = "(" + func.toString() + ")();";
document.body.appendChild(script);

Solution

  • Try to add in your manifest.json:

    "permissions": [
        "*://*.instagram.com",
        "*://*.twitter.com"
    ],
    

    From the Chrome Extension documentation of XHR:

    Requesting cross-origin permissions

    By adding hosts or host match patterns (or both) to the permissions section of the manifest file, the extension can request access to remote servers outside of its origin.

    Useful links

    Edit: Make sure scripts are executed in the correct way see here for more detail.