Bots In Python #2 | Creating Discord Bot That Uses Beem To Get Information | DiscordSteem | Part #1

in #utopian-io6 years ago (edited)

Thumbnail
Hi Everyone! I am back here with another tutorial about making bots in Python. today I am going to be making a discord that will respond to us and give us the information that we need. This is going to be a fun tutorial because I know many steemians use Discord very frequently and developers want to know how to interact with Discord. Here are some commands that the bot will have.

  • !rep [account] - Return the reputation of the account
  • !blog [account] - Returns last 10 posts of the user
  • !feed [account] - Returns feed of the user
  • !comments [account] - Returns last 10 comments of the user

These are the features that I will be adding in this tutorial. There are definitely going to be more, I am looking forward to allow users to do anything with Steemit using Discord. Let's get started with this tutorial.

Repository

Other Repositories

What Will I Learn?

In this tutorial you will learn how you can use Discordpy to interact with Discord and get messages. We are also going to be learning how we can use the information/commands in the messages to perform actions and to get information using Beem. This information will then be sent in the Discord server and of course this all will be done in Python.

Requirements

In order to follow along with this tutorial you will need to have these things installed.

  • Python 3.6
  • Discordpy
  • Beem

Difficulty

  • Intermediate

Tutorial Contents

Creating bot on Discord and adding it to the server

Before we get into coding stuff, we need to perform some action on the Discord side. Open up your browser and got to Discord Developers. Once you get there you will see a quite nice looking page like this. Just click on "Create an application".
Discord Developers
After clicking it you will be redirected to another page in which you will be able to change some settings of your app. The first thing you have to do there is to change the name of the app. I will name mine "DiscordSteem", you can name yours whatever you want. You can also add a profile picture but I won't do that for now. After changing the name make sure to save changes.
Discord Application Setting
Now go to "bot" tab from left side of the screen and click on "Add Bot". A warning may popup, just click "Yes, do it!". After that you will see a screen like this.
Screenshot from 2018-08-18 11-59-41.png
Now we have created our bot. The next thing we will need to do is to add it to the server. You can create a new server or just add it to an existing one. There's one thing you need to know and that is if you are looking to add it to an existing server, make sure you have privileges to add a bot. After making sure you have the server, open the "oauth2" tab from the left side and at the bottom select bot. At the last part, select administrator and then copy the link.
Screenshot from 2018-08-18 12-34-05.png
Now go to that link and select the server in which you want to add that bot and then click "Authorize". There maybe a captcha that you will need to solve but after that bot will be added to the server. You can now open the server and check out that bot has joined the server.
Screenshot from 2018-08-18 12-37-37.png

Starting the bot

The bot should be offline on the server and to make it online we should start coding our bot which we will do right now. First of all, create a new folder that is going to be dedicated to this bot. Inside that folder, create a new file called "bot.py" and open it. The first thing that we are going to do is import discord which we can do by typing that. We will also need to import three more things that we will use. First one is from discord.ext import commands and the second one is from discord.ext.commands import Bot. The last one is asyncio which you can import by typing import asyncio.

The first thing that will be present in every Discord bot is a variable called "bot". Create a variable called "bot" and assign it the value commands.Bot(command_prefix="!"). I want my bot to print "I am ready!" when it is turned on. Under that type or paste this block of code.

@bot.event
async def on_ready():
     print("I am ready!")

A very simple block of code. When ever we want to make our bot do something we will use @bot.event. In the second line, we are assigning when to perform the even. In the last line, we are assigning what event do we have to perform. Pretty easy right?

Now we will start the bot. This is also pretty simple. Leave a line after the previous block of code and the type bot.run("TOKEN"). Inside it paste the token which can be found on "bot" tab of that website. You need to click on "click to reveal token". Don't tell anyone this token or else they can do whatever they want with your bot. Finally run the file by typing python bot.py when you're in the directory of the file. The code we have till now.

# Imports
import discord
from discord.ext import commands
from discord.ext.commands import Bot
import asyncio

# Variables
bot = commands.Bot(command_prefix="!")

# Print When Ready
@bot.event
async def on_ready():
    print("I am ready!")

# Run The Bot
bot.run("TOKEN")

"TOKEN" will be changed according to your token. As you can see in the screenshot below. The bot is now online one the discord server. The bot doesn't do anything at the moment but we will be coding and adding features as we go.
Screenshot from 2018-08-18 14-16-39.png

Creating Commands

Creating the reputation command

Now we are going to start creating our commands. Let's start by a simple command that will repeat whatever the user says after that we will improve it. Under the event which was used for printing to the terminal when bot started, type this block of code.

@bot.command(pass_context=True)
async def rep(ctx, username):
  await bot.say(username)

First of all we are letting Python know that we want to create a command. We have set pass_context=True because it allows us to grab the original message which invoked the command. Then in the second line, we have defined a function named "rep" which stands for both reputation and repeat ; ). We have two parameters in that function, first one is ctx which stands for context (i.e !rep). Then the second parameter is username so our function will look like !rep rodus. In the third line, it just tells the bot to write a message and that message would be the username for now because I would like to check if the bot is working or not. At the moment, you can write any text at the place of username. Let's re-run the bot and check the command.
Screenshot from 2018-08-18 17-22-29.png
Let's make it more interesting now. Remove the await bot.say(username) line from the code. At that place, create a variable called "acc" which stands for account and then assign it the value username.lower(). lower() will convert every letter in the string to lowercase. As you know usernames are always lowercase on Steem so if anyone writes "Rodus" instead of "rodus", it will still work. The next thing we have to do is to import Account from beem.account which we can do by typing from beem.account import Account at the top. Make sure you have Beem installed. In the variable, put the value inside Account(). Now the variable should look like acc = Account(username.lower()). In the next line, type rep = acc.rep. Now we have reputation of the user stored inside the variable, we just need to display it. We will display it with a embed message, for that, create a variable on the next line called "embed" and assign it the value "discord.Embed(title=("DiscordSteem"), description=("Reputation of %s is %s" % (username, rep))) so our embed message will have a title and a description. If you know basics of Python you will know what is happening. At last, we will allow the bot to say the embed message by typing await bot.say(embed=embed). Here's what our code looks like until now.

# Imports
import discord
from discord.ext import commands
from discord.ext.commands import Bot
import asyncio
from beem.account import Account

# Variables
bot = commands.Bot(command_prefix="!")

# Print When Ready
@bot.event
async def on_ready():
    print("I am ready!")
    
# Commands
@bot.command(pass_context=True)
async def rep(ctx, username):
  acc = Account(username.lower())
  rep = acc.rep
  embed = discord.Embed(title=("DiscordSteem"), description=("Reputation of %s is %s" % (username, rep)))
  await bot.say(embed=embed)

# Run The Bot
bot.run("TOKEN")

Here's how the command works. You can see that using this method it displays the full reputation which I think is "okay" for now but you can spend some time and make it the way you want.
Screenshot from 2018-08-18 18-07-27.png

Creating the blog command

The second command that we are going to be making is !blog <user> command. Using this command we will be able to get the last 10 posts of a user. Copy and paste this code after laeaving a line after the previous command.

@bot.command(pass_context=True)
async def blog(ctx, username):
  acc = Account(username.lower())
  for post in acc.blog_history(limit=5, reblogs=False):
    await bot.say(post["title"])

Let me explain this block of code a bit. First three lines are the same as the last command. In the fourth line, we are running a for loop which is looping through each post present in blog_history of the account. We have assigned two parameters, first one is that there should be only 5 posts in the list. You can change that but I think that is a good number for now. The second parameters assigns that there should be no reblogs or also called resteems. You can change that as well. For each post the bot will leave a message that will contain the title of the post. Let's see how it looks.
Screenshot from 2018-08-19 13-15-20.png
As you can see it is working but we can make it more prettier by using embed messages so let's do it. First remove the await bot.say(post["title"]) from the for loop. Instead change it to.

@bot.command(pass_context=True)
async def blog(ctx, username):
  acc = Account(username.lower())
  for post in acc.blog_history(limit=5, reblogs=False):
    embed = discord.Embed(title=(post["title"]), color=(0x00ff00))
    await bot.say(embed=embed)

We have created a variable called "embed" and assigned it a embed message. The title of that embed message will be the same as the title of the post. We have also selected color this time, the color is going to be a hex code. The hex code that I have used is greenish color which is used in many servers. Let's see how it looks now.
Screenshot from 2018-08-19 14-27-22.png
It looks more prominent now. I know we can even make it more better but I think this is okay for now but we will of course improve it in upcoming tutorials. Let's move on to other 2 commands.

Creating feed and comment command

These commands are going to be very similar to the blog command and most of the code is going to be exactly the except for few changes here and there. Let's first create feed command first. Copy and paste this block of code after leaving the line after the blog command.

@bot.command(pass_context=True)
async def feed(ctx, username):
  acc = Account(username.lower())
  for post in acc.feed_history(limit=5):
    embed = discord.Embed(title=(post["title"]), description=("By " + post["author"]),color=(0x00ff00))
    await bot.say(embed=embed)

As you can see almost all of the code is exactly the same but there are three small changes. The first one is the name of the function, it has changed from "blog" to "feed". The second change is that we are now checking "feed_history" instead of "blog_history". The last change is that there is going to the a description this time because posts in the feed are from different author. In the description of the embed message it will tell who has written the post that has been titled that. Here's how it looks when it is working.
Screenshot from 2018-08-19 15-23-16.png

Let's move on to the last function which is also going to be a very similar one. Copy and paste this block of code under the after leaving the line after the last command.

@bot.command(pass_context=True)
async def comments(ctx, username):
  acc = Account(username.lower())
  for post in acc.comment_history(limit=5,):
    embed = discord.Embed(description=(post["body"]),color=(0x00ff00))
    await bot.say(embed=embed)

There are three differences in this, the first one is that the name of the function is different. Now we are checking "comment_history". In the description now are going the body of the comment because comments are short most of the time. There is also no title. Here's how it looks when it is working.
Screenshot from 2018-08-19 15-35-23.png

Final Thoughts

Yay...we have successfully created a Discord bot that uses Beem to get information about Steem Blockchain but this is not over yet. We will be adding more features in the next part of the tutorial. If you have any features that you would like me to add then kindly share them in the comments. Also, if you want me to build any other type of bot kindly let me know in the comments as well. Hopefully we learned something new in this tutorial. Thanks for reading... see ya!

Curriculum

Here's a list of tutorials that are related to building bots in Python.

Proof of Work Done

Note: There are some changes in the code of the repository. There are more comments to help you understand the code more easily. The name of the file is also changed from "bot.py" to "DiscordSteem.py". I have not added the token to my code in code and to be able to use the code you must add the code of your bot. Thanks.

Sort:  

Thank you for your contribution.

  • Screen captures were interesting if they had been marked where the user clicked.
  • Nice work on the explanations of your code, although adding a bit more comments to the code can be helpful as well.

The tutorial is very interesting, I'm waiting for more of your tutorials. Good work!!!

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

Thank you for your review, @portugalcoin!

So far this week you've reviewed 10 contributions. Keep up the good work!

I am really glad you liked my tutorial. I will surely keep those points in mind for next time. Thanks! : )

You really put a lot of effort into this post and your projects overall! Thank you!

Thank you for reading the post and upvoting it. You are the ones that motivate me to keep making them ; )

Aww, thanks! I'll change my upvote to 100%. :)

Thanks, really appreciate it : )

Hey @rodus
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Hi @rodus, I'm @checky ! While checking the mentions made in this post I noticed that @bot.event doesn't exist on Steem. Maybe you made a typo ?

If you found this comment useful, consider upvoting it to help keep this bot running. You can see a list of all available commands by replying with !help.

Congratulations! Your post has been selected as a daily Steemit truffle! It is listed on rank 9 of all contributions awarded today. You can find the TOP DAILY TRUFFLE PICKS HERE.

I upvoted your contribution because to my mind your post is at least 21 SBD worth and should receive 253 votes. It's now up to the lovely Steemit community to make this come true.

I am TrufflePig, an Artificial Intelligence Bot that helps minnows and content curators using Machine Learning. If you are curious how I select content, you can find an explanation here!

Have a nice day and sincerely yours,
trufflepig
TrufflePig

Hi @rodus! We are @steem-ua, a new Steem dApp, computing UserAuthority for all accounts on Steem. We are currently in test modus upvoting quality Utopian-io contributions! Nice work!

Coin Marketplace

STEEM 0.29
TRX 0.12
JST 0.034
BTC 63314.98
ETH 3233.91
USDT 1.00
SBD 3.88