Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 86 additions & 16 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,94 @@
from astrbot.api.event import filter, AstrMessageEvent, MessageEventResult
from astrbot.api.star import Context, Star, register
import io
import requests
from PIL import Image, ImageDraw, ImageFont

from astrbot.api.event import filter, AstrMessageEvent
from astrbot.api.star import Star, Context, register
from astrbot.api import logger

@register("helloworld", "YourName", "一个简单的 Hello World 插件", "1.0.0")
class MyPlugin(Star):

API_URL = "你的 API 地址,例如 http://example.com/order/list"


def render_order_card(data: list):
"""使用 Pillow 渲染排单卡片"""

count = len(data)

# 基础尺寸
width = 900
header_height = 120
row_height = 150
height = header_height + row_height * max(count, 1)

# 白底画布
img = Image.new("RGB", (width, height), "white")
draw = ImageDraw.Draw(img)

# 字体(AstrBot 容器一般有 DejaVu 字体)
font_title = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 46)
font_text = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 38)

# 标题
draw.text((40, 40), f"📋 排单统计:{count} 人", fill="black", font=font_title)

# 内容区起点
y = header_height

if count == 0:
draw.text((40, y + 20), "暂无排单数据", fill="gray", font=font_text)
else:
for item in data:
draw.text((40, y), f"👤 用户:{item['username']}", fill="black", font=font_text)
draw.text((40, y + 45), f"📦 订单号:{item['orderNo']}", fill="black", font=font_text)
draw.text((40, y + 90), f"⏱ 下单时间:{item['orderCreateTime']}", fill="black", font=font_text)
y += row_height

# 保存到字节流
buffer = io.BytesIO()
img.save(buffer, format="PNG")
buffer.seek(0)
return buffer


@register("zyfurry_bot", "jiatao", "排单查询 + 图片渲染插件(Pillow版)", "1.0.0")
class OrderPlugin(Star):
def __init__(self, context: Context):
super().__init__(context)

async def initialize(self):
"""可选择实现异步的插件初始化方法,当实例化该插件类之后会自动调用该方法。"""
@filter.command("order")
async def order_cmd(self, event: AstrMessageEvent):
"""查询排单并以图片形式输出"""

logger.info("开始请求接口获取排单信息…")

try:
resp = requests.get(API_URL, timeout=5)
resp.raise_for_status()
except Exception as e:
logger.error(f"接口请求失败: {e}")
yield event.plain_result("❌ 接口请求失败,请稍后再试")
return

# 解析 JSON
try:
json_data = resp.json()
except Exception as e:
logger.error(f"解析 JSON 失败: {e}")
yield event.plain_result("❌ 数据格式错误")
return

if json_data.get("code") != 0:
yield event.plain_result("❌ 接口返回异常")
return

data_list = json_data.get("data", [])

# 生成图片
img_bytes = render_order_card(data_list)

# 注册指令的装饰器。指令名为 helloworld。注册成功后,发送 `/helloworld` 就会触发这个指令,并回复 `你好, {user_name}!`
@filter.command("helloworld")
async def helloworld(self, event: AstrMessageEvent):
"""这是一个 hello world 指令""" # 这是 handler 的描述,将会被解析方便用户了解插件内容。建议填写。
user_name = event.get_sender_name()
message_str = event.message_str # 用户发的纯文本消息字符串
message_chain = event.get_messages() # 用户所发的消息的消息链 # from astrbot.api.message_components import *
logger.info(message_chain)
yield event.plain_result(f"Hello, {user_name}, 你发了 {message_str}!") # 发送一条纯文本消息
# 由 AstrBot 发送图片
yield event.image_result(img_bytes)

async def terminate(self):
"""可选择实现异步的插件销毁方法,当插件被卸载/停用时会调用。"""
logger.info("插件已卸载")
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
requests
html2image
Pillow