Skip to content

feat: add Feishu/Lark WASM channel plugin#1110

Merged
ilblackdragon merged 1 commit intonearai:stagingfrom
reidliu41:feat/feishu-channel
Mar 15, 2026
Merged

feat: add Feishu/Lark WASM channel plugin#1110
ilblackdragon merged 1 commit intonearai:stagingfrom
reidliu41:feat/feishu-channel

Conversation

@reidliu41
Copy link
Copy Markdown
Contributor

Summary

  • Implement Feishu Event Subscription v2.0 webhook (URL verification + im.message.receive_v1)
  • Token exchange via workspace-cached app credentials with 5-min pre-expiry refresh
  • Host-side secret injection into config JSON (setup.rs) so WASM can access app_id/app_secret without env vars
  • Reply and broadcast via /open-apis/im/v1/messages
  • Enforce allow_from user filtering in message handler
  • DM pairing flow with owner_id restriction
  • Dual API base support: open.feishu.cn (Feishu) / open.larksuite.com (Lark)
  • Registry manifest, bundled channel entry, messaging bundle integration
  • Strip raw config_json debug log to prevent secret leakage

Change Type

  • Bug fix
  • New feature
  • Refactor
  • Documentation
  • CI/Infrastructure
  • Security
  • Dependencies

Linked Issue

part of #1046

Validation

  • cargo fmt
  • cargo clippy --all --benches --tests --examples --all-features
  • Relevant tests pass:
  • Manual testing:

Security Impact

None

Database Impact

None

Blast Radius

Rollback Plan


Review track:

  part of nearai#1046

  - Implement Feishu Event Subscription v2.0 webhook (URL verification + im.message.receive_v1)
  - Token exchange via workspace-cached app credentials with 5-min pre-expiry refresh
  - Host-side secret injection into config JSON (setup.rs) so WASM can access app_id/app_secret without env vars
  - Reply and broadcast via /open-apis/im/v1/messages
  - Enforce allow_from user filtering in message handler
  - DM pairing flow with owner_id restriction
  - Dual API base support: open.feishu.cn (Feishu) / open.larksuite.com (Lark)
  - Registry manifest, bundled channel entry, messaging bundle integration
  - Strip raw config_json debug log to prevent secret leakage
@github-actions github-actions Bot added scope: channel/wasm WASM channel runtime scope: docs Documentation size: XL 500+ changed lines risk: medium Business logic, config, or moderate-risk modules contributor: experienced 6-19 merged PRs labels Mar 13, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant new feature by adding a Feishu/Lark WASM channel plugin. This enables the platform to seamlessly integrate with Feishu and Lark bots, allowing for message reception via webhooks and outbound messaging. The changes include secure handling of API credentials, robust token management, and flexible configuration options to support various deployment scenarios and user interaction policies, thereby expanding the system's communication capabilities.

Highlights

  • New Feishu/Lark WASM Channel: Introduced a new WebAssembly (WASM) channel plugin for Feishu/Lark, enabling communication with Feishu/Lark bots.
  • Webhook and Token Management: Implemented Feishu Event Subscription v2.0 webhook handling, including URL verification, and a robust tenant access token exchange mechanism with 5-minute pre-expiry refresh.
  • Secure Secret Injection: Developed a host-side mechanism to inject app credentials (app_id, app_secret) directly into the WASM channel's configuration, preventing secret leakage and facilitating token exchange.
  • Messaging Capabilities: Enabled replying and broadcasting messages via the Feishu/Lark API, supporting both direct messages (p2p) and group chats with @mentions.
  • User Filtering and DM Pairing: Added allow_from user filtering and a DM pairing flow with owner_id restriction to control who can interact with the bot.
  • Dual API Base Support: Configured support for both Feishu (open.feishu.cn) and Lark (open.larksuite.com) API bases, offering flexibility for different regional deployments.
  • Registry Integration: Integrated the new Feishu channel into the system's registry, including manifest, bundled channel entry, and messaging bundle integration.
Changelog
  • FEATURE_PARITY.md
    • Updated the status of Feishu/Lark integration to 'in progress' (🚧) and noted the new WASM channel with Event Subscription v2.0.
  • channels-src/feishu/Cargo.toml
    • Added a new Cargo.toml file for the feishu-channel WASM component, specifying its name, version, description, and dependencies like wit-bindgen, serde, and serde_json.
  • channels-src/feishu/build.sh
    • Added a new shell script to automate the building of the Feishu/Lark WASM component, including Rust compilation for wasm32-wasip2 target and wasm-tools for component creation and optimization.
  • channels-src/feishu/feishu.capabilities.json
    • Added a new capabilities JSON file defining the Feishu/Lark channel's metadata, authentication requirements, HTTP allowlist for API calls, secret access permissions, and default configuration parameters.
  • channels-src/feishu/src/lib.rs
    • Added the core Rust implementation for the Feishu/Lark WASM channel, including data structures for Feishu API types, webhook handling logic (URL verification, message reception), tenant access token management, and functions for sending replies and broadcast messages.
  • registry/_bundles.json
    • Added the 'channels/feishu' entry to the 'messaging' bundle, making it available as a bundled channel.
  • registry/channels/feishu.json
    • Added a new registry manifest file for the Feishu/Lark channel, providing its display name, description, keywords, source directory, and authentication summary.
  • src/channels/wasm/bundled.rs
    • Added 'feishu' to the KNOWN_CHANNELS array, registering it as a recognized WASM channel.
  • src/channels/wasm/setup.rs
    • Modified the register_channel function to include a call to inject_channel_secrets_into_config for channels requiring direct secret injection into their configuration.
    • Added a new asynchronous function inject_channel_secrets_into_config to handle injecting specific secrets (e.g., app_id, app_secret for Feishu) from the secrets store or environment variables directly into the channel's configuration JSON.
Activity
  • No specific activity (comments, reviews, progress updates) has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new WASM channel plugin for Feishu/Lark, which is a significant feature addition. The implementation is comprehensive, covering webhook handling for Event Subscription v2.0, tenant access token exchange with caching, and message processing that includes user filtering and a DM pairing flow. The host-side changes to inject secrets directly into the WASM configuration for token exchange are well-designed. The code is well-structured and follows the existing patterns for WASM components in the project. I have one suggestion to improve error handling in the pairing request logic to make it more robust, aligning with best practices for clear error reporting.

Comment on lines +499 to +507
let _ = channel_host::pairing_upsert_request(
"feishu",
sender_id,
&meta.to_string(),
);
channel_host::log(
channel_host::LogLevel::Info,
&format!("Pairing request created for {}", sender_id),
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The result of channel_host::pairing_upsert_request is currently ignored. If this call fails, the subsequent log message "Pairing request created for..." would be misleading. It's better to handle the Result to ensure the log reflects the actual outcome and to aid in debugging potential issues with the pairing flow. This aligns with the principle of providing clear and semantically correct error messages.

Suggested change
let _ = channel_host::pairing_upsert_request(
"feishu",
sender_id,
&meta.to_string(),
);
channel_host::log(
channel_host::LogLevel::Info,
&format!("Pairing request created for {}", sender_id),
);
match channel_host::pairing_upsert_request("feishu", sender_id, &meta.to_string()) {
Ok(_) => channel_host::log(
channel_host::LogLevel::Info,
&format!("Pairing request created for {}", sender_id),
),
Err(e) => channel_host::log(
channel_host::LogLevel::Error,
&format!("Failed to create pairing request for {}: {}", sender_id, e),
),
}
References
  1. Create specific error variants for different failure modes (e.g., DownloadFailed with a URL string vs. ManifestRead with a file path) to provide semantically correct and clear error messages. This comment improves error reporting by logging the actual error, which is a step towards providing semantically correct and clear error messages.

Copy link
Copy Markdown
Collaborator

@zmanian zmanian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid WASM channel implementation following established patterns (Telegram, Slack, Discord). Token exchange with 5-min pre-expiry refresh is properly implemented. Host-side integration (setup.rs, registry manifest, bundled channel entry) is complete. This is the better-integrated of the two competing Feishu PRs. LGTM.

@reidliu41
Copy link
Copy Markdown
Contributor Author

This PR is approved and CI is green — could you help merge it? Thanks!

@ilblackdragon ilblackdragon merged commit 97b11ff into nearai:staging Mar 15, 2026
13 checks passed
reidliu41 added a commit to reidliu41/ironclaw that referenced this pull request Mar 15, 2026
…earai#1200)

  The Feishu channel merged in nearai#1110 could not be compiled due to
  mismatches with the WIT-generated bindings. CI did not catch this
  because standalone WASM channel crates are outside the main workspace.

  - Replace nonexistent export_sandboxed_channel! with export! macro
  - Fix http_request body arg: &String -> .as_bytes() for Option<&[u8]>
  - Fix pairing_is_allowed arg: &String -> Some(&str) for Option<&str>
  - Fix emit_message arg: pass &EmittedMessage instead of owned value
  - Add Default derive to TenantAccessTokenData for serde deserialization
  - Remove unused imports (Attachment, PollConfig)
  - Track Cargo.lock consistent with other channel crates
bkutasi pushed a commit to bkutasi/ironclaw that referenced this pull request Mar 28, 2026
part of nearai#1046

  - Implement Feishu Event Subscription v2.0 webhook (URL verification + im.message.receive_v1)
  - Token exchange via workspace-cached app credentials with 5-min pre-expiry refresh
  - Host-side secret injection into config JSON (setup.rs) so WASM can access app_id/app_secret without env vars
  - Reply and broadcast via /open-apis/im/v1/messages
  - Enforce allow_from user filtering in message handler
  - DM pairing flow with owner_id restriction
  - Dual API base support: open.feishu.cn (Feishu) / open.larksuite.com (Lark)
  - Registry manifest, bundled channel entry, messaging bundle integration
  - Strip raw config_json debug log to prevent secret leakage
drchirag1991 pushed a commit to drchirag1991/ironclaw that referenced this pull request Apr 8, 2026
part of nearai#1046

  - Implement Feishu Event Subscription v2.0 webhook (URL verification + im.message.receive_v1)
  - Token exchange via workspace-cached app credentials with 5-min pre-expiry refresh
  - Host-side secret injection into config JSON (setup.rs) so WASM can access app_id/app_secret without env vars
  - Reply and broadcast via /open-apis/im/v1/messages
  - Enforce allow_from user filtering in message handler
  - DM pairing flow with owner_id restriction
  - Dual API base support: open.feishu.cn (Feishu) / open.larksuite.com (Lark)
  - Registry manifest, bundled channel entry, messaging bundle integration
  - Strip raw config_json debug log to prevent secret leakage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: experienced 6-19 merged PRs risk: medium Business logic, config, or moderate-risk modules scope: channel/wasm WASM channel runtime scope: docs Documentation size: XL 500+ changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants