discord.py Project 4: 
 ✍🏽Partnership Bot!
terabyte.

terabyte. @mikeywastaken

About: a super young defloper who speaks the mystical *snake language 🐍*

Location:
place
Joined:
Mar 2, 2021

discord.py Project 4: ✍🏽Partnership Bot!

Publish Date: May 5 '21
15 18

In this article, we're going to create a Discord bot that can guide users through an automatic partnership process!

What's a Discord server partnership?

A discord server partnership is when two servers will send the other's invite link in a designated channel, to share members.

Our end product will look something like this:

The staff of your server will see this:
image

And will be able to click the checkmark or cross to accept or deny the request!

When it is accepted, it will automatically post the ad in a designated channel!
image


Installing discord.ext.forms 🔧

Discord.ext.forms is a module designed specifically to assist bot developers with making forms and surveys! To install it, you need to open a shell and type:

pip install discord-ext-forms
Enter fullscreen mode Exit fullscreen mode

Once that's done, you're ready to start coding!


Coding the bot ⚙

To start this off, we will need to start our commands.Bot instance.

from discord.ext import commands
import discord

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

bot.run(TOKEN_HERE)
Enter fullscreen mode Exit fullscreen mode

Now that we have our bot, let's make our partner command!

from discord.ext import commands
import discord

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

@bot.command()
async def partner(ctx):
    ...

bot.run(TOKEN)
Enter fullscreen mode Exit fullscreen mode

We need to import the Form class from discord.ext.forms to make our form for the partnership command!

from discord.ext.forms import Form
Enter fullscreen mode Exit fullscreen mode

Now, let's start on our form! We likely want to ask for an invite link, a description, and an advertising server, but you can add or remove any of these questions!

In our command, let's make our form:

form = Form(ctx, "Partnership Request")
Enter fullscreen mode Exit fullscreen mode

To add a question, we use the .add_question method of the form.

form.add_question(
        "What's the invite link to your server?", # The question which it will ask
        "invitelink", # What the form will call the result of this question
        "invite" # The type the response should be
    )
Enter fullscreen mode Exit fullscreen mode

Because we have invite as the type, discord.ext.forms will check that the response is an invite and return an invite object.

Now, let's add our other two questions!

@bot.command()
async def partner(ctx):
    form = Form(ctx, "Partnership Request")
    form.add_question(
        "What's the invite link to your server?", # The question which it will ask
        "invitelink", # What the form will call the result of this question
        "invite" # The type the response should be
    )
    form.add_question(
        "What's a description of your server?",
        "description"
    )
    form.add_question(
        "What's your server's advertisement?",
        "advertisement"
    )
Enter fullscreen mode Exit fullscreen mode

The final two don't have a type, because we just want the message's content.

Now, we'll want to begin the form!

results = await form.start()
Enter fullscreen mode Exit fullscreen mode

results will have 3 attributes:

  • invitelink
  • description
  • advertisement

These are the keys that we set these values to earlier!

Now, let's make our embed that shows the staff the submission:

embed = discord.Embed(
        title=f"Partnership Request from {results.invitelink.guild.name}",
        description=f"**Description:** {results.description}",
    )
    embed.set_thumbnail(url=results.invitelink.guild.icon_url)
    embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
Enter fullscreen mode Exit fullscreen mode

Now, let's get our partnerships channel so that we can send our embed there!

partnershipreq = bot.get_channel(partnership_request_channel_id_here)
Enter fullscreen mode Exit fullscreen mode

Lastly, let's send it!

prompt = await partnershipreq.send(embed=embed)
Enter fullscreen mode Exit fullscreen mode

For staff members to be able to accept and deny, we're going to need another form from discord.ext.forms: ReactConfirm.

from discord.ext.forms import Form, ReactConfirm
Enter fullscreen mode Exit fullscreen mode

The reason we saved prompt earlier is because we're going to need it for the accept/deny process. Use ReactConfirm to create a new form called confirm, like this:

confirm = ReactConfirm(user=ctx.author, message=prompt, bot=bot)
accepted = await confirm.start()
Enter fullscreen mode Exit fullscreen mode

Now, the bot, after sending the message, will react with the ✔ and ❌ emoji, and wait for a staff member to choose one.

We're nearly there! Now we just have to send the ad, in an embed of course, into the partnership channel if it gets accepted.

if accepted:
    partners = bot.get_channel(partners_channel_id_here)
    em = discord.Embed(title=results.invitelink.guild.name, 
    description=results.advertisement, color=0x2F3136)
    em.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
    em.set_thumbnail(url=results.invitelink.guild.icon_url)
    await partners.send(embed=em)
Enter fullscreen mode Exit fullscreen mode

Now we're done! Our final code looks something like this:

from discord.ext import commands
import discord
from discord.ext.forms import Form, ReactConfirm

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

@bot.command()
async def partner(ctx):
    form = Form(ctx, "Partnership Request")
    form.add_question(
        "What's the invite link to your server?", # The question which it will ask
        "invitelink", # What the form will call the result of this question
        "invite" # The type the response should be
    )
    form.add_question(
        "What's a description of your server?",
        "description"
    )
    form.add_question(
        "What's your server's advertisement?",
        "advertisement"
    )
    results = await form.start()
    embed = discord.Embed(
        title=f"Partnership Request from {results.invitelink.guild.name}",
        description=f"**Description:** {results.description}",
    )
    embed.set_thumbnail(url=results.invitelink.guild.icon_url)
    embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
    partnershipreq = bot.get_channel(partnership_request_channel_id_here)
    prompt = await partnershipreq.send(embed=embed)
    confirm = ReactConfirm(user=ctx.author, message=prompt,bot=bot)
    accepted = await confirm.start()
    partners = bot.get_channel(partners_channel_id_here)
    em = discord.Embed(title=results.invitelink.guild.name, description=results.advertisement, color=0x2F3136)
    em.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
    em.set_thumbnail(url=results.invitelink.guild.icon_url)
    await partners.send(embed=em)


bot.run(TOKEN)
Enter fullscreen mode Exit fullscreen mode

If you want to see other use cases for this module, check it out here:

GitHub logo thrzl / discord-ext-forms

❓ a simpler way to make forms, surveys, and reaction input using discord.py.

Comments 18 total

  • ffbboy30
    ffbboy30May 20, 2021

    Hi,
    Nice article , Do you have a tips to create a client capable of receiving messages from a channel whose identifier I know?

    • terabyte.
      terabyte.May 25, 2021

      Well, you could check if the channel's ID matches the ID that you have:

      # on_message
      if message.channel.id == your_id:
          # NOW i want to run the rest of the code, inside of this if statement.
      
      Enter fullscreen mode Exit fullscreen mode
      • ffbboy30
        ffbboy30May 25, 2021

        Thanks My problem is the channel connexion , I'm not the channel admin I just want to read message Like in my application.
        Is it possible to register with mail and password like in the app ?

        • terabyte.
          terabyte.May 25, 2021

          Not without using selfbots, which is highly against ToS and will get you banned from Discord. You should just get permission from a channel admin with a link that only has the send/read messages permission, so that it cannot abuse anything.

  • Charanleo25
    Charanleo25May 28, 2021

    It was Amazing, could you make all this code available together rather code snippets.

    • terabyte.
      terabyte.May 28, 2021

      If I understand what you're requesting, I have included the code together at the bottom of the article.

      • Charanleo25
        Charanleo25May 29, 2021

        nope, all those parts of codes like invite, welcome.

  • Janak
    JanakJun 1, 2021

    bro confirm reactions are not coming in embed and code also gives error
    Error:

    confirm = ReactConfirm(message=prompt, bot=bot)
    TypeError: __init__() missing 1 required positional argument: 'user'
    
    Enter fullscreen mode Exit fullscreen mode
    discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: __init__() missing 1 required positional argument: 'user'
    
    Enter fullscreen mode Exit fullscreen mode
    • terabyte.
      terabyte.Jun 1, 2021

      Thanks for letting me know! The updated line should be:

      confirm = ReactConfirm(user=ctx.member,message=prompt, bot=bot)
      
      Enter fullscreen mode Exit fullscreen mode
      • Janak
        JanakJun 1, 2021

        lol bro, still error

        confirm = ReactConfirm(user=ctx.member,message=prompt, bot=bot)
        AttributeError: 'Context' object has no attribute 'member'
        
        Enter fullscreen mode Exit fullscreen mode
        • terabyte.
          terabyte.Jun 1, 2021

          Jeez, I did it in a rush. ctx.member should be ctx.author

          • Janak
            JanakJun 1, 2021

            bro now no errors but when i try to confirm by clicking tick then nothing happens no error, no advertise :(
            ,btw thanks by reading this artical i learned how to use discord forms thanks a lot

            • terabyte.
              terabyte.Jun 5, 2021

              Hmm, i'm unsure about what could be happening. Make sure that your channel ID is correct, and could you send your code? (excluding the token of course)

              • Janak
                JanakJun 5, 2021

                yes

                to send code i removed token and channel ids

                from discord.ext import commands
                import discord
                from discord.ext.forms import Form, ReactConfirm
                
                TOKEN = "token here"
                intents = discord.Intents(messages=True, guilds=True)
                bot = commands.Bot(command_prefix="!", intents=intents)
                
                @bot.command()
                async def partner(ctx):
                    form = Form(ctx, "Partnership Request")
                    form.add_question(
                        "What's the invite link to your server?", # The question which it will ask
                        "invitelink", # What the form will call the result of this question
                        "invite" # The type the response should be
                    )
                    form.add_question(
                        "What's a description of your server?",
                        "description"
                    )
                    form.add_question(
                        "What's your server's advertisement?",
                        "advertisement"
                    )
                    results = await form.start()
                    embed = discord.Embed(
                        title=f"Partnership Request from {results.invitelink.guild.name}",
                        description=f"**Description:** {results.description}",
                    )
                    embed.set_thumbnail(url=results.invitelink.guild.icon_url)
                    embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
                    partnershipreq = bot.get_channel("i removed channel id")
                    prompt = await partnershipreq.send(embed=embed)
                
                    confirm = ReactConfirm(user=ctx.author,message=prompt, bot=bot)
                    accepted = await confirm.start()
                
                    if accepted:
                        partners = bot.get_channel("i removed channel id")
                        em = discord.Embed(title=results.invitelink.guild.name,description=results.advertisement, color=0x2F3136)
                        em.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
                        em.set_thumbnail(url=results.invitelink.guild.icon_url)
                        await partners.send(embed=em)
                
                
                bot.run(TOKEN)
                
                Enter fullscreen mode Exit fullscreen mode
  • edward
    edwardJul 12, 2021

    it says:
    Traceback (most recent call last):
    File "main.py", line 3, in
    from discord.ext.forms import Form, ReactConfirm
    ModuleNotFoundError: No module named 'discord.ext.forms

    • terabyte.
      terabyte.Jul 22, 2021

      Sorry for the late reply, did you pip install discord.ext.forms? Do you have multiple Python installations?

  • Aman-k346
    Aman-k346Sep 2, 2021

    kages/discord/ext/commands/core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
    File "main.py", line 121, in testform
    form = forms.Form(ctx, 'Title')
    NameError: name 'forms' is not defined

    when i try to import forms it's not working

    • Janak
      JanakNov 3, 2021

      first make sure that you have indstalled module or not :

      pip install discord-ext-forms
      
      Enter fullscreen mode Exit fullscreen mode

      and if you already have installed then import module like this :

      from discord.ext.forms import Form, ReactConfirm
      
      Enter fullscreen mode Exit fullscreen mode
Add comment