mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-14 21:52:56 +08:00
✨ 使用uninfo进行群组成员更新 (#1690)
This commit is contained in:
parent
2f459719e8
commit
9e5266a491
22
poetry.lock
generated
22
poetry.lock
generated
@ -2511,6 +2511,26 @@ type = "legacy"
|
||||
url = "https://mirrors.aliyun.com/pypi/simple"
|
||||
reference = "ali"
|
||||
|
||||
[[package]]
|
||||
name = "nonebot-plugin-uninfo"
|
||||
version = "0.4.0"
|
||||
description = "Universal Information Model for Nonebot2"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "nonebot_plugin_uninfo-0.4.0-py3-none-any.whl", hash = "sha256:d60a8491af52b1b2c0cdb3f2e4a4a8d02e66216a33e8d162f1da8bec73b3b701"},
|
||||
{file = "nonebot_plugin_uninfo-0.4.0.tar.gz", hash = "sha256:3e1a494d05639a0227a8565d5cde90ec9724934a7ec32bf1e0bd40404faf9713"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
importlib-metadata = ">=4.13.0"
|
||||
nonebot2 = ">=2.3.0"
|
||||
|
||||
[package.source]
|
||||
type = "legacy"
|
||||
url = "https://mirrors.aliyun.com/pypi/simple"
|
||||
reference = "ali"
|
||||
|
||||
[[package]]
|
||||
name = "nonebot-plugin-userinfo"
|
||||
version = "0.1.3"
|
||||
@ -4925,4 +4945,4 @@ reference = "ali"
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "e66133515a2b17715ddf5f887ec31f128751acda1ea67736e9d27b29a9b16b65"
|
||||
content-hash = "527819a6117da3c41931d968f9238468aee98f2ca97f06e1ba1e7948b6cbe65c"
|
||||
|
||||
@ -51,6 +51,7 @@ nonebot-plugin-alconna = "0.51.1"
|
||||
arclet-alconna = "1.8.23"
|
||||
aiocache = "^0.12.2"
|
||||
py-cpuinfo = "^9.0.0"
|
||||
nonebot-plugin-uninfo = "^0.4.1"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
nonebug = "^0.3.2"
|
||||
|
||||
@ -49,18 +49,15 @@ _notice = on_notice(priority=1, block=False, rule=notice_rule(GroupIncreaseNotic
|
||||
async def _(bot: Bot, session: EventSession, arparma: Arparma):
|
||||
if gid := session.id3 or session.id2:
|
||||
logger.info("更新群组成员信息", arparma.header_result, session=session)
|
||||
await MemberUpdateManage.update(bot, gid)
|
||||
await MessageUtils.build_message("已经成功更新了群组成员信息!").finish(
|
||||
reply_to=True
|
||||
)
|
||||
result = await MemberUpdateManage.update_group_member(bot, gid)
|
||||
await MessageUtils.build_message(result).finish(reply_to=True)
|
||||
await MessageUtils.build_message("群组id为空...").send()
|
||||
|
||||
|
||||
@_notice.handle()
|
||||
async def _(bot: Bot, event: GroupIncreaseNoticeEvent):
|
||||
# TODO: 其他适配器的加群自动更新群组成员信息
|
||||
if str(event.user_id) == bot.self_id:
|
||||
await MemberUpdateManage.update(bot, str(event.group_id))
|
||||
await MemberUpdateManage.update_group_member(bot, str(event.group_id))
|
||||
logger.info(
|
||||
f"{BotConfig.self_nickname}加入群聊更新群组信息",
|
||||
"更新群组成员列表",
|
||||
@ -81,7 +78,9 @@ async def _():
|
||||
if group_list:
|
||||
for group in group_list:
|
||||
try:
|
||||
await MemberUpdateManage.update(bot, group.group_id)
|
||||
await MemberUpdateManage.update_group_member(
|
||||
bot, group.group_id
|
||||
)
|
||||
logger.debug("自动更新群组成员信息成功...")
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
|
||||
@ -1,213 +1,129 @@
|
||||
from datetime import datetime, timezone, timedelta
|
||||
|
||||
import nonebot
|
||||
from nonebot.adapters import Bot
|
||||
|
||||
# from nonebot.adapters.kaiheila import Bot as KaiheilaBot
|
||||
from nonebot.adapters.onebot.v11 import Bot as v11Bot
|
||||
from nonebot.adapters.onebot.v12 import Bot as v12Bot
|
||||
from nonebot_plugin_uninfo import Member, SceneType, get_interface
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.configs.config import Config
|
||||
from zhenxun.models.level_user import LevelUser
|
||||
from zhenxun.utils.platform import PlatformUtils
|
||||
from zhenxun.models.group_member_info import GroupInfoUser
|
||||
|
||||
# from nonebot.adapters.discord import Bot as DiscordBot
|
||||
# from nonebot.adapters.dodo import Bot as DodoBot
|
||||
|
||||
|
||||
class MemberUpdateManage:
|
||||
|
||||
@classmethod
|
||||
async def update(cls, bot: Bot, group_id: str):
|
||||
if not group_id:
|
||||
return logger.warning(
|
||||
f"bot: {bot.self_id},group_id为空,无法更新群成员信息..."
|
||||
)
|
||||
if isinstance(bot, v11Bot):
|
||||
await cls.v11(bot, group_id)
|
||||
elif isinstance(bot, v12Bot):
|
||||
await cls.v12(bot, group_id)
|
||||
# elif isinstance(bot, KaiheilaBot):
|
||||
# await cls.kaiheila(bot, group_id)
|
||||
# elif isinstance(bot, DodoBot):
|
||||
# await cls.dodo(bot, group_id)
|
||||
# elif isinstance(bot, DiscordBot):
|
||||
# await cls.discord(bot, group_id)
|
||||
async def __handle_user(
|
||||
cls,
|
||||
member: Member,
|
||||
db_user: list[GroupInfoUser],
|
||||
group_id: str,
|
||||
data_list: tuple[list, list, list],
|
||||
platform: str | None,
|
||||
):
|
||||
"""单个成员操作
|
||||
|
||||
# @classmethod
|
||||
# async def discord(cls, bot: DiscordBot, group_id: str):
|
||||
# # TODO: discord更新群组成员信息
|
||||
# pass
|
||||
|
||||
# @classmethod
|
||||
# async def dodo(cls, bot: DodoBot, group_id: str):
|
||||
# page_size = 100
|
||||
# result_size = 100
|
||||
# max_id = 0
|
||||
# exist_member_list = []
|
||||
# group_member_list: list[MemberInfo] = []
|
||||
# while result_size == page_size:
|
||||
# group_member_data = await bot.get_member_list(
|
||||
# island_source_id=group_id, page_size=page_size
|
||||
# )
|
||||
# result_size = len(group_member_data.list)
|
||||
# group_member_list += group_member_data.list
|
||||
# max_id = group_member_data.max_id
|
||||
# if group_member_list:
|
||||
# for user in group_member_list:
|
||||
# exist_member_list.append(user.dodo_source_id)
|
||||
# await GroupInfoUser.update_or_create(
|
||||
# user_id=user.dodo_source_id,
|
||||
# group_id=group_id,
|
||||
# defaults={
|
||||
# "user_name": user.nick_name or user.personal_nick_name,
|
||||
# "user_join_time": user.join_time,
|
||||
# "platform": "dodo",
|
||||
# },
|
||||
# )
|
||||
# if delete_member_list := list(
|
||||
# set(exist_member_list).difference(
|
||||
# set(await GroupInfoUser.get_group_member_id_list(group_id))
|
||||
# )
|
||||
# ):
|
||||
# await GroupInfoUser.filter(
|
||||
# user_id__in=delete_member_list, group_id=group_id
|
||||
# ).delete()
|
||||
# logger.info(
|
||||
# f"删除已退群用户",
|
||||
# "更新群组成员信息",
|
||||
# group_id=group_id,
|
||||
# platform="dodo",
|
||||
# )
|
||||
|
||||
# @classmethod
|
||||
# async def kaiheila(cls, bot: KaiheilaBot, group_id: str):
|
||||
# # TODO: kaiheila 更新群组成员信息
|
||||
# pass
|
||||
|
||||
@classmethod
|
||||
async def v11(cls, bot: v11Bot, group_id: str):
|
||||
exist_member_list = []
|
||||
参数:
|
||||
member: Member
|
||||
db_user: db成员数据
|
||||
group_id: 群组id
|
||||
data_list: 数据列表
|
||||
platform: 平台
|
||||
"""
|
||||
driver = nonebot.get_driver()
|
||||
default_auth = Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH")
|
||||
group_member_list = await bot.get_group_member_list(group_id=int(group_id))
|
||||
db_user = await GroupInfoUser.filter(group_id=group_id).all()
|
||||
nickname = member.nick or member.user.name or ""
|
||||
role = member.role
|
||||
db_user_uid = [u.user_id for u in db_user]
|
||||
uid2name = {u.user_id: u.user_name for u in db_user}
|
||||
create_list = []
|
||||
update_list = []
|
||||
delete_list = []
|
||||
for user_info in group_member_list:
|
||||
user_id = str(user_info["user_id"])
|
||||
nickname = user_info["card"] or user_info["nickname"]
|
||||
role = user_info["role"]
|
||||
if (
|
||||
default_auth
|
||||
and role in ["owner", "admin"]
|
||||
and not await LevelUser.is_group_flag(user_id, group_id)
|
||||
if member.id in driver.config.superusers:
|
||||
await LevelUser.set_level(member.id, group_id, 9)
|
||||
elif default_auth:
|
||||
if role != "MEMBER" and not await LevelUser.is_group_flag(
|
||||
member.id, group_id
|
||||
):
|
||||
if role == "owner":
|
||||
await LevelUser.set_level(user_id, group_id, default_auth + 1)
|
||||
else:
|
||||
await LevelUser.set_level(user_id, group_id, default_auth)
|
||||
if user_id in bot.config.superusers:
|
||||
await LevelUser.set_level(user_id, group_id, 9)
|
||||
join_time = datetime.fromtimestamp(
|
||||
user_info["join_time"], timezone(timedelta(hours=8))
|
||||
)
|
||||
if cnt := db_user_uid.count(user_id):
|
||||
users = [u for u in db_user if u.user_id == user_id]
|
||||
if cnt > 1:
|
||||
for u in users[1:]:
|
||||
delete_list.append(u.id)
|
||||
if nickname != uid2name.get(user_id):
|
||||
user = users[0]
|
||||
user.user_name = nickname
|
||||
update_list.append(user)
|
||||
else:
|
||||
create_list.append(
|
||||
GroupInfoUser(
|
||||
user_id=user_id,
|
||||
group_id=group_id,
|
||||
user_name=nickname,
|
||||
user_join_time=join_time,
|
||||
platform="qq",
|
||||
)
|
||||
if role == "OWNER":
|
||||
await LevelUser.set_level(member.id, group_id, default_auth + 1)
|
||||
elif role == "ADMINISTRATOR":
|
||||
await LevelUser.set_level(member.id, group_id, default_auth)
|
||||
if cnt := db_user_uid.count(member.id):
|
||||
users = [u for u in db_user if u.user_id == member.id]
|
||||
if cnt > 1:
|
||||
for u in users[1:]:
|
||||
data_list[2].append(u.id)
|
||||
if nickname != uid2name.get(member.id):
|
||||
user = users[0]
|
||||
user.user_name = nickname
|
||||
data_list[1].append(user)
|
||||
else:
|
||||
data_list[0].append(
|
||||
GroupInfoUser(
|
||||
user_id=member.id,
|
||||
group_id=group_id,
|
||||
user_name=nickname,
|
||||
user_join_time=member.joined_at,
|
||||
platform=platform,
|
||||
)
|
||||
exist_member_list.append(user_id)
|
||||
if create_list:
|
||||
await GroupInfoUser.bulk_create(create_list, 30)
|
||||
logger.debug(
|
||||
f"创建用户数据 {len(create_list)} 条",
|
||||
"更新群组成员信息",
|
||||
target=group_id,
|
||||
)
|
||||
if update_list:
|
||||
await GroupInfoUser.bulk_update(update_list, ["user_name"], 30)
|
||||
logger.debug(
|
||||
f"更新户数据 {len(update_list)} 条", "更新群组成员信息", target=group_id
|
||||
)
|
||||
if delete_list:
|
||||
await GroupInfoUser.filter(id__in=delete_list).delete()
|
||||
logger.debug(f"删除重复数据 Ids: {delete_list}", "更新群组成员信息")
|
||||
|
||||
if delete_member_list := [
|
||||
uid for uid in db_user_uid if uid not in exist_member_list
|
||||
]:
|
||||
await GroupInfoUser.filter(
|
||||
user_id__in=delete_member_list, group_id=group_id
|
||||
).delete()
|
||||
logger.info(
|
||||
f"删除已退群用户 {len(delete_member_list)} 条",
|
||||
"更新群组成员信息",
|
||||
group_id=group_id,
|
||||
platform="qq",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def v12(cls, bot: v12Bot, group_id: str):
|
||||
# TODO: v12更新群组成员信息
|
||||
pass
|
||||
# exist_member_list = []
|
||||
# default_auth = Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH")
|
||||
# group_member_list: list[GetGroupMemberInfoResp] =
|
||||
# await bot.get_group_member_list(
|
||||
# group_id=group_id
|
||||
# )
|
||||
# for user_info in group_member_list:
|
||||
# user_id = user_info.user_id
|
||||
# nickname = user_info.user_displayname or user_info.user_name
|
||||
# role = user_info["role"]
|
||||
# if default_auth:
|
||||
# if role in ["owner", "admin"] and not LevelUser.is_group_flag(
|
||||
# str(user_id), group_id
|
||||
# ):
|
||||
# await LevelUser.set_level(user_id, group_id, default_auth)
|
||||
# if str(user_id) in bot.config.superusers:
|
||||
# await LevelUser.set_level(str(user_id), group_id, 9)
|
||||
# join_time = datetime.strptime(
|
||||
# time.strftime("%Y-%m-%d %H:%M:%S",
|
||||
# time.localtime(user_info["join_time"])),
|
||||
# "%Y-%m-%d %H:%M:%S",
|
||||
# )
|
||||
# await GroupInfoUser.update_or_create(
|
||||
# user_id=str(user_id),
|
||||
# group_id=group_id,
|
||||
# defaults={
|
||||
# "user_name": nickname,
|
||||
# "user_join_time": join_time.replace(
|
||||
# tzinfo=timezone(timedelta(hours=8))
|
||||
# ),
|
||||
# },
|
||||
# )
|
||||
# exist_member_list.append(str(user_id))
|
||||
# logger.debug("更新成功", "更新群组成员信息",
|
||||
# session=user_id, group_id=group_id)
|
||||
# if delete_member_list := list(
|
||||
# set(exist_member_list).difference(
|
||||
# set(await GroupInfoUser.get_group_member_id_list(group_id))
|
||||
# )
|
||||
# ):
|
||||
# await GroupInfoUser.filter(
|
||||
# user_id__in=delete_member_list, group_id=group_id
|
||||
# ).delete()
|
||||
# logger.info(f"删除已退群用户", "更新群组成员信息", group_id=group_id)
|
||||
async def update_group_member(cls, bot: Bot, group_id: str) -> str:
|
||||
"""更新群组成员信息
|
||||
|
||||
参数:
|
||||
bot: Bot
|
||||
group_id: 群组id
|
||||
|
||||
返回:
|
||||
str: 返回消息
|
||||
"""
|
||||
if not group_id:
|
||||
logger.warning(f"bot: {bot.self_id},group_id为空,无法更新群成员信息...")
|
||||
return "群组id为空..."
|
||||
if interface := get_interface(bot):
|
||||
scenes = await interface.get_scenes()
|
||||
platform = PlatformUtils.get_platform(bot)
|
||||
group_list = [s for s in scenes if s.is_group and s.id == group_id]
|
||||
if not group_list:
|
||||
logger.warning(
|
||||
f"bot: {bot.self_id},group_id: {group_id},群组不存在,"
|
||||
"无法更新群成员信息..."
|
||||
)
|
||||
return "更新群组失败,群组不存在..."
|
||||
members = await interface.get_members(SceneType.GROUP, group_list[0].id)
|
||||
db_user = await GroupInfoUser.filter(group_id=group_id).all()
|
||||
db_user_uid = [u.user_id for u in db_user]
|
||||
data_list = ([], [], [])
|
||||
exist_member_list = []
|
||||
for member in members:
|
||||
await cls.__handle_user(member, db_user, group_id, data_list, platform)
|
||||
exist_member_list.append(member.id)
|
||||
if data_list[0]:
|
||||
await GroupInfoUser.bulk_create(data_list[0], 30)
|
||||
logger.debug(
|
||||
f"创建用户数据 {len(data_list[0])} 条",
|
||||
"更新群组成员信息",
|
||||
target=group_id,
|
||||
)
|
||||
if data_list[1]:
|
||||
await GroupInfoUser.bulk_update(data_list[1], ["user_name"], 30)
|
||||
logger.debug(
|
||||
f"更新户数据 {len(data_list[1])} 条",
|
||||
"更新群组成员信息",
|
||||
target=group_id,
|
||||
)
|
||||
if data_list[2]:
|
||||
await GroupInfoUser.filter(id__in=data_list[2]).delete()
|
||||
logger.debug(f"删除重复数据 Ids: {data_list[2]}", "更新群组成员信息")
|
||||
|
||||
if delete_member_list := [
|
||||
uid for uid in db_user_uid if uid not in exist_member_list
|
||||
]:
|
||||
await GroupInfoUser.filter(
|
||||
user_id__in=delete_member_list, group_id=group_id
|
||||
).delete()
|
||||
logger.info(
|
||||
f"删除已退群用户 {len(delete_member_list)} 条",
|
||||
"更新群组成员信息",
|
||||
group_id=group_id,
|
||||
platform="qq",
|
||||
)
|
||||
return "群组成员信息更新完成!"
|
||||
|
||||
@ -7,10 +7,10 @@ import nonebot
|
||||
from pydantic import BaseModel
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot.utils import is_coroutine_callable
|
||||
from nonebot_plugin_uninfo import get_interface
|
||||
from nonebot.adapters.dodo import Bot as DodoBot
|
||||
from nonebot.adapters.onebot.v11 import Bot as v11Bot
|
||||
from nonebot.adapters.onebot.v12 import Bot as v12Bot
|
||||
from nonebot.adapters.discord import Bot as DiscordBot
|
||||
from nonebot.adapters.kaiheila import Bot as KaiheilaBot
|
||||
from nonebot_plugin_alconna.uniseg import Target, Receipt, UniMessage
|
||||
|
||||
@ -380,13 +380,11 @@ class PlatformUtils:
|
||||
返回:
|
||||
str | None: 平台
|
||||
"""
|
||||
if isinstance(bot, v11Bot | v12Bot):
|
||||
return "qq"
|
||||
if isinstance(bot, DodoBot):
|
||||
return "dodo"
|
||||
if isinstance(bot, KaiheilaBot):
|
||||
return "kaiheila"
|
||||
return "discord" if isinstance(bot, DiscordBot) else None
|
||||
if interface := get_interface(bot):
|
||||
info = interface.basic_info()
|
||||
platform = info["scope"].lower()
|
||||
return "qq" if platform.startswith("qq") else platform
|
||||
return "unknown"
|
||||
|
||||
@classmethod
|
||||
async def get_group_list(cls, bot: Bot) -> tuple[list[GroupConsole], str]:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user