Discordで募集をかけるbot

slackの投票機能が好きだったのでそれっぽいものをつくってみた。
投票ではなく募集機能になったが。
###追記
2019/7/30
アンケートも書いた
[DiscordBotにSlackのアンケートみたいな機能をつける](https://ikayome.hateblo.jp/entry/2019/07/19/Discord_Bot%E3%81%ABSlack%E3%81%AE%E3%82%A2%E3%83%B3%E3%82%B1%E3%83%BC%E3%83%88%E3%81%BF%E3%81%9F%E3%81%84%E3%81%AA%E6%A9%9F%E8%83%BD%E3%82%92%E3%81%A4%E3%81%91%E3%82%8B)
2019/7/9
rewite版のコードも掲載しました。
~~**これはasync版でのprogramです。<br>現在、主流となっているrewrite版では使用が変わっています**~~




#動作
**async** `.rect@数字`を送るとこんな感じで動く
`↩`で取り消し,`⏫`で参加する
![bottest.gif](https://qiita-image-store.s3.amazonaws.com/0/272313/f3057021-52cf-6059-7d40-f5ff811cdb7b.gif)

集まらなかった時は、自分で`✖`,`:heavy_multiplication_x:`リアクションを付けてあげると募集が終わる
人望がなくても安心な設計
![image.png](https://qiita-image-store.s3.amazonaws.com/0/272313/154a5238-be2f-1973-4f52-215c2109b773.png)

**rewrite** `.rect {名目} {人数} {時間}`
例)`.rect リグマ 3 600.0`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272313/8941781b-324b-efc1-4f74-d69189d4c2c1.png)



#ソース
**rewrite版**

```python

import discord
from discord.ext import commands
import asyncio

client = commands.Bot(command_prefix='.')
@client.event
async def on_ready():
    print('Logged in as')
    print(client.user.name)
    print(client.user.id)
    print('------')

@client.command()
async def rect(ctx, about = "募集", cnt = 4, settime = 10.0):
    cnt, settime = int(cnt), float(settime)
    reaction_member = [">>>"]
    test = discord.Embed(title=about,colour=0x1e90ff)
    test.add_field(name=f"あと{cnt}人 募集中\n", value=None, inline=True)
    msg = await ctx.send(embed=test)
    #投票の欄
    await msg.add_reaction('⏫')
    await msg.add_reaction('✖')

    def check(reaction, user):
        emoji = str(reaction.emoji)
        if user.bot == True:    # botは無視
            pass
        else:
            return emoji == '⏫' or emoji == '✖'

    while len(reaction_member)-1 <= cnt:
        try:
            reaction, user = await client.wait_for('reaction_add', timeout=settime, check=check)
        except asyncio.TimeoutError:
            await ctx.send('残念、人が足りなかったようだ...')
            break
        else:
            print(str(reaction.emoji))
            if str(reaction.emoji) == '⏫':
                reaction_member.append(user.name)
                cnt -= 1
                test = discord.Embed(title=about,colour=0x1e90ff)
                test.add_field(name=f"あと__{cnt}__人 募集中\n", value='\n'.join(reaction_member), inline=True)
                await msg.edit(embed=test)

                if cnt == 0:
                    test = discord.Embed(title=about,colour=0x1e90ff)
                    test.add_field(name=f"あと__{cnt}__人 募集中\n", value='\n'.join(reaction_member), inline=True)
                    await msg.edit(embed=test)
                    finish = discord.Embed(title=about,colour=0x1e90ff)
                    finish.add_field(name="おっと、メンバーがきまったようだ",value='\n'.join(reaction_member), inline=True)
                    await ctx.send(embed=finish)

            elif str(reaction.emoji) == '✖':
                if user.name in reaction_member:
                    reaction_member.remove(user.name)
                    cnt += 1
                    test = discord.Embed(title=about,colour=0x1e90ff)
                    test.add_field(name=f"あと__{cnt}__人 募集中\n", value='\n'.join(reaction_member), inline=True)
                    await msg.edit(embed=test)
                else:
                    pass
        # リアクション消す。メッセージ管理権限がないとForbidden:エラーが出ます。
        await msg.remove_reaction(str(reaction.emoji), user)


client.run("YOU------TOKEN")
```

以下、async

```python
import discord

client = discord.Client()

@client.event
async def on_message(message):
	"""メンバー募集 (.rect@数字)"""
	if message.content.startswith(".rect"):
		mcount = int(message.content[6:len(message.content)])
		text= "あと{}人 募集中\n"
		revmsg = text.format(mcount)
		#friend_list 押した人のList
		frelist = []
		msg = await client.send_message(message.channel, revmsg)

		#投票の欄
		await client.add_reaction(msg, '\u21a9')
		await client.add_reaction(msg, '⏫')
		await client.pin_message(msg)

		#リアクションをチェックする
		while len(frelist) < int(message.content[6:len(message.content)]):
			target_reaction = await client.wait_for_reaction(message=msg)
			#発言したユーザが同一でない場合 真
			if target_reaction.user != msg.author:
				#==============================================================
				#押された絵文字が既存のものの場合 >> 左　del
				if target_reaction.reaction.emoji == '\u21a9':
					#==========================================================
					#◀のリアクションに追加があったら反応 frelistにuser.nameがあった場合　真
					if target_reaction.user.name in frelist:
						frelist.remove(target_reaction.user.name)
						mcount += 1
						#リストから名前削除
						await client.edit_message(msg, text.format(mcount) +
														'\n'.join(frelist))
							#メッセージを書き換え

					else:
						pass
				#==============================================================
				#押された絵文字が既存のものの場合　>> 右　add
				elif target_reaction.reaction.emoji == '⏫':
					if target_reaction.user.name in frelist:
						pass

					else:
						frelist.append(target_reaction.user.name)
						#リストに名前追加
						mcount = mcount - 1
						await client.edit_message(msg, text.format(mcount) +
														'\n'.join(frelist))


				elif target_reaction.reaction.emoji == '✖':
						await client.edit_message(msg, '募集終了\n'+ '\n'.join(frelist))
						await client.unpin_message(msg)
						break
				await client.remove_reaction(msg, target_reaction.reaction.emoji, target_reaction.user)
				#ユーザーがつけたリアクションを消す※権限によってはエラー
				#==============================================================
		else:
			await client.edit_message(msg, '募集終了\n'+ '\n'.join(frelist))



client.run("あなたのトーーーーーーーーーーーークン")
```

`await client.remove_reaction(msg, target_reaction.reaction.emoji, target_reaction.user)`
は、リアクションを自動で消してくれて便利だけどサーバーで権限がないとエラーが出るので注意
discorddeveloperのサイトで変更できたはず

`await client.pin_message(msg)`と`await client.unpin_message(msg)`は募集が終わるまでメッセージをピン留めしてくれる。
コメントアウトして機能をとめてもいいかも

##参考にしたサイト
>[【Discord】リアクションをスイッチとして使う【Python3】](http://4kane.doorblog.jp/archives/9579818.html)
リアクションをスイッチとして使う発想はなかったのでとても参考になった
4KaNEさんに感謝

>[UnicodeのEmojiの一覧](https://ja.wikipedia.org/wiki/Unicode%E3%81%AEEmoji%E3%81%AE%E4%B8%80%E8%A6%A7)
絵文字のまま入れるとエラーが出るものもあるのでここからUnicordを探して打った方がいいかもしれない