diff --git a/docs_build/adapters/ding.rst b/docs_build/adapters/ding.rst
new file mode 100644
index 00000000..b26dac19
--- /dev/null
+++ b/docs_build/adapters/ding.rst
@@ -0,0 +1,12 @@
+---
+contentSidebar: true
+sidebarDepth: 0
+---
+
+NoneBot.adapters.ding 模块
+============================
+
+.. automodule:: nonebot.adapters.ding
+ :members:
+ :private-members:
+ :show-inheritance:
diff --git a/nonebot/adapters/__init__.py b/nonebot/adapters/__init__.py
index 271ff543..4d1fa60c 100644
--- a/nonebot/adapters/__init__.py
+++ b/nonebot/adapters/__init__.py
@@ -140,7 +140,7 @@ class BaseBot(abc.ABC):
T = TypeVar("T", bound=BaseModel)
-class BaseEvent(Generic[T], abc.ABC):
+class BaseEvent(abc.ABC, Generic[T]):
"""
Event 基类。提供上报信息的关键信息,其余信息可从原始上报消息获取。
"""
@@ -149,7 +149,7 @@ class BaseEvent(Generic[T], abc.ABC):
"""
:参数:
- * ``raw_event: T``: 原始上报消息
+ * ``raw_event: Union[dict, T]``: 原始上报消息
"""
self._raw_event = raw_event
diff --git a/nonebot/adapters/ding/__init__.py b/nonebot/adapters/ding/__init__.py
index 8b5f101d..e9742bf4 100644
--- a/nonebot/adapters/ding/__init__.py
+++ b/nonebot/adapters/ding/__init__.py
@@ -12,4 +12,4 @@
from .bot import Bot
from .event import Event
from .message import Message, MessageSegment
-from .exception import ApiError, SessionExpired, AdapterException
+from .exception import ApiError, SessionExpired, DingAdapterException
diff --git a/nonebot/adapters/ding/bot.py b/nonebot/adapters/ding/bot.py
index 4acfc2fc..bfc106d0 100644
--- a/nonebot/adapters/ding/bot.py
+++ b/nonebot/adapters/ding/bot.py
@@ -4,7 +4,7 @@ import httpx
from nonebot.log import logger
from nonebot.config import Config
from nonebot.message import handle_event
-from nonebot.typing import Driver, WebSocket, NoReturn
+from nonebot.typing import Driver, NoReturn
from nonebot.typing import Any, Union, Optional
from nonebot.adapters import BaseBot
from nonebot.exception import NetworkError, RequestDenied, ApiNotAvailable
@@ -20,19 +20,10 @@ class Bot(BaseBot):
钉钉 协议 Bot 适配。继承属性参考 `BaseBot <./#class-basebot>`_ 。
"""
- def __init__(self,
- driver: Driver,
- connection_type: str,
- config: Config,
- self_id: str,
- *,
- websocket: Optional[WebSocket] = None):
+ def __init__(self, driver: Driver, connection_type: str, config: Config,
+ self_id: str, **kwargs):
- super().__init__(driver,
- connection_type,
- config,
- self_id,
- websocket=websocket)
+ super().__init__(driver, connection_type, config, self_id, **kwargs)
@property
def type(self) -> str:
@@ -56,26 +47,19 @@ class Bot(BaseBot):
# 检查 timestamp
if not timestamp:
- log("WARNING", "Missing `timestamp` Header")
raise RequestDenied(400, "Missing `timestamp` Header")
# 检查 sign
if not sign:
- log("WARNING", "Missing `sign` Header")
raise RequestDenied(400, "Missing `sign` Header")
# 校验 sign 和 timestamp,判断是否是来自钉钉的合法请求
if not check_legal(timestamp, sign, driver):
- log("WARNING", "Signature Header is invalid")
raise RequestDenied(403, "Signature is invalid")
# 检查连接方式
if connection_type not in ["http"]:
- log("WARNING", "Unsupported connection type")
raise RequestDenied(405, "Unsupported connection type")
access_token = driver.config.access_token
if access_token and access_token != access_token:
- log(
- "WARNING", "Authorization Header is invalid"
- if access_token else "Missing Authorization Header")
raise RequestDenied(
403, "Authorization Header is invalid"
if access_token else "Missing Authorization Header")
@@ -116,6 +100,9 @@ class Bot(BaseBot):
- ``NetworkError``: 网络错误
- ``ActionFailed``: API 调用失败
"""
+ if self.connection_type != "http":
+ log("ERROR", "Only support http connection.")
+ return
if "self_id" in data:
self_id = data.pop("self_id")
if self_id:
@@ -125,9 +112,9 @@ class Bot(BaseBot):
log("DEBUG", f"Calling API {api}")
log("DEBUG", f"Calling data {data}")
- if self.connection_type == "http" and api == "post_webhook":
+ if api == "send_message":
raw_event: MessageModel = data["raw_event"]
-
+ # 确保 sessionWebhook 没有过期
if int(datetime.now().timestamp()) > int(
raw_event.sessionWebhookExpiredTime / 1000):
raise SessionExpired
@@ -202,4 +189,4 @@ class Bot(BaseBot):
params["message"] = msg
log("DEBUG", f"send -> params: {params}")
- return await self.call_api("post_webhook", **params)
+ return await self.call_api("send_message", **params)
diff --git a/nonebot/adapters/ding/event.py b/nonebot/adapters/ding/event.py
index f462f0d3..9c9fb50f 100644
--- a/nonebot/adapters/ding/event.py
+++ b/nonebot/adapters/ding/event.py
@@ -1,9 +1,7 @@
-from typing import Literal
+from typing import Literal, Union, Optional
from nonebot.adapters import BaseEvent
-from nonebot.typing import Optional
-from .utils import log
from .message import Message
from .model import MessageModel, ConversationType, TextMessage
@@ -15,9 +13,7 @@ class Event(BaseEvent):
def __init__(self, message: MessageModel):
super().__init__(message)
- if not message.msgtype:
- log("ERROR", "message has no msgtype")
- # 目前钉钉机器人只能接收到 text 类型的消息
+ # 其实目前钉钉机器人只能接收到 text 类型的消息
self._message = Message(getattr(message, message.msgtype or "text"))
@property
@@ -37,12 +33,9 @@ class Event(BaseEvent):
def name(self) -> str:
"""
- 类型: ``str``
- - 说明: 事件名称,由类型与 ``.`` 组合而成
+ - 说明: 事件名称,由 `type`.`detail_type` 组合而成
"""
- n = self.type + "." + self.detail_type
- if self.sub_type:
- n += "." + self.sub_type
- return n
+ return self.type + "." + self.detail_type
@property
def self_id(self) -> str:
@@ -89,12 +82,12 @@ class Event(BaseEvent):
self.raw_event.conversationType = ConversationType.group
@property
- def sub_type(self) -> Optional[str]:
+ def sub_type(self) -> None:
"""
- - 类型: ``Optional[str]``
- - 说明: 事件子类型
+ - 类型: ``None``
+ - 说明: 钉钉适配器无事件子类型
"""
- return ""
+ return None
@sub_type.setter
def sub_type(self, value) -> None:
@@ -134,7 +127,7 @@ class Event(BaseEvent):
@to_me.setter
def to_me(self, value) -> None:
- self.raw_event.isInAtList = value
+ pass
@property
def message(self) -> Optional["Message"]:
@@ -157,7 +150,7 @@ class Event(BaseEvent):
raise ValueError("暂不支持 reply")
@property
- def raw_message(self) -> Optional[TextMessage]:
+ def raw_message(self) -> Optional[Union[TextMessage]]:
"""
- 类型: ``Optional[str]``
- 说明: 原始消息
diff --git a/nonebot/adapters/ding/exception.py b/nonebot/adapters/ding/exception.py
index bfb318c5..7b845afe 100644
--- a/nonebot/adapters/ding/exception.py
+++ b/nonebot/adapters/ding/exception.py
@@ -2,6 +2,12 @@ from nonebot.exception import AdapterException
class DingAdapterException(AdapterException):
+ """
+ :说明:
+
+ 钉钉 Adapter 错误基类
+
+ """
def __init__(self) -> None:
super.__init__("DING")
@@ -11,7 +17,7 @@ class ApiError(DingAdapterException):
"""
:说明:
- API 请求成功返回数据,但 API 操作失败。
+ API 请求返回错误信息。
"""
@@ -24,6 +30,12 @@ class ApiError(DingAdapterException):
class SessionExpired(DingAdapterException):
+ """
+ :说明:
+
+ 发消息的 session 已经过期。
+
+ """
def __repr__(self) -> str:
return f""
diff --git a/nonebot/exception.py b/nonebot/exception.py
index 1f61f5ed..b374f4c5 100644
--- a/nonebot/exception.py
+++ b/nonebot/exception.py
@@ -148,6 +148,15 @@ class ActionFailed(Exception):
class AdapterException(Exception):
+ """
+ :说明:
- def __init__(self, adapter_name) -> None:
+ 代表 Adapter 抛出的异常,所有的 Adapter 都要在内部继承自这个 `Exception`
+
+ :参数:
+
+ * ``adapter_name: str``: 标识 adapter
+ """
+
+ def __init__(self, adapter_name: str) -> None:
self.adapter_name = adapter_name