Skip to content

Commit

Permalink
Fix startup 移到 setup,确保 api 使用 call_api
Browse files Browse the repository at this point in the history
  • Loading branch information
YangRucheng committed Jan 1, 2025
1 parent 18daf00 commit 10599d0
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 60 deletions.
1 change: 1 addition & 0 deletions .github/workflows/pypi-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ jobs:
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
skip-existing: true
27 changes: 9 additions & 18 deletions nonebot/adapters/wxmp/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
from nonebot import get_plugin_config
from nonebot.drivers import (
Request,
Response,
ASGIMixin,
WebSocket,
HTTPServerSetup,
Expand Down Expand Up @@ -80,11 +81,6 @@ def setup(self) -> None:
f"{self.get_name()} Adapter needs a HTTPClient Driver to work."
)

self.driver.on_startup(self.startup)
self.driver.on_shutdown(self.shutdown)

async def startup(self) -> None:
""" 启动 Adapter """
for bot_info in self.wxmp_config.wxmp_bots:
http_setup = HTTPServerSetup(
URL(f"/wxmp/revice/{bot_info.appid}"),
Expand Down Expand Up @@ -123,6 +119,8 @@ async def startup(self) -> None:
)
self.setup_http_server(http_setup)

self.driver.on_shutdown(self.shutdown)

async def shutdown(self) -> None:
""" 关闭 Adapter """
for task in self.tasks:
Expand Down Expand Up @@ -207,29 +205,22 @@ def _get_appid(self, path: str) -> BotInfo | None:
""" 从链接中获取 Bot 配置 """
return path.split('/')[-1]

async def _call_api(self, bot: Bot, api: str, **data: Any) -> dict:
async def _call_api(self, bot: Bot, api: str, **data: Any) -> Response:
""" 调用微信公众平台 API """
access_token = await bot._get_access_token()
body: Any | None = data.get("json", data.get("data", data.get("body", None)))

request = Request(
method=data.get("method", "POST"),
url=f"https://api.weixin.qq.com/cgi-bin{api}",
params={
"access_token": access_token,
} | data.get("params", {}),
headers={
'Content-type': 'application/json',
} | data.get("headers", {}),
content=json.dumps(
data.get("json", data.get("data", data.get("body", {}))),
ensure_ascii=False
).encode("utf-8"),
headers=data.get("headers", {}),
content=json.dumps(body, ensure_ascii=False).encode("utf-8") if body else None,
files=data.get("files", None),
)
resp = await self.request(request)
if resp.status_code != 200 or not resp.content:
raise NetworkError(f"Call API {api} failed with status code {resp.status_code}.")
res: dict = json.loads(resp.content)
if res.get("errcode", 0) != 0:
log("ERROR", f"Call API {api} failed with error {res}")
raise ActionFailed()
return res
return resp
77 changes: 37 additions & 40 deletions nonebot/adapters/wxmp/bot.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from typing import Union, Any, Optional, Type, TYPE_CHECKING, cast, Literal
from typing_extensions import override
import httpx
import json
import time

Expand All @@ -13,6 +12,10 @@
NetworkError,
ApiNotAvailable,
)
from nonebot.drivers import (
Request,
Response,
)

from .event import *
from .config import BotInfo
Expand Down Expand Up @@ -76,6 +79,15 @@ async def _get_access_token(self) -> str:
self._access_token = res["access_token"]
return self._access_token

async def call_json_api(self, api: str, **data: Any) -> dict:
""" 调用微信公众平台 Json API """
resp: Response = await self.call_api(api=api, **data)
res: dict = json.loads(resp.content)
if res.get("errcode", 0) != 0:
log("ERROR", f"Call API {api} failed with error {res}")
raise ActionFailed()
return res

async def send_custom_message(self, user_id: str, message: Message):
""" 发送 客服消息 """
if isinstance(message, str):
Expand All @@ -88,7 +100,7 @@ async def send_custom_message(self, user_id: str, message: Message):
for segment in message:
segment = cast(MessageSegment, segment)
if segment.type == "text":
return await self.call_api(
return await self.call_json_api(
"/message/custom/send",
json={
"touser": user_id,
Expand All @@ -98,7 +110,7 @@ async def send_custom_message(self, user_id: str, message: Message):
)
elif segment.type == "image":
media_id = await self.upload_temp_media("image", segment.data["file"])
return await self.call_api(
return await self.call_json_api(
"/message/custom/send",
json={
"touser": user_id,
Expand All @@ -107,7 +119,7 @@ async def send_custom_message(self, user_id: str, message: Message):
},
)
elif segment.type == "link":
return await self.call_api(
return await self.call_json_api(
"/message/custom/send",
json={
"touser": user_id,
Expand All @@ -122,7 +134,7 @@ async def send_custom_message(self, user_id: str, message: Message):
)
elif segment.type == "miniprogrampage":
media_id = await self.upload_temp_media("image", segment.data["thumb_media"])
return await self.call_api(
return await self.call_json_api(
"/message/custom/send",
json={
"touser": user_id,
Expand All @@ -136,7 +148,7 @@ async def send_custom_message(self, user_id: str, message: Message):
)
elif segment.type == "voice":
media_id = await self.upload_temp_media("voice", segment.data["voice"])
return await self.call_api(
return await self.call_json_api(
"/message/custom/send",
json={
"touser": user_id,
Expand All @@ -150,51 +162,36 @@ async def send_custom_message(self, user_id: str, message: Message):
raise NotImplementedError()

async def upload_temp_media(self, type: Literal["image", "voice", "video", "thumb"], media: bytes) -> str:
""" 上传临时素材
""" 上传临时素材
小程序:仅支持 image
公众号:支持 image, voice, video, thumb
"""
access_token = await self._get_access_token()
async with httpx.AsyncClient() as client:
resp = await client.post(
url=f"https://api.weixin.qq.com/cgi-bin/media/upload",
params={
"access_token": access_token,
"type": type,
},
files={
"media": ("nonebot-upload-image.png", media, "image/png"),
},
)
if resp.status_code != 200:
raise NetworkError(
f"Get media failed with status code {resp.status_code}."
)
res: dict = resp.json()
res = await self.call_json_api(
"/media/upload",
params={
"type": type,
},
files={
"media": ("nonebot-upload-image.png", media, "image/png"),
},
)
log("INFO", f"Upload media: {res}")
return res["media_id"]

async def get_temp_media(self, media_id: str) -> bytes:
""" 获取临时素材 """
access_token = await self._get_access_token()
async with httpx.AsyncClient() as client:
resp = await client.get(
url=f"https://api.weixin.qq.com/cgi-bin/media/get",
params={
"access_token": access_token,
"media_id": media_id,
},
)
if resp.status_code != 200:
raise NetworkError(
f"Get media failed with status code {resp.status_code}."
)
return resp.content
resp: Response = await self.call_api(
"/media/get",
params={
"media_id": media_id,
},
)
return resp.content

async def set_tpying(self, command: Literal["Typing", "CancelTyping"], user_id: str):
async def set_tpying(self, command: Literal["Typing", "CancelTyping"], user_id: str) -> dict:
""" 设置用户输入状态 """
return await self.call_api(
return await self.call_json_api(
"/message/custom/typing",
json={
"touser": user_id,
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[project]
name = "nonebot-adapter-wxmp"
version = "0.0.4"
version = "0.0.5"
description = "Nonebot Adapter for Weixin Official Accounts Platform"
authors = [{ name = "YangRucheng", email = "[email protected]" }]
dependencies = ["nonebot2>=2.2.1", "xmltodict>=0.14.0", "httpx>=0.20.0"]
dependencies = ["nonebot2>=2.2.1", "xmltodict>=0.14.0"]
requires-python = ">=3.10"
readme = "README.md"
license = { text = "MIT" }

0 comments on commit 10599d0

Please sign in to comment.