Serving Gifs With Discord Bot
Tags: python, tutorial, showdev, opensource
Published: 2019-04-27 03:39:21

---
title: Serving Gifs With Discord Bot
published: true
description: Building a Discord Chatbot with Giphy API
tags: python, tutorial, showdev, opensource
canonical_url: https://www.maxongzb.com/serving-gifs-with-discord-bot-reading-time-12-mins
---
![Photo by Andy Kelly on Unsplash](https://thepracticaldev.s3.amazonaws.com/i/mrsm8z3obftfxxeryqhh.jpg)

# Introduction

In this article, we target Python developers who have an interest in learning to build their own chatbots on Discord.

The reader should have some knowledge of Python. To install libraries and create functions in Python.

This is to allow the reader to take advantage of existing chatbot tools to build their very own bot.

Have you ever wondered, you could have your very own personal assistant? To help you do your household chores or tasks for you?

When Apple first announced its AI assistant called **Siri**. 
To the world during their one of their Apple iPhone release. 

Siri took the world by a storm, there were a ton of articles or videos on funny questions. People were asking Siri as if Siri was a real-life person.
 
Today we shall learn to create our very own personal assistant who responses you with gifs instead of just words on Discord using our favourite Python!!!


## What Is Discord?

Discord is a Voice over IP (VoIP) application that provides both text & voice communications.

That is popular among gamers or other communities who would like to use the servers for organising events.

The service is like Telegram or Whatsapp which provides integration for in-chat voice calls and in-game features. 

### Rise of Chatbots

As there more people who started to use messaging clients like WhatsApp, Telegram, Facebook Messenger & Slack.

It has sparked a trend of creating chatbots for a variety of purposes, such as improving customer satisfaction and automating processes.

### Common Usage for Chatbots

Gone are the days where searching for solutions involves you to go to the FAQ page or call the customer support centre.

Instead, these are replaced with a shiny new bot. 

Who is there to tell you jokes, offer you solutions or there to recommend products or services that suit your needs.

## Setup

Alright, let's get our hands down and dirty to start with setting up our server. 

we should register an account on [Discord](https://discordapp.com/). 
 
### Setting Up a Discord Server

After your account creation, log in with your newly created account. You will be on the `channels` page. 

That allows you to add a *server  → plus* icon to add a new server as shown below.

![add server](//images.ctfassets.net/ly2f59p4unnn/3hQ3SpCF7EIuk0KqRUXtEn/83c305f1431f1db63caa0b35897bb0ad/add_server.png)

After clicking on the **plus** icon, you are taken to this page with options to either create a new server or join an existing server.

![create server](//images.ctfassets.net/ly2f59p4unnn/50ZwIrklItaK90rUIUySy8/cc2f1f677efaff4ed88e4e8ab61dc1e4/create_server.png)

Click on the "Create a Server" button, then fill up the server details of your own server and click the **create** button.

![discord server details](//images.ctfassets.net/ly2f59p4unnn/5xCQV9ygLhgTqUP7VlrSbv/37cb93bf7cf3efc2e83745bba17b5c2a/discord_server_details.png)

Congrats!!! You had just created your first server. This server will be used for the remaining of this tutorial. In the meantime take a break before pressing on.

![giphy](//images.ctfassets.net/ly2f59p4unnn/rdWev2lcITJqNpDhy94fV/77d56587546dc3236e2924e583103623/giphy.gif)

### Creating an App & Bot

Alright, let's go to the Discord's [developer portal](https://discordapp.com/login?redirect_to=%2Fdevelopers) at and log in with your account.

Once you are in the developer portal, it will look something like this.

![discord developer portal](//images.ctfassets.net/ly2f59p4unnn/6DHG8Hf1saIBKc1P1QeIZe/0cfcd1fb654d0b43bddf6741512b9cdb/discord_developer_portal.png)

Select the "New Application" button to create a new application. So that your bot will be able to use the token to interact with your server.

![Create new applications](//images.ctfassets.net/ly2f59p4unnn/7ClOvsFf9H7NzTsamyqo6v/a5682219c15a21a881b9406231d94f44/Create_new_applications.png)

Next, on the **left** hand side of the sidebar there a name called `bot`. Click on `bot → Add Bot` button.

![add bot](//images.ctfassets.net/ly2f59p4unnn/7kZ7ysr21sqjxEYG3REtaL/5ee9fdbb18f0efb82afbb4eb08806204/add_bot.png)

A prompt will be displayed to confirm the creation of your bot. Ignore it and continue with clicking on "Yes, do it" button.

![Yes to bot](//images.ctfassets.net/ly2f59p4unnn/1mbspRwSnmyJrOlCzo1usu/0de403ef2f175b814448940f9c3771b2/Yes_to_bot.png)

### Adding Bot to Your Server

Now we will proceed with adding your freshly created bot to the server.

Firstly click on the tab `General Information` on the left side of the application you had created. 

Then click on the **copy** button that is below the client id to copy client id. 

This allows you to form a URL with your application's client id from the developer portal as shown below.

![application client id](//images.ctfassets.net/ly2f59p4unnn/5Eee9o32qcaSdFYMLoYxOx/975ee8cc12e715f0a1a980d1a6103b27/application_client_id.png)

```
https://discordapp.com/api/oauth2/authorize?scope=bot&client_id=bot_client_id
```

Now, open a new tab in your browser and head to the URL you had just formed. 

You're redirected to a website that allows you to approve the **connection** of your bot to the server.

![add bot to server](//images.ctfassets.net/ly2f59p4unnn/722aT2c4Z2zVFbiQjBx04n/4613ceaf164ad60c4aa99336f0525aa1/add_bot_to_server.png)

Congrats!!! Now you have completed the **setup** process of your bot & server. Come back to this tutorial again when you are ready to start coding.

![giphy](//images.ctfassets.net/ly2f59p4unnn/2NMljh2d02BFylKTC9rXl5/761210bcb49cd357f371f95370c72d77/giphy.gif)

### Hello World in Discord Server

Welcome back, let get started to create the bot. Create a folder called `discord`.

Next, create a virtual environment called `venv` in the same folder. 

```console
$ virtualenv --python=python3 venv
$ source venv/bin/activate
```

With the virtual environment that you had created, we must install a library as shown below:

```console
$ python3 -m pip install -U discord.py
```

Create a file called `bot.py` with your bot token founded in the developer portal under the 'Bot tab:

![copy bot token](//images.ctfassets.net/ly2f59p4unnn/6itFDeIqcb6reP28PvkRfZ/30aedbe33528a24c3162a69204f00ded/copy_bot_token.png)

```python
import discord

token = 'your_discord_bot_token'
```

For your bot to work, you need to create a Python class called `DiscordClient`. 

This class has to contain minmually of two functions namely `on_ready()` & `on_message()` as shown below:

```python
class DiscordClient(discord.Client):
    async def on_ready(self):
        pass

    async def on_message(self, message):
        pass
``` 

The `on_ready()` function is used to establish a connection to your server using your  bot's token:

```python
async def on_ready():
    print("Login as")
    print(self.user)
    print("-------")
```

The `on_message()` function response with a **Hello** message whenever a user says "hi":

```python
async def on_message(self, message):
    # Whenever a user other than bot says "hi"
    if message.author != self.user:
        if message.content == 'hi':
            await message.channel.send('Hello')

client = DiscordClient()
client.run(token)
```

After you had included the code for both `on_ready()` & `on_message()` functions. The `bot.py` should look like this for your first bot program:

`bot.py`

```python
import discord

token = 'your_discord_bot_token'


class DiscordClient(discord.Client):
    async def on_ready(self):
        print("Login as")
        print(self.user)
        print("-------")

    async def on_message(self, message):
        # Whenever a user other than bot says "hi"
        if message.author != self.user:
            if message.content == 'hi':
                await message.channel.send('Hello')


client = DiscordClient()
client.run(token)

```

Now let's run the program and go to your  server to type "hi" in the **general channel**:

```console

$ python bot.py

```

![hello response](//images.ctfassets.net/ly2f59p4unnn/5503ui7UhRrhjQhtZdVcL7/805efd74e0733755f5fd5f9557f355f7/hello_response.png)

Awesome!!!! Now that you had made your bot to say "Hello". Let's hop over to commands and play around with it.

## Discord Commands

There is a bunch of useful commands related to users. I'll be cover just the basics. 

For further details about on the commands,  you could head over to the [API Reference Guide](https://discordpy.readthedocs.io/en/latest/ext/commands/commands.html) to check it out. 

### Magic 8 Ball

Commands should be called from `bot2.py` with the **?** prefix.

Using the command called `8ball`. Which responded with a prediction whenever you initiate the command:

`bot2.py`

```python
from discord.ext.commands import Bot
import random

token = 'your_bot_token'
bot = Bot(command_prefix='?')

@bot.event
async def on_ready():
    print("Login as")
    print(bot.user.name)
    print("-------")
    
@bot.command(name='8ball')
async def magic_eight_ball(ctx):
    response =[
        'Without a doubt.', 
        'Outlook good.', 
        'Better not tell you now.', 
        'Cannot predict now.',
        'My reply is no.', 
        'Outlook not so good.',
    ]

    await ctx.send(random.choice(response))

bot.run(token)

```

Let us execute the Python program to test the newly created command by entering '?8ball'. 

![8ball command](//images.ctfassets.net/ly2f59p4unnn/6q8PMtrnJIfAIIOWmZF75W/48e66a41d8742a410764baa13461f0a4/8ball_command.png)
 
### What Is Context?

Do note that for every bot command it requires the parameter `ctx` to be called. 

Which is called [Context](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Context) to initiate various bot related commands.

## Using GIPHY Python Client

Now we shall integrate the Giphy Python client as shown below:

```console

$ pip install giphy_client

```

Once you had completed installing the giphy client, let's head down to the [Giphy developer portal](https://developers.giphy.com/) to register and create a new application. So that you could get the **Giphy API Key**. 

### Get Top 5 Popular Gifs

For `giphy.py`, import the following. Which is the `giphy_client` that helps to initiates the `DefaultApi` and `ApiException`, who deals with the various exception related to the **Giphy** API. 

The `pprints()` is used to display the response in an easy to read format:

```python

import giphy_client
from giphy_client.rest import ApiException
from pprint import pprint

```

The configuration dictionary uses 3 keys namely `api_key` which is the Giphy's API key.

The `query` which is the search term that you search for **Giphy** and lastly `limit` which is the number of gifs that are returned from the search result:

```python
# Create an instance of the API class
api_instance = giphy_client.DefaultApi()
config = {
    'api_key': 'your_api_key',  # Giphy API Key,
    'limit': 1,
    'rating': 'g'
}

try:
    api_response = api_instance.gifs_trending_get(
        config['token'], limit=config['limit'], rating=config['rating'])
    pprint(api_response)

except ApiException as e:
    print("Exception when calling DefaultApi->gifs_trending_get: %s\n" % e)
```

### Search Gifs by Words or Phrase

To search your Gifs by the words, you need to make the following changes.

From `.gifs_search_get()` and add an additional field called `query` in both `config` variable and `api_response` as shown below:

```python
config = {'api_key': 'your_api_key', 'q': 'cheese', 'limit': 1, 'rating': 'g'}

try:
    api_response = api_instance.gifs_search_get(config['api_key'], limit=config['limit'], rating=config['rating'],q=config['q'])

except ApiException as e:
    print("Exception when calling DefaultApi->gifs_search_get: %s\n" % e)
```

### Random Gif

To get a random gif, you need to remove both the `query` & `limit` field from `config` variable.

Besides that, you have to replace the `.gifs_search_get()` to use `.gifs_random_get()` as shown below.

```python

config = {
    'token': 'your_giphy_token',  # Giphy API Key.
}

try:
    api_response = api_instance.gifs_random_get(config['api_key'])

```

Let's take a break and start applying what we had learnt with our bot to serve gifs.

## Bot Serving Gifs in Python

Welcome back :) we shall start by using the Giphy library to search for a gif and upload it onto your server as a response for your bot in the Python program called 'bot2.py'.

### Displaying Gifs in Server

Import the following libraries:

```python
import random
import giphy_client
from discord.ext.commands import Bot
from giphy_client.rest import ApiException
```

After adding the giphy client and the `ApiException`. Let's refactor our original code to include the giphy token:

```python

discord_token = 'your_discord_token'
giphy_token = 'giphy_api_key'

bot = Bot(command_prefix='?')
api_instance = giphy_client.DefaultApi()

```

### Search Gifs

Let us now create a function called `search_gifs()`, where the giphy API will search for the gifs.  

Once we searched for 3 gifs, it will randomly pick a gif and display the **URL** whenever the `8ball`  command is called:

```python

async def search_gifs(query):
    try:
        response = api_instance.gifs_search_get(giphy_token, 
            query, limit=3, rating='g')
        lst = list(response.data)
        gif = random.choices(lst)

        return gif[0].url

    except ApiException as e:
        return "Exception when calling DefaultApi->gifs_search_get: %s\n" % e

```

### Enhancing a Discord Command

We shall now add the `search_gifs()` function into the `magic_eight_ball()` function:

```python

@bot.command(name='8ball')
async def magic_eight_ball(ctx):
    response = [
        'Without a doubt.', 
        'Outlook good.', 
        'Better not tell you now.', 
        'Cannot predict now.',
        'My reply is no.', 
        'Outlook not so good.',
    ]

    gif = await search_gifs('cheese')

    await ctx.send(random.choice(response))
    await ctx.send('Gif URL : ' + gif)
    
```

Once you had refactored your `bot2.py` with the gif search library. It should look like this below:

`bot2.py`

```python

import random
import giphy_client
from discord.ext.commands import Bot
from giphy_client.rest import ApiException

discord_token = 'your_discord_token'
giphy_token = 'giphy_api_key'

bot = Bot(command_prefix='?')
api_instance = giphy_client.DefaultApi()

@bot.event
async def on_ready():
    print("Login as")
    print(bot.user.name)
    print("-------")


async def search_gifs(query):
    try:
        response = api_instance.gifs_search_get(giphy_token, query, limit=3, rating='g')
        lst = list(response.data)
        gif = random.choices(lst)

        return gif[0].url

    except ApiException as e:
        return "Exception when calling DefaultApi->gifs_search_get: %s\n" % e

@bot.command(name='8ball')
async def magic_eight_ball(ctx):
    response = [
        'Without a doubt.',
        'Outlook good.',
        'Better not tell you now.',
        'Cannot predict now.',
        'My reply is no.',
        'Outlook not so good.',
    ]

    gif = await search_gifs('cheese')

    await ctx.send(random.choice(response))
    await ctx.send('Gif URL : ' + gif)

bot.run(discord_token)

```

### Display Gif

Let's execute `bot2.py` to test the `8ball` command by entering the following command to execute your bot2.py:

```console

$ python bot2.py

```  

![8ball command gif](//images.ctfassets.net/ly2f59p4unnn/3wnJZdf0URM5SJFigkLOez/42b33e814771836a89c6827005df2048/8ball_command_gif.png)

Awesome!!! It really works :) alright. Let's take a break and have a KitKat while we start to create gif reaction commands.

![giphy](//images.ctfassets.net/ly2f59p4unnn/3u0Rx1C19y6p2MVuJVEj7r/2853d37b61535f6cadf1b8cb41b327e2/giphy.gif)

## Displaying Reactions by Bot

Till now we had learnt to search for gifs and display our gifs whenever a  command is called by anyone. 

Let's create a bot that serves us gifs based upon the following which is "Hi", "Welcome", "Bye" and "Good Bye" that is called `bot3.py`:

```python

import random
import discord
import giphy_client
from giphy_client.rest import ApiException

discord_token = 'your_discord_token'
giphy_token = 'your_giphy_api_key'

api_instance = giphy_client.DefaultApi()

```

Let's add the `search_gifs()` function which we had previously created.

We increase the number of gifs searched to 5 instead of 3 gifs. It will serve to produce a more random gif response:

```python

def search_gifs(query):
    try:
        return api_instance.gifs_search_get(giphy_token,
 query, limit=5, rating = 'g')
    
    except ApiException as e:
        return "Exception when calling DefaultApi->gifs_search_get: %s\n" % e
        
```

Besides the `search_gifs()` function, we should add in a `gif_response()` which a portion of the code is broken down from the `search_gifs()` to be cleaner and ease of understanding:

```python

def gif_response(emotion):
    gifs = search_gifs(emotion)
    lst = list(gifs.data)
    gif = random.choices(lst)

    return gif[0].url

```

### Hi

Now that we had added the `search_gifs()` & `gif_response()` functions. 

We must include the `DiscordClient` Python class as shown below with the `on_ready()` function for the basic setup of your bot.

```python

class DiscordClient(discord.Client):
    async def on_ready(self):
        print("Login as")
        print(self.user)
        print("-------")

```

Now let us focus on creating the logic for the bot to response whenever a user says "hi" or "hello" to the bot:

```python

async def on_message(self, message):
    # Whenever a user other than bot says "hi"
    if message.author != self.user:
        if message.content == 'hi':
            await message.channel.send('Hi there!!! ' + message.author.mention)
            await message.channel.send(gif_response('hi'))
        
        elif message.content == 'hello':
            await message.channel.send('Hello :) ' + message.author.mention)
            await message.channel.send(gif_response('hello'))
            
```

`bot3.py`

```

import random
import discord
import giphy_client
from giphy_client.rest import ApiException

discord_token = 'your_discord_token'
giphy_token = 'your_giphy_api_key'

api_instance = giphy_client.DefaultApi()


def search_gifs(query):
    try:
        return api_instance.gifs_search_get(giphy_token, query, limit=5, rating = 'g')

    except ApiException as e:
        return "Exception when calling DefaultApi->gifs_search_get: %s\n" % e


def gif_response(emotion):
    gifs = search_gifs(emotion)
    lst = list(gifs.data)
    gif = random.choices(lst)

    return gif[0].url


class DiscordClient(discord.Client):
    async def on_ready(self):
        print("Login as")
        print(self.user)
        print("-------")

    async def on_message(self, message):
        # Whenever a user other than bot says "hi"
        if message.author != self.user:
            if message.content == 'hi':
                await message.channel.send('Hi there!!! ' + message.author.mention)
                await message.channel.send(gif_response('hi'))

            elif message.content == 'hello':
                await message.channel.send('Hello :) ' + message.author.mention)
                await message.channel.send(gif_response('hello'))
                
client = DiscordClient()
client.run(discord_token)

```

![hi response](//images.ctfassets.net/ly2f59p4unnn/7HSGlFsKABaWgqGUkMubA2/f5c9c573ce8c9ccbee44a9681d89c1c9/hi_response.png)

![hello response](//images.ctfassets.net/ly2f59p4unnn/7gTe6atJdUClEg0FwstbYa/a5205db670e1fe8068d829ef008b0467/hello_response.png)

### Welcome

By enhancing the `on_message()` function to include a "welcome" response whenever a user says "welcome":

```python

elif message.content == 'welcome':
    await message.channel.send(message.author.mention + 
        ' Welcome to the discord channel :)')
    await message.channel.send(gif_response('welcome'))

```

![welcome response](//images.ctfassets.net/ly2f59p4unnn/frtIII9e42FEjyaku0gq9/25b7388a5a8d44fa6174a62aacbdb1ea/welcome_response.png)

Using `message.author.mention`, the bot replies to the user

### Good Bye

This is the last response we will add for the bot to say "goodbye" whenever a user says "bye" or "goodbye":

```python

elif message.content == 'bye':
    await message.channel.send(message.author.mention + 
        ' May the force be with you')
    await message.channel.send(gif_response('star wars bye'))

elif message.content == "good bye":
    await message.channel.send(message.author.mention + 
        ' Live long and prosper')
    await message.channel.send(gif_response('salute'))
 
```

![bye response](//images.ctfassets.net/ly2f59p4unnn/5H1R9HGlNEXKH2fb2cTjvu/26cdbb5a3338b620bd981e52611b3242/bye_response.png)

![good bye response](//images.ctfassets.net/ly2f59p4unnn/2fw8uYZqM0BSx9dvlJFmfk/cccc4ecfd16cf6ee39041bc71ef9d81a/good_bye_response.png)

Now if you are lost so far with multiple gif responses don't worry I had included the code block for `bot3.py` as shown below:

`bot3.py`

```python

import random
import discord
import giphy_client
from giphy_client.rest import ApiException

discord_token = 'your_discord_token'
giphy_token = 'your_giphy_api_key'

api_instance = giphy_client.DefaultApi()


def search_gifs(query):
    try:
        return api_instance.gifs_search_get(giphy_token, query, limit=5, rating = 'g')

    except ApiException as e:
        return "Exception when calling DefaultApi->gifs_search_get: %s\n" % e


def gif_response(emotion):
    gifs = search_gifs(emotion)
    lst = list(gifs.data)
    gif = random.choices(lst)

    return gif[0].url


class DiscordClient(discord.Client):
    async def on_ready(self):
        print("Login as")
        print(self.user)
        print("-------")

    async def on_message(self, message):
        # Whenever a user other than bot says "hi"
        if message.author != self.user:
            if message.content == 'hi':
                await message.channel.send('Hi there!!! ' + message.author.mention)
                await message.channel.send(gif_response('hi'))

            elif message.content == 'hello':
                await message.channel.send('Hello :) ' + message.author.mention)
                await message.channel.send(gif_response('hello'))

            elif message.content == 'welcome':
                await message.channel.send(message.author.mention + ' Welcome to the discord channel :)')
                await message.channel.send(gif_response('welcome'))

            elif message.content == 'bye':
                await message.channel.send(message.author.mention + ' May the force be with you')
                await message.channel.send(gif_response('star wars bye'))

            elif message.content == "good bye":
                await message.channel.send(message.author.mention + ' Live long and prosper')
                await message.channel.send(gif_response('salute'))

                
client = DiscordClient()
client.run(discord_token)

``` 

## Conclusion

Wow, It has been quite a ride now that you had become familiar with creating a bot and using a Giphy library. 

Let us summarise what you had learnt in this tutorial.

You now know more about the following:

* What is Discord?
* Rise of Chatbots
* Using Giphy Python Client
* Bot Serving Gifs
* Displaying Reactions By Bot

By creating a working bot that serves gifs to any user.  You can brag about it to your friends. Don't worry I won't judge :)

Your homework is to think of ways to enhance it further. By the use of other RESTful APIs and even create games with it. 

I would recommend you to look at a variety of chatbots to gain **inspiration** to help you to create intuitive and fun bots. I look forward to seeing your bot creations in the future.

## Further Reading

Here's are a few articles and tutorials that could help you in enhancing your bot. 

To be interactive and intuitive to your users while I was researching on how to create this tutorial.

* [Async programming in Python with asyncio](https://dev.to/welldone2094/async-programming-in-python-with-asyncio-12dl)
* [Speed Up Your Python Program With Concurrency](https://realpython.com/python-concurrency/)
* [Building a Discord Bot with Python and Repl.it](https://www.codementor.io/garethdwyer/building-a-discord-bot-with-python-and-repl-it-miblcwejz)
* [Make a Discord Bot with Python](https://www.devdungeon.com/content/make-discord-bot-python)
* [Giphy Python Client](https://github.com/Giphy/giphy-python-client)
* [Why I Create Bus Uncle](https://medium.com/@abhilashmurthy/why-i-created-bus-uncle-40beb665c197)



If you like my article, please **sign up** for Max [Adventurer's Newsletter](http://eepurl.com/dOUoUb) for awesome content I stumble across weekly in **Python**, **Startup** and **Web Development**.

You can also **follow** me to get the **latest** update of my article on **Dev** 

This post was originally posted on Max's blog at [Serving Gifs With Discord Bot - Reading Time: 12 Mins](https://www.maxongzb.com/serving-gifs-with-discord-bot-reading-time-12-mins/) and [Photo by Andy Kelly on Unsplash](https://unsplash.com/photos/0E_vhMVqL9g)