質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Discord

Discordは、ゲーマー向けのボイスチャットアプリです。チャット・通話がブラウザ上で利用可能で、個人専用サーバーも開設できます。通話中でも音楽を流したり、PC画面を共有できるなど多機能な点が特徴です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2548閲覧

自動 テキストチャンネル・ボイスチャンネル作成

poketatsu

総合スコア19

Discord

Discordは、ゲーマー向けのボイスチャットアプリです。チャット・通話がブラウザ上で利用可能で、個人専用サーバーも開設できます。通話中でも音楽を流したり、PC画面を共有できるなど多機能な点が特徴です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/10/01 12:06

編集2023/02/25 12:13

作りたいと思ったきっかけ

パーティビースト(自動ボイスチャンネル作成)というボットと組み合わせて、テキストチャンネルの自動作成を使っていたのですが、
移動するときに、privateのチャットが残ってしまうため、作ろうと思いました。

実現したいこと

・特定のボイスチャンネルを押下したときに自動でボイスチャンネルを作成したい
・ボイスチャンネル作成時に作成したボイスチャンネルに移動させたい。
・テキストチャンネルはどこのボイスチャンネルでも自動作成したい

発生している問題・エラーメッセージ

ボイスチャンネルとテキストチャンネルを自動で作成まではできたのですが、
切断したときに削除をしてくれません。

該当のソースコード

python

1# main.py 2import asyncio 3 4import discord 5 6import environments 7 8client = discord.Client(intents=discord.Intents.all()) 9TOKEN="トークン" 10# テキストチャンネルの先頭につける文字 11CHANNEL_PREFIX = "private_" 12# botたちのロール名 (botはテキストチャンネルに参加していてほしい) 13BOT_ROLE_NAME = "bot" 14 15voice_channelID_1: int = 1234456789123456789 16voice_channelID_2: int = 1234456789123456789 17execute_voice_id: tuple = (voice_channelID_1, voice_channelID_2) 18 19 20 21 22@client.event 23async def on_voice_state_update( 24 member: discord.Member, 25 before: discord.VoiceState, 26 after: discord.VoiceState 27): 28 29 # 同一チャンネル内は無視 30 if before.channel == after.channel: 31 return 32 print(before.channel) 33 print(after.channel) 34 # 新規参加vcが特定のチャンネルの時 35 # ボイスチャンネル参加時の対応 36 before2 = before.channel 37 after2 = after.channel 38 if (before.channel is None): 39 await _create_channel(after, member) 40 # ボイスチャンネル退出時の対応 41 42 if len(before.channel.members) == 0: 43 await _exit_task(before, member) 44 45 # if (after.channel is not None) : 46 # if len(after.channel.members) == 0: 47 # elif len(after.channel is None): 48 # await _exit_task(after, member) 49 50 51 52 53 54 55def _overwrites(guild: discord.Guild, member: discord.Member): 56 overwrites = { 57 guild.default_role: discord.PermissionOverwrite(read_messages=False), 58 member: discord.PermissionOverwrite(read_messages=True) 59 } 60 61 but_role = discord.utils.get(guild.roles, name=BOT_ROLE_NAME) 62 if but_role is not None: 63 overwrites.update( 64 { 65 but_role: discord.PermissionOverwrite(read_messages=True) 66 } 67 ) 68 return overwrites 69 70 71async def _create_channel(after: discord.VoiceState, member: discord.Member): 72 channel = after.channel 73 members = after.channel.members 74 guild = channel.guild 75 76 # チャンネルに対するoverwritesの取得 77 overwrites = _overwrites(guild, member) 78 # チャンネルの作成 79 if(channel.name) == "会議部屋": 80 if len(members)==1: 81 meeting_channel = await channel.category.create_voice_channel( 82 name=f"会議部屋{member.name}" 83 ) 84 85 86 await member.move_to(meeting_channel) 87 88 await channel.category.create_text_channel( 89 name=f"{CHANNEL_PREFIX}{meeting_channel.id}", 90 overwrites=overwrites 91 ) 92 await meeting_channel.connect() 93 94 95 96 if (channel.name) == "個通部屋": 97 if len(members) == 1: 98 personal_channel = await channel.category.create_voice_channel( 99 name=f"個通部屋{member.name}" 100 ) 101 102 await member.move_to(personal_channel) 103 await channel.category.create_text_channel( 104 name=f"{CHANNEL_PREFIX}{personal_channel.id}", 105 overwrites=overwrites 106 ) 107 await personal_channel.connect() 108 #overwrites=overwrites 109 110 # .5秒待つ(連続でAPIを呼び出すとdiscord側に負荷がかかるため) 111 #await asyncio.sleep(.5) 112 # 会議部屋に移動 113 #await member.move_to(meeting_channel) 114 #await asyncio.sleep(.5) 115 # await meeting_channel.connect() 116 117 118async def _exit_task(before: discord.VoiceState, member: discord.Member): 119 120 if len(before.channel.members) == 0: 121 # チャンネルのメンバーが一人かつそれがbotの時、そのbotを退出、チャンネル削除 122 # for _client in client.voice_clients: 123 # 124 # if members[0].id == client.user.id: 125 # await _client.disconnect(force=True) 126 category = before.channel.category 127 # カテゴリ内の会議チャンネルを探す 128 # text_channel = discord.utils.get(category.channels, name=f"{CHANNEL_PREFIX}{member.id}") 129 meeting_channel = discord.utils.get(category.channels, name=f"会議部屋{member.name}") 130 personal_channel = discord.utils.get(category.channels, name=f"個通部屋{member.name}") 131 text_meeting_channel = discord.utils.get(category.channels, name=f"{CHANNEL_PREFIX}{meeting_channel.id}") 132 text_personal_channel = discord.utils.get(category.channels, name=f"{CHANNEL_PREFIX}{personal_channel.id}") 133 134 # チャンネルの削除 135 # if len(before.channel.members) == 0: 136 137 if (before.channel.name== meeting_channel.name) == True: 138 await text_meeting_channel.delete() 139 await meeting_channel.delete() 140 # if len(personal_channel.members) == 0: 141 if (before.channel.name == personal_channel.name) == True: 142 await text_personal_channel.delete() 143 await personal_channel.delete() 144 145client.run(TOKEN)

試したこと

テキストチャンネルとボイスチャンネルの自動作成はできた。

補足情報(FW/ツールのバージョンなど)

ボット歴は短いですが、宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

return discord.utils.get(text_channels, voice_channels, name=channel_name, name2=channel_name_2)

.get()はiterable, **kwargsなので、voice_channelsは検索されません。参考リンク


また、

on_voice_state_update()内での

py

1await _channel_delete(member, before.channel)

これはボイスチャンネルしか削除できません。
また、同関数内の_channel_delete()をせずに、ボイスチャンネルはawait before.channel.delete()で可能です。

投稿2022/10/06 01:52

編集2022/10/06 03:14
pecop

総合スコア409

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

poketatsu

2022/10/06 11:46

初めまして! ご回答ありがとうございます 色々試してみます!
poketatsu

2022/11/15 12:52

こんばんは~ await _channel_delete(member, before.channel)を追加してみたのですが、あらかじめ作っておいたボイスチャンネルが消えて、privateのチャット部屋が残ってしまいます。
pecop

2022/11/17 06:07

例えば、 Aさんがvoice_channelID_1のボイスに入る ↓ 新しくボイス、テキストチャンネルを作る ↓ Aさんを新しくできたボイスチャンネルに移動 ということですか? ------ プライべーとチャンネルがどこで出てくるのかと思ったらpartybeastという外部botのことですか。。 (じぶんはそのbotに詳しくないので意図した答えにはならないかもしれません。。)
poketatsu

2022/11/28 11:27

そうですね あとはprivateのテキストチャットとボイスチャットを消してくれればいいのですが… ボイスチャンネルを自動で作ってくれるのが、partybeastというボットでprivateのチャットはこちらで作成しております。 partybeastと一緒に使うと挙動がおかしくなることがあるので、こちらでpartybeastと同じような動作を実現したいということです。
pecop

2022/11/30 04:28

プライベートのチャンネル作ると参加できる人自分とBOT_ROLE_NAMEを持つロール所持者の身になりますがそれでいいんですか?(要は参加者が自分とロール所持者のみ)
pecop

2022/11/30 04:48

https://gist.github.com/peco2282/b8bb9231e3a301d97d1d4a5ff4966be5 gistに上げました 作成されるチャンネル名は {CHANNEL_PREFIX}{member.name}_text、{CHANNEL_PREFIX}{member.name}_voice です。 今回はチャンネル名で削除するか判断しているため、同じチャンネルを作成した場合、同名のものを削除する場合があります。 それを防ぐ場合、辞書などを使ってchannelIDで管理することをお勧めします。
poketatsu

2023/02/18 12:48 編集

返信が遅れてもうしわけございません。 通話部屋はみんなから見えてないとたしかにだめですね privateチャットに映るのは自分とそこの通話部屋にいる人とサーバーにいるボットのみにしたいです privateボイスはだれでも参加できる状態にしたいです。 チャンネル作成と作成したチャンネルに移動まではできたのですが、 人がいなくなったときに、チャンネルが2つとも残ってしまいます。 他の人が参加した場合、テキストチャンネルの権限が付与されなかったです。 あとは ボイスチャンネル1:個通部屋 ボイスチャンネル2:会議部屋 のように分けられたら理想です 権限のことについて、privateチャットにつきましては、 通話部屋に参加したら見える権限を付与 ボイスチャンネルを退出したら権限をとりprivateチャットをみれないようにしたいです。 privateボイスは人が0になったら消えるようにしたいです チャンネル名はid名を後ろにつけようと思ったのですが、 作成する前のidを取得してしまいます。 vc = await channel.category.create_voice_channel( f"{CHANNEL_PREFIX}{member.name}_voice_{channel.id}" # channelName )
pecop

2023/02/20 01:14

再度gistに上げました https://gist.github.com/8fca1065c6f59e1b6f2f1d5d4acc3983 現段階では作成されたチャンネルのテキストチャンネル、個通部屋に参加できませんが、今コードをいじる時間がないのでできません。 (現段階では最初に参加したメンバーとbotのみ_overwrites関数で指定できています。) チャンネルIDは数値で指定をお願いします。 過程: 指定されたチャンネルに参加した時、3つのチャンネルが作成される(会議部屋のみ公開チャンネル) ユーザー(自分自身)は会議部屋に移動 botも移動 ... ユーザーが退出 botも退出 チャンネル削除
poketatsu

2023/02/21 23:46 編集

ご返信ありがとうございます。 色々とありがとうございます。 会議部屋を押したときは会議部屋とprivateチャットの2つを作成し ボイスチャンネルを抜けて0名になったときはなぜか消えないので消せるようにしたいです。 部屋移動も個通部屋を押しても会議部屋に移動してしまいますが 私の方でも色々試してみます。
poketatsu

2023/02/25 00:18

現状、ボイスチャンネルを3つ作成はしないようにはでき、 会議部屋を押したときは会議部屋を個通部屋を押したときは個通部屋を作成することがなんとかできました。 privatechatの名前はmove toしたあとのボイスチャンネルのID名で作成できたのですが、private Voicechannelのほうだけうまくできないのが今の現状です。 if len(members)==1: meeting_channel = await channel.category.create_voice_channel( ↓問題の場所↓ name=f"会議部屋{member}{discord.VoiceChannel.id}"      ↑問題の場所↑ ) await member.move_to(meeting_channel) await channel.category.create_text_channel( name=f"{CHANNEL_PREFIX}{meeting_channel.id}", overwrites=overwrites )
pecop

2023/02/25 06:14

`discord.VoiceChannel` はdiscordのクラスです。 https://gist.github.com/peco2282/8fca1065c6f59e1b6f2f1d5d4acc3983#file-5pp8zaj4kwg0h1-reply-py-L47 ここについて考えると37行目で定義した`channel = after.channel`が、ユーザーの移動後のボイスチャンネルになります。なので、idはchannel.idで取得できます。 --- discord.○○.△△の場合、△△はクラス変数といって○○クラスの変数になります。基本的に変数はクラス変数ではなく引数等から持ってきます。 例えば discord.Intents.all() はクラス変数です。
poketatsu

2023/02/25 12:09

channel.idで一度試していて、move_toする前のidを取得してしまいます。
poketatsu

2023/02/25 12:17

上記のコードを編集致しましたので、一度ご確認お願い致します。 現在の状況: ・個通と会議部屋をそれぞれ押されたときにボイスチャンネルとテキストチャンネルを作成して移動 ・切断されたときは削除はされません。 ・privatechatは作った人しか今のところ見ることができません ・privatevoiceはだれにでも見えるように致しました。
poketatsu

2023/02/25 13:21

五月雨ですみません。 ボイスチャンネルを作成したときに、ボットもボイスチャンネルに一緒にメンバーとして参加してきてしまうのですが、PyNaCLのエラーを直した際に参加できてしまうみたいでなにか解決策はありますでしょうか。 メッセージをみれるようにだけしたいです。
pecop

2023/02/25 19:03

すみません多少時間かかりますがお待ちください。
poketatsu

2023/02/26 01:54 編集

色々とすみません。 時間がある時で大丈夫です。 以下の2点を解決することができました。 ・切断されたときは削除はされません。 ・privatechatは作った人しか今のところ見ることができません 残る問題は、会議部屋を作成した人が最後に抜けないと残ってしまうというところです。 f"会議部屋{member._user}をf"会議部屋{before.channel.name}にするとmeeting_channel がNoneになってしまいました。 if (before.channel.name): meeting_channel = discord.utils.get(category.channels, name=f"会議部屋{member._user}") text_meeting_channel = discord.utils.get(category.channels, name=f"{CHANNEL_PREFIX}{meeting_channel.id}") await text_meeting_channel.delete() await meeting_channel.delete()
poketatsu

2023/02/26 06:06

無事完成することができました! 間が空いての返信になってしまいすみませんでした!
pecop

2023/03/04 12:52

おぉ良かった。 お疲れ様です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問