This page has been archived for historical purposes.


Selfbots, the greatest thing in the universe

So, my friend, you are wondering what is a selfbot? Well let me tell you a little story.

The first time you see it, you wonder what happened: someone typed for 2 seconds, and a wall of text appears as if by magic. Or something appears and then all of that person's messages disappear one after the other, relegated to /dev/null or some other weird place.

That, my friend, is selfbots in action.

What is a selfbot?

First, let's define what a userbot is. A Userbot is a bot that is running under a user account, instead of a true bot account. Userbots do not have the blue [BOT] tag next to them... and they are not accepted by Discord as a valid way to make bots. At least, not since they introduced bot accounts under their Discord Applications page.

On the other hand, a selfbot runs under an active user account. In other words, your account. When it posts a message, it's like you did. It can edit and delete your messages, has the same permissions you have, is on the same servers. It's you.


What are the rules for selfbots?

I mentioned that userbots are not tolerated by Discord. Selfbots, however, are tolerated under a specific set of semi-offical rules under which they turn a blind eye:

  • A selfbot must not, under any circumstance, respond or react to other user's actions. This means it should not respond to commands, autoreply to certain keywords, welcome users to servers, automatically react, etc. You must be the only one that can control it.

  • A selfbot must not, under any circumstance, do 'invite scraping'. This is the action of detecting server invites in chat, and automatically joining a server using that invite. That is akin to creating a virus, and it is not acceptable.

  • As selfbots run under your account they are subject to the same Terms of Service. That is to say, they should not spam, insult or demean others, post NSFW material, spread viruses or illegal material, etc. They have to follow the same rules that you follow.

IF, and only if you accept the above rules of selfbots, then you may proceed.

Further caveat (which was added recently): Certain user actions done by selfbots will unverify your account, as if you had not verified your email. This includes most "Friend" actions.

How do I make a selfbot?

The code that creates selfbots is essentially the same as regular bots, because... well it's the same library, right?

Respond only to you

The first difference is your message handler. It should start with a line that prevents the bot from interacting with anyone else's messages (see rule #1 above):

client.on("message", message => {
if( !== client.user) return;
// rest of the code for commands go here

This condition says: "if the author of the message is not the bot user, stop processing". This is generic code that works for everyone, and it fulfills our first condition so don't forget it.

The Token

The second difference, is how the bot logs in. To log a regular bot, you grab the Bot Token from the Applications Page, then put it in the client.login() function.

In the case of a selfbot, this token can be obtained from the Discord application, from the Console:

  1. From either the web application, or the installed Discord app, use the CTRL+SHIFT+I keyboard shortcut.

  2. This brings up the Developer Tools. Go to the Application tab

  3. On the left, expand Local Storage, then click on the entry (it should be the only one).

  4. Locate the entry called token, and copy it.


I've already covered why Bot Tokens should remain secret in the Getting Started guide. But this is even more critical. If someone gets a hold your personal token, they are you. They can pretend to be you, send messages as you. They can also massively fuck up any server where you have permissions. Like transfer server control to themselves. Have I stated clearly enough that you should be careful with your token? Ok, good!

Example selfbot commands

Here are a few useful examples of commands that I like to use.

Prune Command

A Prune command is used to delete your own messages from the channel you're on. Since there is no way for any server owner to prevent you from deleting or editing your own messages, this will always work. The command is called as /prune X where 99 is the maximum number of messages to remove, and the prefix depends on your own prefix.

fetchMessages() is limited to 100 messages total, and gets all the messages and not just your own. This means you will probably never be able to delete 100 messages since they'll be mixed in with other people's. I generally don't use it to prune more than 10 messages anyway.

let prefix = "/"; // always use a prefix it's good practice.
client.on("message", message => {
if ( !== client.user) return;
if (!message.content.startsWith(prefix)) return; // ignore messages that... you know the drill.
// We covered this already, yay!
const params = message.content.split(" ").slice(1);
if (message.content.startsWith(prefix + "prune")) {
// get number of messages to prune
let messagecount = parseInt(params[0]);
// get the channel logs{
limit: 100
.then(messages => {
let msg_array = messages.array();
// filter the message to only your own
msg_array = msg_array.filter(m => ===;
// limit to the requested number + 1 for the command message
msg_array.length = messagecount + 1;
// Has to delete messages individually. Cannot use `deleteMessages()` on selfbots. => m.delete().catch(console.error));

I've included the author check, prefix and params slice at the top for this first example - the other examples won't have that.

Custom /lenny and friends

I love lenny, he's really a great friend to have. And his buddy /justright is also pretty cool! This command is... not really a command in the traditional sense of the word, because it's not built with the regular if(msg.content.startsWith("something")) we've seen before.

What it does is, check if the message is only the prefix + any of the names in a map. The map itself can be placed outside of the message handler, or right before the commands are called:

let shortcuts = new Map([
["lenny", "( ͡° ͜ʖ ͡°)"],
["shrug", "¯\\_(ツ)_/¯"],
["justright", "✋😩👌"],
["tableflip", "(╯°□°)╯︵ ┻━┻"],
["unflip", "┬──┬ ノ( ゜-゜ノ)"]

There's technically only 2 "new" commands here. The rest are there because I like to do /tableflip on my mobile phone, and this does it for me! And you can add your own, of course. Like a /doubleflip, for example.

The next step is to add the check at the beginning of your message handler. Well not quite: this code should be right after your prefix check, before you split into parameters, for maximum code efficiency.

let prefix = "/";
client .on("message", message => {
if ( !== client.user) return;
if (!message.content.startsWith(prefix)) return;
// custom shortcut check
let command_name = message.content.slice(1); // removes the prefix, keeps the rest
if (shortcuts.has(command_name)) {
// setTimeout is used here because of a bug in message delays in Discord.
// Otherwise the message would edit and then "seem" to un-edit itself... ¯\_(ツ)_/¯
setTimeout(() => {message.edit(shortcuts.get(command_name))}, 50);
// The Rest of your code
// ...

A complete implementation

Don't really care for coding this all yourself? Want a complete, functional, awesome selfbot all done for you? I got you covered, obviously! Check out Evie's Selfbot on Github!