Write automated script with Tampermonkey and Webpack
Recently I was pulled into an old web-based game called Ghost Trapper. The gist of it is, after a period of time, I can click on a button to trap a ghost, then a count down appears and I have to wait for the count down to stop until I can hunt ghosts again.
Then it hit me, why don’t I automate the process so that I don’t have to spend so much time to play anymore.
Here’s a screenshot of the game.
Note the top left count down. Once it reaches 0, I can click that button again and continue hunting ghosts.
I look around for a solution for automating the process. There are quite a few options:
- Python’s scrapy
- Phantom.js or Casper.js
- Puppeteer
- Tampermonkey (Google Chrome only)
- …
I have some experience in Scrapy, Phantom.js; so I was thinking, why not utilize what I have already known?
… Or I can jump into new things and learn how to do it.
I decided to go with the second option, and I chose Tampermonkey to do the work.
So I quickly wrote a small script to check if the button is active, and if so, click on it.
setTimeout(() => { if (!$('#huntBtn').hasClass('disabled')) { $('#huntBtn').trigger('click'); } }, 3000);
Simple, isn’t it?!
The problem is, I would like to have the script runs on multiple machines, and I want to synchonize the code in all machines, so if I update the code I’ll just need to do it once.
I ended up with the following structure:
- A github project to host the code
- Tampermonkey’s ability to refer to external javascript resources.
My Tampermonkey script
// ==UserScript== // @name ghost-trapper // @namespace http://tampermonkey.net/ // @version 0.1 // @description Ghost Trapper auto // @author lightbringer // @noframes // @require https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js // @require file:///Z:/nodejs/ghost-trapper/ghost-trapper.js // @match http://www.ghost-trappers.com/fb/* // @grant GM_setValue // @grant GM_getValue // ==/UserScript==
My ghost-trapper.js
class GhostTrapper { constructor() { // do stuff } hunt() { if (!$('#huntBtn').hasClass('disabled')) { $('#huntBtn').trigger('click'); } } run() { setTimeout(this.hunt, 3000); } } var gt = new GhostTrapper(); gt.run();
Looking good, however, the script requires 2 files, one from jquery CDN. one from my local machine. And the speed is not very nice (took me a noticeable time before the hunt click happened).
I thought, why can’t I combine them into 1 file? I have experience in Webpack, so let’s try it out.
First I installed necessary packages
npm i --save jquery npm i --save-dev webpack webpack-cli babel-core babel-loader babel-preset-env
Then I created webpack config file
// webpack.config.js const path = require('path'); module.exports = { entry: './src/main.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'ghost-trapper.bundle.js' }, module: { rules: [ { test: /\.js$/, exclude: /(node_modules|bower_components)/, use: { loader: "babel-loader", }, }, ], }, };
Then I create a main file for webpack to point to.
// src/main.js import $ from 'jquery'; import GhostTrapper from './GhostTrapper'; const gt = new GhostTrapper(); gt.run();
After all this, I compile webpack config. And voilĂ , the bundle is ready for me to include into tampermonkey, and it runs exactly what I wanted.
From then on, I added multiple features to my automation tool. The ease of webpack’s watch mode really helps me during development, as I just need to refresh the page and the new code is already deployed.
4 Responses
You offer some great points within this post, but aren’t you lacking something crucial?
Hi,
Thank you for your reply.
I am unclear about what I’m missing here. Could you please elaborate?
I’m unsure about the bullet points.. maybe a bit redundant.
Hi there! Such a good short article, thanks!