How to Script Interactions With a Website

As part of the process for clients signing up for a service for The Blog Fixer, they must create an administrator for us with the correct permissions that allow us to install plugins and take backups. When we do free promotions, as many as half of everyone who signs up for the promotion never end up creating the user for us, and so never get their site scan done.

Sometimes people forget to make the user an administrator, other times they incorrectly type our email address for the user. In many cases, though, their server does not send emails reliable, and so we do not get the user set up email that is usually sent when a user is created. Our workaround is to send an email automation if we don’t receive the signup email within a day or two, and have them set the password for us and submit it via a form. Unfortunately, this is a lot of work for some people, and most of the time the automation email goes ignored.

I recently signed up for a trial of WP SmushIt Pro (an image optimizing plugin), and part of the signup process brings you to their website. Once there, you enter your website’s URL, then they ask you for your admin login. Once submitted, they automatically login to your website, install, and setup the premium version of their plugin. This is cool because WordPress does not have an API which allows you to log in and interact with the admin dashboard, meaning they went through the regular login route and uploaded the plugin the same way a browser would.

After doing some digging, I found a popular Node library called Puppeteer, which helps to automate interactions from a browser while remaining headless (can be used on a server, runs in the background). Below is an example of a Node script that creates a new user on my WordPress website, with the headless mode disabled to show visually what’s going on.

https://var/www/html.youtube.com/watch?v=5fg-cHNaMYE

The source is fairly self explanatory, as the library is easy to use and doesn’t require a ton of configuring.

const puppeteer = require('puppeteer-core');

(async () => {
  const browser = await puppeteer.launch({"executablePath": "C:UsersscaraDocumentschrome-winchrome.exe", "headless": false});
  const page = await browser.newPage();
  await page.goto('https://scarabcoder.com/wp-login.php?redirect_to=https%3A%2F%2Fscarabcoder.com%2Fwp-admin%2Fuser-new.php&reauth=1');
  await page.waitFor(1000);
  await page.type("#user_login", "testadmin");
  await page.type("#user_pass", "testadminpassword123");
  await page.click("#wp-submit");
  await page.waitForNavigation({waitUntil: "networkidle2"});
  
  await page.type("#user_login", "exampleuser");
  await page.type("#email", "[email protected]");
  await page.click("button.wp-generate-pw");
  await page.select("#role", "administrator");
  await page.waitForFunction('document.getElementById("pass1-text").value != ""');
  var el = await page.$("#pass1-text");
  var password = await page.evaluate(el => el.value, el);
  console.log("Generated password for user: " + password);
})();

Going back to the issue mentioned at the start of this post, this means that after a client makes a purchase, we can ask for an admin username and password. After it’s been submitted, we can send that to a Node server that uses Puppeteer to log into their website, set up a user for us, and make sure it’s configured correctly, then encrypt and save the password for our use later.

This also reduces the number of steps they need to take for it to be all ready for us to come in and run it. It makes the whole process much tighter, requiring at the least just entering their username and password, then being done and just have to wait for the final report.