receiver
feishu.events.receiver
¶
create_event_route
¶
create_event_route(dispatcher: EventDispatcher, *, path: str = '/feishu/event', encrypt_key: str | None = None, verification_token: str | None = None, seen_store: Any = _DEFAULT_SEEN_STORE, max_age_seconds: float | None = 300, now: Callable[[], float] = time) -> Route
创建处理飞书事件推送的 Starlette POST 路由。
该端点的处理流程:
- 先读取原始请求体字节(签名校验与 AES 解密都依赖未经改动的原始字节)。
- 当配置了
encrypt_key且请求头包含X-Lark-Signature时, 经 SignatureVerifier 校验签名 并校验时间戳新鲜度(重放时间窗),记录校验结果。 - 若请求体被
encrypt包裹,则先行解密。 - 处理
url_verification握手:握手仅通过内层verification_token鉴权, 不要求 MAC 签名(签名豁免仅在此处生效)。 - 其余正常事件:当配置了
encrypt_key时,签名必须存在、时间戳在max_age_seconds时间窗内且校验通过;缺失签名或时间戳过期将返回 401 (防止 Webhook 注入与重放攻击绕过)。 - 通过
seen_store去重(默认即开启),其余事件以后台任务(BackgroundTask) 异步分发,端点立即返回200 {}。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
EventDispatcher
|
事件分发器。 |
必需 |
|
str
|
路由路径,默认 |
'/feishu/event'
|
|
str | None
|
应用配置的 Encrypt Key;设置后启用解密与签名强校验。 |
None
|
|
str | None
|
握手校验 Token;设置后会校验 |
None
|
|
Any
|
事件去重存储;缺省时使用新建的
InMemorySeenStore,
从而开箱即用地提供去重/防重放保护;显式传入 |
_DEFAULT_SEEN_STORE
|
|
float | None
|
签名请求允许的最大时延(秒),默认 |
300
|
|
Callable[[], float]
|
返回当前 epoch 秒的可调用对象,默认 time.time;可注入以编写确定性测试。 |
time
|
返回:
| 类型 | 描述 |
|---|---|
Route
|
可挂载到 Starlette 应用的 [Route][starlette.routing.Route]。 |
飞书文档
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/events/receiver.py
| Python | |
|---|---|
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | |
create_card_route
¶
create_card_route(dispatcher: EventDispatcher, *, path: str = '/feishu/card', encrypt_key: str | None = None, verification_token: str | None = None, seen_store: Any = _DEFAULT_SEEN_STORE, max_age_seconds: float | None = 300, now: Callable[[], float] = time) -> Route
创建处理飞书卡片交互回调的 Starlette POST 路由。
与 create_event_route 不同,本路由会
**同步**等待分发器执行(不使用后台任务),并将处理函数返回的 {toast, card} 字典
作为同步 JSON 响应返回,以满足飞书对卡片交互约 3 秒的响应时限。当处理函数返回 None 时,
响应为 200 {}。
安全模型与 create_event_route 一致:
url_verification握手仅通过内层verification_token鉴权(签名豁免在此生效)。- 其余事件在配置了
encrypt_key时,必须携带并经 SignatureVerifier 通过X-Lark-Signature校验,且时间戳须在max_age_seconds时间窗内(防重放);缺失、过期或非法签名将返回 401,且处理函数不会被调用。
由于飞书在超时时会重试卡片回调,命中 seen_store 的重复事件会直接返回 {},避免重复触发副作用。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
EventDispatcher
|
事件分发器。 |
必需 |
|
str
|
路由路径,默认 |
'/feishu/card'
|
|
str | None
|
应用配置的 Encrypt Key;设置后启用解密与签名强校验。 |
None
|
|
str | None
|
握手校验 Token;设置后会校验 |
None
|
|
Any
|
事件去重存储;缺省时使用新建的
InMemorySeenStore,
从而开箱即用地提供去重/防重放保护;显式传入 |
_DEFAULT_SEEN_STORE
|
|
float | None
|
签名请求允许的最大时延(秒),默认 |
300
|
|
Callable[[], float]
|
返回当前 epoch 秒的可调用对象,默认 time.time;可注入以编写确定性测试。 |
time
|
返回:
| 类型 | 描述 |
|---|---|
Route
|
可挂载到 Starlette 应用的 [Route][starlette.routing.Route]。 |
飞书文档
示例:
| Python Console Session | |
|---|---|
源代码位于: feishu/events/receiver.py
| Python | |
|---|---|
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | |
create_event_app
¶
create_event_app(dispatcher: EventDispatcher, *, event_path: str = '/feishu/event', card_path: str | None = '/feishu/card', encrypt_key: str | None = None, verification_token: str | None = None, seen_store: Any = _DEFAULT_SEEN_STORE, card_seen_store: Any = _DEFAULT_SEEN_STORE, max_age_seconds: float | None = 300, now: Callable[[], float] = time) -> Starlette
返回一个可独立运行、处理飞书 Webhook 推送的 Starlette 应用。
始终在 event_path 挂载事件路由;当 card_path 不为 None 时,额外在该路径挂载卡片回调路由。
全部安全与路由逻辑分别委托给 create_event_route
与 create_card_route,因此默认即带有
签名新鲜度(防重放)时间窗与去重保护。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
|
EventDispatcher
|
事件分发器。 |
必需 |
|
str
|
事件路由路径,默认 |
'/feishu/event'
|
|
str | None
|
卡片回调路由路径,默认 |
'/feishu/card'
|
|
str | None
|
应用配置的 Encrypt Key;设置后启用解密与签名强校验。 |
None
|
|
str | None
|
握手校验 Token;设置后会校验 |
None
|
|
Any
|
事件路由的去重存储;缺省时各路由自建
InMemorySeenStore,
显式传入 |
_DEFAULT_SEEN_STORE
|
|
Any
|
卡片路由的去重存储;语义同 |
_DEFAULT_SEEN_STORE
|
|
float | None
|
签名请求允许的最大时延(秒),默认 |
300
|
|
Callable[[], float]
|
返回当前 epoch 秒的可调用对象,默认 time.time;可注入以编写确定性测试。 |
time
|
返回:
| 类型 | 描述 |
|---|---|
Starlette
|
已挂载相应路由的 [Starlette][starlette.applications.Starlette] 应用。 |
飞书文档
示例:
| Python Console Session | |
|---|---|