Skip to content

feat: add image message decryption and download#18

Open
echowxsy wants to merge 1 commit intocv-cat:masterfrom
echowxsy:feat/image-decrypt
Open

feat: add image message decryption and download#18
echowxsy wants to merge 1 commit intocv-cat:masterfrom
echowxsy:feat/image-decrypt

Conversation

@echowxsy
Copy link
Copy Markdown

Summary

Feishu encrypts image messages with AES-256-GCM before sending them via WebSocket. This PR adds full support for receiving, decrypting, and saving image messages.

Changes

  • app/api/image_decrypt.py (new): Complete image decryption pipeline

    • AES-256-GCM decryption using key/IV extracted from protobuf message content
    • Raw protobuf parsing to extract image_id, decrypt key, and IV from nested image message structure
    • CDN download with cookie authentication
    • File type detection from magic bytes (JPEG, PNG, WebP, GIF, BMP, TIFF)
    • Local file caching to avoid re-downloading
    • Images saved to ~/.lark/msg/images/
  • builder/proto.py: Handle image messages (type=5) in decode_receive_msg_proto, storing raw content bytes and messageType field

  • app/api/lark_client.py: Update process_msg to detect image messages, extract decrypt info, download and decrypt automatically, pass message_type and image_info to handler

  • app/core/message_service.py: Accept new message_type and image_info parameters, log image details

  • app/core/mcp_server.py: Add download_image MCP tool for on-demand image decryption

Encryption scheme

The WebSocket push for image messages contains:

  1. image_id (e.g., img_v3_xxxx) identifying the image on Feishu CDN
  2. AES-256-GCM encryption key (32-byte key, 12-byte IV) embedded in a nested protobuf structure

Flow: parse protobuf → extract key/IV → download encrypted payload from CDN → decrypt with AES-256-GCM → detect type → save to disk.

Test plan

  • Receive an image message via WebSocket and verify it is auto-decrypted and saved
  • Verify cached images are not re-downloaded
  • Test the download_image MCP tool with known image_id, key_hex, iv_hex
  • Verify file type detection for JPEG, PNG, and WebP images
  • Test with invalid key/IV to verify error handling

🤖 Generated with Claude Code

Feishu encrypts image messages with AES-256-GCM. This adds:

- Image decryption pipeline: download from CDN → decrypt → detect type → save
- Raw protobuf parsing to extract image_id, decrypt key, and IV from
  nested image message content structure
- Local caching to avoid re-downloading images
- Image type detection from magic bytes (JPEG, PNG, WebP, GIF, BMP, TIFF)
- WebSocket handler now processes image messages (type=5) and auto-decrypts
- MCP tool `download_image` for on-demand image decryption
- Images saved to ~/.lark/msg/images/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant