Discord로 통화 중만의 채팅을 만들고 싶다!

만나서 반갑습니다. Qiita 첫 투고입니다.

Discord를 사용할 때 통화중인 사람만 채팅하고 싶지 않습니까?
예를 들어 게임 초대 코드,
말하는 것과 관련된 링크, ...
봇의 명령을 치고 싶을 때,,,,,

이번에는 그럴 때 편리한 통화중에만 사용할 수 있는 채팅방을 ぢ s 자 rd. py 을 이용해 만들어 갑니다.

완제품





준비



먼저 봇 프로그램을 만들기 위한 준비를 한다.

게시시 환경
- 파이썬 3.8.3
- discord.py 1.3.3

이 봇에는 채널을 볼 수 있는 권한, 역할 관리 권한 및 채널 관리 권한이 필요합니다.

여기에서는 섬세한 설명을 생략합니다, 아래의 기사를 참고로 부디.
Python으로 간단한 Discord Bot을 만드는 방법

처리 흐름



처리의 내용을 정리해 갑니다.
  • 회원이 먼저 음성 채팅에 참여합니다
  • Bot이 음성 채팅에 해당하는 텍스트 채팅 룸 만들기
  • 통화 멤버 참가 · 퇴실에 따라 텍스트 채팅 룸에 참가 · 퇴실시킨다
  • 통화 종료시 텍스트 채널 삭제

  • 이번은 즐거움 중시로 텍스트 채널을 종료시에 삭제하는 방향으로 만들어 갑니다.

    프라이빗함 중시로 채팅 이력도 숨기거나 텍스트 채널은 음성 채팅에 완전히 연결되어 버려, 처음에 작성하고 그대로 남겨 사용하는 것도 전혀 있을까 생각합니다.

    구현



    bot.py
    import discord
    client = discord.Client()
    
    # テキストチャンネルの先頭につける文字
    CHANNEL_PREFIX = "private_"
    # botたちのロール名 (botはテキストチャンネルに参加していてほしい)
    BOT_ROLE_NAME = "bot"
    
    
    # 接続できたときに実行される
    @client.event
    async def on_ready():
        # 初期化処理などが行えるよ
        print("On ready")
    
    
    # ボイスチャンネル内の状態が変化したときに実行される
    @client.event
    async def on_voice_state_update(member, before, after):
        # チャンネルを移動していない場合処理をしない
        if before.channel == after.channel:
            return
    
        # チャンネルから退出してきた場合
        if before.channel is not None:
            # ボイスチャンネルに誰もいなくなった場合
            if len(before.channel.members) == 0:
                # テキストチャンネルを削除する
                await _channel_delete(member, before.channel)
            else:
                # テキストチャンネルから退出させる
                await _channel_exit(member, before.channel)
    
        # ボイスチャンネルに参加してきた場合
        if after.channel is not None:
            # 参加したチャンネルの1人目だった場合
            if len(after.channel.members) == 1:
                # テキストチャンネルを作成する
                await _channel_create(member, after.channel)
            else:
                # テキストチャンネルに参加させる
                await _channel_join(member, after.channel)
    
            # 入室時にメンションでチャンネルに案内
            await _channel_send_join(member, after.channel)
    
        print("fin voice state update event")
    
    
    # テキストチャンネルを検索する関数
    def _channel_find(voiceChannel):
        text_channels = voiceChannel.guild.text_channels
        channel_name = CHANNEL_PREFIX + str(voiceChannel.id)
        # 名前からチャンネルオブジェクトを取得する
        return discord.utils.get(text_channels, name=channel_name)
    
    
    # チャンネル作成時の権限リストを返す
    def _init_overwrites(guild, member):
        overwrites = {
            # デフォルトのユーザーはメッセージを見れないように
            guild.default_role: discord.PermissionOverwrite(read_messages=False),
            # 参加したメンバーは見ることができるように
            member: discord.PermissionOverwrite(read_messages=True)
        }
    
        bots_role = discord.utils.get(guild.roles, name=BOT_ROLE_NAME)
        if bots_role is not None:
            # Botもメッセージを見れるように
            bot_overwrite = {
                bots_role: discord.PermissionOverwrite(read_messages=True)
            }
            overwrites.update(bot_overwrite)
    
        return overwrites
    
    
    # テキストチャンネルを作成する関数
    async def _channel_create(member, voiceChannel):
        guild = voiceChannel.guild
    
        channel_name = CHANNEL_PREFIX + str(voiceChannel.id)
        overwrites = _init_overwrites(guild, member)
        category = voiceChannel.category
    
        # テキストチャンネルを作成
        await guild.create_text_channel(
            channel_name, overwrites=overwrites, category=category)
    
    
    # テキストチャンネルを削除する関数
    async def _channel_delete(member, voiceChannel):
        target = _channel_find(voiceChannel)
        if target is not None:
            await target.delete()
    
    
    # テキストチャンネルに参加させる関数
    async def _channel_join(member, voiceChannel):
        target = _channel_find(voiceChannel)
        if target is not None:
            overwrites = discord.PermissionOverwrite(read_messages=True)
            # 該当メンバーに読み取り権限を付与
            await target.set_permissions(member, overwrite=overwrites)
    
    
    # テキストチャンネルから退出させる関数
    async def _channel_exit(member, voiceChannel):
        target = _channel_find(voiceChannel)
        if target is not None:
            # 該当メンバーの読取権限を取り消し
            await target.set_permissions(member, overwrite=None)
    
    
    # 入室時にメンションを飛ばして案内したい
    async def _channel_send_join(member, voiceChannel):
        target = _channel_find(voiceChannel)
        if target is not None:
            await target.send(member.mention + "通話中のチャットはこちらをお使いください")
    
    
    if __name__ == "__main__":
        client.run("あなたのbotのトークン")
    

    위의 코드를 실행하고 음성 채널에 입실하면 'private_[채널 id]'라는 채널이 자동으로 만들어져 참가할 수 있었습니다!
    퇴실하면 제대로 채널이 삭제되었습니다.

    요약



    의외로 간단하게 Discord Bot라고 만들 수 있습니다.

    discord.py 시작하고 싶다! 더 자세히 알고 싶다! 그렇다면
    공식 문서 이나 discord.py입문(1) 등을 추천합니다.

    원하는 기능을 점점 추가하고, 좋은 Discord 라이프를!

    참고



    Python으로 간단한 Discord Bot을 만드는 방법
    discord.py 문서
    discord.py입문(1)

    좋은 웹페이지 즐겨찾기