7

I am trying to get a node.js script to simulate a keypress, such as the up arrow or the a button. Specifically, I am trying to make a clone of Twitch Plays Pokemon. Basically, whenever a command (up, down, left, right, a, b, select, start) is sent via IRC, the server simulates a keypress, which in turn controls a gameboy emulator. So far, I have written this with the IRC module for node.js:

var config = {
    channels: ["#tron"],
    server: "irc.freenode.net",
    botName: "wyatt"
};

var irc = require("irc");

var bot = new irc.Client(config.server, config.botName, {
    channels: config.channels
});

var commandHandler = function(from, text) {
    if(text.toLowerCase() === "up"||text.toLowerCase() === "down"||text.toLowerCase() === "left"||text.toLowerCase() === "right"||text.toLowerCase() === "a"||text.toLowerCase() === "b"||text.toLowerCase() === "select"||text.toLowerCase() === "start") {
        bot.say(config.channels[0], from.toUpperCase() + " sent the " + text.toUpperCase() + " command!");
    } else {
        bot.say(config.channels[0], from.toUpperCase() + ", that wasn't a valid command!");
    }
};

bot.addListener("message", function(from, to, text, message) {
    commandHandler(from, text);
});

To run my script, I type node scriptName.js into a command prompt. I am using Windows 7.

This connects to the freenode channel #tron, which I am using for testing purposes, as it seems to be mainly dormant.

When a user inputs one of the accpted commands, it sends a message like "NIMAID sent the LEFT command!", otherwise it sends "NIMAID, that wasn't a valid command!". As it is, it works flawlessly. So all I need to do is find a way to send a keypress and the final script is just a switch statement away.

The trouble is that any references I can find by searching the internet talks about using node.js in a browser environment, with JQuery or something similar. I need to send keypresses to an emulator.

tldr: I need to send keypresses from a node.js script to an application running on the windows 7 server desktop.

Is there any way to do this?

Nimaid
  • 321
  • 2
  • 3
  • 9
  • What run environment and emulator are you targeting? Outside of the browser world, key handling is *very* platform-specific. – Stuart P. Bentley Feb 18 '14 at 10:30
  • As I said, I'm using a Windows 7 Professional 64 computer. I'm hoping to be able to do something like sendkeys to a particular window. That way, it wouldn't matter what emulator I'm running, as long as the key presses get to the window. If it really comes down to it though, I plan on using Visualboy Advance. – Nimaid Feb 18 '14 at 23:38
  • For windows - I used node's exec function to run a python script that calls pywin32's keyboard events. For linux you can use xdotool. [Here's](https://github.com/eltacodeldiablo/TwitchPlaysX/blob/master/app/keyHandler.js) the file where I called it. I'm using [node](https://github.com/eltacodeldiablo/TwitchPlaysX) for the program as well. – hzoo Mar 10 '14 at 03:31

3 Answers3

5

I made a node module to do this too: https://github.com/kylepaulsen/kbm-robot

var robot = require("kbm-robot");

robot.startJar();

robot.press("alt")
    .press("tab")
    .sleep(100)
    .release("tab")
    .release("alt")
    .sleep(100)
    .typeString("Hello World!")
    .go()
    .then(robot.stopJar);
Kyle Paulsen
  • 956
  • 1
  • 8
  • 22
  • 1
    I tried to use this one in Ubuntu 16, and there is a bug. The stopJar() is not working. So, every time the application is started, a new jar is executed and keep in the background. After initializing a few times, the operational system starts hanging, and later, it completely freezes. – computeiro Mar 10 '17 at 13:18
3

Apparently, there's a win_keyboard module in the npm registry that somebody wrote to control the keyboard in Windows. You can run npm install win_keyboard and use that; it appears to do exactly what you want.

Stuart P. Bentley
  • 10,195
  • 10
  • 55
  • 84
  • Thank you, this looks absolutely perfect! I don't know how I didn't find it. However, whenever I try to do `var keyboard = require("win_keyboard");` I get [http://pastebin.com/sNFViRj5](http://pastebin.com/sNFViRj5). I honestly don't understand what that means, other than the win_keyboard library isn't working. Any help there? – Nimaid Feb 19 '14 at 07:40
  • You'll need to be running the 32-bit version of Node: the 64-bit version can't call out to 32-bit extensions. ([source](http://stackoverflow.com/questions/13035760/node-js-native-module-is-not-a-valid-win32-application-error)) – Stuart P. Bentley Feb 19 '14 at 07:57
  • If you really want a 64-bit version, try emailing the author and asking them to publish the module's source code: https://github.com/junku901 – Stuart P. Bentley Feb 19 '14 at 07:59
  • 1
    Okay, so I install the 32-bit version. When I try to do `var keyboard = require("win_keyboard");`, it tells me it cant find the win_keyboard node. So, I do npm install win_keyboard again, and it looks like it installed. However, when I check my node_modules folder, lo and behold, it actually _deleted_ the win_keyboard folder! When I literally copy the .node file into the script directory and do `var keyboard = require("./win_keyboard");`, it still doesn't find it! This is turning into a chain of more and more tedious problems, but can somebody please help me again? :) – Nimaid Feb 19 '14 at 09:26
  • RobotJS will help here, see my answer above. It has 32/64bit builds and it's cross platform. – Jason Stallings May 18 '16 at 17:43
  • 1
    The link is now broken – Xsmael Mar 06 '17 at 17:37
3

You may try an alternative to RobotJS. It is a very small and still cross platform library to send keys to your operational system called node-key-sender. I developed after getting frustrated with RobotJS and kbm-robot.

Install it with npm install --save-dev node-key-sender.

And send a text to the keyboard using:

var ks = require('node-key-sender');
ks.sendText('This is my text');

Check out the documentation page: https://www.npmjs.com/package/node-key-sender.

computeiro
  • 583
  • 5
  • 6