Posted in discord, nodejs, raspberrypi

discord_bot_joke_randomizer.gif

The main aim of this project is to teach absolute beginners how to create a discord bot and having fun doing it. By absolute beginners, I mean people that had no contact with discordapp before or very little. All of this, without throwing away all the work involved in the work (hopefully).

The project that I have in mind is to create a Discord Bot that will randomly post a joke when it will be commanded to do so. The code will be written in JavaScript if you are stumbling in any issue feel free to ask for help in the comment section.

I chose to write this because when I created a discord bot for the first time, it took me more time then I expected. The main points of this will include, creating the discord bot, creating the server, writing the code for the bot and running the bot. You can skip any of these steps if you don’t need it.

How do I create the Discord Bot?

In order to create a Discord Bot click on the following link and follow the instructions that I had written below:

  1. Chose a name for your Discord Bot, for the project in case I chose the name make jokes, but you are free to choose any name you want. After you name your bot, click on Create app button.

  2. Scroll to the bottom of the page and push the Create a Bot User button. Be aware that this action is irrevocable.

    The below popup will appear and by accepting it, you have a Discord Bot.
    What happens when you convert your applications to a Discord Bot.

  3. After the creation, you will be able to see the username and the token. We will need the token later, make sure that you save it or remember the way find when needing it. 
    Discord bot token position on website

Who do I add the Discord Bot to my DiscordApp Server?

After I learned to create my first Discord Bot, I was completely lost. I think I wasted around 1 hour trying to figure out how to add it to my server/channel. Remember that you need to have the right privleges on the server in order to add the bot.

If you don’t have a discordapp server, create one at https://discordapp.com/channels/@me (pushing the big + button from the top left)  

There are two ways to add a Discord Bot to your channels:

Information to get your Client Id and Generate OAuth2 URL in order to add the bot the a discord server or channel.

  1. The first one and the easiest one is to replace the Client Id in the URL presented below and just click it. It will redirect you to chose the server where to use the bot. 
    https://discordapp.com/oauth2/authorize?client_id={REPLACE_ME_WITH_CLIENT_ID}&scope=bot&permissions=0
  2. The second one is to click on Generate OAuth2 URL, select the correct permissions and an URL will be generated very similarly to the one from the above.

What is the code for a Discord Bot?

As I mentioned at the beginning of the post the code for this Discord Bot will be written in JavaScript executed with nodejs. The library that I love using when I write bots is discord.js, if you choose another tool, please let me know why in the comments section.

In the beginning, I said that the project will generate random jokes. But, where do they come from? For this a public API will be used, I chose one that generates jokes with Chuck Norris. If you don’t like it you can google another one or ever make your own repository of jokes.

The endpoint used to generate jokes is this one: http://api.icndb.com/jokes/random

In order to call the API, we need a library to help us. Fortunately natively, nodejs comes with a simple library http.get that is more than enough for this project.

// references
const auth = require('./auth.json');
const http = require("http");
var Discord = require('discord.js');

// Initialize Discord Bot
var bot = new Discord.Client();
bot.on('ready', (evt) => {
    console.log('Connected');
});

const url =  "http://api.icndb.com/jokes/random";

randomizeJoke = (channel) => {
    // most of the code is taken from documentation
    // https://nodejs.org/dist/latest-v8.x/docs/api/http.html#http_http_get_options_callback
    http.get(url, res => {
        res.setEncoding("utf8");

        let body = "";
        res.on("data", chunk => {
            body += chunk;
        });

        res.on("end", () => {
            body = JSON.parse(body);
            console.log(`Result: ${body.value.joke}`); // for debug purposes
            channel.send(body.value.joke); // send to Discord Channel
        });
    });
} bot.on('message', message => { // Our bot needs to know if it will execute a command // It will listen for messages that will start with `!` var text = message.content; var channel = message.channel; if (text.substring(0, 1) == '!') { var args = text.substring(1).split(' '); var cmd = args[0]; args = args.splice(1); switch(cmd) { // !joke case 'joke': randomizeJoke(channel); break; // Just add any case commands if you want to.. } } }); bot.login(auth.token);

The above code might look scary if you have little experience with JavaScript, but don't let it scare you. Is fairly easy, I will explain the most important parts of the code.

At the beginning of the code, we have the require statements that basically says I want to use these libraries/files (http, discord.js, auth.json) in the following code. 

Below the bot is created var bot = new Discord.Client();, but not logged in to discordapp. Before the bot is login some events are attached, one of the most important is the one that listens for the messages that are posted on the channels.  

bot.on('message',  message => { /* execute commands */ }

In this event, we can read the message (!joke) and respond to it (with the joke).

In the randomizeJoke function, the joke is being read from the API that provides jokes with Chuck Norris. The API is easy to use and we need to use HTTP GET verb, and fortunately, nodejs offers this functionality under this form http.get

If you copy paste this URL http://api.icndb.com/jokes/random in your browser you will be able to see the structure of the JSON that will be answered, it looks like the following:

{
  type: "success",
  value: {
    id: 419,
    joke: "Count from one to ten. That's how long it would take Chuck Norris to kill you...Forty seven times.",
    categories: [ ]
  }
}

This is the reason why I sent to discord channel on the following line of code channel.send(body.value.joke);.

And, at the end of the file the bot is logging in discord bot.login(auth.token);

Maybe you already noticed, we need 2 additional files on this project before we are ready to move to the next step. The first one that is marked as require('./auth.json') in the above code.

Create the file auth.json and don't forget to use the token that I mentioned to save after the bot was created.

{ 
"token": "PUT_YOUR_TOKEN_HERE"
}

One of the most important files is package.json file that is very simple for this project. The only dependency that you need is on discord.js. And that's it, you are good to go on the next section.

{
  "name": "discord-bot-jokes",
  "version": "0.0.2",
  "description": "A bot that will make my day.",
  "main": "bot.js",
  "author": "TheHumbleCode",
  "dependencies": {
    "discord.js": "^11.3.2"
  }
}

How do I run my Discord Bot in Raspberry Pi?

The shortest answer is, everywhere nodejs is supported. The nice part of this project is that it doesn’t have any hard dependency so it is very flexible where you can run it. The most common places will be on your PC, someone else’s PC, a Raspberry Pi or any development board meeting this condition.

I chose to run this bot on a Raspberry Pi, and it’s not the first time I’m doing this.

The first requirement is to install a operating system on Rasp (if you don't already have it) and the second one is to be able to SSH and/or SCP on to it. If you are not able to SCP, don’t worry too much, instead, you can write or copy paste the code through SSH. 

The first step is to install nodejs, if you do not have it already installed it's time to do so. This tutorial explains what you have to do. I will add the commands needed to install nodejs in order to be handy:

wget https://nodejs.org/dist/v7.7.2/node-v7.7.2-linux-armv6l.tar.gz
tar -xzf node-v7.7.2-linux-armv6l.tar.gz
sudo cp -R node-v7.7.2-linux-armv6l/* /usr/local/
export PATH=$PATH:/usr/local/bin

node -v
npm -v

Now make sure that you use SCP to copy the files on to your Raspberry or just use SSH to create the files (touch command) in a folder (mkdir).

After you have all the code I mentioned above (bot.js, auth.json, package.json) in your Raspberry Pi, you need to execute the following command and you are ready to go.

npm install
node bot.js

The results can be seen in the below gif. Now you are ready to make bigger steps and create other projects that make use of discordapp.

Thank you for reading!

Posted in raspberrypi, discord, dht11, nodejs

In my first blog post, I created a Discord Bot that runs on Raspberry Pi Zero and turned a LED on and off. Today I want to continue using this combo but instead of a LED, I will use a DHT11 sensor that reads the humidity and temperature. This information will be posted in a channel from Discord and will be read from a room from my house (1 to 1 relationship here). 

The coolest thing about using Discord is that you can use any device or invite anyone to use the functionality that is made without making complicated setups.

raspberry_pi_temperature_humidity.gif

Hardware specification and setup for DHT11

The temperature and humidity sensor is not very fast, the data must be read once at ~5s. It needs a resistor with a value between 5.1K-10K that will be placed between VCC (Pin 1) and Pin 2.

dht11.png

The table below shows the connections that I made between Raspberry Pi and DHT11. 

DHT pinSignalRaspberry Pi physical pin
13.3V ~ 5.5V 4 (VCC)
2Data 7 (BCM 4) and 4 (VCC) with resistor
3not used 
4Ground 6 (GND)

Below I created the schema that I will use to read the values from DHT11 sensor using fritzing. The resistor that I have used has 10K (ohm). I chose to connect the resistor directly between pin 7 and 4.

schema.png

Reading the sensor and publishing to discord 

To read the DHT11 sensor from nodejs I will use the node-dht-sensor library. 

The file package.json for this project is pretty simple, contains the library mentioned above and discord.js library in order to publish the values read from the sensor to a channel.

{
  "name": "home-manager-sensor",
  "version": "0.0.2",
  "description": "A bot that helps me to automize my home.",
  "main": "bot.js",
  "author": "TheHumbleCode",
  "dependencies": {
    "discord.js": "^11.3.2",
    "node-dht-sensor": "^0.0.34"
  }
}

Mentioning the Discord Bot, don't forget to create the auth.json file and add the token for the bot.

{
 "token": "PUT_YOUR_TOKEN_HERE"
}

To read the sensor every 5 seconds for this example, in a real case every hour will make more sense in order to avoid spamming. In Discord, I created a channel named living-room and use it to send the updates periodically. 

The code is very tight, but it can very easily be implemented commands to stop or to continue publishing the temperature and humidity.

The below code is written to a file named, bot.js

const auth = require('./auth.json');
const Discord = require('discord.js');
const sensor = require('node-dht-sensor');

const DHT = 11;
const SENSOR_PIN = 4;

notifyChannel = function(channel) {
    const sensorResult = sensor.read(DHT, SENSOR_PIN);
    const message = `The current temperature is ${sensorResult.temperature.toFixed(2)} °C and humidity ${sensorResult.humidity.toFixed(2)} %`;
    channel.send(message);
}    

// Initialize Discord Bot
const bot = new Discord.Client();
bot.on('ready', (evt) => {
    console.log('Connected');

    let livingRoomChannel = bot.channels.find('name', 'living-room');
    
    setInterval(() => {
        notifyChannel(livingRoomChannel);
    }, 5000)
});

bot.login(auth.token);

In order for node-dht-sensor library to work on the project, it needs the following prerequisites. I described the steps I used below.

1. Install Broadcom bcm2835 following the steps below (if the version will get obsolete, search for the latest on their website).

wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.55.tar.gz
tar zxvf bcm2835-1.55.tar.gz
cd bcm2835-1.55
./configure make sudo make check sudo make install

2. Install node-gyp to compile native nodejs modules (nodejs addons).

sudo npm install node-gyp -g

3. At the top of the project folder install the dependencies needed (discord.js and node-dht-sensor).

npm install

Now we are ready to start the Discord Bot

node bot.js

Conclusion

Although for this type of data (timestamp, value) makes more sense to be published in a service where it can be seen as a line chart.

The way I like to look at this is like having an audit. Now I need to remote control the AC from far.. far away in order to set up the perfect room temperature.

IMG_20180405_230114.jpg

Thank you for reading!