mirror of
https://github.com/TeamPGM/PagerMaid_Plugins.git
synced 2024-11-25 12:51:04 +00:00
keyword 更新,添加回复文件功能,添加频率限制 (#111)
1. 回复文件 ( file,reply::file_name file_path ) 2. 频率限制,每个群组独立,可以设置,-replyset freq 最短发送间隔
This commit is contained in:
parent
63ffb39d99
commit
928a3ad4c3
262
keyword.py
262
keyword.py
@ -1,10 +1,13 @@
|
|||||||
import re, time, asyncio, requests
|
import re, time, asyncio, requests
|
||||||
from os import path, mkdir, remove
|
from os import path, mkdir, remove
|
||||||
|
from shutil import copyfile
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from base64 import b64encode, b64decode
|
from base64 import b64encode, b64decode
|
||||||
from pagermaid import bot, redis, log, redis_status
|
from pagermaid import bot, redis, log, redis_status
|
||||||
from pagermaid.listener import listener
|
from pagermaid.listener import listener
|
||||||
|
|
||||||
|
msg_freq = 1
|
||||||
|
group_last_time = {}
|
||||||
read_context = {}
|
read_context = {}
|
||||||
|
|
||||||
def is_num(x: str):
|
def is_num(x: str):
|
||||||
@ -74,7 +77,7 @@ def parse_multi(rule: str):
|
|||||||
n_rule.append(data)
|
n_rule.append(data)
|
||||||
return n_rule
|
return n_rule
|
||||||
|
|
||||||
def get_capture(search_data, group_name):
|
def get_capture(search_data, group_name: str):
|
||||||
try:
|
try:
|
||||||
capture_data = search_data.group(group_name)
|
capture_data = search_data.group(group_name)
|
||||||
return capture_data
|
return capture_data
|
||||||
@ -85,12 +88,27 @@ def get_rule(chat_id, rule_type, rule_index):
|
|||||||
rule_index = int(rule_index)
|
rule_index = int(rule_index)
|
||||||
rule_data = get_redis(f"keyword.{chat_id}.{rule_type}")
|
rule_data = get_redis(f"keyword.{chat_id}.{rule_type}")
|
||||||
index = 0
|
index = 0
|
||||||
for k, v in rule_data.items():
|
for k in rule_data.keys():
|
||||||
if index == rule_index:
|
if index == rule_index:
|
||||||
return encode(k)
|
return encode(k)
|
||||||
index += 1
|
index += 1
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def valid_time(chat_id):
|
||||||
|
global msg_freq, group_last_time
|
||||||
|
cus_rate = get_redis(f"keyword.{chat_id}.settings").get("freq", msg_freq)
|
||||||
|
if cus_rate and is_num(str(cus_rate, "ascii")):
|
||||||
|
msg_freq = float(cus_rate)
|
||||||
|
n_time = time.time()
|
||||||
|
chat_id = int(chat_id)
|
||||||
|
if chat_id in group_last_time:
|
||||||
|
if n_time - group_last_time[chat_id] >= msg_freq:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
async def del_msg(context, t_lim):
|
async def del_msg(context, t_lim):
|
||||||
await asyncio.sleep(t_lim)
|
await asyncio.sleep(t_lim)
|
||||||
try:
|
try:
|
||||||
@ -99,38 +117,60 @@ async def del_msg(context, t_lim):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
async def send_reply(chat_id, reply_msg, context):
|
async def send_reply(chat_id, reply_msg, context):
|
||||||
chat = context.chat
|
try:
|
||||||
sender = context.sender
|
chat = context.chat
|
||||||
replace_data = {
|
sender = context.sender
|
||||||
"user_id": sender.id,
|
replace_data = {
|
||||||
"first_name": sender.first_name,
|
"user_id": sender.id,
|
||||||
"last_name": sender.last_name if sender.last_name else "",
|
"first_name": sender.first_name,
|
||||||
"chat_id": chat.id,
|
"last_name": sender.last_name if sender.last_name else "",
|
||||||
"chat_name": chat.title
|
"chat_id": chat.id,
|
||||||
}
|
"chat_name": chat.title
|
||||||
for re_type, re_msg in reply_msg:
|
}
|
||||||
for k, v in replace_data.items():
|
update_last_time = False
|
||||||
re_msg = re_msg.replace(f"${k}", str(v))
|
could_send_msg = valid_time(chat_id)
|
||||||
if re_type == "plain":
|
for re_type, re_msg in reply_msg:
|
||||||
await bot.send_message(chat_id, re_msg)
|
for k, v in replace_data.items():
|
||||||
elif re_type == "reply":
|
re_msg = re_msg.replace(f"${k}", str(v))
|
||||||
await bot.send_message(chat_id, re_msg, reply_to = context.id)
|
type_parse = re_type.split(",")
|
||||||
elif re_type == "file" and len(re_msg.split()) >= 2:
|
if "plain" in type_parse:
|
||||||
if not path.exists("/tmp"): mkdir("/tmp")
|
if could_send_msg:
|
||||||
re_data = re_msg.split()
|
update_last_time = True
|
||||||
file_name = "/tmp/" + re_data[0]
|
await bot.send_message(chat_id, re_msg, reply_to = None)
|
||||||
file_get = requests.get(" ".join(re_data[1: ]))
|
elif "reply" in type_parse:
|
||||||
with open(file_name, "wb") as f:
|
if could_send_msg:
|
||||||
f.write(file_get.content)
|
update_last_time = True
|
||||||
await bot.send_file(chat_id, file_name)
|
await bot.send_message(chat_id, re_msg, reply_to = context.id)
|
||||||
remove(file_name)
|
elif "file" in type_parse and len(re_msg.split()) >= 2:
|
||||||
elif re_type == "op":
|
if could_send_msg:
|
||||||
if re_msg == "delete":
|
update_last_time = True
|
||||||
await context.delete()
|
if not path.exists("/tmp"):
|
||||||
elif re_msg.split()[0] == "sleep" and len(re_msg.split()) == 2:
|
mkdir("/tmp")
|
||||||
sleep_time = re_msg.split()[1]
|
re_data = re_msg.split()
|
||||||
if is_num(sleep_time):
|
file_name = "/tmp/" + re_data[0]
|
||||||
await asyncio.sleep(int(sleep_time))
|
if re_data[1][0:7] == "file://":
|
||||||
|
copyfile(re_data[1][7:], file_name)
|
||||||
|
else:
|
||||||
|
file_get = requests.get(" ".join(re_data[1:]))
|
||||||
|
with open(file_name, "wb") as f:
|
||||||
|
f.write(file_get.content)
|
||||||
|
reply_to = None
|
||||||
|
if "reply" in re_type.split(","):
|
||||||
|
reply_to = context.id
|
||||||
|
await bot.send_file(chat_id, file_name, reply_to = reply_to, force_document = True)
|
||||||
|
remove(file_name)
|
||||||
|
elif "op" in type_parse:
|
||||||
|
if re_msg == "delete":
|
||||||
|
await context.delete()
|
||||||
|
elif re_msg.split()[0] == "sleep" and len(re_msg.split()) == 2:
|
||||||
|
sleep_time = re_msg.split()[1]
|
||||||
|
if is_num(sleep_time):
|
||||||
|
await asyncio.sleep(int(sleep_time))
|
||||||
|
if update_last_time:
|
||||||
|
global group_last_time
|
||||||
|
group_last_time[int(chat_id)] = time.time()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
@listener(is_plugin=True, outgoing=True, command="keyword",
|
@listener(is_plugin=True, outgoing=True, command="keyword",
|
||||||
description="关键词自动回复",
|
description="关键词自动回复",
|
||||||
@ -160,7 +200,8 @@ async def reply(context):
|
|||||||
await context.edit("[Code: -1] 格式错误,格式为 `-keyword` 加上 `new <plain|regex> '<规则>' '<回复信息>'` 或者 `del <plain|regex> '<规则>'` 或者 `list` 或者 `clear <plain|regex>`")
|
await context.edit("[Code: -1] 格式错误,格式为 `-keyword` 加上 `new <plain|regex> '<规则>' '<回复信息>'` 或者 `del <plain|regex> '<规则>'` 或者 `list` 或者 `clear <plain|regex>`")
|
||||||
await del_msg(context, 10)
|
await del_msg(context, 10)
|
||||||
return
|
return
|
||||||
else: parse[0] = parse[0].split()
|
else:
|
||||||
|
parse[0] = parse[0].split()
|
||||||
if parse[0][0] == "new" and len(parse) == 3:
|
if parse[0][0] == "new" and len(parse) == 3:
|
||||||
if parse[0][1] == "plain":
|
if parse[0][1] == "plain":
|
||||||
plain_dict[parse[1]] = parse[2]
|
plain_dict[parse[1]] = parse[2]
|
||||||
@ -177,7 +218,8 @@ async def reply(context):
|
|||||||
elif parse[0][0] in ("del", "delid") and len(parse) == 2:
|
elif parse[0][0] in ("del", "delid") and len(parse) == 2:
|
||||||
if parse[0][0] == "delid":
|
if parse[0][0] == "delid":
|
||||||
parse[1] = get_rule(chat_id, parse[0][1], parse[1])
|
parse[1] = get_rule(chat_id, parse[0][1], parse[1])
|
||||||
if parse[1]: parse[1] = decode(parse[1])
|
if parse[1]:
|
||||||
|
parse[1] = decode(parse[1])
|
||||||
if parse[0][1] == "plain":
|
if parse[0][1] == "plain":
|
||||||
if parse[1] and parse[1] in plain_dict:
|
if parse[1] and parse[1] in plain_dict:
|
||||||
redis.delete(f"keyword.{chat_id}.single.plain.{encode(parse[1])}")
|
redis.delete(f"keyword.{chat_id}.single.plain.{encode(parse[1])}")
|
||||||
@ -258,8 +300,8 @@ async def reply_set(context):
|
|||||||
redis_data = f"keyword.{chat_id}.single.{params[0]}.{rule_data}"
|
redis_data = f"keyword.{chat_id}.single.{params[0]}.{rule_data}"
|
||||||
del params[0:2]
|
del params[0:2]
|
||||||
settings_dict = get_redis(redis_data)
|
settings_dict = get_redis(redis_data)
|
||||||
cmd_list = ["help", "mode", "list", "show", "clear"]
|
cmd_list = ["help", "mode", "list", "freq", "show", "clear"]
|
||||||
cmd_dict = {"help": (1, ), "mode": (2, ), "list": (2, 3), "show": (1, ), "clear": (1, )}
|
cmd_dict = {"help": (1, ), "mode": (2, ), "list": (2, 3), "freq": (2, ), "show": (1, ), "clear": (1, )}
|
||||||
if len(params) < 1:
|
if len(params) < 1:
|
||||||
await context.edit("参数错误")
|
await context.edit("参数错误")
|
||||||
await del_msg(context, 5)
|
await del_msg(context, 5)
|
||||||
@ -275,7 +317,7 @@ async def reply_set(context):
|
|||||||
await del_msg(context, 15)
|
await del_msg(context, 15)
|
||||||
return
|
return
|
||||||
elif params[0] == "show":
|
elif params[0] == "show":
|
||||||
defaults = {"mode": "未设置", "list": "未设置"}
|
defaults = {"mode": "未设置", "list": "未设置", "freq": "未设置"}
|
||||||
msg = "Settings: \n"
|
msg = "Settings: \n"
|
||||||
for k, v in defaults.items():
|
for k, v in defaults.items():
|
||||||
msg += f"`{k}` -> `{settings_dict[k] if k in settings_dict else v}`\n"
|
msg += f"`{k}` -> `{settings_dict[k] if k in settings_dict else v}`\n"
|
||||||
@ -285,12 +327,15 @@ async def reply_set(context):
|
|||||||
if params[1] in ("0", "1"):
|
if params[1] in ("0", "1"):
|
||||||
settings_dict["mode"] = params[1]
|
settings_dict["mode"] = params[1]
|
||||||
redis.set(redis_data, save_rules(settings_dict, None))
|
redis.set(redis_data, save_rules(settings_dict, None))
|
||||||
if params[1] == "0": await context.edit("模式已更改为黑名单")
|
if params[1] == "0":
|
||||||
elif params[1] == "1": await context.edit("模式已更改为白名单")
|
await context.edit("模式已更改为黑名单")
|
||||||
|
elif params[1] == "1":
|
||||||
|
await context.edit("模式已更改为白名单")
|
||||||
await del_msg(context, 5)
|
await del_msg(context, 5)
|
||||||
return
|
return
|
||||||
elif params[1] == "clear":
|
elif params[1] == "clear":
|
||||||
if "mode" in settings_dict: del settings_dict["mode"]
|
if "mode" in settings_dict:
|
||||||
|
del settings_dict["mode"]
|
||||||
redis.set(redis_data, save_rules(settings_dict, None))
|
redis.set(redis_data, save_rules(settings_dict, None))
|
||||||
await context.edit("清除成功")
|
await context.edit("清除成功")
|
||||||
await del_msg(context, 5)
|
await del_msg(context, 5)
|
||||||
@ -315,8 +360,10 @@ async def reply_set(context):
|
|||||||
elif params[1] == "add" and len(params) == 3:
|
elif params[1] == "add" and len(params) == 3:
|
||||||
if is_num(params[2]):
|
if is_num(params[2]):
|
||||||
tmp = settings_dict.get("list", None)
|
tmp = settings_dict.get("list", None)
|
||||||
if not tmp: settings_dict["list"] = params[2]
|
if not tmp:
|
||||||
else: settings_dict["list"] += f",{params[2]}"
|
settings_dict["list"] = params[2]
|
||||||
|
else:
|
||||||
|
settings_dict["list"] += f",{params[2]}"
|
||||||
redis.set(redis_data, save_rules(settings_dict, None))
|
redis.set(redis_data, save_rules(settings_dict, None))
|
||||||
await context.edit("添加成功")
|
await context.edit("添加成功")
|
||||||
await del_msg(context, 5)
|
await del_msg(context, 5)
|
||||||
@ -350,7 +397,8 @@ async def reply_set(context):
|
|||||||
await del_msg(context, 5)
|
await del_msg(context, 5)
|
||||||
return
|
return
|
||||||
elif params[1] == "clear" and len(params) == 2:
|
elif params[1] == "clear" and len(params) == 2:
|
||||||
if "list" in settings_dict: del settings_dict["list"]
|
if "list" in settings_dict:
|
||||||
|
del settings_dict["list"]
|
||||||
redis.set(redis_data, save_rules(settings_dict, None))
|
redis.set(redis_data, save_rules(settings_dict, None))
|
||||||
await context.edit("清除成功")
|
await context.edit("清除成功")
|
||||||
await del_msg(context, 5)
|
await del_msg(context, 5)
|
||||||
@ -359,6 +407,31 @@ async def reply_set(context):
|
|||||||
await context.edit("参数错误")
|
await context.edit("参数错误")
|
||||||
await del_msg(context, 5)
|
await del_msg(context, 5)
|
||||||
return
|
return
|
||||||
|
elif params[0] == "freq":
|
||||||
|
if params[1] == "clear":
|
||||||
|
if "freq" in settings_dict:
|
||||||
|
del settings_dict["freq"]
|
||||||
|
redis.set(redis_data, save_rules(settings_dict, None))
|
||||||
|
await context.edit("清除成功")
|
||||||
|
await del_msg(context, 5)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
tmp = float(params[1])
|
||||||
|
if tmp > 0:
|
||||||
|
settings_dict["freq"] = params[1]
|
||||||
|
redis.set(redis_data, save_rules(settings_dict, None))
|
||||||
|
await context.edit("设置成功")
|
||||||
|
await del_msg(context, 5)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
await context.edit("频率需为正数")
|
||||||
|
await del_msg(context, 5)
|
||||||
|
return
|
||||||
|
except:
|
||||||
|
await context.edit("频率需为正数")
|
||||||
|
await del_msg(context, 5)
|
||||||
|
return
|
||||||
elif params[0] == "clear":
|
elif params[0] == "clear":
|
||||||
redis.delete(redis_data)
|
redis.delete(redis_data)
|
||||||
await context.edit("清除成功")
|
await context.edit("清除成功")
|
||||||
@ -377,49 +450,56 @@ async def auto_reply(context):
|
|||||||
chat_id = context.chat_id
|
chat_id = context.chat_id
|
||||||
sender_id = context.sender_id
|
sender_id = context.sender_id
|
||||||
if chat_id < 0:
|
if chat_id < 0:
|
||||||
plain_dict = get_redis(f"keyword.{chat_id}.plain")
|
if context.id not in read_context:
|
||||||
regex_dict = get_redis(f"keyword.{chat_id}.regex")
|
plain_dict = get_redis(f"keyword.{chat_id}.plain")
|
||||||
g_settings = get_redis("keyword.settings")
|
regex_dict = get_redis(f"keyword.{chat_id}.regex")
|
||||||
n_settings = get_redis(f"keyword.{chat_id}.settings")
|
g_settings = get_redis("keyword.settings")
|
||||||
g_mode = g_settings.get("mode", None)
|
n_settings = get_redis(f"keyword.{chat_id}.settings")
|
||||||
n_mode = n_settings.get("mode", None)
|
g_mode = g_settings.get("mode", None)
|
||||||
mode = "0"
|
n_mode = n_settings.get("mode", None)
|
||||||
g_list = g_settings.get("list", None)
|
mode = "0"
|
||||||
n_list = n_settings.get("list", None)
|
g_list = g_settings.get("list", None)
|
||||||
user_list = []
|
n_list = n_settings.get("list", None)
|
||||||
if g_mode and n_mode: mode = n_mode
|
user_list = []
|
||||||
elif g_mode or n_mode: mode = g_mode if g_mode else n_mode
|
if g_mode and n_mode:
|
||||||
if g_list and n_list: user_list = n_list
|
mode = n_mode
|
||||||
elif g_list or n_list: user_list = g_list if g_list else n_list
|
elif g_mode or n_mode:
|
||||||
send_text = context.text
|
mode = g_mode if g_mode else n_mode
|
||||||
for k, v in plain_dict.items():
|
if g_list and n_list:
|
||||||
if k in send_text and context.id not in read_context:
|
user_list = n_list
|
||||||
tmp = get_redis(f"keyword.{chat_id}.single.plain.{encode(k)}")
|
elif g_list or n_list:
|
||||||
could_reply = validate(str(sender_id), int(mode), user_list)
|
user_list = g_list if g_list else n_list
|
||||||
if tmp:
|
send_text = context.text
|
||||||
could_reply = validate(str(sender_id), int(tmp.get("mode", "0")), tmp.get("list", []))
|
for k, v in plain_dict.items():
|
||||||
if could_reply:
|
if k in send_text:
|
||||||
read_context[context.id] = None
|
tmp = get_redis(f"keyword.{chat_id}.single.plain.{encode(k)}")
|
||||||
await send_reply(chat_id, parse_multi(v), context)
|
could_reply = validate(str(sender_id), int(mode), user_list)
|
||||||
for k, v in regex_dict.items():
|
if tmp:
|
||||||
pattern = re.compile(k)
|
could_reply = validate(str(sender_id), int(tmp.get("mode", "0")), tmp.get("list", []))
|
||||||
if pattern.search(send_text) and context.id not in read_context:
|
if could_reply:
|
||||||
tmp = get_redis(f"keyword.{chat_id}.single.regex.{encode(k)}")
|
read_context[context.id] = None
|
||||||
could_reply = validate(str(sender_id), int(mode), user_list)
|
await send_reply(chat_id, parse_multi(v), context)
|
||||||
if tmp:
|
for k, v in regex_dict.items():
|
||||||
could_reply = validate(str(sender_id), int(tmp.get("mode", "0")), tmp.get("list", []))
|
pattern = re.compile(k)
|
||||||
if could_reply:
|
if pattern.search(send_text):
|
||||||
read_context[context.id] = None
|
tmp = get_redis(f"keyword.{chat_id}.single.regex.{encode(k)}")
|
||||||
catch_pattern = r"\$\{regex_(?P<str>((?!\}).)+)\}"
|
could_reply = validate(str(sender_id), int(mode), user_list)
|
||||||
count = 0
|
if tmp:
|
||||||
while re.search(catch_pattern, v) and count < 20:
|
could_reply = validate(str(sender_id), int(tmp.get("mode", "0")), tmp.get("list", []))
|
||||||
search_data = re.search(k, send_text)
|
if could_reply:
|
||||||
group_name = re.search(catch_pattern, v).group("str")
|
read_context[context.id] = None
|
||||||
capture_data = get_capture(search_data, group_name)
|
catch_pattern = r"\$\{regex_(?P<str>((?!\}).)+)\}"
|
||||||
if not capture_data: capture_data = ""
|
count = 0
|
||||||
if re.search(catch_pattern, capture_data): capture_data = ""
|
while re.search(catch_pattern, v) and count < 20:
|
||||||
v = v.replace("${regex_%s}" % group_name, capture_data)
|
search_data = re.search(k, send_text)
|
||||||
count += 1
|
group_name = re.search(catch_pattern, v).group("str")
|
||||||
await send_reply(chat_id, parse_multi(v), context)
|
capture_data = get_capture(search_data, group_name)
|
||||||
if context.id in read_context:
|
if not capture_data:
|
||||||
del read_context[context.id]
|
capture_data = ""
|
||||||
|
if re.search(catch_pattern, capture_data):
|
||||||
|
capture_data = ""
|
||||||
|
v = v.replace("${regex_%s}" % group_name, capture_data)
|
||||||
|
count += 1
|
||||||
|
await send_reply(chat_id, parse_multi(v), context)
|
||||||
|
else:
|
||||||
|
del read_context[context.id]
|
||||||
|
@ -362,10 +362,10 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "keyword",
|
"name": "keyword",
|
||||||
"version": "2.03",
|
"version": "2.1",
|
||||||
"section": "chat",
|
"section": "chat",
|
||||||
"maintainer": "c3b2a",
|
"maintainer": "c3b2a",
|
||||||
"size": "17.3 kb",
|
"size": "20.3 kb",
|
||||||
"supported": true,
|
"supported": true,
|
||||||
"des-short": "群组关键词自动回复插件",
|
"des-short": "群组关键词自动回复插件",
|
||||||
"des": "命令: keyword, replyset。"
|
"des": "命令: keyword, replyset。"
|
||||||
|
Loading…
Reference in New Issue
Block a user