Files
DanDingNoneBot/danding_bot/plugins/danding_help/help.py

247 lines
11 KiB
Python

from nonebot import on_command, get_plugin_config, get_driver, logger
from nonebot.rule import Rule, fullmatch
from .config import Config
import os
import io
import aiohttp
from PIL import Image as PILImage
from nonebot_plugin_saa import Text, Image, MessageFactory
from nonebot.adapters.onebot.v11 import Bot as V11Bot, Message as V11Message, MessageSegment as V11MessageSegment
from nonebot.adapters.onebot.v11.event import GroupMessageEvent
import random
import asyncio
ALLOWED_GROUPS = [621016172]
async def _group_check(e: GroupMessageEvent) -> bool:
"""Check if message is from an allowed group."""
return e.group_id in ALLOWED_GROUPS
_group_rule = Rule(_group_check)
plugin_config = get_plugin_config(Config)
help = on_command("帮助", rule=_group_rule & fullmatch(('帮助','help')), aliases={"help"}, priority=1, block=True)
@help.handle()
async def _handle_help():
current_dir = os.path.dirname(__file__)
image_path = os.path.join(current_dir, "img", "帮助菜单.jpg")
try:
with open(image_path, "rb") as f:
image_bytes = f.read()
await asyncio.sleep(random.uniform(2, 3))
await MessageFactory([Image(image_bytes)]).send(at_sender=True, reply=True)
except FileNotFoundError:
logger.warning(f"[Help] 帮助菜单图片不存在: {image_path}")
await help.finish("帮助菜单图片暂时不可用,请联系管理员")
downdload = on_command("下载", rule=_group_rule & fullmatch(('下载',"dl","downdload")), aliases={"dl","downdload"}, priority=1, block=True)
@downdload.handle()
async def _handle_download():
await asyncio.sleep(random.uniform(2, 3))
await downdload.finish(plugin_config.DowndLoadStr)
wd = on_command("帮助文档", rule=_group_rule & fullmatch(('帮助文档',"wd")), aliases={"wd"}, priority=1, block=True)
@wd.handle()
async def _handle_wd():
await asyncio.sleep(random.uniform(2, 3))
await wd.finish("https://www.danding.vip")
free = on_command("公益版", rule=_group_rule & fullmatch(('公益版',"free","gyb")), aliases={"free","gyb"}, priority=1, block=True)
@free.handle()
async def _handle_free():
await asyncio.sleep(random.uniform(2, 3))
await help.finish(plugin_config.FreeStr)
pro = on_command("正式版", rule=_group_rule & fullmatch(('正式版',"pro","zsb")), aliases={"pro","zsb"}, priority=1, block=True)
@pro.handle()
async def _handle_pro():
await asyncio.sleep(random.uniform(2, 3))
await help.finish(plugin_config.ProStr)
dyh = on_command("正式版御魂双开", rule=_group_rule & fullmatch(('正式版御魂双开',"dyh")), aliases={"dyh"}, priority=1, block=True)
@dyh.handle()
async def _handle_dyh():
current_dir = os.path.dirname(__file__)
image_path = os.path.join(current_dir, "img", "御魂双开方法.jpg")
try:
with open(image_path, "rb") as f:
image_bytes = f.read()
await asyncio.sleep(random.uniform(2, 3))
await MessageFactory([Text("御魂双开方法见下图"), Image(image_bytes)]).send(at_sender=True, reply=True)
except FileNotFoundError:
logger.warning(f"[Help] 御魂双开图片不存在: {image_path}")
await dyh.finish("教程图片暂时不可用,请联系管理员")
htr = on_command("正式版如何运行", rule=_group_rule & fullmatch(('正式版如何运行',"htr")), aliases={"htr"}, priority=1, block=True)
@htr.handle()
async def _handle_htr():
current_dir = os.path.dirname(__file__)
image_path = os.path.join(current_dir, "img", "开软件教程.jpg")
try:
with open(image_path, "rb") as f:
image_bytes = f.read()
await asyncio.sleep(random.uniform(2, 3))
await MessageFactory([Text("How To Run? Look!"), Image(image_bytes)]).send(at_sender=True, reply=True)
except FileNotFoundError:
logger.warning(f"[Help] 运行教程图片不存在: {image_path}")
await htr.finish("教程图片暂时不可用,请联系管理员")
order = on_command("下单", rule=_group_rule & fullmatch(('下单',"xd")), aliases={"xd"}, priority=1, block=True)
@order.handle()
async def _handle_order():
await asyncio.sleep(random.uniform(2, 3))
await order.finish(plugin_config.OrderStr)
daily_trial = on_command("每日试用", rule=_group_rule & fullmatch(('每日试用',"mrss")), aliases={"mrss"}, priority=1, block=True)
@daily_trial.handle()
async def _handle_daily_trial():
await asyncio.sleep(random.uniform(2, 3))
await daily_trial.finish(plugin_config.DailyTrialStr)
activity = on_command("活动", rule=_group_rule & fullmatch(('活动', '最新活动', '群活动', 'hd')), aliases={"最新活动", "群活动", "hd"}, priority=1, block=True)
@activity.handle()
async def _handle_activity(bot: V11Bot, event: GroupMessageEvent):
await asyncio.sleep(random.uniform(1.5, 2.5))
driver_config = get_driver().config
api_host = (
getattr(driver_config, "danding_api_host", None)
or os.environ.get("DANDING_API_HOST")
or getattr(plugin_config, "DDApi_Host", "https://api.danding.vip/DD/")
).rstrip("/")
target_url = f"{api_host}/get_active_activities"
try:
async with aiohttp.ClientSession() as session:
async with session.get(target_url, timeout=aiohttp.ClientTimeout(total=10)) as resp:
if resp.status != 200:
logger.error(f"[Help] 获取活动列表状态码异常: {resp.status}")
await activity.finish("获取活动信息失败,请稍后再试")
res = await resp.json()
except Exception as e:
logger.error(f"[Help] 获取活动列表请求失败: {e}")
await activity.finish("活动服务暂时不可用,请稍后再试")
return
items = res.get("data", [])
if not isinstance(items, list) or not items:
await activity.finish(plugin_config.NoActivityStr)
return
poster_items = [it for it in items if it.get("poster_url") or it.get("poster_path")]
# 无海报时回退为文字列表
if not poster_items:
msg_lines = ["📢 当前运营活动:"]
for it in items:
name = it.get("活动名", "未知活动")
start = it.get("活动开始时间", "")
end = it.get("活动截止时间", "")
notice = it.get("活动公告", "")
msg_lines.append(f"\n{name}\n时间:{start} ~ {end}\n说明:{notice}")
await MessageFactory([Text("\n".join(msg_lines))]).send(at_sender=True, reply=True)
return
# 单个活动直接以图文消息发送
if len(poster_items) == 1:
it = poster_items[0]
poster_url = it.get("poster_url")
if not poster_url and it.get("poster_path"):
poster_url = f"{api_host}/activity-posters/{it['poster_path'].replace('activity-posters/', '')}"
name = it.get("活动名", "运营活动")
start = it.get("活动开始时间", "")
end = it.get("活动截止时间", "")
announcement = it.get("活动公告", "")
desc = f"🎉【{name}\n⏰ 活动时间:{start}{end}"
if announcement:
desc += f"\n📝 活动说明:{announcement}"
try:
async with aiohttp.ClientSession() as session:
async with session.get(poster_url, timeout=aiohttp.ClientTimeout(total=15)) as img_resp:
if img_resp.status == 200:
img_bytes = await img_resp.read()
try:
with PILImage.open(io.BytesIO(img_bytes)) as pil_img:
out_io = io.BytesIO()
pil_img.convert("RGB").save(out_io, format="JPEG", quality=90)
img_bytes = out_io.getvalue()
except Exception as conv_err:
logger.warning(f"[Help] 海报图片格式转换跳过: {conv_err}")
await MessageFactory([Text(desc), Image(img_bytes)]).send(at_sender=True, reply=True)
return
except Exception as e:
logger.error(f"[Help] 单活动海报发送异常: {e}")
await activity.finish("当前活动海报加载失败,请稍后重试")
return
# 多个活动:打包为合并转发消息发送,避免多图刷屏
nodes = []
bot_info = await bot.get_login_info()
bot_id = bot_info.get("user_id", event.self_id)
bot_name = bot_info.get("nickname", "蛋定助手")
# 首节点:概览提示
summary_text = f"📢 当前共有 {len(poster_items)} 个运营活动进行中:\n" + "\n".join(
[f"{idx + 1}. {it.get('活动名', '未知活动')}" for idx, it in enumerate(poster_items)]
)
nodes.append(V11MessageSegment.node_custom(
user_id=bot_id,
nickname=bot_name,
content=V11Message([V11MessageSegment.text(summary_text)])
))
async with aiohttp.ClientSession() as session:
for it in poster_items:
poster_url = it.get("poster_url")
if not poster_url and it.get("poster_path"):
poster_url = f"{api_host}/activity-posters/{it['poster_path'].replace('activity-posters/', '')}"
name = it.get("活动名", "运营活动")
start = it.get("活动开始时间", "")
end = it.get("活动截止时间", "")
announcement = it.get("活动公告", "")
card_msg = V11Message()
card_desc = f"🎉【{name}\n⏰ 活动时间:{start}{end}"
if announcement:
card_desc += f"\n📝 活动说明:{announcement}"
card_msg.append(V11MessageSegment.text(card_desc))
try:
async with session.get(poster_url, timeout=aiohttp.ClientTimeout(total=15)) as img_resp:
if img_resp.status == 200:
img_bytes = await img_resp.read()
try:
with PILImage.open(io.BytesIO(img_bytes)) as pil_img:
out_io = io.BytesIO()
pil_img.convert("RGB").save(out_io, format="JPEG", quality=90)
img_bytes = out_io.getvalue()
except Exception as conv_err:
logger.warning(f"[Help] 海报图片转换跳过: {conv_err}")
card_msg.append(V11MessageSegment.image(img_bytes))
except Exception as dl_err:
logger.warning(f"[Help] 多活动海报拉取失败({name}): {dl_err}")
nodes.append(V11MessageSegment.node_custom(
user_id=bot_id,
nickname=bot_name,
content=card_msg
))
try:
await bot.send_group_forward_msg(group_id=event.group_id, messages=nodes)
except Exception as fwd_err:
logger.error(f"[Help] 发送合并转发失败: {fwd_err},尝试降级逐条发送")
# 降级处理
for node in nodes[1:]:
try:
await bot.send_group_msg(group_id=event.group_id, message=node.data["content"])
await asyncio.sleep(1)
except Exception as snd_err:
logger.error(f"[Help] 降级发送单条失败: {snd_err}")