非同期でレスポンスを返す
chrome.runtime.onMessageイベントやchrome.runtime.onMessageExternalイベントで非同期でレスポンスを返したい場合、コールバックメソッドでtrueを返せばできるようになる。
chrome.runtime.onMessage.addListener((message, sender, response) => {
asyncMethod((arg) => {
response(arg);
});
return true; // <= trueを返す
});
他の拡張機能やChromeアプリ間でメッセージの送受信を行う
chrome.runtime.sendMessage()の第一引数に他の拡張機能やChromeアプリのIDを指定して実行すると、その拡張機能やChromeアプリにメッセージを送信することができる。
また、他の拡張機能やChromeアプリからメッセージを受け取る場合は、chrome.runtime.onMessageExternalイベントを使用する。
これにより、拡張機能同士や拡張機能とChromeアプリ間といったメッセージ送受信が可能になる。
manifest.jsonにexternally_connectableキーがなくても他の拡張機能やChromeアプリとのメッセージの送受信ができるが、externally_connectableキーがある場合はidsサブキーで送受信を行う他の拡張機能やChromeアプリのIDを指定しないとメッセージの送受信は行えない。(後述するページからメッセージ送信と組み合わせて使う場合など)
メッセージ受信は、backgroundでなければならず、content_scriptでは受け取ることができない。
{
...
"externally_connectable": {
"ids": [
"他の拡張機能やChromeアプリのID"
]
}
// メッセージ送信
chrome.runtime.sendMessage('他の拡張機能やChromeアプリのID', message, (responseMessage) => {
// レスポンス受信処理
,,,
});
chrome.runtime.onMessageExternal.addListener((message, sender, response) => {
// メッセージ受信処理
...
// レスポンスを返す
response(responseMessage);
});
ページからメッセージ送信
manifest.jsonにexternally_connectableキーを追加し、matchesサブキーにURLパターンを設定すれば、
そのURLパターンにマッチしたページから直接メッセージを送信することができる。
この場合も同様に、送信側はchrome.runtime.sendMessageの第一引数に送信する拡張機能のIDを指定して送信、受信側はchrome.runtime.onMessageExternalイベントを使用する。
メッセージ送信でのレスポンスを受信することはできるが、拡張機能側からページに対してchrome.runtime.sendMessageでメッセージを送信することはできない。
送信先は拡張機能に限り、Chromeアプリには送信できないみたい。
また、同様にメッセージの受信はbackgroundでしか行えない。ただ、ページ内でのイベントはcontent_script内でも拾えるので、window.dispatchEvent(CustomEvent)などを使用すれば、ページとcontent_script間でのメッセージ(データ)の送受信は可能である。
{
...
"externally_connectable": {
"matches": [
"https://hoge.fuga/*"
]
}
// メッセージ送信
chrome.runtime.sendMessage('拡張機能のID', message, (responseMessage) => {
// レスポンス受信処理
,,,
});
chrome.runtime.onMessageExternal.addListener((message, sender, response) => {
// メッセージ受信処理
...
// レスポンスを返す
response(responseMessage);
});
ちょっと応用
インラインインストールを実装するとき、公式に書かれている方法では、インストールボタンを最初表示していて対象の拡張機能がインストールされていれば非表示にするという方法をとっており、この方法だと拡張機能をインストールしていてもちらっとインストールボタンが見えてしまう。
ページからメッセージを受信できるようにすれば、インストールされていない場合はsendMessageのresponseがundefinedになるため(拡張機能側では、ページからのインストールチェックメッセージの場合、undefined以外のレスポンスを返すようにする)、インストールボタンを最初非表示にしておき、undefinedだったら表示させるようにすればちらっと見えたりすることなくインストールボタン表示の制御が可能になる。