Google Chromeの拡張機能の Native Message で、Service Workerとして動作している “background.js” で chrome.runtime.sendNativeMessage を実行した場合に “TypeError: chrome.runtime.sendNativeMessage is not a function” エラーになる場合の原因と対処法を備忘録的に投稿しておきます。
Native Messageで外部プログラムを実行
Chrome 拡張機能では外部のプログラムを実行できる Native Message 機能を利用が利用できます。
先回、C#のコンソールアプリを自作して Chrome拡張機能のアイコンをクリックしたイベントで実行させるための手順を紹介していきます。
詳しい内容は別記事をご覧ください。
関数が見つからない原因
例えば、次のようなコードを実行した場合に
chrome.contextMenus.onClicked.addListener(async (info, tab) => {
chrome.scripting.executeScript({
target: { tabId: tab.id },
func: async (m3u8Url) => {
chrome.runtime.sendNativeMessage(
'native.message.sample',
{param1:'Hello', param2: str},
errorHandle(function(response, thread) {
console.log(response);
return true;
}
));
}
}
“TypeError: chrome.runtime.sendNativeMessage is not a function” エラーになる場合があります。
直訳すると “[sendNativeMessage]関数が見つからない” で、関数が書かれている場所(スコープ)では、関数が見つからないという理由です。
ドキュメントを確認すると、”sendNativeMessage” や “connectNative” は、Service Worker 内で実行する必要があるらしい。
[manifest.js] では[background.js]を Service Worker として実行しているはずなのにエラーになってしました。
{
"name": "ネイティブメッセージ",
"manifest_version": 3,
"version": "0.1",
"permissions": ["activeTab", "nativeMessaging"],
"action": {
"default_icon": "icons/icon-48.png"
},
"icons": {
"48": "icons/icon-48.png",
"128": "icons/icon-128.png"
},
"background": {
"service_worker": "background.js"
}
}
ここから先は難解なんですが、[chrome.scripting.executeScript]で囲まれた部分は、どうやら Service Worker ではない部分(つまり contents_script な部分)のようで、ここに書いているのがエラーの原因でした。
エラーの対処法
原因が分かれば、対処法としては比較的簡単で[chrome.runtime.onMessage]で迂回させます。
まずは、[chrome.scripting.executeScript]の外側(トップレベルを推奨)に実行したい関数を出します。
function sendToNative(p1, p2) {
chrome.runtime.sendNativeMessage(
'native.message.sample',
{param1:p1, param2: p2},
errorHandle(function(response, thread) {
console.log(response);
return true;
}
));
}
次にメッセージを受信する部分を追加して、条件(”NM_SAMPLE”の部分)を指定して外だしした関数(sendToNative)を呼びます。
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
if (msg.action === "NM_SAMPLE") {
sendToNative(msg.data, "World!");
return true;
}
}
最後に[chrome.scripting.executeScript]の部分からメッセージを送信します。
chrome.contextMenus.onClicked.addListener(async (info, tab) => {
chrome.scripting.executeScript({
target: { tabId: tab.id },
func: async (_) => {
chrome.runtime.sendMessage({
action: "NM_SAMPLE",
data: "Hello"
});
//chrome.runtime.sendNativeMessage(
// 'native.message.sample',
// {param1:'Hello', param2: str},
// errorHandle(function(response, thread) {
// console.log(response);
// return true;
// }
//));
}
}
[chrome.scripting.executeScript]内で[sendNativeMessage]が直接実行されなくなったのでエラーが回避できました。
Google Chromeから実行する際に[Invalid native messaging host name specified]エラーになる場合には、別記事をご覧ください。
まとめ
今回は、Google Chromeの拡張機能の Native Message で、Service Workerとして動作している “background.js” で chrome.runtime.sendNativeMessage を実行した場合に “TypeError: chrome.runtime.sendNativeMessage is not a function” エラーになる場合の原因と対処法について紹介しました。
NativeMessageを利用するとC#などで作成した別アプリケーションをChrome拡張機能からデータの受け渡しが可能です。
また、[sendNativeMessage]や[connectNative]は、Chrome拡張機能のService Worker`として実行されている部分では実行できないため、それ以外の部分で実行すると”TypeError: … sendNativeMessage is not a function” エラーになります。
エラーになる場合には、sendMessage などで別のスコープに追加した関数などに迂回させる必要があります。
Google Chrome 拡張機能で chrome.runtime.sendNativeMessage 実行時に”TypeError: … sendNativeMessage is not a function” エラーが表示される人の参考になれば幸いです。
スポンサーリンク
最後までご覧いただきありがとうございます。
