@adrfelipe
That is the opposite of what I said. I don't even think what you wrote is possible. IFrames are sandboxed and don't have access to APIs. Perhaps they would be if you're storing the HTML in the files section of Canvas rather than on an external server (I would discourage that approach),
The iFrame would not have access to the API to make the call. The code that you inject into the custom JavaScript would have to have the postMessage. Your iFrame HTML would have to have its own JavaScript that would have an eventListener for the "message" event type to listen for the message sent by the postMessage sent from the parent frame and then act on it.
As for the best method, I would not go that far. I think the best method is probably to use an external tool or LTI, but there are cases where that isn't going to work for people. But with an external LTI, Canvas can pass all of the information that you need to pass to the external tool and then it can act on it and deliver the content.
An LTI is not the easiest way (easiest is different from best). My solution was based off of what you had written that you already had working. My confusion was why you would be using postMessage in the first place if you didn't know about the eventListener so that you could use it?
Canvas has an eventListener for messages coming from LTIs. It allows you to request a full window launch, toggle the course navigation menu, hide the right side wrapper, resize the iframe, get the window size, show the module navigation, scroll to the top of the page, show an alert for screen readers, show an alert using the Canvas system, enable scroll events, and a couple of others.
Some of those require a token that is sent during the LTI launch, but others could be used by JavaScript acting within an iFrame. However, most of those are probably not things that you need, so if you were to do it the way you wrote and try to post a message from the iframe to the parent frame by adding an event listener in the custom JavaScript and the postMessage in the JavaScript within an iframe, you would want to make sure that the events bubble back to Canvas' handler so you didn't break other things. It's much saner to add the postMessage in the global JavaScript and the event listener in the JavaScript within your HTML file.