How to Integrate Feishu Bot with OpenDeepWiki: A Complete Implementation Guide

OpenDeepWiki integrates Feishu Bot through a unified Message Provider architecture that handles authentication, webhook validation, and message formatting via the FeishuProvider class in the AIDotNet/OpenDeepWiki repository.

The AIDotNet/OpenDeepWiki project provides a modular chat infrastructure that abstracts platform-specific bot implementations into reusable providers. When you integrate Feishu Bot with OpenDeepWiki, you leverage the Message Provider mechanism located in src/OpenDeepWiki/Chat/Providers/Feishu/ to handle tenant access tokens, webhook security verification, and bidirectional message parsing.

Understanding the Feishu Provider Architecture

Core Components and File Structure

The Feishu integration resides in the src/OpenDeepWiki/Chat/Providers/Feishu/ directory and consists of four primary files:

Configuration Options (FeishuProviderOptions)

The FeishuProviderOptions class in FeishuProviderOptions.cs exposes the following configuration properties under the Chat:Providers:Feishu section:

  • AppId and AppSecret — Tenant credentials from the Feishu Open Platform.
  • VerificationToken — Used to validate incoming webhook requests.
  • EncryptKey — Optional AES key for decrypting encrypted webhook payloads.
  • ApiBaseUrl — Defaults to https://open.feishu.cn/open-apis.
  • TokenCacheSeconds — Access token cache duration (default 7000 seconds).

Configuring Feishu Bot Integration in OpenDeepWiki

appsettings.json Configuration

Add the Feishu provider configuration to your appsettings.json or secure configuration source:

{
  "Chat": {
    "Providers": {
      "Feishu": {
        "AppId": "<your_app_id>",
        "AppSecret": "<your_app_secret>",
        "VerificationToken": "<your_verification_token>",
        "EncryptKey": "<your_encrypt_key>",
        "ApiBaseUrl": "https://open.feishu.cn/open-apis",
        "TokenCacheSeconds": 7000,
        "Enabled": true,
        "MessageInterval": "00:00:01"
      }
    }
  }
}

Store sensitive values in environment variables or Azure Key Vault rather than committing them to source control.

Service Registration in Program.cs

Register the chat services and Feishu provider in your Program.cs:

builder.Services.AddChatServices(builder.Configuration);

The AddChatServices extension method in ChatServiceExtensions.cs performs the following registrations:

  1. Binds FeishuProviderOptions to the configuration section Chat:Providers:Feishu.
  2. Adds a named HttpClient for FeishuProvider with base address and default headers.
  3. Registers FeishuProvider as a scoped service implementing IMessageProvider.
  4. Adds the provider instance to the IMessageProvider collection for automatic discovery during startup.

Implementing the Feishu Bot Workflow

Initialization and Access Token Management

During application startup, the ProviderInitializationService calls FeishuProvider.InitializeAsync, which invokes GetAccessTokenAsync (lines 50-71 in FeishuProvider.cs). This method:

  • Posts app_id and app_secret to auth/v3/tenant_access_token/internal.
  • Caches the returned token for TokenCacheSeconds (default 7000 seconds) in memory.
  • Uses SemaphoreSlim to prevent concurrent token refresh requests.
// Internal implementation detail from FeishuProvider.cs
private async Task<string> GetAccessTokenAsync(CancellationToken ct)
{
    // Checks cache first, then requests new token if expired
    // Uses SemaphoreSlim for thread safety
}

Webhook Validation and Security

Incoming webhook requests from Feishu pass through ValidateWebhookAsync (lines 95-124), which handles:

  • URL Verification: Returns the challenge parameter for Feishu platform verification.
  • Token Validation: Compares the request token against VerificationToken.
  • Decryption: If EncryptKey is configured, decrypts AES-encrypted payloads before validation.

Parsing Incoming Messages

The ParseMessageAsync method (lines 74-132) converts Feishu-specific payloads into the unified ChatMessage model:

  1. Deserializes the raw JSON into FeishuWebhookEvent.
  2. Decrypts if necessary using the configured EncryptKey.
  3. Identifies event types (im.message.receive_v1 or message).
  4. Extracts message_type and content via ParseFeishuMessageContent.
  5. Returns a ChatMessage containing MessageId, SenderId, ReceiverId, Content, MessageType, Timestamp, and Metadata.

Sending Replies and Cards

The SendMessageAsync method (lines 140-191) handles outbound communication:

  • Retrieves a valid AccessToken via GetAccessTokenAsync.
  • Calls DegradeMessage to convert unsupported message types to text.
  • Uses ConvertToFeishuFormat to generate Feishu-specific msg_type and content JSON.
  • POSTs to im/v1/messages via HttpClient.
  • Implements retry logic via IsRetryableError and SendWithRetryAsync for transient failures.

For interactive cards, use the static helper methods:

// Create a simple text card
var cardJson = FeishuProvider.CreateTextCard(
    title: "系统通知",
    content: "OpenDeepWiki 已成功接收到你的请求。",
    headerColor: "indigo");

// Create a multi-section card
var multiCard = FeishuProvider.CreateMultiSectionCard(
    title: "任务进度",
    sections: new[] { 
        new { title = "步骤 1", content = "已完成" },
        new { title = "步骤 2", content = "进行中" }
    });

Building a Custom Feishu Bot Handler

Implement the IMessageHandler interface to create custom bot logic:

public class EchoBot : IMessageHandler
{
    private readonly IMessageRouter _router;
    private readonly ILogger<EchoBot> _logger;

    public EchoBot(IMessageRouter router, ILogger<EchoBot> logger)
    {
        _router = router;
        _logger = logger;
    }

    public async Task HandleAsync(IChatMessage message, CancellationToken ct)
    {
        if (message.Platform != "feishu") return;

        var reply = new ChatMessage
        {
            MessageId = Guid.NewGuid().ToString(),
            SenderId = message.ReceiverId,          // 机器人自己的 OpenId
            ReceiverId = message.SenderId,
            Content = $"你刚才说: {message.Content}",
            MessageType = ChatMessageType.Text,
            Platform = "feishu",
            Timestamp = DateTimeOffset.UtcNow
        };

        var provider = _router.GetProvider("feishu");
        var result = await provider.SendMessageAsync(reply, reply.ReceiverId, ct);
        if (!result.Success)
        {
            _logger.LogWarning("发送回显失败: {Error}", result.ErrorMessage);
        }
    }
}

Summary

  • OpenDeepWiki uses a Message Provider pattern to abstract platform-specific bot implementations, with Feishu support located in src/OpenDeepWiki/Chat/Providers/Feishu/.
  • The FeishuProvider class handles the complete lifecycle: tenant access token caching, webhook validation, message parsing, and sending with automatic retry logic.
  • Configuration requires AppId, AppSecret, and VerificationToken from the Feishu Open Platform, stored securely in appsettings.json under the Chat:Providers:Feishu section.
  • Register services using builder.Services.AddChatServices(builder.Configuration) in Program.cs to automatically discover and initialize the Feishu provider.
  • Implement IMessageHandler to build custom bot logic, using the provider's static methods like CreateTextCard for rich interactive messages.

Frequently Asked Questions

What configuration values do I need from the Feishu Open Platform?

You need four critical values from your Feishu application's credentials page: App ID and App Secret for OAuth authentication, Verification Token for webhook security validation, and optionally Encrypt Key if you enable message encryption. Map these to FeishuProviderOptions in your appsettings.json under the Chat:Providers:Feishu section.

How does OpenDeepWiki handle Feishu access token expiration?

The FeishuProvider implements automatic token caching in GetAccessTokenAsync (lines 61-71 of FeishuProvider.cs). It caches the tenant access token for 7000 seconds by default (configurable via TokenCacheSeconds) and uses a SemaphoreSlim to prevent concurrent refresh requests when the token expires. The initialization service automatically refreshes tokens during application startup.

Can I send interactive cards instead of plain text?

Yes, the FeishuProvider includes static helper methods CreateTextCard and CreateMultiSectionCard (lines 81-135) that generate JSON payloads for Feishu's interactive card format. Set your ChatMessage.MessageType to ChatMessageType.Card and pass the generated JSON string as the Content property. The provider automatically converts this to Feishu's msg_type: interactive format when sending via SendMessageAsync.

How do I verify the Feishu webhook is working locally?

Use the ValidateWebhookAsync method (lines 95-124 in FeishuProvider.cs) to handle Feishu's URL verification challenge. When Feishu sends a verification request containing a challenge parameter, this method returns the challenge value for you to echo back. For local development, ensure your endpoint is publicly accessible via tools like ngrok, and verify that your VerificationToken matches the value in your Feishu app settings to pass signature validation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →