Spaces:
Running
Running
Improve code, rename command to tree_command, add bot.command
Browse files- discord.json +17 -1
- discord_bot.py +127 -44
discord.json
CHANGED
@@ -7,7 +7,7 @@
|
|
7 |
},
|
8 |
{
|
9 |
"type": "startswith",
|
10 |
-
"content": "
|
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(
|
|
|
|
|
|
|
29 |
tree = bot.tree
|
30 |
|
31 |
|
32 |
-
|
33 |
-
with open("discord.json", "r") as f:
|
34 |
-
json_data = json.load(f)
|
35 |
|
36 |
|
37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
|
39 |
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
for param in parameters])}
|
45 |
'''
|
46 |
-
return result
|
47 |
|
48 |
|
49 |
-
# 生成调用用户自定义的函数的参数
|
50 |
def generate_user_function_param_str(parameters: list = []) -> str:
|
51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
for param in parameters])}'''
|
53 |
-
return result
|
54 |
|
55 |
|
56 |
-
# 生成tree add_command
|
57 |
def generate_tree_add_command(command: dict = {}) -> str:
|
58 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
|
|
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()
|