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:
FeishuProvider.cs— The main implementation class inheriting fromBaseMessageProvider, containingInitializeAsync,ValidateWebhookAsync,ParseMessageAsync, andSendMessageAsyncmethods.FeishuProviderOptions.cs— The configuration model mappingappsettings.jsonvalues to strongly-typed properties.FeishuModels.cs— POCO definitions for Feishu webhook events, API responses, and card structures.ChatServiceExtensions.cs— Dependency injection registration logic located atsrc/OpenDeepWiki/Chat/ChatServiceExtensions.cs.
Configuration Options (FeishuProviderOptions)
The FeishuProviderOptions class in FeishuProviderOptions.cs exposes the following configuration properties under the Chat:Providers:Feishu section:
AppIdandAppSecret— 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 tohttps://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:
- Binds
FeishuProviderOptionsto the configuration sectionChat:Providers:Feishu. - Adds a named
HttpClientforFeishuProviderwith base address and default headers. - Registers
FeishuProvideras a scoped service implementingIMessageProvider. - Adds the provider instance to the
IMessageProvidercollection 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_idandapp_secrettoauth/v3/tenant_access_token/internal. - Caches the returned token for
TokenCacheSeconds(default 7000 seconds) in memory. - Uses
SemaphoreSlimto 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
challengeparameter for Feishu platform verification. - Token Validation: Compares the request token against
VerificationToken. - Decryption: If
EncryptKeyis 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:
- Deserializes the raw JSON into
FeishuWebhookEvent. - Decrypts if necessary using the configured
EncryptKey. - Identifies event types (
im.message.receive_v1ormessage). - Extracts
message_typeand content viaParseFeishuMessageContent. - Returns a
ChatMessagecontainingMessageId,SenderId,ReceiverId,Content,MessageType,Timestamp, andMetadata.
Sending Replies and Cards
The SendMessageAsync method (lines 140-191) handles outbound communication:
- Retrieves a valid AccessToken via
GetAccessTokenAsync. - Calls
DegradeMessageto convert unsupported message types to text. - Uses
ConvertToFeishuFormatto generate Feishu-specificmsg_typeandcontentJSON. - POSTs to
im/v1/messagesviaHttpClient. - Implements retry logic via
IsRetryableErrorandSendWithRetryAsyncfor 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, andVerificationTokenfrom the Feishu Open Platform, stored securely inappsettings.jsonunder theChat:Providers:Feishusection. - Register services using
builder.Services.AddChatServices(builder.Configuration)inProgram.csto automatically discover and initialize the Feishu provider. - Implement IMessageHandler to build custom bot logic, using the provider's static methods like
CreateTextCardfor 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →