回答編集履歴

10

複数の引数・引数がないときに対応

2021/10/24 23:55

投稿

fj68
fj68

スコア752

test CHANGED
@@ -13,6 +13,12 @@
13
13
 
14
14
 
15
15
  以下のコードではトークンや合言葉など見られてはまずいものを環境変数から読み込むようにしていますので、HerokuのConfig Varsに適宜設定するか書き換えてください。
16
+
17
+
18
+
19
+ 【追記】
20
+
21
+ `add_role()`の2つ目以降の引数に`?r`の引数が渡されるので、いくつ渡されてもいいように可変引数とし、引数がなかったり引数に渡されたフレーズが間違っていれば「合言葉が間違っています」と表示するようにしました。
16
22
 
17
23
 
18
24
 
@@ -100,21 +106,27 @@
100
106
 
101
107
  @bot.command(name='r')
102
108
 
103
- async def add_role(ctx, word):
109
+ async def add_role(ctx, *args):
104
110
 
105
111
  """DM経由かつ合言葉が合っていれば役職を付与"""
112
+
113
+ # 「?r あああ いいい」 → add_role(ctx, ['あああ', 'いいい']) → 'あああ いいい'
114
+
115
+ # 「?r」 → add_role(ctx, []) → ''
116
+
117
+ word = ' '.join(args)
106
118
 
107
119
  if role is not None and is_DM(ctx.message) and word == WORD:
108
120
 
109
121
  user = guild.get_member(ctx.message.author.id)
110
122
 
111
- await ctx.send("Roles added")
123
+ await ctx.send("役職を付与しました。")
112
124
 
113
125
  await user.add_roles(role)
114
126
 
115
127
  else:
116
128
 
117
- await ctx.send('Fail to add roles')
129
+ await ctx.send('合言葉が間違っています。')
118
130
 
119
131
 
120
132
 

9

型変換を追加

2021/10/24 23:55

投稿

fj68
fj68

スコア752

test CHANGED
@@ -32,9 +32,9 @@
32
32
 
33
33
  TOKEN = os.getenv('DISCORD_BOT_TOKEN')
34
34
 
35
- GUILD_ID = os.getenv('DISCORD_BOT_GUILD_ID')
35
+ GUILD_ID = int(os.getenv('DISCORD_BOT_GUILD_ID'))
36
36
 
37
- ROLE_ID = os.getenv('DISCORD_BOT_ROLE_ID')
37
+ ROLE_ID = int(os.getenv('DISCORD_BOT_ROLE_ID'))
38
38
 
39
39
  WORD = os.getenv('DISCORD_BOT_WORD')
40
40
 

8

command_prefixを修正

2021/10/23 11:47

投稿

fj68
fj68

スコア752

test CHANGED
@@ -46,7 +46,7 @@
46
46
 
47
47
  intents.members = True
48
48
 
49
- bot = Bot(command_prefix='/', intents=intents)
49
+ bot = Bot(command_prefix='?', intents=intents)
50
50
 
51
51
 
52
52
 

7

説明を追記

2021/10/23 09:40

投稿

fj68
fj68

スコア752

test CHANGED
@@ -160,6 +160,10 @@
160
160
 
161
161
  以下、少し見にくいかもしれませんが、動作した環境の各種設定です。
162
162
 
163
+ 権限はサーバの設定から変更することはできず、Botを導入するためのURLを生成するときにしか指定できませんので、変更したい場合は一度Botをサーバから削除して導入し直す必要があるようです。
164
+
165
+ Botの削除は「サーバの設定→Integrations→Bot名→Delete Integration」で可能です。
166
+
163
167
 
164
168
 
165
169
  ![インテント](37ea0f9a446af515bc37e5ab0854da08.png)

6

設定がわかるスクショを追加

2021/10/22 18:40

投稿

fj68
fj68

スコア752

test CHANGED
@@ -158,4 +158,20 @@
158
158
 
159
159
 
160
160
 
161
+ 以下、少し見にくいかもしれませんが、動作した環境の各種設定です。
162
+
163
+
164
+
165
+ ![インテント](37ea0f9a446af515bc37e5ab0854da08.png)
166
+
167
+ ![パーミッション1](d5515a0a4921886d749d8f02de512e57.png)
168
+
169
+ ![パーミッション2](4cc9a4710544cec2af8ef6dfa33b53ea.png)
170
+
171
+ ![権限](8cb7df0634cafa5c0b626bb721f9fafe.png)
172
+
173
+ ![権限の順番](9ad77c0b2e94c3e3202c733bfb448928.png)
174
+
175
+
176
+
161
177
  以上、お役に立てれば幸いです

5

インテントの説明を追記

2021/10/22 18:36

投稿

fj68
fj68

スコア752

test CHANGED
@@ -130,6 +130,8 @@
130
130
 
131
131
  Manage RolesやSend Messagesが必要になります(とりあえず全部与えて試していたので、もしかしたら他にも必要な権限があるかもしれません)。
132
132
 
133
+ 同時に、2つあるインテントの設定もオンにしてください。
134
+
133
135
  詳しくは以下の質問の回答が画像付きなのでおすすめです。
134
136
 
135
137
 

4

説明を追加し、コードを修正

2021/10/22 16:46

投稿

fj68
fj68

スコア752

test CHANGED
@@ -2,7 +2,17 @@
2
2
 
3
3
  ただしDMの場合、`ctx.message.guild`は`None`になってしまうそうなので、事前に`guild`と`role`を取得しておきましょう。
4
4
 
5
+
6
+
7
+ また、`DMChannel`からのメッセージの場合、`context.message.author`は`Member`ではなく`User`となります。
8
+
9
+ `Member.add_roles()`を使うためには`guild.get_member(context.message.author.id)`で改めて対応する`Member`オブジェクトを取得する必要があります。
10
+
11
+ そして、`guild.get_member()`を使用するには`Intents`というオブジェクトを使ってオプションを設定してあげる必要があります。
12
+
13
+
14
+
5
- コードはこん感じでどうでしょうか。
15
+ 以下のコードトークンや合言葉など見られてはまずいものを環境変数から読み込むよにしていますの、HerokuのConfig Varsに適宜設定する書き換えてください
6
16
 
7
17
 
8
18
 
@@ -14,29 +24,39 @@
14
24
 
15
25
  import os
16
26
 
17
- import sys
27
+ import traceback
18
28
 
19
29
 
20
30
 
31
+
32
+
21
- TOKEN = '' # ご自分のトークンに置き換えてください
33
+ TOKEN = os.getenv('DISCORD_BOT_TOKEN')
34
+
35
+ GUILD_ID = os.getenv('DISCORD_BOT_GUILD_ID')
36
+
37
+ ROLE_ID = os.getenv('DISCORD_BOT_ROLE_ID')
38
+
39
+ WORD = os.getenv('DISCORD_BOT_WORD')
22
40
 
23
41
 
24
42
 
25
- # discord.ext.commands.Botはdiscord.Clientのサブクラスなので
26
43
 
27
- # discord.Clientのメソッド(get_guild()とか)も使える
28
44
 
45
+ intents = discord.Intents.default()
46
+
47
+ intents.members = True
48
+
29
- bot = Bot(command_prefix='?')
49
+ bot = Bot(command_prefix='/', intents=intents)
30
50
 
31
51
 
32
52
 
33
- GUILD_ID = 0
34
-
35
- ROLE_ID = 0
36
53
 
37
54
 
55
+ guild = None
38
56
 
39
57
  role = None
58
+
59
+
40
60
 
41
61
 
42
62
 
@@ -44,7 +64,7 @@
44
64
 
45
65
  async def on_ready():
46
66
 
47
- """Bot起動時にroleを取得"""
67
+ global guild
48
68
 
49
69
  global role
50
70
 
@@ -54,9 +74,27 @@
54
74
 
55
75
 
56
76
 
77
+
78
+
79
+ @bot.event
80
+
81
+ async def on_command_error(ctx, error):
82
+
83
+ orig_error = getattr(error, "original", error)
84
+
85
+ error_msg = ''.join(traceback.TracebackException.from_exception(orig_error).format())
86
+
87
+ await ctx.send(error_msg)
88
+
89
+
90
+
91
+
92
+
57
93
  def is_DM(message):
58
94
 
59
95
  return isinstance(message.channel, discord.DMChannel)
96
+
97
+
60
98
 
61
99
 
62
100
 
@@ -66,9 +104,17 @@
66
104
 
67
105
  """DM経由かつ合言葉が合っていれば役職を付与"""
68
106
 
69
- if role is not None and is_DM(ctx.message) and word == 'ラーメン大好き':
107
+ if role is not None and is_DM(ctx.message) and word == WORD:
70
108
 
109
+ user = guild.get_member(ctx.message.author.id)
110
+
111
+ await ctx.send("Roles added")
112
+
71
- await ctx.message.author.add_roles(role)
113
+ await user.add_roles(role)
114
+
115
+ else:
116
+
117
+ await ctx.send('Fail to add roles')
72
118
 
73
119
 
74
120
 
@@ -78,9 +124,31 @@
78
124
 
79
125
 
80
126
 
127
+ Botの権限も重要です。
128
+
129
+ Discord Developer PotalでBotをサーバに登録するためのURLを生成するときにBotの権限を指定します。
130
+
131
+ Manage RolesやSend Messagesが必要になります(とりあえず全部与えて試していたので、もしかしたら他にも必要な権限があるかもしれません)。
132
+
133
+ 詳しくは以下の質問の回答が画像付きなのでおすすめです。
134
+
135
+
136
+
137
+ [Discord - How to give my bot permissions. [Javascript] - Stack Overflow](https://stackoverflow.com/questions/50224362/discord-how-to-give-my-bot-permissions-javascript)
138
+
139
+
140
+
141
+ その上で、サーバーの設定画面でBot用の権限(自動で作成されます)が他の権限よりも上に来るように設定しましょう。
142
+
143
+ これをしないと一部のユーザに対して操作できなくなったりするそうです。
144
+
145
+
146
+
81
147
  参考:
82
148
 
149
+ - [Discord Bot 最速チュートリアル【Python&Heroku&GitHub】 ​- Qiita](https://qiita.com/1ntegrale9/items/aa4b373e8895273875a8)
83
150
 
151
+ - [python - Permission error for discord.py bot despite having admin permissions - Stack Overflow](https://stackoverflow.com/questions/67665861/permission-error-for-discord-py-bot-despite-having-admin-permissions)
84
152
 
85
153
  - [discord.py入門(1) - Qiita](https://qiita.com/sizumita/items/9d44ae7d1ce007391699)
86
154
 
@@ -88,4 +156,4 @@
88
156
 
89
157
 
90
158
 
91
- 以上、お役に立てれば幸いです
159
+ 以上、お役に立てれば幸いです

3

コード修正

2021/10/22 16:43

投稿

fj68
fj68

スコア752

test CHANGED
@@ -12,9 +12,13 @@
12
12
 
13
13
  from discord.ext.commands import Bot
14
14
 
15
+ import os
16
+
17
+ import sys
15
18
 
16
19
 
20
+
17
- TOKEN = '...' # ご自分のTOKENに置き換えてください
21
+ TOKEN = '' # ご自分のトークンに置き換えてください
18
22
 
19
23
 
20
24
 
@@ -42,9 +46,17 @@
42
46
 
43
47
  """Bot起動時にroleを取得"""
44
48
 
49
+ global role
50
+
45
51
  guild = bot.get_guild(GUILD_ID)
46
52
 
47
53
  role = guild.get_role(ROLE_ID)
54
+
55
+
56
+
57
+ def is_DM(message):
58
+
59
+ return isinstance(message.channel, discord.DMChannel)
48
60
 
49
61
 
50
62
 
@@ -54,11 +66,7 @@
54
66
 
55
67
  """DM経由かつ合言葉が合っていれば役職を付与"""
56
68
 
57
- if (role is not None
58
-
59
- and isinstance(ctx.message.channel, discord.DMChannel)
60
-
61
- and word == 'ラーメン大好き'):
69
+ if role is not None and is_DM(ctx.message) and word == 'ラーメン大好き':
62
70
 
63
71
  await ctx.message.author.add_roles(role)
64
72
 

2

コード修正

2021/10/22 10:23

投稿

fj68
fj68

スコア752

test CHANGED
@@ -11,6 +11,10 @@
11
11
  import discord
12
12
 
13
13
  from discord.ext.commands import Bot
14
+
15
+
16
+
17
+ TOKEN = '...' # ご自分のTOKENに置き換えてください
14
18
 
15
19
 
16
20
 
@@ -58,6 +62,10 @@
58
62
 
59
63
  await ctx.message.author.add_roles(role)
60
64
 
65
+
66
+
67
+ bot.run(TOKEN)
68
+
61
69
  ```
62
70
 
63
71
 

1

コード修正

2021/10/22 01:52

投稿

fj68
fj68

スコア752

test CHANGED
@@ -50,11 +50,11 @@
50
50
 
51
51
  """DM経由かつ合言葉が合っていれば役職を付与"""
52
52
 
53
- if role is not None
53
+ if (role is not None
54
54
 
55
55
  and isinstance(ctx.message.channel, discord.DMChannel)
56
56
 
57
- and word == 'ラーメン大好き':
57
+ and word == 'ラーメン大好き'):
58
58
 
59
59
  await ctx.message.author.add_roles(role)
60
60