Created
July 4, 2017 21:08
-
-
Save Vexs/f2c1bfd6bda68a661a71accd300d2adc to your computer and use it in GitHub Desktop.
Simple polling function for a discord.py discord bot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) |
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))
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
For those still trying to use this with the newer versions, you can still make this work, just keep in mind that you will need to exchange at minimum the following functions:
self.bot.say
=>ctx.send(embed=embed)
self.bot.add_reaction
=>react_message.add_reactions(reaction)
self.bot.edit_message
=>react_message.edit(embed=embed)
You will want to make similar changes to the tally function, replacing any
self.bot
references with the updated method on either the object or master class function