WeWorkFinanceSDK

repository·main·Indexed 43 days ago

https://github.com/nicexai/weworkfinancesdk

A Go wrapper for the official WeWork Enterprise WeChat Session Archive C SDK. It enables developers in Linux environments to synchronize, decrypt, and retrieve chat messages and media files from enterprise WeChat sessions. Key features include initializing clients via NewClient, fetching encrypted records with GetChatData, decrypting messages using DecryptData, and downloading media chunks through GetMediaData.

Tokens
8.2K
Snippets
26
Records
29
Agent score
56%

What's inside WeWorkFinanceSDK

  1. Install the WeWorkFinanceSDK

    main

    To use the WeWorkFinanceSDK in your Go project, follow these steps:

    1. Install the Go module:

      go get -u github.com/NICEXAI/WeWorkFinanceSDK
    2. Configure the C shared library: The SDK is a wrapper around the official WeWork C SDK and currently only supports linux environments. You must provide the libWeWorkFinanceSdk_C.so dynamic library:

      • Copy libWeWorkFinanceSdk_C.so from the github.com/NICEXAI/WeWorkFinanceSDK/lib directory to your system's default dynamic library folder.
      • OR copy it to any folder and set the LD_LIBRARY_PATH environment variable to that folder's path:
        export LD_LIBRARY_PATH=$(pwd)
    go get -u github.com/NICEXAI/WeWorkFinanceSDK
  2. Handle media messages (Image, Voice, Video, File)

    main

    Media messages in the SDK typically include an SdkFileID used to download the actual media resource. For integrity, most media types also provide an Md5Sum to verify the file content.

    • ImageMessage: Contains SdkFileID, Md5Sum, and FileSize.
    • VoiceMessage: Contains SdkFileID, VoiceSize, PlayLength, and Md5Sum.
    • VideoMessage: Contains SdkFileID, FileSize, PlayLength, and Md5Sum.
    • FileMessage: Contains FileName, FileExt, SdkFileID, FileSize, and Md5Sum.
  3. Handle Meeting and VoIP messages

    main

    The SDK provides specialized structures for meeting-related activities and VoIP calls:

    • MeetingMessage: Used for invitations (MeetingType 101) and processing (MeetingType 102). It includes MeetingID to correlate related messages and Status (e.g., 1: Attending, 2: Rejected, 5: Cancelled).
    • MeetingVoiceCallMessage: Provides archives of meeting audio, including DemoFileData (document sharing info) and ShareScreenData (screen sharing info).
    • VoiptextMessage: Captures VoIP call details like Callduration (seconds) and Invitetype (1: Single Video, 2: Single Voice, 3: Multi Video, 4: Multi Voice).
  4. Complete Example: Syncing and saving an image

    main

    This example demonstrates the full lifecycle: initializing the client, syncing chat data, decrypting an image message, downloading its media chunks, and saving it to a file.

    package main
    
    import (
    	"bytes"
    	"fmt"
    	"github.com/NICEXAI/WeWorkFinanceSDK"
    	"io/ioutil"
    	"os"
    	"path"
    )
    
    func main() {
    	corpID := "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    	corpSecret := "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    	rsaPrivateKey := `
    -----BEGIN RSA PRIVATE KEY-----
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    -----END RSA PRIVATE KEY-----
    `
    
    	// Initialize client
    	client, err := WeWorkFinanceSDK.NewClient(corpID, corpSecret, rsaPrivateKey)
    	if err != nil {
    		fmt.Printf("SDK 初始化失败:%v \n", err)
    		return
    	}
    
    	// Sync messages
    	chatDataList, err := client.GetChatData(0, 100, "", "", 3)
    	if err != nil {
    		fmt.Printf("消息同步失败:%v \n", err)
    		return
    	}
    
    	for _, chatData := range chatDataList {
    		// Decrypt message
    		chatInfo, err := client.DecryptData(chatData.EncryptRandomKey, chatData.EncryptChatMsg)
    		if err != nil {
    			fmt.Printf("消息解密失败:%v \n", err)
    			return
    		}
    
    		if chatInfo.Type == "image" {
    			image := chatInfo.GetImageMessage()
    			sdkfileid := image.Image.SdkFileID
    
    			isFinish := false
    			buffer := bytes.Buffer{}
    			index_buf := ""
    			for !isFinish {
    				// Get media data chunks
    				mediaData, err := client.GetMediaData(index_buf, sdkfileid, "", "", 5)
    				if err != nil {
    					fmt.Printf("媒体数据拉取失败:%v \n", err)
    					return
    				}
    				buffer.Write(mediaData.Data)
    				if mediaData.IsFinish {
    					isFinish = mediaData.IsFinish
    				}
    				index_buf = mediaData.OutIndexBuf
    			}
    			filePath, _ := os.Getwd()
    			filePath = path.Join(filePath, "test.png")
    			err := ioutil.WriteFile(filePath, buffer.Bytes(), 0666)
    			if err != nil {
    				fmt.Printf("文件存储失败:%v \n", err)
    				return
    			}
    			break
    		}
    	}
    }
  5. Retrieve media data (images/files)

    main

    If a decrypted message is an image, you can download the media content using client.GetMediaData. Because media files may be delivered in chunks, you must loop until IsFinish is true.

    Workflow:

    1. Identify the SdkFileID from the image message object.
    2. Call client.GetMediaData using the sdkfileid and the index_buf from the previous call.
    3. Append the Data from the response to a buffer.
    4. Update your index_buf with mediaData.OutIndexBuf for the next iteration.
    5. Stop when mediaData.IsFinish is true.

    Parameters for GetMediaData:

    • index_buf (string): The index buffer from the previous response.
    • sdkfileid (string): The file ID to retrieve.
    • search_key (string): Optional search key.
    • search_value (string): Optional search value.
    • limit (int): Chunk limit.
    mediaData, err := client.GetMediaData(index_buf, sdkfileid, "", "", 5)
    // ...
    index_buf = mediaData.OutIndexBuf
  6. Sync and decrypt chat messages

    main

    The SDK allows you to retrieve encrypted chat data and decrypt it into readable message information.

    1. Get Chat Data

    Call client.GetChatData to retrieve a list of encrypted chat messages.

    Parameters:

    • offset (int): The starting offset for synchronization.
    • limit (int): The number of messages to retrieve.
    • search_key (string): Search key (optional).
    • search_value (string): Search value (optional).
    • type (int): Message type filter.

    2. Decrypt Data

    Iterate through the returned chatDataList and use client.DecryptData to decrypt individual messages.

    Parameters:

    • encryptRandomKey (string): The random key from the chatData object.
    • encryptChatMsg (string): The encrypted message content from the chatData object.

    Returns:

    • chatInfo: An object containing the decrypted message details (e.g., Type, GetImageMessage()).
    chatDataList, err := client.GetChatData(0, 100, "", "", 3)
    // ...
    chatInfo, err := client.DecryptData(chatData.EncryptRandomKey, chatData.EncryptChatMsg)
  7. Initialize the WeWorkFinanceSDK client

    main

    Use WeWorkFinanceSDK.NewClient to initialize the SDK client. You will need your enterprise WeChat corpID, corpSecret, and an RSA private key for decryption.

    Parameters:

    • corpID (string): Your enterprise WeChat CorpID.
    • corpSecret (string): Your enterprise WeChat Secret.
    • rsaPrivateKey (string): Your RSA private key in PEM format.

    Returns:

    • client: The initialized client instance.
    • err: An error if initialization fails.
    client, err := WeWorkFinanceSDK.NewClient(corpID, corpSecret, rsaPrivateKey)
  8. Decrypt chat messages with DecryptData

    main

    Use DecryptData to convert encrypted chat messages into readable ChatMessage objects. This method uses the RSA private key provided during client initialization to decrypt the encrypt_random_key first, then decrypts the actual message.

    Parameters:

    • encryptRandomKey: The encrypt_random_key value obtained from GetChatData.
    • encryptMsg: The encrypt_chat_msg value obtained from GetChatData.
    • specificPrivateKey: (Optional) An alternative RSA private key. If an empty string is provided, the client's default privateKey is used.

    Returns:

    • A ChatMessage object and an error.

    ChatMessage Fields:

    • Id: Message ID.
    • From: Sender ID.
    • ToList: Recipient list.
    • Action: Message action.
    • Type: Message type.
    // Assuming 'item' is a ChatData object from GetChatData
    msg, err := client.DecryptData(item.EncryptRandomKey, item.EncryptChatMessage, "")
    if err != nil {
        // handle error
    }
    fmt.Printf("Message from %s: %s\n", msg.From, msg.Type)
  9. Initialize the SDK client with NewClient

    main

    Use NewClient to create a new Client instance. This requires your enterprise credentials and the RSA private key used for message decryption.

    Parameters:

    • corpId: The enterprise ID (e.g., wwd08c8exxxx5ab44d). Found in the WeCom Admin Console under 'My Enterprise' -> 'Enterprise Information'.
    • corpSecret: The Secret for chat content archiving. Found in 'Management Tools' -> 'Chat Content Archiving'.
    • rsaPrivateKey: The message encryption private key. Found in 'Management Tools' -> 'Message Encryption Public Key' (use the corresponding private key).

    Returns:

    • A Client interface and an error. If the error is nil, initialization was successful (return code 0).
    client, err := WeWorkFinanceSDK.NewClient("YOUR_CORP_ID", "YOUR_CORP_SECRET", "YOUR_RSA_PRIVATE_KEY")
    if err != nil {
        // handle error
    }
    defer client.Free()
  10. Release SDK resources with Free

    main

    When the SdkClient is no longer needed, call Free() to release the underlying C memory and destroy the SDK instance. This should be called via defer immediately after successful initialization to prevent memory leaks.

    client, err := WeWorkFinanceSDK.NewClient(corpId, secret, key)
    if err == nil {
        defer client.Free()
    }
    client.Free()
  11. Handle encrypted chat data with ChatRawData and ChatData

    main

    When receiving raw chat data from the SDK, use ChatRawData to check for errors and access the list of ChatData objects. Each ChatData contains encrypted content that requires decryption using the SDK's DecryptData method.

    Decryption Workflow:

    1. Identify the PublickeyVer and EncryptRandomKey from the ChatData object.
    2. Base64 decode the EncryptRandomKey.
    3. Use the decoded key and the EncryptChatMsg (the ciphertext) with the SDK's DecryptData method to obtain the plaintext message.

    Key Fields in ChatData:

    • Seq: A uint64 message sequence ID. Use the largest seq from your last response to fetch subsequent messages.
    • MsgId: A unique identifier for the message, useful for deduplication.
    • PublickeyVer: The version of the public key used for encryption.
    • EncryptRandomKey: Base64 encoded content that, once decoded and decrypted with the appropriate private key, is used to decrypt the actual message.
    • EncryptChatMsg: The encrypted message ciphertext.
    // Example structure of ChatRawData
    type ChatRawData struct {
    	Error
    	ChatDataList []ChatData `json:"chatdata,omitempty"` 
    }
    
    // Example structure of ChatData
    type ChatData struct {
    	Seq              uint64 `json:"seq,omitempty"`                
    	MsgId            string `json:"msgid,omitempty"`              
    	PublickeyVer     uint32 `json:"publickey_ver,omitempty"`      
    	EncryptRandomKey string `json:"encrypt_random_key,omitempty"` 
    	EncryptChatMsg   string `json:"encrypt_chat_msg,omitempty"`   
    }
  12. Use the Client interface to interact with WeWork Finance SDK

    main

    The Client interface is the primary entry point for the WeWork Finance SDK. It provides methods for retrieving chat history, decrypting encrypted messages, and fetching media data.

    Key Lifecycle Management: Always call Free() when you are finished with the client to release the underlying C pointers and prevent memory leaks.

    var client WeWorkFinanceSDK.Client
    // ... use client ...
    client.Free()