search
LoginSignup
1

More than 5 years have passed since last update.

posted at

updated at

DartでChrome拡張機能でBackgroundとContent Scriptの通信をする

背景

DartでChrome拡張機能を作るときにはchromeパッケージを使うと思いますが
sendMessageAPI周りが正しく動かないのであきらめてdart:jsパッケージを使って手動で解決する方法です。

正しく動かないコード

content.dart
main() async {
  var res = await chrome.runtime.sendMessage('soy source');
  print(res);
}
background.dart
main() async* {
  await for (var msgEvent in chrome.runtime.onMessage) {
    print(msgEvent.message);
    msgEvent.sendResponse('hello' + msgEvent.message);
  }
}

Uncaught Error: Could not establish connection. Receiving end does not exist.(...)というエラーが出ます。
error.png

動くコード

context["chrome"]からメッセージング用のAPIを取り出して使います。

Content Script -> Background -> Content Script

content2.dart
void main() {
  context['chrome']['runtime'].callMethod('sendMessage',
      [ "soy source", (result) => print(result)]);//二秒後に "hello tab: xxx name:soy source" と表示されます。
}
background2.dart
void main() {
  var jsObject = context['chrome']['runtime']['onMessage'];
  (jsObject is JsObject ? jsObject : new JsObject.fromBrowserObject(jsObject))
      .callMethod('addListener', [onMessage]);
}

bool onMessage(request, sender,JsFunction response) {
  var tabID = new JsObject.fromBrowserObject(sender)["tab"]["id"];
  new Timer(new Duration(seconds: 2), () {
    response.apply(["hello tab: $tabID name:$request"]);
  });
  return true; //trueにしないと非同期でレスポンスを返せません。
}

Background -> Content Script -> Background

content3.dart
void main(){
  var jsObject = context['chrome']['runtime']['onMessage'];
  (jsObject is JsObject ? jsObject : new JsObject.fromBrowserObject(jsObject))
      .callMethod('addListener', [onMessage]);


}

void onMessage(request, sender,JsFunction sendResponse) {
  print("request $request");
  sendResponse.apply(["hey $request"]);
}
background3.dart
void main() {
  new Timer(new Duration(seconds: 5),(){ //拡張機能をリロードしてから五秒以内にContent Scriptが挿入されているページをリロードしないとうまく動きません。
    context['chrome']['tabs'].callMethod( 
        'sendMessage', [ 376, "マヨネーズ",(result) => print(result)]); //"hey マヨネーズ"と表示されます
  });
}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
1