Skip to content

Commit

Permalink
Merge pull request #63 from Cassius0924/feat-all-forwarding
Browse files Browse the repository at this point in the history
[Feature] 消息转发支持来自所有人
  • Loading branch information
Cassius0924 authored Feb 22, 2024
2 parents 31f192f + a8ccd2d commit c603ff6
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 30 deletions.
5 changes: 5 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,9 @@ repos:
hooks:
- id: isort
name: isort (python)
- repo: https://github.com/PyCQA/bandit
rev: 1.7.7
hooks:
- id: bandit
args: ['-c', 'pyproject.toml']

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ python3 -m wechatter
| --- | --- | --- | --- |
| `message_forwarding_enabled` | | 功能开关,是否开启消息转发 | 默认为 `False` |
| `message_forwarding_rule_list` | | 消息规则列表,每个规则包含三个字段:`from_list``to_person_list``to_group_list` | |
| | `from_list` | 消息转发来源列表,即消息发送者 | 可以填多个用户名称或群名称 |
| | `from_list` | 消息转发来源列表,即消息发送者 | 可以填多个用户名称或群名称,若要转发所有消息则使用 `["%ALL"]` |
| | `from_list_exclude` | 消息转发来源排除列表,不转发此列表的用户和群 | 只在 `from_list``["%ALL"]` 时生效 |
| | `to_person_list` | 消息转发目标用户列表,即消息接收用户 | 可以填多个用户名称或为空列表 |
| | `to_group_list` | 消息转发目标群列表,即消息接收群 | 可以填多个群名称或为空列表 |

Expand All @@ -189,7 +190,6 @@ python3 -m wechatter
| `all_task_cron_enabled` | 所有定时任务的总开关 | 默认为 `True` |
| `task_cron_list` | 定时任务列表,每个任务包含四个字段:`task``enabled``cron``commands` | |

[//]: # (引导用户查看定时任务配置详细docs/task_cron_config_detail)
关于定时任务配置详细请参阅[定时任务配置详细](docs/task_cron_config_detail.md)

### ⚙️ Custom Command Key 配置
Expand Down
12 changes: 8 additions & 4 deletions config.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,15 @@ github_webhook_receive_person_list: [ ]
github_webhook_receive_group_list: [ ]

# Message Forwarding:消息转发
message_forwarding_enabled: True
message_forwarding_enabled: False
message_forwarding_rule_list:
- from_list: [ "缘" ]
to_person_list: [ ]
to_group_list: [ "WeChatter" ]
- from_list: [ "%ALL" ]
from_list_exclude: [ "You" ]
to_person_list: [ "You" ]
to_group_list: [ ]
- from_list: [ "Jay", "Tom" ]
to_person_list: [ "Cassius" ]
to_group_list: [ "Team" ]

# Task Cron:定时任务
# 配置说明:https://github.com/Cassius0924/WeChatter/blob/master/docs/task_cron_config_detail.md
Expand Down
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ line_length = 88
multi_line_output = 3
include_trailing_comma = true
combine_as_imports = true


# bandit
[tool.bandit]
skips = ["B101"]
2 changes: 1 addition & 1 deletion wechatter/commands/_commands/trivia.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
desc="获取冷知识。",
)
def trivia_command_handler(to: Union[str, SendTo], message: str = "") -> None:
random_number = random.randint(1, 917)
random_number = random.randint(1, 917) # nosec
try:
response = get_request(
url=f"http://www.quzhishi.com/shiwangelengzhishi/{random_number}.html"
Expand Down
85 changes: 66 additions & 19 deletions wechatter/message/message_forwarder.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List
from typing import Dict, List

from loguru import logger

Expand All @@ -10,38 +10,85 @@
from wechatter.sender import sender


def _forwarding_by_rule(message_obj: Message, rule: Dict):
"""
根据规则转发消息
:param message_obj: 消息对象
:param rule: 规则
"""
# 应用 exclude 规则
# 开始转发消息
to_person_list = rule["to_person_list"]
if message_obj.sender_name in rule.get("from_list_exclude", []):
return
if to_person_list:
msg = _construct_forwarding_message(message_obj)
sender.mass_send_msg(to_person_list, msg, is_group=False)
logger.info(f"转发消息:{message_obj.sender_name} -> {to_person_list}")
to_group_list = rule["to_group_list"]
if to_group_list:
msg = _construct_forwarding_message(message_obj)
sender.mass_send_msg(to_group_list, msg, is_group=True)
logger.info(f"转发消息:{message_obj.sender_name} -> {to_group_list}")


class MessageForwarder:
"""
消息转发器类
"""

def __init__(self, rule_list: List):
self.rule_list = rule_list
"""
初始化
:param rule_list: 转发规则列表
"""
self.all_message_rule = {
"from_list_exclude": [],
"to_group_list": [],
"to_person_list": [],
}
self.specific_message_rules = {}

for rule in rule_list:
if "%ALL" in rule["from_list"]:
self.all_message_rule["from_list_exclude"].extend(
rule.get("from_list_exclude", [])
)
self.all_message_rule["to_group_list"].extend(
rule.get("to_group_list", [])
)
self.all_message_rule["to_person_list"].extend(
rule.get("to_person_list", [])
)
else:
for from_name in rule["from_list"]:
if from_name not in self.specific_message_rules:
self.specific_message_rules[from_name] = {
"to_group_list": [],
"to_person_list": [],
}
self.specific_message_rules[from_name]["to_group_list"].extend(
rule.get("to_group_list", [])
)
self.specific_message_rules[from_name]["to_person_list"].extend(
rule.get("to_person_list", [])
)

def forward_message(self, message_obj: Message):
def forwarding(self, message_obj: Message):
"""
消息转发
:param message_obj: 消息对象
"""
# TODO: 转发文件
from_name = message_obj.sender_name

# TODO: from_list 支持通配符
# 判断消息来源是否符合转发规则
if self.all_message_rule:
rule = self.all_message_rule
_forwarding_by_rule(message_obj, rule)

# 判断消息是否符合转发规则
for rule in self.rule_list:
# 判断消息来源是否符合转发规则
if from_name in rule["from_list"]:
# 构造转发消息
msg = _construct_forwarding_message(message_obj)
to_person_list = rule.get("to_person_list")
if to_person_list:
logger.info(f"转发消息:{from_name} -> {to_person_list}")
sender.mass_send_msg(to_person_list, msg, is_group=False)
to_group_list = rule.get("to_group_list")
if to_group_list:
logger.info(f"转发消息:{from_name} -> {to_group_list}")
sender.mass_send_msg(to_group_list, msg, is_group=True)
if message_obj.sender_name in self.specific_message_rules.keys():
rule = self.specific_message_rules[message_obj.sender_name]
_forwarding_by_rule(message_obj, rule)

@staticmethod
def reply_forwarded_message(message_obj: Message):
Expand Down
6 changes: 4 additions & 2 deletions wechatter/message/message_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ def _get_quoted_response(quotable_id: str) -> QuotedResponse:
return quoted_response


message_forwarder = MessageForwarder(config["message_forwarding_rule_list"])


class MessageHandler:
"""
消息处理器,用于处理用户发来的消息
Expand All @@ -94,8 +97,7 @@ def handle_message(self, message_obj: Message):
"""

if config["message_forwarding_enabled"]:
message_forwarder = MessageForwarder(config["message_forwarding_rule_list"])
message_forwarder.forward_message(message_obj)
message_forwarder.forwarding(message_obj)

if message_obj.forwarded_source:
message_forwarder.reply_forwarded_message(message_obj)
Expand Down
2 changes: 1 addition & 1 deletion wechatter/models/wechat/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def forwarded_source(self) -> Optional[Tuple[str, bool]]:
group_format = GROUP_FORWARDING_MESSAGE_FORMAT.replace("[", "\[").replace(
"]", "\]"
)
pattern = re.compile(f'{group_format % ("(.+)", "(.+)")}')
pattern = re.compile(f'{group_format % ("(.*)", "(.+)")}')
try:
# 将名字和该名字是否为群都返回,便于在回复时判断
return re.search(pattern, self.content).group(2), True
Expand Down
2 changes: 1 addition & 1 deletion wechatter/wechatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def main():

# 启动uvicorn
port = config["wechatter_port"]
uvicorn.run(app, host="0.0.0.0", port=port)
uvicorn.run(app, host="0.0.0.0", port=port) # nosec


if __name__ == "__main__":
Expand Down

0 comments on commit c603ff6

Please sign in to comment.