A simple Discord Self-bot using console. Intended for quick scripts runnable directly from the devtools. Can also be used with Node.js for quick simple scripts!
Automating user accounts is against Discord's Terms of Service. You might get banned if you abuse it (too much spam, unusual activity).
- Close Discord client (
Quit Discord
in system tray) - Open the settings file, it's location depends on your OS:
- Windows:
%appdata%\discord\settings.json
- macOS:
~/Library/Application Support/Discord/settings.json
- Linux:
~/.config/discord/settings.json
- Windows:
- Add
"DANGEROUS_ENABLE_DEVTOOLS_ONLY_ENABLE_IF_YOU_KNOW_WHAT_YOURE_DOING": true,
(this is necessary since last update) - Save the file
- Restart Discord client
- Open Chrome devtools on Discord using
Ctrl + shift + i
- Go to the console tab and paste the entire
index.js
script - Send a message in any channel/DM, this will automatically set your auth token into the script
- ...
- Profit!
If you want to disable the token from being automatically set, use autoUpdateToken = false
at the start of your bot script. You can extract the auth token manually by doing this:
- Open Chrome devtools on Discord using
Ctrl + shift + i
- Go to the console tab and paste the entire
index.js
script - Go to the network tab and send a message in any channel/DM
- A new entry should appear, click it then copy the
Authorization
header (in theRequest Headers
section) - Paste it in
authHeader
at the end of the script in the console
You can now use any function provided by this script in the console like await api.someFunction()
. Don't forget await
or the server's response will not be printed to the console.
Use the api.id()
function to update the variable gid
guild id and cid
channel id to what you are currently watching.
Note: It's a good idea to wrap your code in its own scope { code }
or you might get an error when reusing the same variable names later!
Update cid
to the channel you are watching, get the last 100 messages, send a message, edit then delete.
{
api.id()
// or api.update_guildId_and_channelId_withCurrentlyVisible()
let channelId = cid
// or let channelId = api.getConfig().channelId
// Send a message
let sentMessage = await api.sendMessage(channelId, `Hello! π My name is ${user.username}!`)
await api.delay(2000)
// Edit a message
let editedMessage = await api.editMessage(channelId, sentMessage.id, 'Hello, edited! βοΈ')
await api.delay(2000)
// Delete a message
await api.deleteMessage(channelId, editedMessage.id)
await api.delay(2000)
// Log the last 100 messages in the console
let messages = await api.getMessages(channelId)
console.log(messages)
}
Types are provided at types.d.ts
. You can use them in your IDE to get typings and develop your script in a better environment. The typings are not fully complete, but it's better than nothing (PRs are welcome!).
The script will not work with Node.js (and not supposed to be made for it), you need to copy/paste it in the Discord console to run it.
Don't forget to paste the full index.js
script in the console first to get the api
variable!
git clone [email protected]:rigwild/discord-self-bot-console.git
# or
git clone https://github.com/rigwild/discord-self-bot-console.git
cd discord-self-bot-console
code .
Doing the following, you should be able to get typings. Open myScripts/example.js
.
// myScripts/example.js
// @ts-check
const { api } = require('../index.js')
// Copy paste the below code inside the Discord console
;(async () => {
const user = await api.getCurrentUser()
console.log(user.username)
})()
SENDING EMBEDS AS A USER ACCOUNT IS NOT POSSIBLE ANYMORE, DISCORD UPDATED ITS API (see this reddit post)
See Can I run it without opening Discord?
See Is it possible to use multiple tokens?
This specific script only works for user accounts. If you want to use a bot account, you need to use the provided Node.js version (see above).
Why can't I use a bot account with the Discord client?
See How to list all custom emojis urls from all guilds you are a member of
See How to react with emoji or custom emoji ? π€
See Send slash commands (/something)
See Add and remove reactions to every message on a channel
{
api.id()
let channelId = cid
const sentMessage = await api.sendMessage(channelId, 'Hello, please open a thread here! π')
// A new thread opened in reply to a message
const createdThread = await api.createThread(channelId, sentMessage.id, 'A cool thread π€')
const sentMessage2 = await api.sendMessage(createdThread.id, 'Here it is, this is a thread! π')
await api.replyToMessage(createdThread.id, sentMessage2.id, 'Thanks! βοΈ')
// A clean new thread without any message in it (not opened on any message!)
await api.createThreadWithoutMessage(channelId, 'Another thread π')
}
Send a message
to a channel (channelId
) every minute then delete it (useful for XP farming in some servers).
You can use loop = false
at any time to stop it.
{
api.id()
let channelId = cid
let message = 'Hi, I like spamming π¦'
var loop = true
let count = 0
while (loop) {
const sentMessage = await api.sendMessage(channelId, message)
await api.deleteMessage(channelId, sentMessage.id)
console.log(`Sent ${++count} messages`)
await api.delay(61000) // 61 seconds
}
}
To farm XP with multiple accounts, check Is it possible to farm XP using multiple tokens?
Delete the amount
messages from user (userId
) sent to a channel/DM (channelId
) appearing before message (beforeMessageId
) and wait delayMs
milliseconds everytime.
I use sometimes to fully clear my DMs as Discord does not offer it as a feature.
You can use loop = false
at any time to stop it.
Discord recently made its rate limiting strictier. I recommend 1100ms as a minimum to not get rate limited. Make it even bigger if you are affraid of getting banned.
{
api.id()
let channelId = cid
let userId = '012345678987654321'
let amount = 99999999
let delayMs = 1100
let beforeMessageId = '8999999999999999999' // Leave it like this to delete from latest
let deletionCount = 0
var loop = true
while (loop) {
const messages = await api.getMessages(channelId, 100, { before: beforeMessageId })
// We reached the start of the conversation
if (messages.length < 100 && messages.filter(x => x.author.id === userId && (x.type === 0 || x.type === 19)).length === 0) {
loop = false
console.log(`[${deletionCount}/${amount}] Reached the start of the conversations! Ending.`)
continue
}
// Update last message snowflake for next iteration
beforeMessageId = messages[0].id
for (const aMessage of messages) {
if (loop === false) break
// Check if the max amount was reached
if (deletionCount >= amount) {
loop = false
console.log(`[${deletionCount}/${amount}] Deleted the requested amount of messages! Ending.`)
break
}
// Update last message snowflake for next iteration
beforeMessageId = aMessage.id
// Check if the message should be deleted
if (aMessage.author.id === userId && (aMessage.type === 0 || aMessage.type === 19)) {
await api.deleteMessage(channelId, aMessage.id)
deletionCount++
console.log(`[${deletionCount}/${amount}] Deleted a message!`)
if (deletionCount < amount) await api.delay(delayMs)
}
}
await api.delay(delayMs)
}
}
Pass your custom function!
This example will apply all reactions already there on all messages, then add π if message says hi!!
or hello
.
{
api.id()
let channelId = cid
let amount = 99999999
let delayMs = 500
let actionFn = async (channelId, message) => {
//
// Your custom code here
//
let wasActiontriggered = false
// Copy all reactions already present on message
for (const reaction of message.reactions || []) {
let reactionToAdd = reaction.emoji.id ? `${reaction.emoji.name}:${reaction.emoji.id}` : reaction.emoji.name
await api.addReaction(channelId, message.id, reactionToAdd)
wasActiontriggered = true
await api.delay(delayMs)
}
// If person said `hello!!!` or `hi!`, react with waving hand π
if (message.content.match(/^(?:hi|hello)!*$/)) {
await api.addReaction(channelId, message.id, 'π')
wasActiontriggered = true
}
// Return a boolean indicating if you did something to the message
// If true, will log and apply delay
return wasActiontriggered
}
let beforeMessageId = '8999999999999999999' // Leave it like this to react from latest
let count = 0
var loop = true
while (loop) {
const messages = await api.getMessages(channelId, 100, { before: beforeMessageId })
// We reached the start of the conversation
if (messages.length < 100 && messages.filter(x => x.type === 0 || x.type === 19).length === 0) {
loop = false
console.log(`[${count}/${amount}] Reached the start of the conversation! Ending.`)
continue
}
// Update last message snowflake for next iteration
beforeMessageId = messages[0].id
for (const aMessage of messages) {
if (loop === false) break
// Check if the max amount was reached
if (count >= amount) {
loop = false
console.log(`[${count}/${amount}] Treated the requested amount of messages! Ending.`)
break
}
// Update last message snowflake for next iteration
beforeMessageId = aMessage.id
// Check if the message should be reacted
if (aMessage.type === 0 || aMessage.type === 19) {
let wasActiontriggered = await actionFn(channelId, aMessage)
// Apply delay and log only if return true
if (wasActiontriggered) {
count++
console.log(`[${count}/${amount}] Treated a message! ID=${aMessage.id}`)
if (count < amount) await api.delay(delayMs)
}
}
}
await api.delay(delayMs)
}
}
I don't know, maybe. I have used lots of scripts in the past, often deleted 100k+ messages of mine accross private messages and servers and never got banned, ever.
But I can't guarantee anything. Use at your own risk.
Automating user accounts is againt Discord's Terms of Service.
This is intended for small scripts, not to implement a full-featured bot.
If you need to listen to events or do something more advanced you can use the discord.js package with your user token (with v11.3.2 and below though, they deprecated user token support starting v11.4.0!).
Note: As they don't support user bots anymore, it may break at any time (with Discord changing their APIs).
Post your requests in the Discussions tab. Please search if your request was not mentionned in an earlier post before asking.
Of course! Post it in the Discussions tab. Please search if a similar script was shared earlier before posting.
Initially, this was posted as a gist for myself. As there's interest for such a thing, I figured out making a proper repo was better to share scripts.
The full list of available functions is available in types.d.ts
.
api.id()
api.update_guildId_and_channelId_withCurrentlyVisible()
api.delay(ms)
api.apiCall(apiPath, body, method = 'GET')
api.getMessages(channelOrThreadId, limit?, params = {})
api.sendMessage(channelOrThreadId, message, tts?, body = {})
api.replyToMessage(channelOrThreadId, repliedMessageId, message, tts?, body = {})
api.editMessage(channelOrThreadId, messageId, newMessage, body = {})
api.deleteMessage(channelOrThreadId, messageId)
api.createThread(channelId, toOpenThreadInmessageId, name, autoArchiveDuration?, body = {})
api.getCurrentUser()
api.editCurrentUser(username?, bio?, body = {})
// and more...
api.delay(ms: number) => Promise<void>
Wait for ms
milliseconds.
await delay(1500)
await api.delay(1500)
api.downloadFileByUrl(url: string, filename: string) => Promise<void>
Download a file at url
and name it filename
.
See How to download attachments (file, image) from a message?
await api.downloadFileByUrl('https://cataas.com/cat', 'cat.png')
await api.downloadFileByUrl(messages[0].attachments[0].url, messages[0].attachments[0].filename)
api.id() => void
(old alias)
api.update_guildId_and_channelId_withCurrentlyVisible() => void
Update the variable gid
guild id and cid
channel id to what you are currently watching in the Discord client.
id()
api.id()
api.getConfig(): Readonly<{
authHeader: string,
autoUpdateToken: boolean,
guildId: string,
channelId: string,
gid: string,
cid: string,
}>
Returns the current configuration, read-only. Useful if you want to use typings in your IDE.
Set configuration
api.setConfigAutoUpdateToken(autoUpdateToken: boolean): void
api.setConfigGid(guildId: string): void
api.setConfigGuildId(guildId: string): void
api.setConfigCid(channelId: string): void
api.setConfigChannelId(channelId: string): void
authHeader
: You Discord account auth tokenautoUpdateToken
: If true, the token will be automatically updated in the bot when a request is sent from the client (e.g sending a message)gid
: Current guild id (update to what you are currently watching usingapi.id()
)cid
: Current channel id (update to what you are currently watching usingapi.id()
)