mirror of
https://github.com/mdn/webextensions-examples.git
synced 2026-04-17 06:48:37 +02:00
Merge pull request #89 from mdn/native-messaging
Added native messaging example
This commit is contained in:
33
native-messaging/README.md
Normal file
33
native-messaging/README.md
Normal file
@@ -0,0 +1,33 @@
|
||||
This is a very simple example of how to use [native messaging](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Native_messaging) to exchange messages between a WebExtension and a native application.
|
||||
|
||||
The WebExtension, which can be found under "add-on", connects to the native application and listens to messages from it. It then sends a message to the native application when the user clicks on the WebExtension's browser action. The message payload is just "ping".
|
||||
|
||||
The native application, which can be found under "app", listens for messages from the WebExtension. When it receives a message, the native application sends a response message whose payload is just "pong". The native application is written in Python.
|
||||
|
||||
## Setup ##
|
||||
|
||||
To get this working, there's a little setup to do.
|
||||
|
||||
### Mac OS/Linux setup ###
|
||||
|
||||
1. Check that the [file permissions](https://en.wikipedia.org/wiki/File_system_permissions) for "ping_pong.py" include the `execute` permission.
|
||||
2. Edit the "path" property of "ping_pong.json" to point to the location of "ping_pong.py" on your computer.
|
||||
3. copy "ping_pong.json" to the correct location on your computer. See [App manifest location ](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Native_messaging#App_manifest_location) to find the correct location for your OS.
|
||||
|
||||
### Windows setup ###
|
||||
|
||||
1. Check you have Python installed, and that your system's PATH environment variable includes the path to Python. See [Using Python on Windows](https://docs.python.org/2/using/windows.html). You'll need to restart the web browser after making this change, or the browser won't pick up the new environment variable.
|
||||
2. Edit the "path" property of "ping_pong.json" to point to the location of "ping_pong_win.bat" on your computer. Note that you'll need to escape the Windows directory separator, like this: `"path": "C:\\Users\\MDN\\native-messaging\\app\\ping_pong_win.bat"`.
|
||||
3. Edit "ping_pong_win.bat" to refer to the location of "ping_pong.py" on your computer.
|
||||
4. Add a registry key containing the path to "ping_pong.json" on your computer. See [App manifest location ](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Native_messaging#App_manifest_location) to find details of the registry key to add.
|
||||
|
||||
## Testing the example ##
|
||||
|
||||
Then just install the add-on as usual, by visiting about:debugging, clicking "Load Temporary Add-on", and selecting the add-on's "manifest.json".
|
||||
|
||||
You should see a new browser action icon in the toolbar. Open the console ("Tools/Web Developer/Browser Console" in Firefox), and click the browser action icon. You should see output like this in the console:
|
||||
|
||||
Sending: ping
|
||||
Received: pong
|
||||
|
||||
If you don't see this output, see the [Troubleshooting guide](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Native_messaging#Troubleshooting) for ideas.
|
||||
19
native-messaging/add-on/background.js
Normal file
19
native-messaging/add-on/background.js
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
On startup, connect to the "ping_pong" app.
|
||||
*/
|
||||
var port = browser.runtime.connectNative("ping_pong");
|
||||
|
||||
/*
|
||||
Listen for messages from the app.
|
||||
*/
|
||||
port.onMessage.addListener((response) => {
|
||||
console.log("Received: " + response);
|
||||
});
|
||||
|
||||
/*
|
||||
On a click on the browser action, send the app a message.
|
||||
*/
|
||||
browser.browserAction.onClicked.addListener(() => {
|
||||
console.log("Sending: ping");
|
||||
port.postMessage("ping");
|
||||
});
|
||||
1
native-messaging/add-on/icons/LICENSE
Normal file
1
native-messaging/add-on/icons/LICENSE
Normal file
@@ -0,0 +1 @@
|
||||
The icon used here is taken from the "Miscellany Web icons" set by Maria & Guillem (https://www.iconfinder.com/andromina), and is used under the Creative Commons (Attribution 3.0 Unported) license.
|
||||
8
native-messaging/add-on/icons/message.svg
Normal file
8
native-messaging/add-on/icons/message.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg height="128px" style="enable-background:new 0 0 143 128;" version="1.1" viewBox="0 0 143 128" width="143px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style type="text/css">
|
||||
<![CDATA[
|
||||
.st0{fill:#EF3E42;}
|
||||
.st1{fill:#FFFFFF;}
|
||||
.st2{fill:none;}
|
||||
.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
|
||||
]]>
|
||||
</style><defs/><path d="M132.2,105.3L96.1,69l36.2-36.1V105.3L132.2,105.3z M14.9,112.1l36.4-36.4l8,7.9c3,3,6.6,5,11,5s8-2,11-5l8-7.9l36.4,36.4 H14.9L14.9,112.1z M125.9,25.3L74,77.4c-1,1-1.9,1.6-3.7,1.6s-2.7-0.6-3.7-1.6L14.7,25.3H125.9L125.9,25.3z M8.4,32.9L44.6,69 L8.4,105.3V32.9L8.4,32.9z"/><rect class="st2" height="128" id="_x3C_Slice_x3E__100_" width="143"/></svg>
|
||||
|
After Width: | Height: | Size: 859 B |
28
native-messaging/add-on/manifest.json
Normal file
28
native-messaging/add-on/manifest.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
|
||||
"description": "Native messaging example add-on",
|
||||
"manifest_version": 2,
|
||||
"name": "Native messaging example",
|
||||
"version": "1.0",
|
||||
"icons": {
|
||||
"48": "icons/message.svg"
|
||||
},
|
||||
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"id": "ping_pong@example.org",
|
||||
"strict_min_version": "50.0"
|
||||
}
|
||||
},
|
||||
|
||||
"background": {
|
||||
"scripts": ["background.js"]
|
||||
},
|
||||
|
||||
"browser_action": {
|
||||
"default_icon": "icons/message.svg"
|
||||
},
|
||||
|
||||
"permissions": ["nativeMessaging"]
|
||||
|
||||
}
|
||||
7
native-messaging/app/ping_pong.json
Normal file
7
native-messaging/app/ping_pong.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "ping_pong",
|
||||
"description": "Example host for native messaging",
|
||||
"path": "/path/to/native-messaging/app/ping_pong.py",
|
||||
"type": "stdio",
|
||||
"allowed_extensions": [ "ping_pong@example.org" ]
|
||||
}
|
||||
30
native-messaging/app/ping_pong.py
Executable file
30
native-messaging/app/ping_pong.py
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, json, struct
|
||||
|
||||
# Read a message from stdin and decode it.
|
||||
def getMessage():
|
||||
rawLength = sys.stdin.read(4)
|
||||
if len(rawLength) == 0:
|
||||
sys.exit(0)
|
||||
messageLength = struct.unpack('@I', rawLength)[0]
|
||||
message = sys.stdin.read(messageLength)
|
||||
return json.loads(message)
|
||||
|
||||
# Encode a message for transmission,
|
||||
# given its content.
|
||||
def encodeMessage(messageContent):
|
||||
encodedContent = json.dumps(messageContent)
|
||||
encodedLength = struct.pack('@I', len(encodedContent))
|
||||
return {'length': encodedLength, 'content': encodedContent}
|
||||
|
||||
# Send an encoded message to stdout
|
||||
def sendMessage(encodedMessage):
|
||||
sys.stdout.write(encodedMessage['length'])
|
||||
sys.stdout.write(encodedMessage['content'])
|
||||
sys.stdout.flush()
|
||||
|
||||
while True:
|
||||
receivedMessage = getMessage()
|
||||
if (receivedMessage == "ping"):
|
||||
sendMessage(encodeMessage("pong"))
|
||||
3
native-messaging/app/ping_pong_win.bat
Normal file
3
native-messaging/app/ping_pong_win.bat
Normal file
@@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
|
||||
call python C:\path\to\ping_pong.py
|
||||
Reference in New Issue
Block a user