Considering that you said you can modify the remote website's code, and I don't see how to fix the postMessage solution, here are a couple of alternatives. I would love to know if there is a way to fix the postMessage approach, as it is the recommended one from the docs!
First off, you will need to coordinate your scripts from a central background page, which can keep track of open tabs.
Custom DOM events
This is an old recommendation from Chrome docs, that was replaced with window.postMessage example. It is described here (disregard the old chrome.extension.connect API) and consists of firing a custom event in shared DOM.
So, a sample architecture would be a background page deciding which tab to post message to, and sending that tab a message via chrome.tabs.sendMessage, to which your content script listens with chrome.runtime.onMessage. The tab's content script can then communicate with the page using the above custom event technique.
One possible approach to keeping tack of tabs: have the tabs permission to be able to enumerate all open tabs with the chrome.tabs API. Your background page can then decide which tab to message based on URL.
Another possible approach, to eliminate need for the scary tabs permission, is to have your content scripts report to the background page with chrome.runtime.connect as soon as they are initialized. The background page then can keep track of all active instances of your script and therefore decide which tab to message.
Webpage connecting to your extension
This is a "modern" way of doing communication with one exact extension.
It is described in the Chrome docs here. You can define your extension as externally connectable from your webpage, and your webpage initiates a port connection with your background script.
Then, as above, you can track live ports and use them for communication, cutting out the content script middleman.