QZ Tray

repository·master·Indexed 21 days ago

https://github.com/qzind/tray

A browser plugin and JavaScript library (version 2.2.6) that enables web applications to communicate with local hardware, such as printers, serial ports, USB, and HID devices. It provides a WebSocket-based API for finding printers, managing print configurations, sending raw or pixel-based print jobs, and handling digital signatures for secure hardware communication.

Tokens
8.1K
Snippets
21
Records
29
Agent score
75%

What's inside qz-tray

  1. Choose the correct support channel for QZ Tray

    master

    Before opening a GitHub issue, determine if your problem is a software bug or a support question.

    • For Support Questions: Do not open a GitHub issue. Instead, check the FAQ and the wiki first.
    • For Software Bugs: You can open bug reports directly on GitHub.

    Depending on your subscription status, use the following channels for assistance:

    1. Community Support (No paid subscription): Use the community support channel at https://qz.io/support/.
    2. Premium Support (Active support license): Send support requests directly to support@qz.io.
  2. Handle security and digital signatures

    master

    QZ Tray requires digital signatures for certain sensitive operations (e.g., printing, accessing USB/HID devices). You must implement two main handlers in qz.security to manage this:

    1. Certificate Handling: Implement qz.security.certHandler to provide the site's public certificate. This is called when the connection is established.
    2. Signature Generation: Implement qz.security.signatureFactory to generate digital signatures for requested calls. This function is called whenever a command requires a signature.

    By default, qz.security.signAlgorithm is set to "SHA1".

    // Example pattern for implementing security handlers
    qz.security.certHandler = async function() {
        // Return your certificate (e.g., from a server endpoint)
        const response = await fetch('/path/to/certificate');
        return await response.text();
    };
    
    qz.security.signatureFactory = async function(toSign) {
        // 'toSign' contains the data that needs to be hashed and signed
        const response = await fetch('/path/to/sign', {
            method: 'POST',
            body: JSON.stringify(toSign)
        });
        const result = await response.json();
        return result.signature;
    };
  3. Basic usage of qz-tray in JavaScript

    master

    To use qz-tray in a JavaScript environment (such as Node.js), you must first connect to the QZ Tray websocket. Once connected, you can perform operations like finding available printers, creating print configurations, and sending print jobs.

    Common workflow:

    1. Connect via qz.websocket.connect().
    2. Perform printer or configuration tasks.
    3. Execute print commands using qz.print(config, data).
    4. Disconnect using qz.websocket.disconnect().

    Always handle errors using .catch() to manage connection failures or printing errors.

    const qz = require("qz-tray");
    
    qz.websocket.connect().then(() => {
        return qz.printers.find();
    }).then((printers) => {
        console.log(printers);
        let config = qz.configs.create('PDF');
        return qz.print(config, [{
            type: 'pixel',
            format: 'html',
            flavor: 'plain',
            data: '<h1>Hello JavaScript!</h1>'
        }]);
    }).then(() => {
        return qz.websocket.disconnect();
    }).then(() => {
        // process.exit(0);
    }).catch((err) => {
        console.error(err);
        // process.exit(1);
    });
  4. Configure default printing options

    master

    The qz.printing.defaultConfig object contains the default settings used for new printer configurations. These can be globally overridden using qz.configs.setDefaults.

    Common properties include:

    • colorType: e.g., 'color'
    • copies: Number of copies (default 1)
    • orientation: Paper orientation
    • scaleContent: Boolean (default true)
    • units: e.g., 'in'
    • rasterize: Boolean to determine if content should be rasterized
    • forceRaw: Boolean for raw printing
  5. Configure QZ Tray connection settings

    master

    The qz.websocket.connectConfig object defines the default parameters used when establishing a connection to the QZ Tray software. You can override these values by passing an options object to qz.websocket.connect.

    Key configuration properties include:

    • host: An array of hostnames (e.g., ["localhost", "localhost.qz.io"]).
    • usingSecure: Boolean indicating whether to use the secure protocol (wss://).
    • protocol: An object containing secure (e.g., "wss://") and insecure (e.g., "ws://") prefixes.
    • port: An object containing arrays of secure and insecure ports.
    • keepAlive: Time in seconds between pings to maintain the connection.
    • retries: Number of reconnection attempts before failing.
    • delay: Seconds to wait before initiating a connection.
    // Example of what the default connectConfig looks like
    // You can pass a subset of these to qz.websocket.connect(options)
    {
      host: ["localhost", "localhost.qz.io"],
      usingSecure: true,
      protocol: {
        secure: "wss://",
        insecure: "ws://"
      },
      port: {
        secure: [8181, 8282, 8383, 8484],
        insecure: [8182, 8283, 8384, 8485]
      },
      keepAlive: 60,
      retries: 0,
      delay: 0
    }
  6. Configure security and signing via qz.security

    master

    The qz.security namespace manages the certificates and digital signatures required for secure QZ Tray connections.

    Key Methods:

    • setCertificatePromise(promiseHandler, options): Sets the resolver for acquiring the site's certificate. The promiseHandler can be a function, an async function, or a Promise that resolves with the public certificate. Use options.rejectOnFailure to control behavior on failure.
    • setSignaturePromise(promiseFactory): Sets the factory used to sign API calls. The factory accepts dataToSign and returns a function (or async function) that resolves with the signed string.
    • setSignatureAlgorithm(algorithm): Sets the algorithm for signature verification. Supported values: SHA1, SHA256, SHA512.
    • getSignatureAlgorithm(): Returns the currently configured signing algorithm.
    // Example: Setting a signature promise
    qz.security.setSignaturePromise(function(dataToSign) {
      return function(resolve, reject) {
        $.ajax("/signing-url?data=" + dataToSign).then(resolve, reject);
      };
    });
  7. Manage printer queues with clearQueue

    master

    Use qz.printers.clearQueue to clear the print queue for a specific printer. This does not delete jobs that have already been retained by the system. You can clear the entire queue for a printer or cancel a specific job using its jobId.

    // Clear all jobs for a specific printer
    qz.printers.clearQueue('My Printer Name');
    
    // Clear a specific job by ID (requires printerName)
    qz.printers.clearQueue({
        printerName: 'My Printer Name',
        jobId: 12345
    });
  8. Control USB devices with qz.usb

    master

    The qz.usb namespace provides low-level interaction with USB devices.

    • listDevices(includeHubs): Lists connected USB devices, including vendor/product IDs.
    • listInterfaces(deviceInfo): Lists available interfaces for a device.
    • listEndpoints(deviceInfo): Lists available endpoints on a specific interface.
    • claimDevice(deviceInfo): Claims a USB interface to enable data transfer.
    • isClaimed(deviceInfo): Checks if a device is currently claimed.
    • sendData(deviceInfo): Sends data to a claimed device via a specific endpoint. deviceInfo must include vendorId, productId, endpoint, and data.
    • setUsbCallbacks(calls): Registers functions to handle USB events (RECEIVE or ERROR).
    const device = { vendorId: '0x1234', productId: '0x5678' };
    
    qz.usb.listInterfaces(device).then(interfaces => {
        const deviceInfo = {
            ...device,
            interface: interfaces[0],
            endpoint: '0x01'
        };
        
        return qz.usb.claimDevice(deviceInfo).then(() => deviceInfo);
    }).then(deviceInfo => {
        return qz.usb.sendData({
            ...deviceInfo,
            data: 'USB Data',
            type: 'PLAIN'
        });
    });
  9. Interact with serial ports using qz.serial

    master

    The qz.serial namespace provides tools for RS232, COM, and TTY communication.

    • findPorts(): Returns a list of available communication ports.
    • openPort(port, options): Opens a specific port. Options include baudRate, dataBits, stopBits, parity, and flowControl.
    • sendData(port, data, options): Sends data to an open port. Data can be a string or an object with type (FILE, PLAIN, HEX, BASE64).
    • closePort(port): Closes the specified port.
    • setSerialCallbacks(calls): Registers functions to handle responses (RECEIVE or ERROR) from open ports.
    // Find and open a port
    qz.serial.findPorts().then(ports => {
        const portName = ports[0];
        return qz.serial.openPort(portName, { baudRate: 9600 });
    }).then(() => {
        // Set up response handling
        qz.serial.setSerialCallbacks((event) => {
            console.log('Serial response:', event.output);
        });
        // Send data
        return qz.serial.sendData('COM3', 'Hello Device');
    });