DEV Community

Cover image for Hosting a Discord bot on Repl.it
Fizal Sarif
Fizal Sarif

Posted on • Updated on

Hosting a Discord bot on Repl.it

As Blog posts age the content becomes a bit stale. The information here might not be accurate anymore.

If you're an avid discord user you've definitely seen a bot (or 10) in the server(s) you're a part of. If you're a programmer of some sorts (hobby, college student, or tired professional) you've probably thought "I could make this better! 🤓".

This article is great if:

  • You have no access to a credit card and want to host your projects somewhere your friends (and potential employers) can access them 24/7.
  • You have the coolest discord bot idea and you're able to code rock paper scissors in some programming language. I used JavaScript for this example but this concept can be applied to Ruby, Python, Java, etc.
  • You know how package managers work for whatever programming language you'll try this with.
  • You're a cheapo like me and want to run a discord bot or a hundred discord bots for FREE!

Turn back now if you need a bot with voice capabilities. We'll be using Repl.it to host our bot and it's a pain to install ffmpeg on it.

Step 1: Create a Bot User

a) Sign into your discord account on https://discordapp.com and create a new application here. Then add a bot user to that application:
screenshot of a bot user

b) Next save your bot's token for later use:
Save your bot's token

c) The last thing we need from this portal is your bot's invite URL. This determines what your bot has permission to do. At the very least it needs permission to send messages. Make sure to invite it to your server using that URL!
Get your bot's invite url.

Step 2: Head to Repl.it

If you haven't heard of it Repl.it is an online IDE of sorts that lets you create and share small projects. It's pretty amazing and has constantly been adding features to help you do more online. We call these repls.

a) Create a new JavaScript repl.
Create a new Nodejs Repl

b) First thing we need to make sure a webserver is running in our repl. Repl.it will kill a running repl when you close the browser tab unless it's serving web content. Then Repl will keep it alive for an hour even if you close the tab. Paste the following code in your repl and Repl.it will automatically install packages for you and start an express webserver.

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => res.send('Hello World!'));

app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`));
Enter fullscreen mode Exit fullscreen mode

If you look to the left, a file called package.json should have appeared.
packagejson
This file holds any packages you require in your repl. Plus any other scripts we might make. Just like a regular NodeJs project.

I chose express as my webserver. If you're working with Python you'd probably use Flask, Ruby would have Sinatra. For java however I would recommend investigating com.sun.net.httpserver.HttpServer for a speedy start up time.

c) Next we need to instantiate our bot.

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => res.send('Hello World!'));

app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`));

// ================= START BOT CODE ===================
const Discord = require('discord.js');
const client = new Discord.Client();

client.on('ready', () => {
  console.log(`Logged in as ${client.user.tag}!`);
});

client.on('message', msg => {
  if (msg.content === 'ping') {
    msg.reply('pong!');
  }
});
// You really don't want your token here since your repl's code
// is publically available. We'll take advantage of a Repl.it 
// feature to hide the token we got earlier. 
client.login(process.env.DISCORD_TOKEN);
Enter fullscreen mode Exit fullscreen mode

ping pong is sort of like the hello world for bots. Once we start this up you should see your bot online in your server. If you send the word ping in your server the bot should reply with pong.

After you've pasted that code snippet in, don't click restart yet!

d) Create a .env file

On the left create a file called .env, the content of the file should be:

DISCORD_TOKEN=your_token
Enter fullscreen mode Exit fullscreen mode

This will help us hide your token from the rest of the world. Read more about it here in Repl.it's Docs.

Now that the proper credentials are in, you can click restart now. Your bot should be online!
bot online
it alive boss

Congrats! You can peruse the discord.js documentation to implement all the cool bot features you can dream of!

Step 3: Keepin' our bot alive

stayin' alive

As I mentioned before Repl.it puts repls to sleep. Here's a note from their docs about that:

Once deployed, the server will continue to run in the background, even after you close the browser tab. The server will stay awake and active until an hour after its last request, after which it will enter a sleeping stage. Sleeping repls will be woken up as soon as it receives another request; there is no need to re-run the repl. However, if you make changes to your server, you will need to restart the repl in order to see those changes reflected in the live version.

We're going to use Uptime Robot to keep our bot online.

a) Copy the url for your repl's webserver.
url

b) Create an account on Uptime Robot and create a monitor to ping your server every 5 minutes
keepin dem alive

That's it! We're done. Have fun with your 24/7 hosted bot. Sometimes the bot might be offline. But for 99% of the day it'll be online thanks to Uptime Robot.

Happy Coding Folks!

Latest comments (46)

Collapse
 
devyxx profile image
devyxx

My bot didnt come online i did everything

Collapse
 
agiltriono profile image
Agil Triono

i have been created one discord bot it is been in development but i have the fork version so to try this , it work !!
Used uptimerobot for every 30 minutes with delay 1 minutes .

Collapse
 
bradtft profile image
BradTFT

so when i paste my webserver url into uptime robot is just says "Enter a valid IP or FQDN" any fixes for this?

Collapse
 
wylimee profile image
emily :) |open commisions|

It doesn't work, what to do
also with the new secrets thing idk what
for the "Next we need to instantiate our bot." do we like put it in the same file?

Collapse
 
partybot profile image
PartyBoy Gaming

I can’t find my web server link what do I do?
(Ps I dont have the web tab in the bottom)

Collapse
 
creationsstudios profile image
Creations Studios

Hi it won't work. The bot isn't online and in repl it said the token is invalid.

Collapse
 
opielix profile image
Opilite Elix

same

Collapse
 
opielix profile image
Opilite Elix

and the repl brakes and can't wake up

Collapse
 
creationsstudios profile image
Creations Studios

Server {
insecureHTTPParser: undefined,
_events: [Object: null prototype] {
request: [Function: app] EventEmitter {
_events: [Object: null prototype],
_eventsCount: 1,
_maxListeners: undefined,
setMaxListeners: [Function: setMaxListeners],
getMaxListeners: [Function: getMaxListeners],
emit: [Function],
addListener: [Function: addListener],
on: [Function: addListener],
prependListener: [Function: prependListener],
once: [Function: once],
prependOnceListener: [Function: prependOnceListener],
removeListener: [Function: removeListener],
off: [Function: removeListener],
removeAllListeners: [Function: removeAllListeners],
listeners: [Function: listeners],
rawListeners: [Function: rawListeners],
listenerCount: [Function: listenerCount],
eventNames: [Function: eventNames],
init: [Function: init],
defaultConfiguration: [Function: defaultConfiguration],
lazyrouter: [Function: lazyrouter],
handle: [Function: handle],
use: [Function: use],
route: [Function: route],
engine: [Function: engine],
param: [Function: param],
set: [Function: set],
path: [Function: path],
enabled: [Function: enabled],
disabled: [Function: disabled],
enable: [Function: enable],
disable: [Function: disable],
acl: [Function],
bind: [Function],
checkout: [Function],
connect: [Function],
copy: [Function],
delete: [Function],
get: [Function],
head: [Function],
link: [Function],
lock: [Function],
'm-search': [Function],
merge: [Function],
mkactivity: [Function],
mkcalendar: [Function],
mkcol: [Function],
move: [Function],
notify: [Function],
options: [Function],
patch: [Function],
post: [Function],
pri: [Function],
propfind: [Function],
proppatch: [Function],
purge: [Function],
put: [Function],
rebind: [Function],
report: [Function],
search: [Function],
source: [Function],
subscribe: [Function],
trace: [Function],
unbind: [Function],
unlink: [Function],
unlock: [Function],
unsubscribe: [Function],
all: [Function: all],
del: [Function],
render: [Function: render],
listen: [Function: listen],
request: [IncomingMessage],
response: [ServerResponse],
cache: {},
engines: {},
settings: [Object],
locals: [Object: null prototype],
mountpath: '/',
_router: [Function]
},
connection: [Function: connectionListener],
listening: [Function: bound onceWrapper] { listener: [Function] }
},
_eventsCount: 3,
_maxListeners: undefined,
_connections: 0,
_handle: TCP {
reading: false,
onconnection: [Function: onconnection],
[Symbol(owner_symbol)]: [Circular]
},
_usingWorkers: false,
_workers: [],
_unref: false,
allowHalfOpen: true,
pauseOnConnect: false,
httpAllowHalfOpen: false,
timeout: 120000,
keepAliveTimeout: 5000,
maxHeadersCount: null,
Promise {
Error [TOKEN_INVALID]: An invalid token was provided.
at Client.login (/home/runner/ReminderBot/node_modules/discord.js/src/client/Client.js:206:52)
at /home/runner/ReminderBot/index.js:24:8
at Script.runInContext (vm.js:130:18)
at Object. (/run_dir/interp.js:209:20)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Function.executeUserEntryPoint as runMain
at internal/main/run_main_module.js:17:47 {
[Symbol(code)]: 'TOKEN_INVALID'
}
}
Hint: hit control+c anytime to enter REPL.
Example app listening at localhost:3000
(node:316) UnhandledPromiseRejectionWarning: Error [TOKEN_INVALID]: An invalid token was provided.
at Client.login (/home/runner/ReminderBot/node_modules/discord.js/src/client/Client.js:206:52)
at /home/runner/ReminderBot/index.js:24:8
at Script.runInContext (vm.js:130:18)
at Object. (/run_dir/interp.js:209:20)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Function.executeUserEntryPoint as runMain
at internal/main/run_main_module.js:17:47
(node:316) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a
Promise {
Error [TOKEN_INVALID]: An invalid token was provided.
at Client.login (/home/runner/ReminderBot/node_modules/discord.js/src/client/Client.js:206:52)
at /home/runner/ReminderBot/index.js:24:8
at Script.runInContext (vm.js:130:18)
at Object. (/run_dir/interp.js:209:20)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Function.executeUserEntryPoint as runMain
at internal/main/run_main_module.js:17:47 {
[Symbol(code)]: 'TOKEN_INVALID'
}
}
Hint: hit control+c anytime to enter REPL.
Example app listening at localhost:3000
(node:359) UnhandledPromiseRejectionWarning: Error [TOKEN_INVALID]: An invalid token was provided.
at Client.login (/home/runner/ReminderBot/node_modules/discord.js/src/client/Client.js:206:52)
at /home/runner/ReminderBot/index.js:24:8
at Script.runInContext (vm.js:130:18)
at Object. (/run_dir/interp.js:209:20)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Function.executeUserEntryPoint as runMain
at internal/main/run_main_module.js:17:47
(node:359) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a
TypeError: Cannot read property 'env' of undefined
at /home/runner/ReminderBot/index.js:24:28
at Script.runInContext (vm.js:130:18)
at Object. (/run_dir/interp.js:209:20)
at Module._compile (internal/modules/cjs/loader.js:999:30)
Promise {
Error [TOKEN_INVALID]: An invalid token was provided.
at Client.login (/home/runner/ReminderBot/node_modules/discord.js/src/client/Client.js:206:52)
at /home/runner/ReminderBot/index.js:24:8
at Script.runInContext (vm.js:130:18)
at Object. (/run_dir/interp.js:209:20)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Function.executeUserEntryPoint as runMain
at internal/main/run_main_module.js:17:47 {
[Symbol(code)]: 'TOKEN_INVALID'
}
}
Hint: hit control+c anytime to enter REPL.
Example app listening at localhost:3000
(node:456) UnhandledPromiseRejectionWarning: Error [TOKEN_INVALID]: An invalid token was provided.
at Client.login (/home/runner/ReminderBot/node_modules/discord.js/src/client/Client.js:206:52)
at /home/runner/ReminderBot/index.js:24:8
at Script.runInContext (vm.js:130:18)
at Object. (/run_dir/interp.js:209:20)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Function.executeUserEntryPoint as runMain
at internal/main/run_main_module.js:17:47
(node:456) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a
Promise {
Error [TOKEN_INVALID]: An invalid token was provided.
at Client.login (/home/runner/ReminderBot/node_modules/discord.js/src/client/Client.js:206:52)
at /home/runner/ReminderBot/index.js:24:8
at Script.runInContext (vm.js:130:18)
at Object. (/run_dir/interp.js:209:20)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Function.executeUserEntryPoint as runMain
at internal/main/run_main_module.js:17:47 {
[Symbol(code)]: 'TOKEN_INVALID'
}
}
Hint: hit control+c anytime to enter REPL.
Example app listening at localhost:3000
(node:496) UnhandledPromiseRejectionWarning: Error [TOKEN_INVALID]: An invalid token was provided.
at Client.login (/home/runner/ReminderBot/node_modules/discord.js/src/client/Client.js:206:52)
at /home/runner/ReminderBot/index.js:24:8
at Script.runInContext (vm.js:130:18)
at Object. (/run_dir/interp.js:209:20)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Function.executeUserEntryPoint as runMain
at internal/main/run_main_module.js:17:47
(node:496) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see nodejs.org/api/cli.html#cli_unhand...). (rejection id: 1)
(node:496) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Here is the console

Collapse
 
cyrah profile image
Cyrah Aerin Cirineo

so how do i add a prefix to the bot ?!

ive been trying to do it for awhile but it hasnt been working

Collapse
 
avuleee profile image
avuleee

You have to go to the Secret Enviroment and type in "DISCORD_TOKEN" as the key and your bot's token in value for .env.

Collapse
 
venomoussteam81 profile image
VenomousSteam81

Hey, they made it so people cant make .env files anymore. You have to use Secrets (Environment Variables) tab on the side. Can you make an updated version?

Collapse
 
venomoussteam81 profile image
VenomousSteam81

Nevermind. I figured out a solution!

Collapse
 
gio2chi profile image
Gio2chi

It still works?

Collapse
 
hassan_bh profile image
Hassan-BH

I don't know how to thank you dude.
You rock!

Collapse
 
aryasarukkai profile image
Arya Sarukkai

With this, people can access the code and token of this bot though, right?

Collapse
 
anmols149 profile image
AnmolS149

no the .env file is private and can be only viewed by you...plus what are the odds of someone searching your rep and then scrolling through it to find your token...also you can always regenerate it...

Collapse
 
bestplayerxu profile image
bestPlayerXu

no. the .env file is the only private-hidden file.

Collapse
 
mataskrivickas profile image
Force Studios - Comms Open

It's good, i'm pretty sure you're using "Atom" as a coding platform. Visual Code & Atom is same. Almost every coding software is the same and can be used on as long as you have discord.js downloaded by downloading node.js

Collapse
 
mlgmemezboi profile image
Existable

How do I make it so then I can add more commands instead of just the ping command?

Collapse
 
mataskrivickas profile image
Force Studios - Comms Open
  1. Get discord.js by downloading node.js
  2. I would recommend this code if you want a 2nd answer from the person and bot:

client.on('message', msg => {
if (msg.content === 'PERSONS MESSAGE') {
msg.reply('BOTS REPLY');
} else if (msg.content === 'PERSONS MESSAGE') {
msg.reply('BOTS REPLY')
}
});

// This is the full message command

Some comments may only be visible to logged-in visitors. Sign in to view all comments.