javascriptpythonbatch-filegoogle-chrome-extensionchrome-native-messaging

How to send/receive text message via nativeMessaging in Chrome?


I'm trying to send the url of the currently active tab to a python script. My extension already starts running the script and tries to send the url. However I have so far been unsuccessfull in receiving the url with the running script.

popup.js:

dlvideo.addEventListener("click", async () => {
    chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => {
        // Get current url
        url = tabs[0].url;
        
        // Connect to python script
        port = chrome.runtime.connectNative('com.ytdlp.batdlvideo');
        port.onDisconnect.addListener(function() {
            console.log("Disconnected");
        });
        port.onMessage.addListener(function(msg) {
            console.log("Received" + msg);
        });

        // Send url to script
        port.postMessage({ text: url });
    });
});

dlvideo.py (the code seems to get stuck here at the start of the while-loop):

import sys

if sys.platform == "win32":
    import os, msvcrt
    msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)

url = None
while True:
    # The loop seems to get stuck here:
    text_length_bytes = sys.stdin.read(4)

    if len(text_length_bytes) == 0:
        print("test.py: sys.exit0")
        sys.exit(0)
        
    text_length = struct.unpack('i', text_length_bytes)[0]
    text = sys.stdin.read(text_length).decode('utf-8')
    if text.startswith('http'):
        url = text
        print(str(url))
        break
    else:
        print(text)

Other files are probably not relevant, but I'll put them here just in case: yt_dlp.bat:

@echo off
start cmd /k python "%~dp0/dlvideo.py" %*

manifestAPP.json:

{
    "name": "com.ytdlp.batdlvideo",
    "description": "Youtube-dlp",
    "path": "C:\\Users\\.....\\native-apps\\dlvideo\\yt_dlp.bat",
    "type": "stdio",
    "allowed_origins": [
        "chrome-extension://-extensionid-/"
    ]
}

Can someone help?


Solution

  • Ok, I think in my case the problem was that only one message is sent to the host and the host is not yet ready by the time it is sent?

    Well, this at least is the code that worked for me:

    popup.js and manifestAPP.json can stay the same.

    dlvideo.py:

    import struct
    import json
    import sys
    import os
    
    # Changes the stdio-mode
    if sys.platform == "win32":
        import os, msvcrt
        msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
        msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
    
    # Read native message from chrome window
    text_message_length = sys.stdin.buffer.read(4)
    text_length = struct.unpack("i", text_message_length)[0]
    text_decoded = sys.stdin.buffer.read(text_length).decode("utf-8")
    text_asstr = json.loads(text_decoded)
    
    # Get URL
    url = text_asstr['text']
    

    yt_dlp.bat:

    @echo off
    python dlvideo.py %*