joytou commited on
Commit
79a7353
·
1 Parent(s): e3c9205

Improve code, rename command to tree_command, add bot.command

Browse files
Files changed (2) hide show
  1. discord.json +17 -1
  2. discord_bot.py +127 -44
discord.json CHANGED
@@ -7,7 +7,7 @@
7
  },
8
  {
9
  "type": "startswith",
10
- "content": "$hello",
11
  "response": "Hello!"
12
  },
13
  {
@@ -17,6 +17,22 @@
17
  }
18
  ],
19
  "command": [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  {
21
  "name": "greet",
22
  "description": "Greets the specified user",
 
7
  },
8
  {
9
  "type": "startswith",
10
+ "content": "hello",
11
  "response": "Hello!"
12
  },
13
  {
 
17
  }
18
  ],
19
  "command": [
20
+ {
21
+ "name": "ping",
22
+ "response": "pong"
23
+ },
24
+ {
25
+ "name": "hello",
26
+ "function": "greet",
27
+ "parameters": [
28
+ {
29
+ "name": "name",
30
+ "type": "str"
31
+ }
32
+ ]
33
+ }
34
+ ],
35
+ "app_command": [
36
  {
37
  "name": "greet",
38
  "description": "Greets the specified user",
discord_bot.py CHANGED
@@ -1,6 +1,7 @@
1
  # This code is based on the following example:
2
  # https://discordpy.readthedocs.io/en/stable/quickstart.html#a-minimal-bot
3
 
 
4
  import os
5
  import discord
6
  from discord import app_commands
@@ -12,6 +13,10 @@ import inspect
12
  from async_eval import eval
13
 
14
 
 
 
 
 
15
 
16
  # 创建一个字典,将规则类型映射到相应的条件检查函数
17
  check_functions = {
@@ -25,61 +30,139 @@ check_functions = {
25
  # 定义bot和tree
26
  intents = discord.Intents.default()
27
  intents.message_content = True
28
- bot = commands.Bot(command_prefix='>', intents=intents)
 
 
 
29
  tree = bot.tree
30
 
31
 
32
- # 读取json
33
- with open("discord.json", "r") as f:
34
- json_data = json.load(f)
35
 
36
 
37
- COMMAND_NAME_PREFIX="discord_bot_call_"
 
 
 
 
 
 
 
 
38
 
39
 
40
- # 生成discord command的callback的调用参数
41
- def generate_discord_command_callback_param_str(parameters: list = []) -> str:
42
- result=f'''
43
- interaction: discord.Interaction{''.join([f", {param['name']}: {param['type']}"
 
 
 
 
 
 
 
44
  for param in parameters])}
45
  '''
46
- return result
47
 
48
 
49
- # 生成调用用户自定义的函数的参数
50
  def generate_user_function_param_str(parameters: list = []) -> str:
51
- result=f'''{', '.join([f"{param['name']}={param['name']}"
 
 
 
 
 
 
 
 
52
  for param in parameters])}'''
53
- return result
54
 
55
 
56
- # 生成tree add_command
57
  def generate_tree_add_command(command: dict = {}) -> str:
58
- result=f'''
 
 
 
 
 
 
 
59
  tree.add_command(app_commands.Command(
60
  name="{command['name']}",
61
  description="{command['description']}",
62
  callback={COMMAND_NAME_PREFIX}{command['name']}
63
  ))
64
  '''
65
- return result
66
 
67
 
68
- # 生成discord command的callback的调用函数
69
  def generate_discord_command_callback_function_str(command: dict = {}) -> str:
70
- result=f'''
71
- async def {COMMAND_NAME_PREFIX}{command['name']}({generate_discord_command_callback_param_str(command['parameters'])}):
 
 
 
 
 
 
 
72
  await interaction.response.defer()
73
- result = await {command['function']}({generate_user_function_param_str(command['parameters'])})
74
  if result is not None:
75
  await interaction.followup.send(result)
76
  '''
77
- return result
78
 
79
 
80
- for command in json_data["command"]:
81
- exec(generate_discord_command_callback_function_str(command))
82
- exec(generate_tree_add_command(command))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
 
85
  async def greet(name: str):
@@ -91,6 +174,7 @@ async def get_kudos():
91
  return f'Error: {details["code"]} {details["reason"]}'
92
  return f'The amount of Kudos this user has is {details["kudos"]}'
93
 
 
94
  async def generate_status(id: str):
95
  async with HordeAPI.generateCheck(id) as details:
96
  if "kudos" not in details:
@@ -115,11 +199,6 @@ async def generate_status(id: str):
115
  return f'Position in queue: {details["queue_position"]}, wait time: {details["wait_time"]}s'
116
 
117
 
118
- @bot.command()
119
- async def ping(ctx):
120
- await ctx.send('pong')
121
-
122
-
123
  @bot.event
124
  async def on_ready():
125
  await tree.sync()
@@ -132,20 +211,21 @@ async def on_message(message):
132
  if message.author == bot.user:
133
  return
134
 
135
- for rule in json_data["message"]:
136
- rule_type = rule["type"]
137
- content = rule["content"]
138
-
139
- # 根据规则类型动态调用对应的判断函数
140
- if check_functions.get(rule_type, lambda c, m: False)(content, message):
141
- # 如果规则指定了函数,则调用对应的函数
142
- if "function" in rule:
143
- function_name = rule["function"]
144
- result = eval(f"await {function_name}()")
145
- await message.channel.send(result)
146
- # 否则发送预定义的响应消息
147
- elif "response" in rule:
148
- await message.channel.send(rule["response"])
 
149
 
150
  # 确保命令系统正常工作
151
  await bot.process_commands(message)
@@ -184,7 +264,7 @@ def sendMessageToChannel(data):
184
 
185
  def run():
186
  try:
187
- token = os.environ.get("TOKEN") or ""
188
  if token == "":
189
  raise Exception("Please add your token to the Secrets pane.")
190
  bot.run(token)
@@ -203,3 +283,6 @@ def run():
203
  def discord_bot():
204
  print("Running discord_bot")
205
  run()
 
 
 
 
1
  # This code is based on the following example:
2
  # https://discordpy.readthedocs.io/en/stable/quickstart.html#a-minimal-bot
3
 
4
+ import sys
5
  import os
6
  import discord
7
  from discord import app_commands
 
13
  from async_eval import eval
14
 
15
 
16
+ # 读取json
17
+ with open("discord.json", "r") as f:
18
+ json_data = json.load(f)
19
+
20
 
21
  # 创建一个字典,将规则类型映射到相应的条件检查函数
22
  check_functions = {
 
30
  # 定义bot和tree
31
  intents = discord.Intents.default()
32
  intents.message_content = True
33
+ bot = commands.Bot(
34
+ command_prefix=json_data["command_prefix"] if "command_prefix" in json_data else '>',
35
+ intents=intents
36
+ )
37
  tree = bot.tree
38
 
39
 
40
+ COMMAND_NAME_PREFIX=json_data["command_name_prefix"] if "command_name_prefix" in json_data else "discord_bot_call_"
 
 
41
 
42
 
43
+ def load_module_by_function_name(name: str = ""):
44
+ """
45
+ 根据函数名称,导入对应的模块
46
+ Args:
47
+ name: 函数名称
48
+ """
49
+ module_name=name.split(".")[0]
50
+ if name.find(".") > 0 and module_name not in sys.modules:
51
+ exec(f"import {module_name}")
52
 
53
 
54
+ def generate_discord_command_callback_param_str(pre: str = '', parameters: list = []) -> str:
55
+ """
56
+ 生成discord command的callback的调用参数
57
+ Args:
58
+ pre: 前置固定参数
59
+ parameters: 参数列表
60
+ Returns:
61
+ string: 生成的调用参数的代码
62
+ """
63
+ return f'''
64
+ {pre}{''.join([f", {param['name']}: {param['type']}"
65
  for param in parameters])}
66
  '''
 
67
 
68
 
 
69
  def generate_user_function_param_str(parameters: list = []) -> str:
70
+ """
71
+ 生成调用用户自定义的函数的参数
72
+ Args:
73
+ parameters: 参数列表
74
+ Returns:
75
+ str: 生成的调用参数的代码
76
+
77
+ """
78
+ return f'''{', '.join([f"{param['name']}={param['name']}"
79
  for param in parameters])}'''
 
80
 
81
 
 
82
  def generate_tree_add_command(command: dict = {}) -> str:
83
+ """
84
+ 生成tree add_command
85
+ Args:
86
+ command: command
87
+ Returns:
88
+ str: 生成的调用代码
89
+ """
90
+ return f'''
91
  tree.add_command(app_commands.Command(
92
  name="{command['name']}",
93
  description="{command['description']}",
94
  callback={COMMAND_NAME_PREFIX}{command['name']}
95
  ))
96
  '''
 
97
 
98
 
 
99
  def generate_discord_command_callback_function_str(command: dict = {}) -> str:
100
+ """
101
+ 生成discord command的callback的调用函数
102
+ Args:
103
+ command: command
104
+ Returns:
105
+ str: 生成的调用代码
106
+ """
107
+ return f'''
108
+ async def {COMMAND_NAME_PREFIX}{command['name']}({generate_discord_command_callback_param_str('interaction: discord.Interaction', command['parameters'] if 'parameters' in command else [])}):
109
  await interaction.response.defer()
110
+ result = await {command['function']}({generate_user_function_param_str(command['parameters'] if 'parameters' in command else [])})
111
  if result is not None:
112
  await interaction.followup.send(result)
113
  '''
 
114
 
115
 
116
+ def generate_bot_command_send(command: dict = {}) -> str:
117
+ """
118
+ 生成bot.command的send语句
119
+ Args:
120
+ command: command
121
+ Returns:
122
+ str: 生成的调用代码
123
+ """
124
+ return f'''await ctx.send(\"{command['response']}\")'''
125
+
126
+
127
+ def generate_bot_command_callback(command: dict = {}) -> str:
128
+ """
129
+ 生成bot.command的调用用户函数和send语句
130
+ Args:
131
+ command: command
132
+ Returns:
133
+ str: 生成的调用代码
134
+ """
135
+ return f'''result = await {command['function']}({generate_user_function_param_str(command['parameters'] if 'parameters' in command else [])})
136
+ await ctx.send(result)'''
137
+
138
+
139
+ def generate_bot_command_def(command: dict = {}) -> str:
140
+ """
141
+ 生成bot.command的定义函数
142
+ Args:
143
+ command: command
144
+ Returns:
145
+ str: 生成的调用代码
146
+ """
147
+ return f'''
148
+ @bot.command()
149
+ async def {command['name']}({generate_discord_command_callback_param_str('ctx', command['parameters'] if 'parameters' in command else [])}):
150
+ {generate_bot_command_send(command) if "response" in command else generate_bot_command_callback(command)}
151
+ '''
152
+
153
+
154
+ if "app_command" in json_data:
155
+ for command in json_data["app_command"]:
156
+ load_module_by_function_name(command["function"])
157
+ exec(generate_discord_command_callback_function_str(command))
158
+ exec(generate_tree_add_command(command))
159
+
160
+
161
+ if "command" in json_data:
162
+ for command in json_data["command"]:
163
+ if "function" in command:
164
+ load_module_by_function_name(command["function"])
165
+ exec(generate_bot_command_def(command))
166
 
167
 
168
  async def greet(name: str):
 
174
  return f'Error: {details["code"]} {details["reason"]}'
175
  return f'The amount of Kudos this user has is {details["kudos"]}'
176
 
177
+
178
  async def generate_status(id: str):
179
  async with HordeAPI.generateCheck(id) as details:
180
  if "kudos" not in details:
 
199
  return f'Position in queue: {details["queue_position"]}, wait time: {details["wait_time"]}s'
200
 
201
 
 
 
 
 
 
202
  @bot.event
203
  async def on_ready():
204
  await tree.sync()
 
211
  if message.author == bot.user:
212
  return
213
 
214
+ if "message" in json_data:
215
+ for rule in json_data["message"]:
216
+ rule_type = rule["type"]
217
+ content = rule["content"]
218
+
219
+ # 根据规则类型动态调用对应的判断函数
220
+ if check_functions.get(rule_type, lambda c, m: False)(content, message):
221
+ # 如果规则指定了函数,则调用对应的函数
222
+ if "function" in rule:
223
+ function_name = rule["function"]
224
+ result = eval(f"await {function_name}()")
225
+ await message.channel.send(result)
226
+ # 否则发送预定义的响应消息
227
+ elif "response" in rule:
228
+ await message.channel.send(rule["response"])
229
 
230
  # 确保命令系统正常工作
231
  await bot.process_commands(message)
 
264
 
265
  def run():
266
  try:
267
+ token = json_data["token"] if "token" in json_data else (os.environ.get("TOKEN") or "")
268
  if token == "":
269
  raise Exception("Please add your token to the Secrets pane.")
270
  bot.run(token)
 
283
  def discord_bot():
284
  print("Running discord_bot")
285
  run()
286
+
287
+ if __name__ == "__main__":
288
+ discord_bot()