forked from kumo0621/kumo_speaking_
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstart.py
More file actions
135 lines (111 loc) · 5.47 KB
/
Copy pathstart.py
File metadata and controls
135 lines (111 loc) · 5.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import os
import discord
from discord.ext import commands
from discord import app_commands
import yaml
import logging
from datetime import datetime, timedelta, timezone
# 設定ファイルを読み込み
base_dir = os.environ.get("APP_BASEDIR", ".")
config_path = os.path.join(base_dir, "config.yml")
with open(config_path, 'r') as config_file:
config = yaml.safe_load(config_file)
TOKEN = os.environ.get("DISCORD_TOKEN") or config["token"]
VOICE_CHANNEL_IDS = config["voice_channel_ids"]
BOT_USER_IDS = config["bot_user_ids"]
log_channel_id = config['log_channel_id']
intents = discord.Intents.default()
intents.members = True
intents.guilds = True
intents.voice_states = True
intents.message_content = True # これを追加
client = commands.Bot(command_prefix='!', intents=intents)
def is_within_time_range(time_set):
"""現在の時刻が指定された時間範囲内かどうかをチェックする関数"""
now = datetime.now().time()
start_time = datetime.strptime(time_set['start'], "%H:%M").time()
end_time = datetime.strptime(time_set['end'], "%H:%M").time()
if start_time <= end_time:
return start_time <= now <= end_time
else:
# 終了時間が翌日にまたがる場合
return now >= start_time or now <= end_time
@client.event
async def on_ready():
synced = await client.tree.sync()
print(f'Logged in as {client.user}')
@client.event
async def on_voice_state_update(member, before, after):
for channel_id in VOICE_CHANNEL_IDS:
voice_channel = discord.utils.get(client.get_all_channels(), id=channel_id)
if not voice_channel:
continue
# ── 監視対象 Bot がいるか確認 ─────────────────────────
bot_in_channel = next(
(m for m in voice_channel.members if m.id in BOT_USER_IDS),
None
)
# ── Bot しかいない状態なら 60 秒タイムアウト ─────────────
if bot_in_channel and len(voice_channel.members) == 1:
try:
timeout_until = datetime.now(timezone.utc) + timedelta(seconds=60)
await bot_in_channel.timeout(
timeout_until, # ← キーワードを外す
reason="ひとりぼっち VC 自動タイムアウト (60 s)"
)
except discord.Forbidden:
print("タイムアウト権限がありません(Moderate Members が必要)")
except discord.HTTPException as e:
print(f"タイムアウト失敗: {e}")
break # 対象チャンネルの処理が終わったらループ抜け
if before.channel != after.channel:
# 新しいVCに入った場合の処理
if after.channel is not None and after.channel.id in map(int, VOICE_CHANNEL_IDS):
# 新しいVCのメンバーリストを取得
new_channel_members = after.channel.members
# 新しいVCに誰もいなかった場合
if len(new_channel_members) == 1:
# ログ用のチャンネルを取得
log_channel = client.get_channel(log_channel_id)
if log_channel is not None:
await log_channel.send(f' {after.channel.name} で {member.display_name}({member.name}) がVCをはじめました。')
else:
print("ログチャンネルが見つかりませんでした")
@client.event
async def on_disconnect():
# ボットが切断されたときのイベント
logging.warning('ボットが切断されました!')
@client.event
async def on_resumed():
# ボットが再接続されたときのイベント
logging.info('ボットが再接続されました!')
@discord.app_commands.context_menu(name="通話から切断")
async def disconnect_from_voice(interaction: discord.Interaction, member: discord.Member):
# Botに必要な権限があるか確認
if not interaction.guild.me.guild_permissions.move_members:
await interaction.response.send_message("Botに『メンバーを移動する』権限がありません。", ephemeral=True)
return
# ユーザーがボイスチャンネルにいるか確認
if member.voice and member.voice.channel:
try:
# ボイスチャンネルを取得
channel = member.voice.channel
# ユーザーを通話から切断
await member.move_to(None)
# 該当VCにメッセージを送信
await channel.send(
f"{interaction.user.display_name} が {member.display_name} を通話から切断しました。"
)
# インタラクション応答
await interaction.response.send_message(
f"{member.display_name} を通話から切断しました。", ephemeral=True
)
except discord.Forbidden:
await interaction.response.send_message("このユーザーを切断する権限がありません。", ephemeral=True)
except discord.HTTPException as e:
await interaction.response.send_message(f"エラーが発生しました: {e}", ephemeral=True)
else:
await interaction.response.send_message(f"{member.display_name} は通話に参加していません。", ephemeral=True)
# コンテキストメニューコマンドを登録
client.tree.add_command(disconnect_from_voice)
client.run(TOKEN)