diff --git a/client.js b/client.js
index d1f8018..925ffe0 100644
--- a/client.js
+++ b/client.js
@@ -1,4 +1,4 @@
-botmon_client = {
+({
init: function() {
/* send the page view request: */
@@ -27,8 +27,8 @@ botmon_client = {
'lg': navigator.language.substring(0,2),
'lt': ( document._botmon ? Date.now() - document._botmon.t0 : null),
'id': (document._botmon.session || 'null').replaceAll('\"', ''),
- 'r': document.referrer /*,
- 'tz': new Date().getTimezoneOffset(),
+ 'r': document.referrer,
+ 'tz': new Date().getTimezoneOffset() /*,
'url': window.location.href,
'scr': screen.width+':'+screen.height,
'l': navigator.languages */
@@ -64,7 +64,7 @@ botmon_client = {
+ ( sessionId ? '&id=' + encodeURIComponent(sessionId) : '')
+ ( uid ? '&u=' + encodeURIComponent(uid) : '');
const response = await fetch(url + req, {
- /*method: 'HEAD'*/
+ method: 'HEAD'
});
if (!response.ok) {
throw new Error(response.status + ' ' + response.statusText + ' - ' + url);
@@ -76,7 +76,4 @@ botmon_client = {
// setTimeout(this._onHeartbeat.bind(this, this._src.replace( this._scriptName, '/tick.php')),this._heartbeat * 1000);
}
}
-}
-
-// init the script:
-botmon_client.init();
\ No newline at end of file
+}).init();
\ No newline at end of file
diff --git a/config/known-bots.json b/config/known-bots.json
index 60ca4a5..48b53c1 100644
--- a/config/known-bots.json
+++ b/config/known-bots.json
@@ -244,10 +244,22 @@
"rx": ["TikTokSpider"],
"url": "https://darkvisitors.com/agents/tiktokspider"
},
- {"id": "HaloBot",
+ {"id": "halobot",
"n": "HaloBot", "geo": "FR",
"r": ["HaloBot"],
"rx": [" HaloBot\\/(\\d+)\\."],
"url": "https://darkvisitors.com/agents/tiktokspider"
+ },
+ {"id": "wayback",
+ "n": "Internet Archive",
+ "r": ["archive.org_bot"],
+ "rx": [" archive.org_bot "],
+ "url": "https://archive.org/details/archive.org_bot"
+ },
+ {"id": "alibaba",
+ "n": "Alibaba AliyunSec Bot",
+ "r": ["AliyunSecBot"],
+ "rx": ["AliyunSecBot/Aliyun"],
+ "url": "https://www.aqtronix.com/useragents/?Action=ShowAgentDetails&Name=AliyunSecBot"
}
]
\ No newline at end of file
diff --git a/img/bots.png b/img/bots.png
index 087993f..20bb90a 100644
Binary files a/img/bots.png and b/img/bots.png differ
diff --git a/img/referers.png b/img/referers.png
index ff68e5b..1650a2b 100644
Binary files a/img/referers.png and b/img/referers.png differ
diff --git a/plugin.info.txt b/plugin.info.txt
index ec31480..26588af 100644
--- a/plugin.info.txt
+++ b/plugin.info.txt
@@ -1,7 +1,7 @@
base botmon
author Sascha Leib
email ad@hominem.com
-date 2025-09-16
+date 2025-09-19
name Bot Monitoring
desc A tool for monitoring and analysing bot traffic to your wiki (under development)
url https://www.dokuwiki.org/plugin:botmon
diff --git a/script.js b/script.js
index c957faa..abfdba8 100644
--- a/script.js
+++ b/script.js
@@ -7,11 +7,18 @@
const BM_USERTYPE = Object.freeze({
'UNKNOWN': 'unknown',
'KNOWN_USER': 'user',
- 'HUMAN': 'human',
+ 'PROBABLY_HUMAN': 'human',
'LIKELY_BOT': 'likely_bot',
'KNOWN_BOT': 'known_bot'
});
+// enumeration of log types:
+const BM_LOGTYPE = Object.freeze({
+ 'SERVER': 'srv',
+ 'CLIENT': 'log',
+ 'TICKER': 'tck'
+});
+
/* BotMon root object */
const BotMon = {
@@ -189,7 +196,7 @@ BotMon.live = {
// are all the flags set?
if (data._dispatchBotsLoaded && data._dispatchClientsLoaded && data._dispatchPlatformsLoaded && data._dispatchRulesLoaded) {
// chain the log files loading:
- BotMon.live.data.loadLogFile('srv', BotMon.live.data._onServerLogLoaded);
+ BotMon.live.data.loadLogFile(BM_LOGTYPE.SERVER, BotMon.live.data._onServerLogLoaded);
}
},
// flags to track which data files have been loaded:
@@ -203,7 +210,7 @@ BotMon.live = {
//console.info('BotMon.live.data._onServerLogLoaded()');
// chain the client log file to load:
- BotMon.live.data.loadLogFile('log', BotMon.live.data._onClientLogLoaded);
+ BotMon.live.data.loadLogFile(BM_LOGTYPE.CLIENT, BotMon.live.data._onClientLogLoaded);
},
// event callback, after the client log has been loaded:
@@ -211,7 +218,7 @@ BotMon.live = {
//console.info('BotMon.live.data._onClientLogLoaded()');
// chain the ticks file to load:
- BotMon.live.data.loadLogFile('tck', BotMon.live.data._onTicksLogLoaded);
+ BotMon.live.data.loadLogFile(BM_LOGTYPE.TICKER, BotMon.live.data._onTicksLogLoaded);
},
@@ -237,8 +244,8 @@ BotMon.live = {
_visitors: [],
// find an already existing visitor record:
- findVisitor: function(visitor) {
- //console.info('BotMon.live.data.model.findVisitor()');
+ findVisitor: function(visitor, type) {
+ //console.info('BotMon.live.data.model.findVisitor()', type);
//console.log(visitor);
// shortcut to make code more readable:
@@ -246,34 +253,36 @@ BotMon.live = {
const timeout = 60 * 60 * 1000; // session timeout: One hour
- // loop over all visitors already registered:
- for (let i=0; i
3 ? '.' + tld : '' ) );
+ refId = ( tld == 'localhost' ? tld : hArr[hArr.length-2]);
refName = hArr[hArr.length-2] + '.' + tld;
}
@@ -757,7 +775,7 @@ BotMon.live = {
case BM_USERTYPE.KNOWN_USER:
arr = me._countries.user;
break;
- case BM_USERTYPE.HUMAN:
+ case BM_USERTYPE.PROBABLY_HUMAN:
arr = me._countries.human;
break;
case BM_USERTYPE.LIKELY_BOT:
@@ -803,7 +821,7 @@ BotMon.live = {
case BM_USERTYPE.KNOWN_USER:
arr = me._countries.user;
break;
- case BM_USERTYPE.HUMAN:
+ case BM_USERTYPE.PROBABLY_HUMAN:
arr = me._countries.human;
break;
case BM_USERTYPE.LIKELY_BOT:
@@ -1445,14 +1463,14 @@ BotMon.live = {
// register the visit in the model:
switch(type) {
- case 'srv':
+ case BM_LOGTYPE.SERVER:
BotMon.live.data.model.registerVisit(data, type);
break;
- case 'log':
+ case BM_LOGTYPE.CLIENT:
data.typ = 'js';
BotMon.live.data.model.updateVisit(data);
break;
- case 'tck':
+ case BM_LOGTYPE.TICKER:
data.typ = 'js';
BotMon.live.data.model.updateTicks(data);
break;
@@ -1538,7 +1556,7 @@ BotMon.live = {
// update known bots list:
const botElement = document.getElementById('botmon__botslist'); /* Known bots */
if (botElement) {
- botElement.innerHTML = `Known bots (top ${maxItemsPerList})`;
+ botElement.innerHTML = `Top visiting bots:`;
let botList = BotMon.live.data.analytics.getTopBots(maxItemsPerList);
botList.forEach( (botInfo) => {
@@ -1567,7 +1585,7 @@ BotMon.live = {
// update the top bot countries list:
const botCountries = document.getElementById('botmon__today__countries');
if (botCountries) {
- botCountries.appendChild(makeElement('dt', {}, `Bot Countries (top ${maxItemsPerList})`));
+ botCountries.appendChild(makeElement('dt', {}, `Top bot Countries:`));
const countryList = BotMon.live.data.analytics.getCountryList('likely_bot', 5);
countryList.forEach( (cInfo) => {
const cLi = makeElement('dd');
@@ -1582,7 +1600,7 @@ BotMon.live = {
if (wmoverview) {
const bounceRate = Math.round(data.totalVisits / data.totalPageViews * 100);
- wmoverview.appendChild(makeElement('dt', {}, "Overview"));
+ wmoverview.appendChild(makeElement('dt', {}, "Visitor overview"));
for (let i = 0; i < 3; i++) {
const dd = makeElement('dd');
let title = '';
@@ -1805,7 +1823,7 @@ BotMon.live = {
const platformName = (data._platform ? data._platform.n : 'Unknown');
const clientName = (data._client ? data._client.n: 'Unknown');
- const sumClass = ( data._seenBy.indexOf('srv') < 0 ? 'noServer' : 'hasServer');
+ const sumClass = ( data._seenBy.indexOf(BM_LOGTYPE.SERVER) < 0 ? 'noServer' : 'hasServer');
const li = make('li'); // root list item
const details = make('details');
@@ -1868,8 +1886,8 @@ BotMon.live = {
}
// referer icons:
- if ((data._type == BM_USERTYPE.HUMAN || data._type == BM_USERTYPE.LIKELY_BOT) && data.ref) {
- const refInfo = BotMon.live.data.analytics.getRefererInfo(new URL(data.ref));
+ if ((data._type == BM_USERTYPE.PROBABLY_HUMAN || data._type == BM_USERTYPE.LIKELY_BOT) && data.ref) {
+ const refInfo = BotMon.live.data.analytics.getRefererInfo(data.ref);
span1.appendChild(make('span', {
'class': 'icon_only referer ref_' + refInfo.id,
'title': "Referer: " + data.ref
diff --git a/style.less b/style.less
index 55a86e5..944bc56 100644
--- a/style.less
+++ b/style.less
@@ -51,6 +51,8 @@
&.bot_claude::before { background-position-y: -160px }
&.bot_applemsgs::before { background-position-y: -180px }
&.bot_reddit::before { background-position-y: -200px }
+ &.bot_wayback::before { background-position-y: -220px }
+ &.bot_alibaba::before { background-position-y: -241px }
&.bot_other::before { background-image: url('img/more.svg') }
/* platform icons */
@@ -333,6 +335,7 @@
&.ctry_nu::before { background-position-y: -4941px }
&.ctry_local::before { background-image: url('img/addr.png') } /* localhost */
+ &.ctry_other::before { background-image: url('img/more.svg') } /* other countries */
/* Session icons */
&.session::before { background-image: url('img/idtyp.png') }
@@ -358,6 +361,9 @@
&.ref_yandex::before { background-position-y: -160px }
&.ref_chatgpt::before { background-position-y: -180px }
&.ref_brave::before { background-position-y: -200px }
+ &.ref_wikipedia::before { background-position-y: -220px }
+ &.ref_denkfehler::before { background-position-y: -240px }
+ &.ref_fallacies::before { background-position-y: -260px }
&.ref_other::before { background-image: url('img/more.svg') }
}