Skip to content

Instantly share code, notes, and snippets.

@Vexs
Created July 4, 2017 21:08
Show Gist options
  • Save Vexs/f2c1bfd6bda68a661a71accd300d2adc to your computer and use it in GitHub Desktop.
Save Vexs/f2c1bfd6bda68a661a71accd300d2adc to your computer and use it in GitHub Desktop.
Simple polling function for a discord.py discord bot
import discord
from discord.ext import commands
class QuickPoll:
""""""
def __init__(self, bot):
self.bot = bot
@commands.command(pass_context=True)
async def quickpoll(self, ctx, question, *options: str):
if len(options) <= 1:
await self.bot.say('You need more than one option to make a poll!')
return
if len(options) > 10:
await self.bot.say('You cannot make a poll for more than 10 things!')
return
if len(options) == 2 and options[0] == 'yes' and options[1] == 'no':
reactions = ['✅', '❌']
else:
reactions = ['1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣', '9⃣', '🔟']
description = []
for x, option in enumerate(options):
description += '\n {} {}'.format(reactions[x], option)
embed = discord.Embed(title=question, description=''.join(description))
react_message = await self.bot.say(embed=embed)
for reaction in reactions[:len(options)]:
await self.bot.add_reaction(react_message, reaction)
embed.set_footer(text='Poll ID: {}'.format(react_message.id))
await self.bot.edit_message(react_message, embed=embed)
@commands.command(pass_context=True)
async def tally(self, ctx, id):
poll_message = await self.bot.get_message(ctx.message.channel, id)
if not poll_message.embeds:
return
embed = poll_message.embeds[0]
if poll_message.author != ctx.message.server.me:
return
if not embed['footer']['text'].startswith('Poll ID:'):
return
unformatted_options = [x.strip() for x in embed['description'].split('\n')]
opt_dict = {x[:2]: x[3:] for x in unformatted_options} if unformatted_options[0][0] == '1' \
else {x[:1]: x[2:] for x in unformatted_options}
# check if we're using numbers for the poll, or x/checkmark, parse accordingly
voters = [ctx.message.server.me.id] # add the bot's ID to the list of voters to exclude it's votes
tally = {x: 0 for x in opt_dict.keys()}
for reaction in poll_message.reactions:
if reaction.emoji in opt_dict.keys():
reactors = await self.bot.get_reaction_users(reaction)
for reactor in reactors:
if reactor.id not in voters:
tally[reaction.emoji] += 1
voters.append(reactor.id)
output = 'Results of the poll for "{}":\n'.format(embed['title']) + \
'\n'.join(['{}: {}'.format(opt_dict[key], tally[key]) for key in tally.keys()])
await self.bot.say(output)
def setup(bot):
bot.add_cog(QuickPoll(bot))
@tomlin7
Copy link

tomlin7 commented Nov 23, 2020

help
image

you didn't give the required arguments

@ha1fdan
Copy link

ha1fdan commented Jan 4, 2021

help
image

use: await self.bot.send("...")

@Karjala22
Copy link

1.5 discord.py rewrite

import discord
from discord.ext import commands


class QuickPoll(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.command(pass_context=True)
    async def poll(self, ctx, question, *options: str):
        if len(options) <= 1:
            await ctx.send('You need more than one option to make a poll!')
            return
        if len(options) > 10:
            await ctx.send('You cannot make a poll for more than 10 things!')
            return

        if len(options) == 2 and options[0] == 'yes' and options[1] == 'no':
            reactions = ['✅', '❌']
        else:
            reactions = ['1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣', '9⃣', '🔟']

        description = []
        for x, option in enumerate(options):
            description += '\n {} {}'.format(reactions[x], option)
        embed = discord.Embed(title=question, description=''.join(description))
        react_message = await ctx.send(embed=embed)
        for reaction in reactions[:len(options)]:
            await react_message.add_reaction(reaction)
        embed.set_footer(text='Poll ID: {}'.format(react_message.id))
        await react_message.edit_message(embed=embed)

    @commands.command(pass_context=True)
    async def tally(self, ctx, id=None):
        poll_message = await ctx.channel.fetch_message(id)
        embed = poll_message.embeds[0]
        unformatted_options = [x.strip() for x in embed.description.split('\n')]
        print(f'unformatted{unformatted_options}')
        opt_dict = {x[:2]: x[3:] for x in unformatted_options} if unformatted_options[0][0] == '1' \
            else {x[:1]: x[2:] for x in unformatted_options}
        # check if we're using numbers for the poll, or x/checkmark, parse accordingly
        voters = [self.bot.user.id]  # add the bot's ID to the list of voters to exclude it's votes

        tally = {x: 0 for x in opt_dict.keys()}
        for reaction in poll_message.reactions:
            if reaction.emoji in opt_dict.keys():
                reactors = await reaction.users().flatten()
                for reactor in reactors:
                    if reactor.id not in voters:
                        tally[reaction.emoji] += 1
                        voters.append(reactor.id)
        output = f"Results of the poll for '{embed.title}':\n" + '\n'.join(['{}: {}'.format(opt_dict[key], tally[key]) for key in tally.keys()])
        await ctx.send(output)


def setup(bot):
    bot.add_cog(QuickPoll(bot))

I think this line no longer works in latest API.

await react_message.edit_message(embed=embed)

The correct one is just edit https://discordpy.readthedocs.io/en/latest/api.html#discord.Message.edit

This worked for me
await react_message.edit(embed=embed)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment