YOURLS, which stands for Your Own URL Shortener, is a great open source platform to run a private URL shortener (a la bitly), it allows great control over links structure and traffic monitoring for each short url, plus giving a “brand feeling” to links shared.
I like things that work fast and simple, which is why I’ve enabled the public front end, so I can just type my short domain and get my short url in two clicks, without having to log into the admin panel each time I need to use it. My copy of YOURLS is hosted at https://sresc.io, which is my name initial followed by my surname, destiny wanted that it ends with “io” vowels, which is also a trendy TLD right now, lucky!
But as noted in the default front end template, a public interface does attract spammers, yet the current implementation of the built-in antispam plugin doesn’t allow to white-list domains or IP which means that WordPress plugins that uses the YOURLS api to retrieve custom short links may be blocked as well if the hosting machine IP is present in one of those lists for any reason, this may happen with shared-hosting if one or your neighbors acted mischievously.
Notice that temporarily deactivating the antispam plugin in YOURLS before publishing to allow WordPress to successfully retrieve a short url and then reactivating it won’t do it because as soon as the plugin is activated it will check all URLs currently stored and delete those which source matches the blacklists, I filed a bug report on GitHub about this, but it seems it’s a feature (?).
One of the main reasons I wanted to set up my own url shortener was to have my WordPress blog to retrieve automatically a custom url without much pain, but this “feature” would kill my main purpose, which is why I turned off the plugin.
After running without a spam filter for some months, I did notice a big increas in spam links being tossed in my yourls db, so I thought about using an alternative to the merciless antispam, the YourlsBlacklistIPs plugin which allows to manually add the IPs to be blocked in a textarea
list.
So now we have the tool to list all the bad guys that put trash in our shortener untill now … but how to proceed? We can run a search in the admin panel for the most common spam words but we would end with hundreds of pages without any batch command to operate on them. Well if you came all this way to build your private url shortener chances are high that you are either a coder or a geek that knows how to use the browser’s console, meaning we can solve this problem with few lines of JavaScript.
Search spam words with an high rows-per-page number
The first thing to do is to ensure that there is a big number in the rows input field, so that the evil links are presented on the same page all at once. Another filter we can add is to look up for links that have less than 1 hit, meaning trash links that have been put there just for sake of stealing space on the DB, but beware with this operation! I do check at least once that the links I create do work by trying them, so all my links do have at least one hit thus will not be found with this filter.
Get all the spammy IPs to paste them in YourlsBlacklistIPs
Now that we have all the trash grouped in front of us we can first deal with the evildoers by retrieving their IPs with the following :
var allIP = []; $('td.ip').each(function(){ var ip = $(this).text(); allIP.push(ip); }) console.log( allIP.join('\n') );
This will look up all the IPs displayed in the third column and save them in the declared array, then the console will ouput them as a list with one per line, which is the format accepted by the plugin, now it’s possible to select© all the IPs and then paste them in the plugin’s textarea
.
Hit save and rejoice, they will never bother you again, ever.
Delete all links
Now that we took care of the bad guys we wanna deal with the trash, going through each row to click the delete action for hundreds or thousands of entries is definitely not appealing, so let’s make jQuery handle the click operation for us, yes?
$('td.actions').each(function(){ var deleteBtn = $(this).find('.button_delete'); deleteBtn.trigger('click'); })
As soon as you hit the enter key to run the code, an alert asking for confirm to delete the link will popup, hit enter again and another one will appear, and again, and again … just press and keep pressed the enter key and let it feast upon the alerts to trash all those links in a matter of seconds.
Liberating, wasn’t it? 😀
Full Gist
And here is the full gist to pull off what we talked about, enjoy.