Adding a Meme Generator to Your Discord Bot: A Step-by-Step Guide
Tags: tutorial, discord, api
Published: 2023-01-01 11:00:00

### There are two main ways you can add a meme generator to your Discord bot:

1. Use an image manipulation library (like **PIL** or **OpenCV**) to create memes by overlaying text or other images on top of meme templates. This requires you to have all the Meme images/templates upfront and be able to code all the functionality to make the memes themselves using you preferred image manipulation library.

2. Use a API to handle the meme generation. There a several options available for this use case. Its fairly easy to integrate with since you just have to make HTTP requests and all the hassle with images, fonts and maintenance is abstracted away to the API developer. The only downside is the cost but I thinks it evens out when you think about server costs, image hosting and the development time you are saving. I have chosen this option for the following tutorial.

## Creating a Bot Account
_You can skip directly to **Setting up RapidAPI** section if you already have a bot._

I will be using **Python** and the [discord.py](https://discordpy.readthedocs.io/en/stable/index.html) package to set up a Discord bot the steps to get started are pretty much the same regardless of the language:

1. Install the **Discord.py** library for Python by running the following command:  
`pip install discord`
2. Create a new Python file for your bot and paste in the following code:
    ``` python
    # This example requires the 'message_content' intent.

    import discord

    intents = discord.Intents.default()
    intents.message_content = True

    client = discord.Client(intents=intents)

    @client.event
    async def on_ready():
        print(f'We have logged in as {client.user}')

    @client.event
    async def on_message(message):
        if message.author == client.user:
            return

        if message.content.startswith('$hello'):
            await message.channel.send('Hello!')

    client.run('TOKEN')
    ```
3. Go to the [Discord Developer Portal](https://discord.com/developers/applications) and log in with your Discord account.
4. Click the "New Application" button.
5. Give your application a name and click the "Create" button.
6. Go to the Bot section and click the "Add a Bot" button.
7. Click the "Reset Token" button then the "Copy" button next to the "Token" field and replace the "TOKEN" string from step 2.
8. Run the Python file to start the bot. You should see the message "Logged in as [bot name]" in the console, indicating that the bot is ready to use.

### Inviting Your Bot To A Server
First make sure that you are logged in on the [Discord Website](https://discord.com/)

1. On the [Discord Developer Portal](https://discord.com/developers/applications) in the Settings menu navigate to OAuth2 then URL Generator
2. Check mark the "bot" under "SCOPES" and "Send Messages" (feel free to add additional permissions if you need them) under "BOT PREMISSIONS"
![Discord Developer Portal OAuth2 URL Generator Selected bot and send message](https://i.imgur.com/pIp0erR.png)
3. Go to the Generated URL and select a discord server to add the bot to.

You can now communicate with the bot in the server by using a prefix like "$" as shown in the example bellow.
![Discord chat with bot responding hello](https://i.imgur.com/r4uDNDj.png)

## Setting up RapidAPI
_**Disclaimer** - I am the creator of the Meme Generator API used in the examples_

First you need to create an account on [RapidAPI](https://rapidapi.com/) then navigate to the [Meme Generator API](https://rapidapi.com/eximia-eximia-default/api/meme-generator-and-template-database) page. ![RapidAPI page](https://i.imgur.com/6hlBCeO.png)

Then you can just use the example call on the RapidAPI page to get the variables required for the requests.
``` python
url = 'https://meme-generator-and-template-database.p.rapidapi.com'

headers = {
	'X-RapidAPI-Key': 'RAPIDAPI-KEY',
	'X-RapidAPI-Host': 'meme-generator-and-template-database.p.rapidapi.com'
}
```
## Adding Discord Bot Comands
First lets create a chat command to search all the available templates:

``` python
templates = json.loads(requests.request("GET", url+'/templates', headers=headers).text)

@client.event
async def on_message(message):
    if message.author == client.user:
        return
    
    if message.content.startswith('$templates'):
        search_str = message.content[11:]
        templates_list = [x for x in templates if x.startswith(search_str)]

        if len(templates_list) == 0:
            await message.channel.send('No templates found')
            return
        
        return_message = ''
        for i in templates_list:
            return_message += f'{i}: {templates[i]}\n'
        await message.channel.send(return_message)
```

The command searches the templates that start with the search characters and responds with their full names and number of text fields the memes usually go with.

![example template search in discord chat](https://i.imgur.com/T2tIq65.png)

Next lets make a command that generates memes for us:

``` python
@client.event
async def on_message(message):
    if message.author == client.user:
        return

    if message.content.startswith('$meme'):
        msg_content = message.content[6:].split(';')
        if msg_content[0] not in templates:
            await message.channel.send('Template not found')
            return
        
        payload = {}
        for i in range(1, len(msg_content)):
            payload['text'+str(i-1)] = {
                "text": msg_content[i].strip(),
                "size": 30
            }
        
        async with aiohttp.ClientSession() as session:
            async with session.post(url+'/template/'+msg_content[0], json=payload, headers=headers) as response:
                with io.BytesIO(await response.read()) as file:
                    await message.channel.send(file=discord.File(file, 'meme_img.jpeg'))
```

You can make anything the separator in the command I choose ";" since it's less likely to appear in a text a user wants on a meme.
![meme in a discord chat](https://i.imgur.com/P3YOB8g.png)

Its not required to use all the text fields of a meme template. And from the search command you can see how many it usually uses.
![meme with more text in discord chat](https://i.imgur.com/67CEaDC.png)

## Adding More API Functionality to Your Discord Bot
So far we covered two endpoints, there are more endpoints you can use:
- **POST /caption/{image}**: This endpoint is used to add caption text above or below an image, expanding the image proportionally to the text height.
- **POST /text-box/{image}**: This endpoint allows users to define up to 15 text boxes and specify the exact positions of those text boxes, along with the font and optional rotation.
- **GET /fonts**: Returns a list of all available fonts that can be used with other endpoints. Some fonts are language specific so beware.

_Visit the [API Page](https://rapidapi.com/eximia-eximia-default/api/meme-generator-and-template-database) on RapidAPI and try it in the playground_