diff --git a/admin.php b/admin.php index 6e1b3e1..2869ebd 100644 --- a/admin.php +++ b/admin.php @@ -55,7 +55,7 @@ class admin_plugin_botmon extends AdminPlugin {
Loading …
- Overview + Bots overview
@@ -63,7 +63,7 @@ class admin_plugin_botmon extends AdminPlugin {
- Web metrics (humans only) + Humans’ web metrics
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') } }