0

I am working on an extension. It is a product tracking extension. When the page loads it inject a button in product page and when user clicks the button It authenticate that user using google oauth2. I have done authentication but now I am unable to send message from oauth.js (popup.js) to content.js

I have tried all the same kind of solutions here so many times but I think my problem is different.

Sometimes message receive in content.js after 5 seconds of sending but most of the time it does not

Sometimes message receive after 5,6 seconds but most of the time it does not. A message often shows(not always)

"Unchecked runtime.lastError: The message port closed before a response was received."

Message is sending when authentication api send response.

Please have a look. The user clicks this button

https://www.screencast.com/t/TVm7OW1t2GP

A popup opens to authenticate user

https://www.screencast.com/t/lhEWel1OskHf

When user authenticate by clicking the button then I am getting userinfo using api and then wants to send that info to content.js

I have already tried these links:

Here is the code

menifest.json

{
"update_url": "https://clients2.google.com/service/update2/crx",

   "background": {
      "scripts": [ "scripts/background.js" ]
   },
   "content_scripts": [ {

      "all_frames": false,
      "css": [ "styles/main.css" ],
      "js": [ "bower_components/jquery/dist/jquery.min.js", "scripts/contentscript.js" ],
      "matches": [ "<all_urls>","http://*.flipkart.com/*", "https://*.flipkart.com/*", "http://*.amazon.com/*", "https://*.amazon.in/*", "http://*.snapdeal.com/*", "https://*.snapdeal.com/*", "http://*.jabong.com/*", "https://*.jabong.com/*", "http://*.infibeam.com/*", "https://*.infibeam.com/*", "http://*.paytm.com/*", "https://*.paytm.com/*" ],
      "run_at": "document_end"
   } ],
   "description": "Track product prices on Amazon.in, Flipkart, Snapdeal, Jabong, Infibeam, etc.. and save money!",
   "externally_connectable": {
      "matches": [ "*://*.pricetrack.abc/*" ]
   },
   "icons": {
      "128": "images/icon-128.png",
      "16": "images/icon-16.png"
   },
   "oauth2": {
    "client_id": "774-a5iurgts5hi81lrfhgtb4esdfqqi76n8.apps.googleusercontent.com",
    "scopes":["openid", "email", "profile","https://www.googleapis.com/auth/contacts.readonly"]
  },
  "browser_action": {       
    "default_title": "filter",
    "default_popup": "popup.html"
  },

  "key": "MIIBIjANBgsfdfB",
   "manifest_version": 2,
   "name": "PriceTrack.In Shopping Assistant",
   "permissions": [  "identity","cookies", "storage", "tabs", "alarms", "webRequest", "*://*.pricetrack.in/*", "http://*.flipkart.com/*", "https://*.flipkart.com/*", "http://*.amazon.com/*", "https://*.amazon.in/*", "http://*.snapdeal.com/*", "https://*.snapdeal.com/*", "http://*.jabong.com/*", "https://*.jabong.com/*", "http://*.infibeam.com/*", "https://*.infibeam.com/*", "http://*.paytm.com/*", "https://*.paytm.com/*" ],
   "version": "0.0.5",
   "web_accessible_resources": [ "images/*.gif" ]
}

contentscript.js

"use strict";

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
      console.log('here3');
    if( request.message === "clicked_browser_action" ) {
        console.log('here');
      // var firstHref = $("a[href^='http']").eq(0).attr("href");

      // // console.log(firstHref);
      // // alert(firstHref);
      // // This line is new!
      // chrome.runtime.sendMessage({"message": "open_new_tab", "url": firstHref});
    }
  }
);

// chrome.runtime.onMessage.addListener(
// function(request, sender, sendResponse) {
//     console.log(sender.tab ?
//                 "from a content script:" + sender.tab.url :
//                 "from the extension");


//     console.log("received message from popup: "+request.greeting);

//     sendResponse({farewell: "I'm good, thank you popup!"});
// });

function getPid(a) {
    return a.indexOf("flipkart") >= 0 ? jq(".btn-buy-now").attr("data-pid") : a.indexOf("amazon") >= 0 ? jq("#ASIN").val() : a.indexOf("snapdeal") >= 0 ? jq("#productId").val() : a.indexOf("jabong") >= 0 ? jq("#catalogConfigId").val() : a.indexOf("infibeam") >= 0 ? jq("#listingId").val() : a.indexOf("paytm") >= 0 ? jq("#listingId").val() : void 0
}

function getButtonText(a) {
    return "<br/><div style='text-align:center'><button id=\"ptadd\" class='" + a + ' pure-button button-success button-xlarge\'>Add to pricetrack</button><div id="ptprogress" class="noshow"><img src="' + chrome.extension.getURL("images/progress.gif") + '"/></div><div id="ptaddstatus"/></div></br>'
}

function getPid(a) {
    return a.indexOf("flipkart") >= 0 ? jq(".btn-buy-now").attr("data-pid") : a.indexOf("amazon") >= 0 ? jq("#ASIN").val() : a.indexOf("snapdeal") >= 0 ? jq("#productId").val() : a.indexOf("jabong") >= 0 ? jq("#catalogConfigId").val() : a.indexOf("infibeam") >= 0 ? jq("#listingId").val() : a.indexOf("paytm") >= 0 ? jq("#listingId").val() : void 0
}

var host = "https://pricetrack.in",
    getItemURL = host + "/getItems",
    checkURL = host + "/check",
    addItemURL = host + "/addItem",
    jq = $.noConflict(),
    attachListener = function(a, b, c) {

        // console.log(a);
        //  console.log(b);
        //   console.log(c);
        //   alert(a);
        //    alert(b);
        //   alert(c);


        //when click on green button
        jq("#ptadd") ? jq("#ptadd").off("click").click(function(d) {
            d.preventDefault(), jq("#ptprogress").addClass("show"), jq("#ptaddstatus").html("");
            chrome.runtime.sendMessage("ptlogin", function(a) {

            });

            // var e = new XMLHttpRequest;
            // e.open("GET", checkURL, !0), e.onload = function(d) {
            //     if (4 === e.readyState){
            //         if (200 !== e.status){ 
            //             jq("#ptprogress").removeClass("show"), jq("#ptaddstatus").html("You need to login to pricetrack.in. Try to add product after logging in."), chrome.runtime.sendMessage("ptlogin", function(a) {
            //                 console.log("Got response - " + a)
            //             });
            //         }    
            //         else {
            //             console.log("User is logged in");
            //             var f = new XMLHttpRequest;
            //             f.open("POST", addItemURL, !0), f.setRequestHeader("Content-Type", "application/json"), f.send('{"url":"' + a + '"}'), f.onload = function(a) {
            //                 if (4 === f.readyState)
            //                     if (jq("#ptprogress").removeClass("show"), 200 !== f.status) jq("#ptaddstatus").html("Failed to add product to watchlist"), console.log("Failed to add product");
            //                     else {
            //                         var d = f.responseText,
            //                             e = JSON.parse(d);
            //                         console.log("Add  product response " + d), e && e.msg && "T" === e.msg ? (jq("#ptaddstatus").html("Added product to watchlist"), jq("#ptadd").hide(), b && (c.trackedItems || (c.trackedItems = []), c.trackedItems.push(b), chrome.storage.sync.set(c, function() {
            //                             console.log("Saved new item")
            //                         }))) : (jq("#ptaddstatus").html("Failed to add product to watchlist"), console.log("Failed to add"))
            //                     }
            //             }
            //         }
            //     }    
            // }, e.send()
        }) : console.error("Could not attach listener to pricetrack button")
    },
    renderButton = function(a, b, c) {
        var d, e = jq("button.ptadd");
        if (e && e.length > 0) return void console.log("Add to pricetrack button added");
        if (a.indexOf("flipkart") >= 0) d = jq("button._3zLR9i._3Plo8Q._16LyaZ._36SmAs"), d && d.length > 0 && (console.info("This is a flipkart product page " + a), d.parent().closest("form").after("<div><center><br/>" + getButtonText("flipkart") + "</center></div>"));
        else if (a.indexOf("amazon") >= 0) {
            var f = "([A-Z0-9]{10})",
                g = "0",
                h = a.match(f);
            h && 2 === h.length && (g = h[0]), "0" !== g && (console.info("This is amazon product page " + a), jq("#add-to-cart-button").parent().closest("div").before(getButtonText("amazon")), jq("#bb_atc_button").parent().closest("div").before(getButtonText("amazon")), jq("#buybox-see-all-buying-choices-announce").parent().closest("div").before(getButtonText("amazon")))
        } else a.indexOf("snapdeal") >= 0 ? (d = jq("#buy-button-id"), d && d.length > 0 && (console.info("This is a snapdeal product page " + a), d.parent().closest("div").before(getButtonText("flipkart")))) : a.indexOf("jabong") >= 0 ? (d = jq("#add-to-cart"), d && d.length > 0 && (console.info("This is a jabong product page " + a), d.parent().closest("div").before(getButtonText("flipkart")))) : a.indexOf("infibeam") >= 0 ? (d = jq("input.buyimg.buy-image.btn-image-buy"), d && d.length > 0 && (console.info("This is a infibeam product page " + a), d.parent().closest("div").before(getButtonText("flipkart")))) : a.indexOf("paytm") >= 0 && (d = jq("div.buy-bar > button.md-button"), d && d.length > 0 && (console.info("This is a paytm product page " + a), d.closest("div").after(getButtonText("flipkart"))));
        attachListener(a, b, c)
    },
    renderButtonInital = function() {
        var a = jq(location).attr("href");
        chrome.storage.sync.get("trackedItems", function(b) {
            var c = b;
            console.log("Found stored items: " + JSON.stringify(c));
            var d = getPid(a);
            console.log("PID is " + d), c && c.trackedItems && -1 !== c.trackedItems.indexOf(d) ? console.log(d + " is in stored data") : renderButton(a, d, b)
        })
    };
jq(document).ready(function() {

    var a = jq(location).attr("href");
    a.indexOf("flipkart") < 0 && a.indexOf("paytm") < 0 && renderButtonInital()
}); 
// chrome.runtime.onMessage.addListener(function(a, b, c) {
//     if (console.log("Got message in content script " + a.action), "getItems" === a.action) {
//         var d = new XMLHttpRequest;
//         d.open("GET", getItemURL, !0), d.onload = function(a) {
//             4 === d.readyState && (200 !== d.status ? console.log("Failed to fetch tracked items list") : chrome.storage.sync.set({
//                 trackedItems: JSON.parse(d.responseText)
//             }, function() {
//                 console.log("Saved " + JSON.parse(d.responseText))
//             }))
//         }, d.send()
//     } else "renderButton" === a.action && renderButtonInital()
// });

oauth.js

'use strict';

window.onload = function() {
  document.querySelector('button').addEventListener('click', function() {
    chrome.identity.getAuthToken({interactive: true}, function(token) {
      var init = {
        method: 'GET',
        async: true,
        headers: {
          Authorization: 'Bearer ' + token,
          'Content-Type': 'application/json'
        },
        'contentType': 'json'
      };
      console.log(token);

      if (token) {
        //alert('Already Logged in');
         console.log(token);
          var x = new XMLHttpRequest();
          x.open('GET', 'https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=' + token);
          x.onload = function() {
              console.log(x.response);
                chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
                var activeTab = tabs[0];
                console.log(activeTab.id);
                chrome.tabs.sendMessage(activeTab.id, {"message": "clicked_browser_action"});
              });
          };

          x.send();

      }
    });
  });
};

=============================

background.js

"use strict";

function popUpCreationCallBack(a) {
    popupTabId = a
}
chrome.runtime.onInstalled.addListener(function(a) {
    console.log("previousVersion", a.previousVersion)
});
var webRequestCallBack = function(a) {
        (a.url.indexOf("api/3/page/dynamic/product") > 0 || a.url.indexOf("catalog.paytm.com/v1/p") > 0) && (console.log(JSON.stringify(a)), chrome.tabs.sendMessage(a.tabId, {
            action: "renderButton"
        }, function(b) {
            console.log(b + " - sending renderButton messsage to tab " + a.tabId)
        }))
    },
    metadata = {
        urls: ["*://*.pricetrack.in/*", "http://*.flipkart.com/*", "https://*.flipkart.com/*", "http://*.amazon.in/*", "https://*.amazon.in/*", "http://*.snapdeal.com/*", "https://*.snapdeal.com/*", "http://*.jabong.com/*", "https://*.jabong.com/*", "http://*.infibeam.com/*", "https://*.infibeam.com/*", "http://*.paytm.com/*", "https://*.paytm.com/*"]
    };
chrome.webRequest.onCompleted.addListener(webRequestCallBack, metadata);
var refreshTrackedItemAlarm = "refreshTrackedItemAlarm";
chrome.alarms.create(refreshTrackedItemAlarm, {
    delayInMinutes: 1,
    periodInMinutes: 30
}), chrome.alarms.onAlarm.addListener(function(a) {
    a.name === refreshTrackedItemAlarm && chrome.tabs.query({
        active: !0
    }, function(a) {
        a.forEach(function(a) {
            (a.url.indexOf("flipkart") > 0 || a.url.indexOf("amazon") > 0 || a.url.indexOf("snapdeal") > 0 || a.url.indexOf("jabong") > 0 || a.url.indexOf("infibeam") > 0 || a.url.indexOf("paytm") > 0) && chrome.tabs.sendMessage(a.id, {
                action: "getItems"
            }, function(a) {
                console.log(a + " - sending messsages to tab")
            })
        })
    })
}), console.log("'Allo 'Allo! Event Page for Page Action");

var popupTabId;
chrome.runtime.onMessage.addListener(function(a, b, c) {
    if (console.log("Got request internal - " + a), "ptlogin" === a) {
        var d = 440,
            e = 440,
            f = screen.width / 2 - d / 2,
            g = screen.height / 2 - e / 2;
        chrome.tabs.create({
            url: chrome.extension.getURL("dialog.html"),
            active: !1
        }, function(a) {
            chrome.windows.create({
                tabId: a.id,
                type: "popup",
                focused: !0,
                width: d,
                height: e,
                left: f,
                top: g
            }, popUpCreationCallBack(a.id))
        })
    }
    return !0
}), chrome.runtime.onMessageExternal.addListener(function(a, b, c) {
    return console.log("Got request external - " + a), "closepopup" === a && popupTabId && (c("closed"), chrome.tabs.remove(popupTabId), console.log("Popup closed")), !0
});

dialog.html

<!DOCTYPE html>
<html>

<head>
    <title>Login to Pricetrack.In</title>
    <link rel="stylesheet" type="text/css" href="styles/main.css">
    <script type="text/javascript" src="scripts/oauth.js"></script>
</head>

<body>
    <CENTER>
        <div style="width: 90%">
            <ul style="list-style-type: none;padding: 0;margin: 0;">
                <li style="margin-bottom : 15px;">
                    <!-- <a href="https://www.pricetrack.in/auth/google?redirect=/ptlogindone" class="button-success pure-button button-xlarge">Sign In with Google</a> -->
                    <button>Sign In with Google</button>
                </li>
        </div>
    </CENTER>
</body>

</html>
halfer
  • 19,824
  • 17
  • 99
  • 186
dev
  • 555
  • 1
  • 13
  • 31
  • The problem is caused by your onMessage listener returning true (`return !0`) so the messaging channel is kept open, but you never use sendResponse inside. Either remove `return !0` or make sure sendResponse is used **and** the calling code has a callback. – wOxxOm Jun 08 '19 at 10:18
  • @wOxxOm i have commented all !0 in the background.js but nothing happens. Also this error is now showing when i click auth button Unchecked runtime.lastError: The message port closed before a response was received. – dev Jun 08 '19 at 10:43
  • Make sure to click the reload icon in chrome://extensions page and also reload the relevant web page. Also make sure you've unified sendMessage/sendResponse/callbacks as suggested. – wOxxOm Jun 08 '19 at 11:12
  • @wOxxOm i am refreshing and also tried to close and open browser. Nothing working. – dev Jun 08 '19 at 11:19
  • Well, I don't think I can help without debugging the actual extension myself, which I'm reluctant to do, so I'll just reiterate the importance of what I said above: you should either remove callbacks from all of your sendMessage calls or add proper sendResponse into onMessage listeners. You may also want to simply suppress the error if everything else is working correctly by adding a line like `chrome.runtime.lastError;` to all of API callbacks. – wOxxOm Jun 08 '19 at 11:32

0 Answers0