Skip to content

fix(feishu): approval card not updating after button click — use PATCH instead of PUT #9533

@a13777796919-bit

Description

@a13777796919-bit

Bug: When clicking approve/deny on the interactive approval card in Feishu, the card does not update to show the decision (green/red). The card remains in its original orange state.

Root cause: _update_approval_card() in gateway/platforms/feishu.py uses UpdateMessageRequest (HTTP PUT) to update the card. Feishu's PUT endpoint replaces the entire message, which strips the interactive elements (buttons). The update appears to succeed silently but the card loses its card rendering.

Fix: Use PatchMessageRequest (HTTP PATCH) instead, which updates only the specified fields while preserving the message's interactive card format.

Changes:

  1. Add imports:
from lark_oapi.api.im.v1 import PatchMessageRequest, PatchMessageRequestBody
  1. In _update_approval_card(), replace:
body = self._build_update_message_body(msg_type="interactive", content=payload)
request = self._build_update_message_request(message_id=message_id, request_body=body)
await asyncio.to_thread(self._client.im.v1.message.update, request)

With:

body = PatchMessageRequestBody.builder().content(payload).build()
request = PatchMessageRequest.builder().message_id(message_id).request_body(body).build()
await asyncio.to_thread(self._client.im.v1.message.patch, request)

Key difference: PatchMessageRequestBody only needs .content() (no .msg_type()), and calls .patch instead of .update.

SDK: lark-oapi >= 1.5.3 already includes PatchMessageRequest and PatchMessageRequestBody.

Additional improvement: Split the guard clause if not self._client or not message_id: return into two separate checks with warning logs for easier debugging when message_id is empty.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existscomp/gatewayGateway runner, session dispatch, deliveryplatform/feishuFeishu / Lark adaptersweeper:implemented-on-mainSweeper: behavior already present on current maintype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions