An unofficial .NET 10 wrapper for the WeChat Work (WeCom) Finance SDK (企业微信会话内容存档 SDK). This library encapsulates the C SDK provided by Tencent, offering a convenient, strong-typed C# interface for fetching, decrypting, and parsing chat history.
WeWorkChatClient class handles P/Invoke complexity and resource management (IDisposable), directly integrates RSA and AES decryption for convenience, and supports encrypted PEM private keys with a password.WeWorkChatMessage and specific types like TextMessage, ImageMessage, etc.).GetChatMessages method combines fetching, RSA key decryption, and message AES decryption into a single, easy-to-use call.WeWorkFinanceSdk.csproj in your solution.libs/ folder are correctly copied to the output directory. The .csproj file is configured to handle this automatically for libs/win-x64 and libs/linux-x64.Initialize the client with your Corporate ID (CorpId) and Secret.
using WeWorkFinanceSdk;
using WeWorkFinanceSdk.Models;
// Replace with your actual CorpId and Secret
string corpId = "wwd08c8exxxx5ab44d";
string secret = "your_secret_key";
using var client = new WeWorkChatClient(corpId, secret);
Fetch a batch of encrypted chat messages using the sequence number (seq).
ulong seq = 0; // Start from 0, then update with the latest 'seq' from the response
uint limit = 100; // Max 1000
string proxy = ""; // Optional proxy
string passwd = ""; // Optional proxy password
int timeout = 10; // Timeout in seconds
// Returns a JSON string containing the encrypted list
string chatDataJson = client.GetChatData(seq, limit, proxy, passwd, timeout);
Console.WriteLine(chatDataJson);
The GetChatMessages method combines fetching, RSA key decryption, and message AES decryption into a single call. This requires providing your RSA private key in PEM format when initializing WeWorkChatClient.
// 1. Initialize client with your RSA Private Key (PEM format)
string rsaPrivateKey = @"-----BEGIN RSA PRIVATE KEY-----
... your actual private key content ...
-----END RSA PRIVATE KEY-----";
// If your private key is encrypted (e.g., has ENCRYPTED in the header), provide a password:
string? privateKeyPassword = "your_key_password"; // Or null if not encrypted
using var client = new WeWorkChatClient(corpId, secret, rsaPrivateKey, privateKeyPassword); // Use the new constructor
// 2. Fetch and automatically decrypt messages
var response = client.GetChatMessages(seq: 0, limit: 100); // Use the new method
if (response.ErrCode == 0)
{
Console.WriteLine($"Successfully fetched and decrypted {response.Messages.Count} messages. Last Seq: {response.LastSeq}");
foreach (var message in response.Messages)
{
Console.WriteLine($"MsgId: {message.MsgId}, Type: {message.MsgType}");
if (message.MsgType == "text" && message.Text != null)
{
Console.WriteLine($"Content: {message.Text.Content}");
}
// ... handle other message types
}
}
else
{
Console.WriteLine($"Failed to fetch and decrypt messages: {response.ErrMsg} (ErrCode: {response.ErrCode})");
}
If you need to perform RSA decryption manually (e.g., in a separate service) or only want the raw decrypted JSON string:
You can still use the DecryptChatMessage method:
string encryptRandomKey = "..."; // From GetChatData response
string encryptChatMsg = "..."; // From GetChatData response
// Manually decrypt 'encryptRandomKey' to get the AES Key
string decryptedAesKey = MyRSADecryptionMethod(encryptRandomKey, myPrivateKey, myPassword); // Your RSA decryption logic (pass password if key is encrypted)
WeWorkChatMessage? message = client.DecryptChatMessage(decryptedAesKey, encryptChatMsg);
// ... process message
Download images, videos, or files using the sdkfileid.
string sdkFileId = "..."; // From Image/Video/File message
string indexBuf = ""; // Start with empty string
string savePath = "downloaded_file.jpg";
using var fs = new FileStream(savePath, FileMode.Create, FileAccess.Write);
while (true)
{
// Fetch a chunk of data
var chunk = client.GetMediaData(indexBuf, sdkFileId);
if (chunk.Data.Length > 0)
{
fs.Write(chunk.Data, 0, chunk.Data.Length);
}
if (chunk.IsFinish)
{
break;
}
// Update indexBuf for the next chunk
indexBuf = chunk.OutIndexBuf;
}
WeWorkChatClient is the main entry point for interacting with the SDK. It implements IDisposable.
public WeWorkChatClient(string corpId, string secret, string? privateKey = null, string? privateKeyPassword = null)
corpId: Your WeCom Corporate ID.secret: Your Chat History Archiving Secret.privateKey: (Optional) Your enterprise's RSA private key in PEM format. Required for GetChatMessages to automatically decrypt encrypt_random_key.privateKeyPassword: (Optional) Password for the privateKey if it is encrypted.public WeWorkChatBatchResponse GetChatMessages(ulong seq, uint limit = 1000, string proxy = "", string passwd = "", int timeout = 10)
Fetches encrypted chat data, decrypts the RSA keys, and decrypts the messages into strongly-typed objects. Requires privateKey to be provided in the constructor.
seq: The cursor sequence number. Start with 0.limit: Number of messages to fetch (Max 1000).proxy & passwd: Optional proxy settings.timeout: Request timeout in seconds.WeWorkChatBatchResponse object containing a list of WeWorkChatMessage and the last processed sequence number.public string GetChatData(ulong seq, uint limit, string proxy = "", string passwd = "", int timeout = 10)
Fetches encrypted chat data.
seq: The cursor sequence number. Start with 0.limit: Number of messages to fetch (Max 1000).proxy & passwd: Optional proxy settings.timeout: Request timeout in seconds.public WeWorkChatMessage? DecryptChatMessage(string encryptKey, string encryptMsg)
Decrypts an encrypted message payload and deserializes it into a WeWorkChatMessage object.
encryptKey: The AES key (decrypted from encrypt_random_key using your RSA private key).encryptMsg: The encrypt_chat_msg payload from the chat data.WeWorkChatMessage object or null if decryption fails.public string DecryptData(string encryptKey, string encryptMsg)
Low-level decryption method.
public MediaDataChunk GetMediaData(string indexBuf, string sdkFileId, string proxy = "", string passwd = "", int timeout = 10)
Downloads a chunk of a media file.
indexBuf: The cursor for the current download chunk. Pass empty string "" for the first chunk.sdkFileId: The ID of the file to download.MediaDataChunk containing the data bytes, next index buffer, and finish status.Releases the native SDK resources.
WeWorkFinanceSdk/: The main C# project.
FinanceSdk.cs: Native P/Invoke definitions.WeWorkChatClient.cs: High-level wrapper class.Models/: Strong-typed message classes (WeWorkChatMessage.cs etc.).libs/: Native libraries (required at runtime).
win-x64/: WeWorkFinanceSdk.dll, libcrypto-3-x64.dll, etc.linux-x64/: libWeWorkFinanceSdk.so.include/: C header files (for reference).