Feishu Bot Integration Callback Requirements in OpenDeepWiki: A Complete Implementation Guide
To integrate a Feishu Bot with OpenDeepWiki, your webhook endpoint must handle POST requests with JSON bodies, validate the VerificationToken against the request token, respond to url_verification challenges, and optionally decrypt encrypted messages using the EncryptKey.
The Feishu Bot integration callback requirements in the OpenDeepWiki project are implemented through the FeishuProvider class, which handles secure webhook validation, message parsing, and token management. This guide explains the technical requirements for setting up a compliant Feishu Bot callback endpoint using the actual implementation found in the AIDotNet/OpenDeepWiki repository.
Core Callback Requirements for Feishu Bot Integration
The FeishuProvider.ValidateWebhookAsync method in src/OpenDeepWiki/Chat/Providers/Feishu/FeishuProvider.cs enforces several critical requirements for incoming webhooks.
POST Request Handling and Body Buffering
Feishu sends callbacks as application/json POST requests. The implementation requires enabling request buffering to allow multiple reads of the request body:
// From FeishuProvider.cs lines 94-101
public async Task<WebhookValidationResult> ValidateWebhookAsync(HttpRequest request)
{
request.EnableBuffering(); // Critical: allows re-reading the body
using var reader = new StreamReader(request.Body, Encoding.UTF8, leaveOpen: true);
var rawBody = await reader.ReadToEndAsync();
request.Body.Position = 0; // Reset position for subsequent reads
}
Verification Token Validation
Every callback must include a verification token that matches the configured FeishuProviderOptions.VerificationToken. The provider checks both v1.0 (token field) and v2.0 (header.token) formats:
// From FeishuProvider.cs lines 102-108 and 138-142
var json = JsonDocument.Parse(rawBody);
var token = json.RootElement.TryGetProperty("token", out var t)
? t.GetString()
: json.RootElement.GetProperty("header").GetProperty("token").GetString();
if (token != _options.VerificationToken)
{
return WebhookValidationResult.Failed("Invalid verification token");
}
URL Verification Challenge
When first configuring the webhook URL in Feishu, the platform sends a url_verification event containing a challenge field. Your endpoint must return this exact challenge in the response:
// From FeishuProvider.cs lines 124-136
if (json.RootElement.TryGetProperty("type", out var typeElement)
&& typeElement.GetString() == "url_verification")
{
var challenge = json.RootElement.GetProperty("challenge").GetString();
return WebhookValidationResult.Success(challenge: challenge);
}
Message Encryption Handling
If encryption is enabled in the Feishu console, callbacks include an encrypt field containing AES-encrypted data. The provider requires the EncryptKey from FeishuProviderOptions to decrypt:
// From FeishuProvider.cs lines 114-124
if (json.RootElement.TryGetProperty("encrypt", out var encryptElement))
{
var encryptKey = _options.EncryptKey;
if (string.IsNullOrEmpty(encryptKey))
{
return WebhookValidationResult.Failed("EncryptKey not configured but message is encrypted");
}
var decrypted = DecryptMessage(encryptElement.GetString(), encryptKey);
json = JsonDocument.Parse(decrypted);
}
Configuring FeishuProviderOptions for Secure Callbacks
The FeishuProviderOptions class in src/OpenDeepWiki/Chat/Providers/Feishu/FeishuProviderOptions.cs defines the configuration schema required for callback validation:
{
"Feishu": {
"AppId": "cli_xxxxxxxxxxxxxxxx",
"AppSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"VerificationToken": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"EncryptKey": "optional_key_for_encryption",
"ApiBaseUrl": "https://open.feishu.cn/open-apis"
}
}
Critical security note: The VerificationToken is mandatory for all webhook integrations, while EncryptKey is only required if you enable encryption in the Feishu developer console.
Implementing the Webhook Endpoint in ASP.NET Core
To satisfy the Feishu Bot integration callback requirements, implement a POST endpoint that delegates validation to FeishuProvider:
using OpenDeepWiki.Chat.Providers.Feishu;
var builder = WebApplication.CreateBuilder(args);
// Configure options
builder.Services.Configure<FeishuProviderOptions>(
builder.Configuration.GetSection("Feishu"));
builder.Services.AddHttpClient<FeishuProvider>();
builder.Services.AddSingleton<FeishuProvider>();
var app = builder.Build();
// Webhook endpoint
app.MapPost("/api/feishu/webhook", async (
HttpRequest request,
FeishuProvider provider,
CancellationToken ct) =>
{
// Validate webhook (handles token, encryption, url_verification)
var validation = await provider.ValidateWebhookAsync(request);
if (!validation.Success)
{
return Results.BadRequest(new { error = validation.ErrorMessage });
}
// Handle URL verification challenge
if (!string.IsNullOrEmpty(validation.Challenge))
{
return Results.Json(new { challenge = validation.Challenge });
}
// Parse the validated message
var message = await provider.ParseMessageAsync(request);
if (message != null)
{
// Process business logic here
Console.WriteLine($"Received: {message.Content}");
}
return Results.Ok();
});
app.Run();
The ValidateWebhookAsync method in src/OpenDeepWiki/Chat/Providers/Feishu/FeishuProvider.cs handles all callback requirements internally, including body buffering, token validation, decryption, and challenge responses.
Parsing and Processing Feishu Messages
After validation, use ParseMessageAsync to convert the Feishu event into the standard ChatMessage format:
public async Task<ChatMessage?> ParseMessageAsync(HttpRequest request)
{
request.EnableBuffering();
using var reader = new StreamReader(request.Body, Encoding.UTF8, leaveOpen: true);
var rawJson = await reader.ReadToEndAsync();
request.Body.Position = 0;
// Parse based on Feishu event structure (v2.0 format)
var doc = JsonDocument.Parse(rawJson);
var eventData = doc.RootElement.GetProperty("event");
return new ChatMessage
{
MessageId = eventData.GetProperty("message_id").GetString(),
SenderId = eventData.GetProperty("sender").GetProperty("sender_id").GetProperty("open_id").GetString(),
Content = eventData.GetProperty("content").GetString(),
MessageType = ParseMessageType(eventData.GetProperty("msg_type").GetString()),
Platform = "feishu",
Timestamp = DateTimeOffset.FromUnixTimeMilliseconds(
eventData.GetProperty("create_time").GetInt64())
};
}
Summary
Integrating a Feishu Bot with OpenDeepWiki requires implementing specific callback requirements to ensure secure and reliable webhook communication:
- POST Request Handling: Enable request buffering using
EnableBuffering()to allow multiple reads of the JSON body inValidateWebhookAsync. - Verification Token: Configure
FeishuProviderOptions.VerificationTokento match the token sent in Feishu callbacks (v1.0tokenor v2.0header.token). - URL Verification: Return the exact
challengevalue when receivingtype: "url_verification"events during initial setup. - Encryption Support: Provide
EncryptKeyin options and implement decryption logic if encryption is enabled in the Feishu console. - Event Parsing: Use
ParseMessageAsyncto convert validated Feishu events into standardChatMessageobjects for processing.
Frequently Asked Questions
What is the VerificationToken in Feishu Bot integration?
The VerificationToken is a security credential configured in FeishuProviderOptions that validates incoming webhooks originate from Feishu. According to the implementation in src/OpenDeepWiki/Chat/Providers/Feishu/FeishuProvider.cs, the provider checks this token against the token field (v1.0) or header.token field (v2.0) in the JSON payload. If they do not match, the webhook is rejected with a validation error.
How do I handle encrypted callbacks from Feishu?
If you enable encryption in the Feishu developer console, callbacks include an encrypt field containing AES-encrypted data. To handle this in OpenDeepWiki, configure the EncryptKey property in FeishuProviderOptions. The ValidateWebhookAsync method in FeishuProvider.cs automatically detects the encrypt field and calls DecryptMessage using your configured key. If the key is missing but encryption is present, validation fails with an appropriate error message.
What response should my webhook return for URL verification?
During initial configuration, Feishu sends a url_verification event containing a unique challenge string. Your endpoint must return HTTP 200 with a JSON body containing exactly { "challenge": "received_challenge_value" }. In the OpenDeepWiki implementation, the ValidateWebhookAsync method returns a WebhookValidationResult with the Challenge property populated when it detects type: "url_verification", which you then return in your controller or minimal API endpoint.
Where is the FeishuProvider implemented in OpenDeepWiki?
The FeishuProvider class is implemented in src/OpenDeepWiki/Chat/Providers/Feishu/FeishuProvider.cs within the AIDotNet/OpenDeepWiki repository. This file contains the core logic for webhook validation (ValidateWebhookAsync), message parsing (ParseMessageAsync), token management, and message sending. The corresponding configuration options are defined in FeishuProviderOptions.cs in the same directory, while data models reside in FeishuModels.cs.
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 →