Skip to content

Instantly share code, notes, and snippets.

@bellydrum
Last active March 18, 2019 17:56
Show Gist options
  • Save bellydrum/83dc4630a588f352820666fb42f912ba to your computer and use it in GitHub Desktop.
Save bellydrum/83dc4630a588f352820666fb42f912ba to your computer and use it in GitHub Desktop.
Checks if a bot is auto-clicking a specified DOM element.
/**
* clickBotChecker.js
* ------------------------------------------------------------------------------
* ABOUT:
* clickBotChecker.userIsBot() returns true if it thinks a bot is clicking your specified DOM element.
* METHOD
* .userIsBot() does the following to determine auto-clicking behavior:
* 1. Store the timestamp of every n clicks for analysis
* 2. Once three timestamps have been stored, every n clicks, find the absolute value of the difference between:
* a. ( (the average of the last three timestamps) * 3 )
* b. ( the last three timestamps * 3 )
* 3. If the absolute value of the difference between the two values is less than 5,
* then the user is clicking with extremely precise frequency and is most likely a bot.
* USAGE:
* 1. Put this code above where you want it to be used.
* 2. Inside your click event handler, increment clickBotChecker.currentSessionScore by 1.
* 3. Use clickBotChecker.userIsBot() inside your DOM element click event handler and handle the result (true / false).
**/
const clickBotChecker = {
/* global app variables **/
currentSessionScore: 0,
timeSinceLastCheck: Date.now(),
timeGapsBetweenChecks: [],
userIsBot: (checkFrequency) => {
/** do a click frequency check every checkFrequency clicks. **/
if ( ( clickBotChecker.currentSessionScore > checkFrequency * 2 ) &&
( clickBotChecker.currentSessionScore % checkFrequency === 0 ) ) {
/* log click behavior */
const now = Date.now()
const timeGap = now - clickBotChecker.timeSinceLastCheck
clickBotChecker.timeSinceLastCheck = now
clickBotChecker.timeGapsBetweenChecks.push( timeGap )
/* determine if click behavior implies bot usage */
if (clickBotChecker.timeGapsBetweenChecks.length > 3) {
const gapsToCheck = clickBotChecker.timeGapsBetweenChecks.slice( -3 )
const averageOfLastThreeChecks = (
parseInt( gapsToCheck.reduce( ( n, m ) => n + m, 0 ) / gapsToCheck.length)
)
const userIsBot = ( Math.abs( gapsToCheck[0] - averageOfLastThreeChecks ) < 5 ) &&
( Math.abs( gapsToCheck[1] - averageOfLastThreeChecks ) < 5 ) &&
( Math.abs( gapsToCheck[2] - averageOfLastThreeChecks ) < 5 )
return userIsBot
}
}
},
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment