mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 14:22:55 +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"
|
url = "https://mirrors.aliyun.com/pypi/simple"
|
||||||
reference = "ali"
|
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]]
|
[[package]]
|
||||||
name = "nonebot-plugin-userinfo"
|
name = "nonebot-plugin-userinfo"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
@ -4925,4 +4945,4 @@ reference = "ali"
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.10"
|
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"
|
arclet-alconna = "1.8.23"
|
||||||
aiocache = "^0.12.2"
|
aiocache = "^0.12.2"
|
||||||
py-cpuinfo = "^9.0.0"
|
py-cpuinfo = "^9.0.0"
|
||||||
|
nonebot-plugin-uninfo = "^0.4.1"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
nonebug = "^0.3.2"
|
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):
|
async def _(bot: Bot, session: EventSession, arparma: Arparma):
|
||||||
if gid := session.id3 or session.id2:
|
if gid := session.id3 or session.id2:
|
||||||
logger.info("更新群组成员信息", arparma.header_result, session=session)
|
logger.info("更新群组成员信息", arparma.header_result, session=session)
|
||||||
await MemberUpdateManage.update(bot, gid)
|
result = await MemberUpdateManage.update_group_member(bot, gid)
|
||||||
await MessageUtils.build_message("已经成功更新了群组成员信息!").finish(
|
await MessageUtils.build_message(result).finish(reply_to=True)
|
||||||
reply_to=True
|
|
||||||
)
|
|
||||||
await MessageUtils.build_message("群组id为空...").send()
|
await MessageUtils.build_message("群组id为空...").send()
|
||||||
|
|
||||||
|
|
||||||
@_notice.handle()
|
@_notice.handle()
|
||||||
async def _(bot: Bot, event: GroupIncreaseNoticeEvent):
|
async def _(bot: Bot, event: GroupIncreaseNoticeEvent):
|
||||||
# TODO: 其他适配器的加群自动更新群组成员信息
|
|
||||||
if str(event.user_id) == bot.self_id:
|
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(
|
logger.info(
|
||||||
f"{BotConfig.self_nickname}加入群聊更新群组信息",
|
f"{BotConfig.self_nickname}加入群聊更新群组信息",
|
||||||
"更新群组成员列表",
|
"更新群组成员列表",
|
||||||
@ -81,7 +78,9 @@ async def _():
|
|||||||
if group_list:
|
if group_list:
|
||||||
for group in group_list:
|
for group in group_list:
|
||||||
try:
|
try:
|
||||||
await MemberUpdateManage.update(bot, group.group_id)
|
await MemberUpdateManage.update_group_member(
|
||||||
|
bot, group.group_id
|
||||||
|
)
|
||||||
logger.debug("自动更新群组成员信息成功...")
|
logger.debug("自动更新群组成员信息成功...")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(
|
logger.error(
|
||||||
|
|||||||
@ -1,213 +1,129 @@
|
|||||||
from datetime import datetime, timezone, timedelta
|
import nonebot
|
||||||
|
|
||||||
from nonebot.adapters import Bot
|
from nonebot.adapters import Bot
|
||||||
|
from nonebot_plugin_uninfo import Member, SceneType, get_interface
|
||||||
# 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 zhenxun.services.log import logger
|
from zhenxun.services.log import logger
|
||||||
from zhenxun.configs.config import Config
|
from zhenxun.configs.config import Config
|
||||||
from zhenxun.models.level_user import LevelUser
|
from zhenxun.models.level_user import LevelUser
|
||||||
|
from zhenxun.utils.platform import PlatformUtils
|
||||||
from zhenxun.models.group_member_info import GroupInfoUser
|
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:
|
class MemberUpdateManage:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def update(cls, bot: Bot, group_id: str):
|
async def __handle_user(
|
||||||
if not group_id:
|
cls,
|
||||||
return logger.warning(
|
member: Member,
|
||||||
f"bot: {bot.self_id},group_id为空,无法更新群成员信息..."
|
db_user: list[GroupInfoUser],
|
||||||
)
|
group_id: str,
|
||||||
if isinstance(bot, v11Bot):
|
data_list: tuple[list, list, list],
|
||||||
await cls.v11(bot, group_id)
|
platform: str | None,
|
||||||
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)
|
|
||||||
|
|
||||||
# @classmethod
|
参数:
|
||||||
# async def discord(cls, bot: DiscordBot, group_id: str):
|
member: Member
|
||||||
# # TODO: discord更新群组成员信息
|
db_user: db成员数据
|
||||||
# pass
|
group_id: 群组id
|
||||||
|
data_list: 数据列表
|
||||||
# @classmethod
|
platform: 平台
|
||||||
# async def dodo(cls, bot: DodoBot, group_id: str):
|
"""
|
||||||
# page_size = 100
|
driver = nonebot.get_driver()
|
||||||
# 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 = []
|
|
||||||
default_auth = Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH")
|
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))
|
nickname = member.nick or member.user.name or ""
|
||||||
db_user = await GroupInfoUser.filter(group_id=group_id).all()
|
role = member.role
|
||||||
db_user_uid = [u.user_id for u in db_user]
|
db_user_uid = [u.user_id for u in db_user]
|
||||||
uid2name = {u.user_id: u.user_name for u in db_user}
|
uid2name = {u.user_id: u.user_name for u in db_user}
|
||||||
create_list = []
|
if member.id in driver.config.superusers:
|
||||||
update_list = []
|
await LevelUser.set_level(member.id, group_id, 9)
|
||||||
delete_list = []
|
elif default_auth:
|
||||||
for user_info in group_member_list:
|
if role != "MEMBER" and not await LevelUser.is_group_flag(
|
||||||
user_id = str(user_info["user_id"])
|
member.id, group_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 role == "owner":
|
if role == "OWNER":
|
||||||
await LevelUser.set_level(user_id, group_id, default_auth + 1)
|
await LevelUser.set_level(member.id, group_id, default_auth + 1)
|
||||||
else:
|
elif role == "ADMINISTRATOR":
|
||||||
await LevelUser.set_level(user_id, group_id, default_auth)
|
await LevelUser.set_level(member.id, group_id, default_auth)
|
||||||
if user_id in bot.config.superusers:
|
if cnt := db_user_uid.count(member.id):
|
||||||
await LevelUser.set_level(user_id, group_id, 9)
|
users = [u for u in db_user if u.user_id == member.id]
|
||||||
join_time = datetime.fromtimestamp(
|
if cnt > 1:
|
||||||
user_info["join_time"], timezone(timedelta(hours=8))
|
for u in users[1:]:
|
||||||
)
|
data_list[2].append(u.id)
|
||||||
if cnt := db_user_uid.count(user_id):
|
if nickname != uid2name.get(member.id):
|
||||||
users = [u for u in db_user if u.user_id == user_id]
|
user = users[0]
|
||||||
if cnt > 1:
|
user.user_name = nickname
|
||||||
for u in users[1:]:
|
data_list[1].append(user)
|
||||||
delete_list.append(u.id)
|
else:
|
||||||
if nickname != uid2name.get(user_id):
|
data_list[0].append(
|
||||||
user = users[0]
|
GroupInfoUser(
|
||||||
user.user_name = nickname
|
user_id=member.id,
|
||||||
update_list.append(user)
|
group_id=group_id,
|
||||||
else:
|
user_name=nickname,
|
||||||
create_list.append(
|
user_join_time=member.joined_at,
|
||||||
GroupInfoUser(
|
platform=platform,
|
||||||
user_id=user_id,
|
|
||||||
group_id=group_id,
|
|
||||||
user_name=nickname,
|
|
||||||
user_join_time=join_time,
|
|
||||||
platform="qq",
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
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
|
@classmethod
|
||||||
async def v12(cls, bot: v12Bot, group_id: str):
|
async def update_group_member(cls, bot: Bot, group_id: str) -> str:
|
||||||
# TODO: v12更新群组成员信息
|
"""更新群组成员信息
|
||||||
pass
|
|
||||||
# exist_member_list = []
|
参数:
|
||||||
# default_auth = Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH")
|
bot: Bot
|
||||||
# group_member_list: list[GetGroupMemberInfoResp] =
|
group_id: 群组id
|
||||||
# await bot.get_group_member_list(
|
|
||||||
# group_id=group_id
|
返回:
|
||||||
# )
|
str: 返回消息
|
||||||
# for user_info in group_member_list:
|
"""
|
||||||
# user_id = user_info.user_id
|
if not group_id:
|
||||||
# nickname = user_info.user_displayname or user_info.user_name
|
logger.warning(f"bot: {bot.self_id},group_id为空,无法更新群成员信息...")
|
||||||
# role = user_info["role"]
|
return "群组id为空..."
|
||||||
# if default_auth:
|
if interface := get_interface(bot):
|
||||||
# if role in ["owner", "admin"] and not LevelUser.is_group_flag(
|
scenes = await interface.get_scenes()
|
||||||
# str(user_id), group_id
|
platform = PlatformUtils.get_platform(bot)
|
||||||
# ):
|
group_list = [s for s in scenes if s.is_group and s.id == group_id]
|
||||||
# await LevelUser.set_level(user_id, group_id, default_auth)
|
if not group_list:
|
||||||
# if str(user_id) in bot.config.superusers:
|
logger.warning(
|
||||||
# await LevelUser.set_level(str(user_id), group_id, 9)
|
f"bot: {bot.self_id},group_id: {group_id},群组不存在,"
|
||||||
# join_time = datetime.strptime(
|
"无法更新群成员信息..."
|
||||||
# time.strftime("%Y-%m-%d %H:%M:%S",
|
)
|
||||||
# time.localtime(user_info["join_time"])),
|
return "更新群组失败,群组不存在..."
|
||||||
# "%Y-%m-%d %H:%M:%S",
|
members = await interface.get_members(SceneType.GROUP, group_list[0].id)
|
||||||
# )
|
db_user = await GroupInfoUser.filter(group_id=group_id).all()
|
||||||
# await GroupInfoUser.update_or_create(
|
db_user_uid = [u.user_id for u in db_user]
|
||||||
# user_id=str(user_id),
|
data_list = ([], [], [])
|
||||||
# group_id=group_id,
|
exist_member_list = []
|
||||||
# defaults={
|
for member in members:
|
||||||
# "user_name": nickname,
|
await cls.__handle_user(member, db_user, group_id, data_list, platform)
|
||||||
# "user_join_time": join_time.replace(
|
exist_member_list.append(member.id)
|
||||||
# tzinfo=timezone(timedelta(hours=8))
|
if data_list[0]:
|
||||||
# ),
|
await GroupInfoUser.bulk_create(data_list[0], 30)
|
||||||
# },
|
logger.debug(
|
||||||
# )
|
f"创建用户数据 {len(data_list[0])} 条",
|
||||||
# exist_member_list.append(str(user_id))
|
"更新群组成员信息",
|
||||||
# logger.debug("更新成功", "更新群组成员信息",
|
target=group_id,
|
||||||
# session=user_id, group_id=group_id)
|
)
|
||||||
# if delete_member_list := list(
|
if data_list[1]:
|
||||||
# set(exist_member_list).difference(
|
await GroupInfoUser.bulk_update(data_list[1], ["user_name"], 30)
|
||||||
# set(await GroupInfoUser.get_group_member_id_list(group_id))
|
logger.debug(
|
||||||
# )
|
f"更新户数据 {len(data_list[1])} 条",
|
||||||
# ):
|
"更新群组成员信息",
|
||||||
# await GroupInfoUser.filter(
|
target=group_id,
|
||||||
# user_id__in=delete_member_list, group_id=group_id
|
)
|
||||||
# ).delete()
|
if data_list[2]:
|
||||||
# logger.info(f"删除已退群用户", "更新群组成员信息", group_id=group_id)
|
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 pydantic import BaseModel
|
||||||
from nonebot.adapters import Bot
|
from nonebot.adapters import Bot
|
||||||
from nonebot.utils import is_coroutine_callable
|
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.dodo import Bot as DodoBot
|
||||||
from nonebot.adapters.onebot.v11 import Bot as v11Bot
|
from nonebot.adapters.onebot.v11 import Bot as v11Bot
|
||||||
from nonebot.adapters.onebot.v12 import Bot as v12Bot
|
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.adapters.kaiheila import Bot as KaiheilaBot
|
||||||
from nonebot_plugin_alconna.uniseg import Target, Receipt, UniMessage
|
from nonebot_plugin_alconna.uniseg import Target, Receipt, UniMessage
|
||||||
|
|
||||||
@ -380,13 +380,11 @@ class PlatformUtils:
|
|||||||
返回:
|
返回:
|
||||||
str | None: 平台
|
str | None: 平台
|
||||||
"""
|
"""
|
||||||
if isinstance(bot, v11Bot | v12Bot):
|
if interface := get_interface(bot):
|
||||||
return "qq"
|
info = interface.basic_info()
|
||||||
if isinstance(bot, DodoBot):
|
platform = info["scope"].lower()
|
||||||
return "dodo"
|
return "qq" if platform.startswith("qq") else platform
|
||||||
if isinstance(bot, KaiheilaBot):
|
return "unknown"
|
||||||
return "kaiheila"
|
|
||||||
return "discord" if isinstance(bot, DiscordBot) else None
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def get_group_list(cls, bot: Bot) -> tuple[list[GroupConsole], str]:
|
async def get_group_list(cls, bot: Bot) -> tuple[list[GroupConsole], str]:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user