Skip to content

💥 replace the communication layer with larkify - #178

Merged
StarHeartHunt merged 3 commits into
masterfrom
feat/larkify
Nov 7, 2026
Merged

StarHeartHunt merged 3 commits into
masterfrom
feat/larkify

Conversation

@StarHeartHunt

Copy link
Copy Markdown
Member

Replaces the hand-written HTTP, token, webhook and WebSocket code with larkify, a typed Feishu / Lark SDK built on httpx2 and pydantic. This follows the way adapter-github builds on githubkit. Events, messages, and the existing Bot methods are unchanged.

This is a breaking change and is released as 3.0.0. The new migration guide covers it for users.

Changes

Communication layer

  • Bot.feishu is a larkify client, created on first use so that a Bot can still be built with a fake adapter in plugin tests.
  • Dispatcher overrides EventDispatcher.adispatch, so webhooks and the long connection share one entry point. larkify handles URL verification, decryption, signatures, and acknowledgements. Events still go through json_to_event.
  • nonebot.adapters.feishu.ws is removed, along with frame_pb2. Adapter.startup runs larkify.ws.WSClient instead.
  • larkify logs now go through LoguruHandler, so LOG_LEVEL and loguru sinks apply to them.
  • The tenant token still comes from tenant_access_token/internal. Moving to the newer OAuth endpoint can happen separately, once it has been tried on a real app.

New: bot.rest

response = await bot.rest.im.v1.message.async_get("om_xxx")
print(response.parsed_data)

As in adapter-github, these calls go through call_api, so on_calling_api and on_called_api still run. One difference: positional arguments work here. The path parameters of the generated methods can be positional, so a keyword-only proxy would pass type checking and then fail at runtime.

bot.call_api("im/v1/messages", method="GET", ...) keeps working and returns the same shape.

Breaking changes

Area 2.x 3.0
HTTP 4xx, 5xx NetworkError ActionFailed
HTTP 200 with a non-zero code returns the body ActionFailed
Token request rejected NetworkError ActionFailed
Bot info fails at startup aborts startup skips that bot and logs an error
URL verification with a wrong token 200 401
Encrypted event, missing or bad signature 200 401
Wrong or missing verification token 403 or 400 401
Long connection reconnect delay fixed 3 seconds set by Feishu
Long connection, unrecoverable error retries forever disconnects the bot and logs an error
pydantic 1.x and 2.x 2.11 or later

ActionFailed was documented on Bot.call_api but never raised. Rate-limited requests and server errors on idempotent requests are now retried automatically. POST requests are not retried after a server error, so a message cannot be sent twice.

send_request, get_api_url, get_tenant_access_token, AESCipher, cache, and TenantAccessTokenResponse are removed.

Behavior that stays the same

  • A plain http:// api_base still works, through insecure_allow_http. The defaults are https, so http can only come from explicit configuration.
  • API_TIMEOUT=null still means no timeout, and _timeout still applies per call.
  • Deliveries without a header, which means event v1, still get a 400.

Dependencies

protobuf, cashews, and pycryptodome are replaced by larkify[crypto,ws] and httpx2. A forward driver is no longer needed: webhooks need an ASGI driver, and bots that only use the long connection can run on DRIVER=~none.

Testing

  • pytest: 102 passed on Python 3.11 and 3.15, also from a clean export with the locked dependencies. The test driver is now ~fastapi alone.
  • tests/test_feishu_ws.py is rewritten, because the old tests covered the removed internals. Events now travel over a real socket to Bot.handle_event.
  • New webhook tests cover wrong tokens, event v1, malformed bodies, and encrypted deliveries with good, missing, and forged signatures. tests/test_feishu_api.py covers call_api and bot.rest.
  • Smoke test with a real nonebot.run() on ~none against a local fake Feishu: a long connection event reached a matcher, and bot.send called the API with a token.
  • pnpm build, scripts/build_api_docs.py, and Ruff pass. Pyright reports nothing new in nonebot/.

Not tested against real Feishu. Everything above uses local fake servers. Before releasing, please try one app on each of these:

  • Webhook with an Encrypt Key, including the signature check
  • Long connection
  • Sending a message and uploading a file

Release notes

  • The commit :bookmark: release 3.0.0 only sets the version. Pruning website/versioned_docs and running the Release workflow are left for release time.
  • release-drafter.yml refers to Breaking and major labels, but neither exists in this repository, so this PR is labeled enhancement. The tag comes from pyproject.toml, so the version is not affected.

Tokens, HTTP, webhook verification and the long connection now come from larkify, following the approach of adapter-github. The events, messages and Bot methods stay as they are.
Covers the driver requirements, calling the API and what changes coming from 2.x.
@StarHeartHunt StarHeartHunt added the enhancement New feature or request label Nov 7, 2026
@github-actions

github-actions Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

@codecov

codecov Bot commented Nov 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.29060% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.50%. Comparing base (201aa75) to head (fc3d18c).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
nonebot/adapters/feishu/adapter.py 97.53% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #178      +/-   ##
==========================================
+ Coverage   83.82%   87.50%   +3.68%     
==========================================
  Files          15       11       -4     
  Lines        1719     1497     -222     
==========================================
- Hits         1441     1310     -131     
+ Misses        278      187      -91     
Flag Coverage Δ
unittests 87.50% <98.29%> (+3.68%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@StarHeartHunt
StarHeartHunt merged commit fdeb08a into master Nov 7, 2026
21 checks passed
@StarHeartHunt
StarHeartHunt deleted the feat/larkify branch November 7, 2026 08:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant