feat: beauty

This commit is contained in:
hp0912 2026-03-12 22:13:48 +08:00
parent fad57fcc5e
commit b239d7b16d
2 changed files with 150 additions and 0 deletions

72
skills/beauty/SKILL.md Normal file
View File

@ -0,0 +1,72 @@
---
name: beauty
description: "当用户发送「999」时触发。调用美女图片接口获取图片链接再调用本地微信机器人发图接口把图片发给当前用户。"
argument-hint: "无需参数,直接调用即可"
---
# Beauty Skill
## 描述
这是一个用于获取美女图片并直接发送给当前用户的技能。
当用户发送 `999` 时,调用外部接口获取图片链接,再调用本地微信机器人接口把图片发出去。
这个仓库里额外提供了一个可执行脚本 `beauty/scripts/beauty.py`,方便宿主机器人直接调用。
## 触发条件
- 用户发送 `999`
## 接口信息
- 获取图片地址:`https://api.pearktrue.cn/api/today_wife`
- 请求方式:`GET`
- 发图接口:`http://127.0.0.1:{ROBOT_WECHAT_CLIENT_PORT}/api/v1/robot/message/send/image/url`
- 请求方式:`POST`
- 本地脚本:`beauty/scripts/beauty.py`
- 获取图片返回示例:
```json
{
"code": 200,
"msg": "获取成功",
"data": {
"image_url": "https://api.pearktrue.cn/api_assets/wife/9a6a9c38-7d6e-464f-8930-eb9dac41cde9.webp",
"role_name": "初音未来、巡音流歌",
"width": 2480,
"height": 3508
},
"api_source": "官方API网:https://api.pearktrue.cn/"
}
```
- 关键字段:`data.image_url`,表示需要发送出去的图片链接。
## 环境变量
- `ROBOT_WECHAT_CLIENT_PORT`:本地微信机器人服务端口。
- `ROBOT_FROM_WX_ID`:当前消息来源用户的 wxid。
## 执行步骤
1. 当用户发送 `999` 时触发该技能。
2. 在仓库根目录下执行本地脚本:`python3 beauty/scripts/beauty.py`。
3. 脚本内部发送 `GET` 请求到 `https://api.pearktrue.cn/api/today_wife`
4. 脚本解析返回的 JSON并提取 `data.image_url`
5. 脚本从环境变量中读取 `ROBOT_WECHAT_CLIENT_PORT``ROBOT_FROM_WX_ID`
6. 脚本发送 `POST` 请求到 `http://127.0.0.1:{ROBOT_WECHAT_CLIENT_PORT}/api/v1/robot/message/send/image/url`,请求体为:
```json
{
"to_wxid": "{ROBOT_FROM_WX_ID}",
"image_urls": ["image_url"]
}
```
7. 如果任一步骤失败,回复兜底文案:`今天的美女图片暂时没拿到,等我再找找。`
## 回复要求
- 成功时,直接发送图片,不要额外追加解释文字。
- 失败时,使用固定兜底文案回复。

View File

@ -0,0 +1,78 @@
#!/usr/bin/env python3
from __future__ import annotations
import json
import os
import sys
import urllib.error
import urllib.request
FETCH_API_URL = "https://api.pearktrue.cn/api/today_wife"
FALLBACK_TEXT = "今天的美女图片暂时没拿到,等我再找找。"
def fetch_image_url() -> str | None:
try:
with urllib.request.urlopen(FETCH_API_URL, timeout=10) as response:
payload = json.load(response)
except (urllib.error.URLError, TimeoutError, json.JSONDecodeError):
return None
data = payload.get("data")
if not isinstance(data, dict):
return None
image_url = data.get("image_url")
if isinstance(image_url, str) and image_url.strip():
return image_url.strip()
return None
def send_image(image_url: str) -> bool:
robot_port = os.environ.get("ROBOT_WECHAT_CLIENT_PORT", "").strip()
to_wxid = os.environ.get("ROBOT_FROM_WX_ID", "").strip()
if not robot_port or not to_wxid:
return False
api_url = (
f"http://127.0.0.1:{robot_port}/api/v1/robot/message/send/image/url"
)
body = json.dumps(
{
"to_wxid": to_wxid,
"image_urls": [image_url],
}
).encode("utf-8")
request = urllib.request.Request(
api_url,
data=body,
headers={"Content-Type": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(request, timeout=10) as response:
if 200 <= response.status < 300:
return True
payload = json.load(response)
except (urllib.error.URLError, TimeoutError, json.JSONDecodeError):
return False
code = payload.get("code")
return code == 200 or code == 0
def main() -> int:
image_url = fetch_image_url()
if image_url and send_image(image_url):
return 0
sys.stdout.write(FALLBACK_TEXT)
sys.stdout.write("\n")
return 0
if __name__ == "__main__":
raise SystemExit(main())