2.3.0 • Published 1 year ago

keysender v2.3.0

Weekly downloads
5
License
MIT
Repository
github
Last release
1 year ago

keysender

Node.js Desktop Automation for Windows. Emulate the mouse and keyboard physical or virtual inputs, capture workwindow, register global hotkeys.


Installation

Install Windows Build Tools:

npm install --global windows-build-tools

Install node-gyp:

npm install -g node-gyp

Install keysender using npm:

npm install keysender

or yarn:

yarn add keysender

Example

import { Hardware, GlobalHotkey } from "keysender";

const notepad = new Hardware(null, "Notepad"); // find Notepad handle by className and set it as workwindow

new GlobalHotkey({
  // register hotkey
  key: "f1",
  mode: "once",
  async action() {
    if (
      (notepad.workwindow.isOpen() || notepad.workwindow.refresh()) &&
      notepad.workwindow.isForeground()
    ) {
      notepad.workwindow.setView({ x: 0, y: 0 }); // move workwindow to top left corner of the screen

      const { width, height } = notepad.workwindow.getView();

      await notepad.mouse.humanMoveTo(width / 2, height / 2); // makes human similar mouse movement from current cursor position to middle of "Notepad" window

      await notepad.keyboard.printText("hello"); // instantly types "hello"

      await notepad.keyboard.sendKey("space", 50); // press key "space", await for 50 milliseconds, release key "space"

      await notepad.keyboard.sendKeys(["w", "o", "r", "l", "d"], [25, 50], 50);

      await notepad.keyboard.sendKey(["ctrl", "s"], 50); // press key combination "ctrl+s", await for 50 milliseconds, release key combination
    }
  },
});

Api


Hardware or Virtual

/** Use entire desktop as workwindow */
constructor();
/** Use the first window with {handle} */
constructor(handle: number);
/**
 * Use the first window with {title} and/or {className} and sets it as current workwindow
 * */
constructor(title: string | null, className?: string | null);
/**
 * Use the first child window with {childClassName} and/or {childTitle}
 * of window with {parentHandle} and sets it as current workwindow
 * */
constructor(
  parentHandle: number,
  childClassName: string | null,
  childTitle?: string | null
);
/**
 * Use the first child window with {childClassName} and/or {childTitle}
 * of the first found window with {parentTitle} and/or {parentClassName}
 * and sets it as current workwindow
 * */
constructor(
  parentTitle: string | null,
  parentClassName: string | null,
  childClassName: string | null,
  childTitle?: string | null
);

Classes Hardware and Virtual provide the same keyboard, mouse and workwindow methods and have the same constructors, but:

  • Class Hardware provides keyboard and mouse methods implementations on hardware level by inserts the events serially into the keyboard or mouse input stream. These events are not interspersed with other keyboard or mouse input events inserted either by the user (with the keyboard or mouse).
  • Class Virtual provides keyboard and mouse methods implementations on virtual level by sending messages to workwindow, so it could work with background window.

    Note: Virtual keyboard and mouse methods do not work for all windows, for example, input line in certain window may accept message from printText method, but sendKey method makes no effect outside input line, or the window may accept a keystroke message from sendKey method but not accept mouse movement message from moveTo method.

import { Hardware, Virtual } from "keysender";

const foo = new Hardware("Some title");

const bar = new Virtual(null, "SomeClassName");

const foobar = new Hardware(
  "Some parent title",
  "SomeParentClassName",
  "SomeChildClassName"
);

keyboard

Provides methods to synthesize keystrokes


sendKey

sendKey(
  key: KeyboardButton | KeyboardButton[],
  delayAfterPress?: number | [from: number, to: number],
  delayAfterRelease?: number | [from: number, to: number]
): Promise<void>;

Pressing and releasing key or combination of keys

ArgumentDescriptionDefault Value
keykey or array with combination of keys
delayAfterPressmilliseconds to await after key pressed35
delayAfterReleasemilliseconds to await after key released0
import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

await obj.keyboard.sendKey("a");

await obj.keyboard.sendKey("a", 50);

await obj.keyboard.sendKey("a", 50, 90);

await obj.keyboard.sendKey(["ctrl", "shift", "a"], [25, 50]);

toggleKey

toggleKey(
  key: KeyboardButton | KeyboardButton[],
  state: boolean,
  delay?: number | [from: number, to: number]
): Promise<void>;

Toggling key or combination of keys to provided state

ArgumentDescriptionDefault Value
keykey or array with combination of keys
statekey state selection: true for press, false for release
delaymilliseconds to await after key toggling0
import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

await obj.keyboard.toggleKey("a", true);

await obj.keyboard.toggleKey("a", false, 50);

await obj.keyboard.toggleKey(["ctrl", "shift", "a"], true, [25, 50]);

sendKeys

sendKeys(
  keys: (KeyboardButton | KeyboardButton[])[],
  delayAfterPress?: number | [from: number, to: number],
  delayAfterRelease?: number | [from: number, to: number],
  delay?: number | [from: number, to: number]
): Promise<void>;

sendKeys.cancelCurrent(): Promise<void>

Pressing and releasing array of keys or combinations of keys

ArgumentDescriptionDefault Value
keysarray with keys
afterPressDelaymilliseconds to await after each key pressed35
afterReleaseDelaymilliseconds to await after each key released (excluding last)35
delaymilliseconds to await after last key released0
import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

await obj.keyboard.sendKeys(["a", "b"]);

await obj.keyboard.sendKeys(["a", "b"], 50);

await obj.keyboard.sendKeys(["a", "b"], 50, 90);

await obj.keyboard.sendKeys(["a", "b"], [25, 50], 25, 45);

printText

printText(
  text: string,
  delayAfterCharTyping?: number | [from: number, to: number],
  delay?: number | [from: number, to: number]
): Promise<void>;

printText.cancelCurrent(): Promise<void>

Prints given text

ArgumentDescriptionDefault Value
textstring to print
delayAfterCharTypingmilliseconds to await after each char typing (excluding last)0
delaymilliseconds to await after text printed0
import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

await obj.keyboard.printText("hello world");

await obj.keyboard.printText("hello world", 50);

await obj.keyboard.printText("hello world", [25, 50], 25);

mouse

Provides methods to synthesize mouse motions, and button clicks


click

click(
  button?: MouseButton,
  delayAfterPress?: number | [from: number, to: number],
  delayAfterRelease?: number | [from: number, to: number]
): Promise<void>;
ArgumentDescriptionDefault Value
buttonname of mouse button"left"
delayAfterPressmilliseconds to await after button pressed35
delayAfterReleasemilliseconds to await after button released0
import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

await obj.mouse.click();

await obj.mouse.click("right", 25, 15);

toggle

toggle(button: MouseButton, state: boolean, delay?: number | [from: number, to: number]): Promise<void>;

Switch mouse button state

ArgumentDescriptionDefault Value
buttonname of mouse button
statebutton state selection: true for press, false for release
delaymilliseconds to await after switching button state0
import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

await obj.mouse.toggle("left", true);

await obj.mouse.toggle("right", false, 25);

moveTo

moveTo(x: number, y: number, delay?: number | [from: number, to: number]): Promise<void>;

Move mouse to x, y in current workwindow

ArgumentDescriptionDefault Value
delaymilliseconds to await after mouse movement0
import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

await obj.mouse.moveTo(25, 25);

await obj.mouse.moveTo(50, 50, 50);

move

move(x: number, y: number, delay?: number | [from: number, to: number]): Promise<void>;

Move mouse from current position by x, y relatively

ArgumentDescriptionDefault Value
delaymilliseconds to await after mouse movement0
import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

await obj.mouse.move(25, 25);

await obj.mouse.move(-50, 50, 50);

humanMoveTo

humanMoveTo(
  x: number,
  y: number,
  speed?: number,
  deviation?: number,
  delay?: number | [from: number, to: number]
): Promise<void>;

humanMoveTo.cancelCurrent(): Promise<void>

Simulate human similar mouse movement from current cursor position to x, y in current workwindow

ArgumentDescriptionDefault Value
speedmove speed5
deviationmovement curvature30
delaymilliseconds to await after movement end0
import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

await obj.mouse.humanMoveTo(25, 25);

scrollWheel

scrollWheel(amount: number, delay?: number | [from: number, to: number]): Promise<void>;
ArgumentDescriptionDefault Value
amountamount of wheel movement, positive value indicates that the wheel was rotated forward, away from the user, negative value indicates that the wheel was rotated backward, toward the user
delaymilliseconds to await after wheel scroll0
import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

await obj.mouse.scrollWheel(-1);

getPos

getPos(): Position;

Returns current cursor position relative to workwindow

import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

await obj.mouse.moveTo(25, 50);

console.log(obj.mouse.getPos()); // {x: 25, y: 50}

workwindow

Provides methods to work with workwindow


set

/** Sets entire desktop as current workwindow */
set();
/** Sets current workwindow by {handle} */
set(handle: number): void;
/**
 * Finds the first window with {title}
 * and/or {className} and sets it as current workwindow
 * */
set(title: string | null, className?: string | null): void;
/**
 * Finds the first child window with {childClassName}
 * and/or {childTitle} of window with {parentHandle}
 * and sets it as current workwindow
 * */
set(parentHandle: number, childClassName: string | null, childTitle?: string | null): void;
/**
 * Finds the first child window with {childClassName}
 * and/or {childTitle} of the first found window with {parentTitle}
 * and/or {parentClassName} and sets it as current workwindow
 * */
set(parentTitle: string | null, parentClassName: string | null, childClassName: string | null, childTitle?: string | null): void;

Same as constructor.

import { Hardware } from "keysender";

const obj = new Hardware("Some title"); // or Virtual

obj.workwindow.set(null, "SomeClass");

get

get(): {
  handle: number;
  className: string;
  title: string;
};
import { Hardware } from "keysender";

const obj = new Hardware("Some title"); // or Virtual

console.log(obj.workwindow.get()); // { handle, title, className }

refresh

refresh(): boolean;

Tries to find a new workwindow using already defined handle, className, childTitle, childClassName, returns true if new workwindow successfully find (new handle not equal to 0), false if it is not

import { Hardware } from "keysender";

const obj = new Hardware("Some title"); // or Virtual

obj.workwindow.refresh();

setView

setView(view: Partial<Position & Size>): void;

Sets workwindow position and/or size

Object fieldDescription
xwindow x position
ywindow y position
widthwindow width
heightwindow height
import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

obj.workwindow.setView({ x: 25 });

obj.workwindow.setView({ y: 25, width: 1200 });

obj.workwindow.setView({ x: 50, y: 25, width: 1200, height: 800 });

getView

getView(): Position & Size;

Returns object with workwindow position and size

import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

console.log(obj.workwindow.getView()); // { x, y, width, height }

setForeground

setForeground(): void;

Makes the current workwindow the foreground window

import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

obj.workwindow.setForeground();

isForeground

isForeground(): boolean;

Checks if the current workwindow is a foreground window

import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

console.log(obj.workwindow.isForeground());

isOpen

isOpen(): boolean;

Checks if the current workwindow exist

import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

console.log(obj.workwindow.isOpen());

kill

kill(): void;

Terminates current workwindow by killing it's thread

import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

obj.workwindow.kill();

close

close(): void;

Closes current workwindow by sending close message to it

import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

obj.workwindow.close();

capture

  capture(part: Position & Size, format?: "rgba" | "bgra" | "grey"): Image;
  capture(
    part: Position & Size,
    format: "monochrome",
    threshold?: number
  ): Image;
  capture(format?: "rgba" | "bgra" | "grey"): Image;
  capture(format: "monochrome", threshold?: number): Image;

Takes a screenshot of the current workwindow (even if it is in the background) or the desktop

ArgumentDescriptionDefault Value
partobject { x, y, height, width } with position and size to be captured
formatcolor format of returned image, could be "rgba", "bgra", "grey" or "monochrome" Note: the bgra format has the best performance, but the alpha channel of pixels is not always 255."rgba"
thresholdcolor limit for "monochrome" format, if the pixel value is smaller than the threshold, it is set to 0, otherwise it is set to 255127

Returns object { data, width, height }

fieldDescription
dataBuffer with pixels
widthwidth of captured img
heightheight of captured img
import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

const desktop = new Hardware();

obj.workwindow.capture();

desktop.workwindow.capture();

obj.workwindow.capture({ x: 25, y: 25, width: 500, height: 500 });

desktop.workwindow.capture({ x: 25, y: 25, width: 500, height: 500 });

obj.workwindow.capture("grey");

obj.workwindow.capture(
  { x: 25, y: 25, width: 500, height: 500 },
  "monochrome",
  200
);

colorAt

colorAt(x: number, y: number, returnType?: "string"): string;
colorAt(x: number, y: number, returnType: "array"): RGB;
colorAt(x: number, y: number, returnType: "number"): number;

Returns pixel color in x, y of current workwindow (or screen if handle was unset)

import { Hardware } from "keysender";

const obj = new Hardware(handle); // or Virtual

const desktop = new Hardware();

obj.workwindow.colorAt(25, 25); // returns workwindow color in [25, 25] in "rrggbb" format

obj.workwindow.colorAt(25, 25, "array"); // returns workwindow color in [25, 25] in [r,g,b] format

obj.workwindow.colorAt(25, 25, "number"); // returns workwindow color in [25, 25] in decimal format

desktop.workwindow.colorAt(25, 25); // returns screen color in [25, 25] in "rrggbb" format

Interrupt method execution

Execution of some methods (sendKeys, printText, humanMoveTo) can be interrupted by calling cancelCurrent method, as in the example below:

const obj = new Hardware();

obj.mouse.humanMoveTo(100, 100);

await obj.mouse.humanMoveTo.cancelCurrent();

You can call cancelCurrent even if no method currently executing (it will have no effect and return resolved promise) or call it multiple times (each call will return the same promise as the first call)


GlobalHotkey

enum Reason {
  BY_KEYBOARD,
  BY_ACTION,
  BY_STOP,
}

type HotkeyOptions<S = never, R = never> = {
  key: KeyboardRegularButton | number;
} & ([S] extends [never]
  ? {
      defaultState?: undefined;
    }
  : {
      defaultState: S;
    }) &
  (
    | {
        mode: "once";
        action(this: GlobalHotkey<S, R>): void | Promise<void>;
      }
    | {
        mode: "toggle" | "hold";
        isEnable?(this: GlobalHotkey<S, R>): boolean | Promise<boolean>;
        before?(this: GlobalHotkey<S, R>): void | Promise<void>;
        action(this: GlobalHotkey<S, R>): boolean | Promise<boolean>;
        after?(
          this: GlobalHotkey<S, R>,
          reason: Reason | R
        ): void | Promise<void>;
        delay?: Delay;
      }
  );

class GlobalHotkey<S = never, R = never> {
  constructor(options: HotkeyOptions<S, R>);

  stop(reason?: Reason.BY_STOP | R): Promise<void> | undefined;

  reassignment(newKey: KeyboardRegularButton | number): void;

  unregister(): void;

  delete(): void;

  hotkeyState: boolean;

  state: S;

  static unregisterAll(): void;

  static deleteAll(): void;
}

Registers a hotkey, if any hotkey is already registered for this key, unregisters the previous hotkey and registers a new hotkey

fieldDescriptionDefault Value
keyhotkey
modeif "once" - action will call one time for each key press, if "hold" - action will repeat every delay milliseconds while key is pressed or action returns true, if "toggle" - action starts repeat repeat every delay milliseconds after key first time pressed and stops after key second time pressed or action returns false
isEnable?method to check if hotkey is need to be executing() => true
before?if mode is "hold" or "toggle" - method to be executed before the action loop
actionfunction to be call after hotkey was pressed
after?if mode is "hold" or "toggle" - function to be call after hotkey work is end, first param is reason of ending, reason of action loop ending, can be one of Reason enum (if ended by action - Reason.BY_ACTION, if ended by keyboard - Reason.BY_KEYBOARD) or reason from stop method
delay?if mode is "hold" or "toggle" - sets delay between action calls35
defaultState?default state
import { GlobalHotkey } from "keysender";

new GlobalHotkey({
  // logs "hi" after pressing "num+"
  key: "num+",
  mode: "once",
  action() {
    console.log("hi");
  },
});

new GlobalHotkey({
  // logs "hi" every 50 milliseconds while "num*" is pressed
  key: "num*",
  mode: "hold",
  action() {
    console.log("hi");

    return true;
  },
  delay: 50,
});

let i = 0;

new GlobalHotkey({
  // logs "hi" every 50 milliseconds after "num/" is pressed
  key: "num/", // until "num/" be pressed again or i become > 50
  mode: "toggle",
  action() {
    i++;

    if (i > 50) {
      return false;
    }

    console.log("hi");

    return true;
  },
});

let j = 0;

new GlobalHotkey({
  // after "a" is pressed if i <= 50 - logs "hi" every 50 milliseconds
  key: "a", // until "a" be pressed again
  mode: "toggle",
  isEnable() {
    return j <= 50;
  },
  action() {
    j++;

    console.log(j);

    return true;
  },
  delay: 50,
});

new GlobalHotkey({
  // logs "hi" every 50 milliseconds while "num-" is pressed,
  key: "num-", //   logs Release.BY_KEYBOARD when "num-" is released
  mode: "hold",
  action() {
    console.log("hi");

    return true;
  },
  after(reason) {
    console.log(reason);
  },
});

stop

stop(reason?: Reason.BY_STOP | R): Promise<void>;

Stops the loop of action executing

ArgumentDescriptionDefault Value
reasonreason to after methodReason.BY_STOP
import { GlobalHotkey } from "keysender";

const hotkey = new GlobalHotkey<never, "someReason">({
  key: "num-",
  mode: "toggle",
  action() {
    // some action here

    return true;
  },
  after(reason) {
    if (reason === "someReason") {
      console.log("stopped");
    }
  },
});

new GlobalHotkey({
  key: "num+",
  mode: "once",
  async action() {
    await hotkey.stop("someReason");

    console.log("num- action was stopped");
  },
});

reassignment

reassignment(newHotkey: KeyboardRegularButton | number): void;

Reassignments hotkey

import { GlobalHotkey } from "keysender";

const foo = new GlobalHotkey({
  key: "num+",
  mode: "once",
  action() {
    console.log("hi");
  },
});

foo.reassignment("a");

unregister

unregister(): void;

Unregisters a hotkey, but it can still be reassignment using the reassignment method

import { GlobalHotkey } from "keysender";

const foo = new GlobalHotkey({
  key: "num+",
  mode: "once",
  action() {
    console.log("hi");
  },
});

foo.unregister();

delete

delete(): void;

Delete a hotkey, it can't be reassignment

import { GlobalHotkey } from "keysender";

const foo = new GlobalHotkey({
  key: "num+",
  mode: "once",
  action() {
    console.log("hi");
  },
});

foo.delete();

state

Any state that can be used via this in isEnable, before, action, after methods or via GlobalHotkey instance

type State = { counter: number };

const hotkey = new GlobalHotkey<State>({
  key: "f1",
  mode: "toggle",
  action() {
    this.state.counter++;

    console.log(this.state.counter);

    return true;
  },
  defaultState: { counter: 0 },
});

new GlobalHotkey({
  key: "f2",
  mode: "once",
  action() {
    hotkey.state.counter--;
  },
});

isRunning

isRunning: boolean;

flag indicating that an action is currently being performed


unregisterAll

static unregisterAll(): void;

Unregister all hotkeys, but they still can be reassignment by reassignment method

import { GlobalHotkey } from "keysender";

GlobalHotkey.unregisterAll();

deleteAll

static deleteAll(): void;

Delete all hotkeys

import { GlobalHotkey } from "keysender";

GlobalHotkey.deleteAll();

LowLevelHook

enum Reason {
  BY_KEYBOARD,
  BY_ACTION,
  BY_STOP,
}

type LowLevelHookOptions<S = never, R = never> = (
  | {
      device: "keyboard";
      button: KeyboardButton | number;
    }
  | {
      device: "mouse";
      button: MouseButton;
    }
) &
  ([S] extends [never]
    ? {
        defaultState?: undefined;
      }
    : {
        defaultState: S;
      }) &
  (
    | {
        mode: "once";
        action(this: LowLevelHook<S, R>): void | Promise<void>;
      }
    | {
        mode: "toggle" | "hold";
        isEnable?(this: LowLevelHook<S, R>): boolean | Promise<boolean>;
        before?(this: LowLevelHook<S, R>): void | Promise<void>;
        action(this: LowLevelHook<S, R>): boolean | Promise<boolean>;
        after?(
          this: LowLevelHook<S, R>,
          reason: Reason | R
        ): void | Promise<void>;
        delay?: Delay;
      }
  );

class LowLevelHook<S = never, R = never> {
  constructor(options: LowLevelHookOptions<S, R>);

  stop(reason?: Reason.BY_STOP | R): Promise<void> | undefined;

  delete(): void;

  isRunning: boolean;

  state: S;

  static deleteAll(): void;

  static on<D extends "keyboard" | "mouse">(
    device: D,
    button: D extends "mouse" ? MouseButton | "wheel" : KeyboardButton | number,
    state: boolean,
    listener: () => void
  ): () => void;
}

Similar to GlobalHotkey, but also allows you to add callback for mouse, does not block the key itself, can't be provoked by synthetic clicks, can add multiple callbacks for the same button

import { LowLevelHook } from "keysender";

new LowLevelHook({
  device: "keyboard",
  key: "a",
  mode: "hold",
  action() {
    console.log("'a' pressed");

    return true;
  },
});

new LowLevelHook({
  device: "mouse",
  key: "left",
  mode: "once",
  action() {
    console.log("left mouse button was pressed");
  },
});

on

static on<D extends "keyboard" | "mouse">(
  device: D,
  button: D extends "mouse" ? MouseButton | "wheel" : KeyboardButton | number,
  state: boolean,
  listener: () => void
): () => void;

Adds listener for given device, button and state

import { LowLevelHook } from "keysender";

LowLevelHook.on("mouse", "left", true, () => {
  console.log("left mouse button was pressed");
});

LowLevelHook.on("keyboard", "a", false, () => {
  console.log("a was released");
});

LowLevelHook.on("mouse", "wheel", true, () => {
  console.log("wheel went forward");
});

disableInput

type BlockedInput = {
  state: boolean;
} & (
  | {
      device: "mouse";
      button: MouseButton | "wheel";
    }
  | {
      device: "keyboard";
      button: KeyboardRegularButton | KeyboardSpecButton;
    }
);

type DisableInputOptions = {
  mouse?: (MouseButton | "wheel-forward" | "wheel-back" | "move")[];
  keyboard?: KeyboardButton[];
};

function disableInput(disable: true, options?: DisableInputOptions): void;

function disableInput(
  disable: false,
  options?: DisableInputOptions
): BlockedInput[];

Disables or enables the device buttons provided in options, if some device was not provided, disables or enables all functionality of it. Enabling returns array with information about blocked inputs since the last time disableInput execution (skips mouse move records because it is called too often)

import { disableInput } from "keysender";

disableInput(true); // disables all inputs from mouse and keyboard

disableInput(true, { mouse: [] }); // disables all inputs from keyboard

disableInput(true, { keyboard: [], mouse: ["move"] }); // disables mouse move

disableInput(false); // enables all inputs

isButtonPressed

function isButtonPressed<D extends "keyboard" | "mouse">(
  device: D,
  button: D extends "keyboard" ? KeyboardButton | number : MouseButton
): boolean;

Returns array with objects {handle, title, className} of all open windows

import { isButtonPressed } from "keysender";

console.log(isButtonPressed("mouse", "x1"));

console.log(isButtonPressed("keyboard", "f1"));

textToImg

function textToImg(
  text: string,
  path: string,
  fontSize: number,
  options?: TextToImgOptions
): Image;

Draws text using the specified font (supports .ttf and .otf only)

ArgumentDescription
texttext to draw
pathfont path
fontSizefont size in px
optionsobject with options

Options object:

FieldDescriptionDefault Value
enableActualHeightif true - height of returned img be equal to fontSize (some characters may be trimmed top or bottom)false
enableAntiAliasingif true - anti-aliasing enabledtrue
colortext color, could be in r, g, b or "rrggbb" or number formats0xffffff (white)
backgroundColorbackground color, could be in r, g, b or "rrggbb" or number formats0 (black)
formatcolor format of return data, could be "rgba", "bgra", "grey" Note: "bgra" format has the best performance, but alpha chanel of each pixel will be 0"rgba"

Returns:

FieldDescription
dataBuffer with pixels
widthwidth of drawn text
heightheight of drawn text
import { textToImg } from "keysender";

const img1 = textToImg("Hello World!", "./path/to/font.ttf", 12);

const img2 = textToImg("Hello World!", "./path/to/font.otf", 24, {
  enableAntiAliasing: false,
  format: "grey",
});

const img3 = textToImg("Hello World!", "./path/to/font.otf", 36, {
  enableActualHeight: true,
  color: "ff0000",
  backgroundColor: [0, 255, 0],
});

getAllWindows

function getAllWindows(): Array<{
  handle: number;
  className: string;
  title: string;
}>;

Returns array with objects {handle, title, className} of all open windows

import { getAllWindows } from "keysender";

console.log(getAllWindows());

getWindowChildren

function getWindowChildren(parentHandle: number): {
  handle: number;
  className: string;
  title: string;
}[];
function getWindowChildren(
  parentTitle: string | null,
  parentClassName?: string | null
): {
  handle: number;
  className: string;
  title: string;
}[];

Returns array with objects {handle, title, className} with all children of given window

import { getWindowChildren } from "keysender";

console.log(getWindowChildren(parentHandle));

console.log(getWindowChildren("Some title"));

console.log(getWindowChildren(null, "SomeClass"));

console.log(getWindowChildren("Some title", "SomeClass"));

getScreenSize

function getScreenSize(): size;

Returns object with screen size

import { getScreenSize } from "keysender";

console.log(getScreenSize());

vkToString

function vkToString(virtualKey: number): KeyboardButton;

Returns string name of virtualKey

import { vkToString } from "keysender";

console.log(vkToString(66)); // "b"

sleep

function sleep(ms: number | [from: number, to: number]): Promise<void>;

This method used under the hood of all async methods

import { sleep } from "keysender";

await sleep(25);

await sleep([25, 50]);

KeyboardButton

toggleKey, sendKey, sendKeys, GlobalHotkey supports for following keys or numbers(virtual key codes)

type KeyboardRegularButton =
  | "backspace"
  | "tab"
  | "enter"
  | "pause"
  | "capsLock"
  | "escape"
  | "space"
  | "pageUp"
  | "pageDown"
  | "end"
  | "home"
  | "left"
  | "up"
  | "right"
  | "down"
  | "printScreen"
  | "insert"
  | "delete"
  | "0"
  | "1"
  | "2"
  | "3"
  | "4"
  | "5"
  | "6"
  | "7"
  | "8"
  | "9"
  | "a"
  | "b"
  | "c"
  | "d"
  | "e"
  | "f"
  | "g"
  | "h"
  | "i"
  | "j"
  | "k"
  | "l"
  | "m"
  | "n"
  | "o"
  | "p"
  | "q"
  | "r"
  | "s"
  | "t"
  | "u"
  | "v"
  | "w"
  | "x"
  | "y"
  | "z"
  | "num0"
  | "num0"
  | "num1"
  | "num2"
  | "num3"
  | "num4"
  | "num5"
  | "num6"
  | "num7"
  | "num8"
  | "num9"
  | "num*"
  | "num+"
  | "num,"
  | "num-"
  | "num."
  | "num/"
  | "f1"
  | "f2"
  | "f3"
  | "f4"
  | "f5"
  | "f6"
  | "f7"
  | "f8"
  | "f9"
  | "f10"
  | "f11"
  | "f12"
  | "f13"
  | "f14"
  | "f15"
  | "f16"
  | "f17"
  | "f18"
  | "f19"
  | "f20"
  | "f21"
  | "f22"
  | "f23"
  | "f24"
  | "numLock"
  | "scrollLock"
  | ";"
  | "="
  | ","
  | "-"
  | "."
  | "/"
  | "`"
  | "["
  | "\\"
  | "]"
  | "'";

type KeyboardSpecButton =
  | "alt"
  | "ctrl"
  | "shift"
  | "lShift"
  | "rShift"
  | "lCtrl"
  | "rCtrl"
  | "lAlt"
  | "rAlt"
  | "lWin"
  | "rWin";

type KeyboardButton = KeyboardRegularButton | KeyboardSpecButton | number;

License

MIT © Krombik

2.3.0

1 year ago

2.2.1

1 year ago

2.1.2

1 year ago

2.2.0

1 year ago

2.1.1

1 year ago

2.1.4

1 year ago

2.0.5

2 years ago

2.1.3

1 year ago

2.0.4

2 years ago

2.0.7

2 years ago

2.0.6

2 years ago

2.0.8

2 years ago

2.1.0

1 year ago

2.0.3

2 years ago

2.0.2

2 years ago

2.0.1

2 years ago

2.0.0

2 years ago

1.6.5

3 years ago

1.6.4

3 years ago

1.6.3

3 years ago

1.6.2

3 years ago

1.6.1

3 years ago

1.6.0

3 years ago

1.5.6

3 years ago

1.5.5

3 years ago

1.5.4

3 years ago

1.5.3

3 years ago

1.5.2

4 years ago

1.5.1

4 years ago

1.5.0

4 years ago

1.4.0

4 years ago

1.3.1

4 years ago

1.3.0

4 years ago

1.2.1

4 years ago

1.2.0

4 years ago

1.1.0

4 years ago

1.0.3

4 years ago

1.0.2

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago

0.0.5

4 years ago

0.0.4

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago