silenceper/wechat

repository·v2·Indexed 26 days ago

https://github.com/silenceper/wechat

A simple and easy-to-use WeChat SDK developed in Go. It provides comprehensive support for various WeChat services, including Official Accounts, Mini Programs, Mini Games, WeChat Pay, Enterprise WeChat (Work WeChat), the WeChat Open Platform, and Intelligent Dialogue (AISpeech) services. The SDK includes support for WeChat Cloud Development (TCB) and virtual payment features.

Tokens
9.9K
Snippets
12
Records
70
Agent score
90%

What's inside silenceper/wechat

  1. Overview of WeChat SDK modules

    v2

    The SDK provides specialized modules for different WeChat services:

    • officialaccount: WeChat Official Account API
    • miniprogram: WeChat Mini Program API
    • minigame: WeChat Mini Game API
    • pay: WeChat Pay API
    • openplatform: WeChat Open Platform API
    • work: WeChat Work (Enterprise WeChat) API
    • aispeech: Intelligent Speech/Dialogue API
  2. Overview of WeChat Pay integration

    v2
    This package provides integration capabilities for WeChat Pay (微信支付). For detailed API specifications, request parameters, and business logic, refer to the official WeChat Pay documentation.
  3. Explore WeChat API documentation categories

    v2

    The WeChat SDK provides API documentation organized by service type. You can find detailed API specifications, request methods, and implementation status for the following modules:

    • Official Account (officialaccount.md): APIs related to WeChat Official Accounts.
    • Mini Program (miniprogram.md): APIs for WeChat Mini Programs.
    • Mini Game (minigame.md): APIs for WeChat Mini Games.
    • Open Platform (oplatform.md): APIs for the WeChat Open Platform.
    • WeChat Pay (wxpay.md): APIs for WeChat Pay integration.
    • Work WeChat (work.md): APIs for Enterprise WeChat (Work WeChat).
    • Intelligent Dialogue (aispeech.md): APIs for AI speech/dialogue services.
  4. Quickstart: Handle WeChat Official Account messages

    v2

    To handle incoming messages and send replies for a WeChat Official Account, initialize a wechat.NewWechat() instance, configure it with an offConfig.Config (including AppID, AppSecret, Token, and a Cache implementation), and use GetOfficialAccount to obtain the official account instance. Use GetServer(req, rw) to create a server handler that processes HTTP requests and responses. You can define custom logic using SetMessageHandler and finalize the interaction by calling server.Serve() and server.Send().

    import "github.com/silenceper/wechat/v2"
    
    // Use memcache to save access_token, or choose redis/custom cache
    wc := wechat.NewWechat()
    memory := cache.NewMemory()
    cfg := &offConfig.Config{
        AppID:     "xxx",
        AppSecret: "xxx",
        Token:     "xxx",
        // EncodingAESKey: "xxxx",
        Cache: memory,
    }
    officialAccount := wc.GetOfficialAccount(cfg)
    
    // Pass request and responseWriter
    server := officialAccount.GetServer(req, rw)
    // Set the message handler
    server.SetMessageHandler(func(msg *message.MixMessage) *message.Reply {
    
        // Reply to message: demonstrate replying with the user's own content
        text := message.NewText(msg.Content)
        return &message.Reply{MsgType: message.MsgTypeText, MsgData: text}
    })
    
    // Process message reception and reply
    err := server.Serve()
    if err != nil {
        fmt.Println(err)
        return
    }
    // Send the reply message
    server.Send()
  5. Quickstart WeChat Mini Program SDK

    v2

    To initialize the WeChat Mini Program module, create a new WeChat instance, define a configuration with your AppID, AppSecret, and a cache implementation, and then retrieve the Mini Program client using GetMiniProgram(cfg).

    wc := wechat.NewWechat()
    memory := cache.NewMemory()
    cfg := &miniConfig.Config{
        AppID:     "xxx",
        AppSecret: "xxx",
        Cache: memory,
    }
    miniprogram := wc.GetMiniProgram(cfg)
    miniprogram.GetAnalysis().GetAnalysisDailyRetain()
  6. Implement WeChat Open Platform server-side message handling

    v2

    To handle incoming messages from the WeChat Open Platform, initialize a wechat.NewWechat() instance, configure it with an openplatform.Config object, and use GetOpenPlatform to obtain an Open Platform instance.

    Use GetServer(req, rw) to create a server instance that handles the HTTP request and response writer. You must define a message handler using SetMessageHandler. Within this handler, you can process different InfoType values. For example, when receiving a message.InfoTypeVerifyTicket, use SetComponentAccessToken to validate the ticket and return success to the response writer.

    Finally, call server.Serve() to process the incoming request and server.Send() to dispatch any replies.

    wc := wechat.NewWechat()
    memory := cache.NewMemory()
    cfg := &openplatform.Config{
        AppID:         "xxx",
        AppSecret:     "xxx",
        Token:         "xxx",
        EncodingAESKey: "xxx",
        Cache:         memory,
    }
    
    openPlatform := wc.GetOpenPlatform(cfg)
    // Pass the request and responseWriter
    server := openPlatform.GetServer(req, rw)
    
    // Set the message handler
    server.SetMessageHandler(func(msg *message.MixMessage) *message.Reply {
        if msg.InfoType == message.InfoTypeVerifyTicket {
            componentVerifyTicket, err := openPlatform.SetComponentAccessToken(msg.ComponentVerifyTicket)
            if err != nil {
                log.Println(err)
                return nil
            }
            // debug 
            fmt.Println(componentVerifyTicket)
            rw.Write([]byte("success"))
            return nil
        }
        // handle other messages
        return nil
    })
    
    // Process message reception and replies
    err := server.Serve()
    if err != nil {
        fmt.Println(err)
        return
    }
    // Send the reply message
    server.Send()
  7. Initialize the WeChat Cloud Development (TCB) SDK

    v2

    To use the WeChat Cloud Development (TCB) features, you must first initialize a wechat.Config object with your AppID, AppSecret, and a Cache implementation (such as Memcache, Redis, or a custom cache) to handle access_token storage. Then, create a wechat.Wechat instance and call GetTcb() to obtain the TCB client.

    // Use memcache to save access_token; you can also choose redis or a custom cache
    memCache := cache.NewMemcache("127.0.0.1:11211")
    
    // Configure WeChat parameters
    config := &wechat.Config{
        AppID:     "your app id",
        AppSecret: "your app secret",
        Cache:     memCache,
    }
    wc := wechat.NewWechat(config)
    wcTcb := wc.GetTcb()
  8. Import, Publish, and Manage Dialog Q&A

    v2

    The dialogClient provides methods to import Q&A data via JSON, track asynchronous tasks, publish changes to the bot, and check publication progress.

    • ImportJSON: Imports a list of BotIntent objects. Use dialog.ImportJSONRequest to specify the Mode and Data.
    • FetchAsync: Retrieves the result of an asynchronous task using a TaskID via dialog.FetchAsyncRequest.
    • Publish: Publishes the imported changes to the bot.
    • GetEffectiveProgress: Checks the progress of the publication in a specific environment (e.g., online) via dialog.EffectiveProgressRequest.
    // 1. Import JSON data
    task, err := dialogClient.ImportJSON(&dialog.ImportJSONRequest{
    	Mode: 0,
    	Data: []dialog.BotIntent{{
    		Skill:     "售前咨询",
    		Intent:    "查询营业时间",
    		Disable:   false,
    		Questions: []string{"你们几点开门", "营业时间是什么时候"},
    		Answers:   []string{"我们的营业时间是周一至周五 9:00-18:00"},
    	}},
    })
    if err != nil {
    	return err
    }
    
    // 2. Fetch async result
    asyncResult, err := dialogClient.FetchAsync(&dialog.FetchAsyncRequest{
    	TaskID: task.TaskID,
    })
    if err != nil {
    	return err
    }
    
    // 3. Publish
    publish, err := dialogClient.Publish()
    if err != nil {
    	return err
    }
    
    // 4. Check progress
    progress, err := dialogClient.GetEffectiveProgress(&dialog.EffectiveProgressRequest{
    	Env: "online",
    })
  9. Use the MsgAudit SDK to sync and decrypt messages

    v2

    To use the Message Audit functionality, initialize a wechat.Wechat client, retrieve the Work client with your credentials, and then call GetMsgAudit().

    Key workflow steps:

    1. Initialize: Use wechat.NewWechat() and workClient.GetMsgAudit().
    2. Sync Messages: Use client.GetChatData(offset, limit, ...) to retrieve encrypted chat data.
    3. Decrypt: Use client.DecryptData(encryptRandomKey, encryptChatMsg) to turn encrypted data into readable chatInfo.
    4. Handle Media: For image types, use chatInfo.GetImageMessage() to get the SdkFileID, then loop through client.GetMediaData(...) until IsFinish is true to download the full file.
    5. Cleanup: Always call client.Free() to release the SDK instance resources.
    package main
    
    import (
    	"bytes"
    	"fmt"
    	"github.com/silenceper/wechat/v2"
    	"github.com/silenceper/wechat/v2/work/msgaudit"
    	"github.com/silenceper/wechat/v2/work/config"
    	"io/ioutil"
    	"os"
    	"path"
    )
    
    func main() {
    	// Initialize client
    	wechatClient := wechat.NewWechat()
    
    	workClient := wechatClient.GetWork(&config.Config{
    		CorpID:        "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    		CorpSecret:    "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    		RasPrivateKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    	})
    
    	client, err := workClient.GetMsgAudit()
    	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{}
    			indexBuf := ""
    			for !isFinish {
    				// Get media data
    				mediaData, err := client.GetMediaData(indexBuf, sdkFileID, "", "", 5)
    				if err != nil {
    					fmt.Printf("媒体数据拉取失败:%v \n", err)
    					return
    				}
    				buffer.Write(mediaData.Data)
    				if mediaData.IsFinish {
    					isFinish = mediaData.IsFinish
    				}
    				indexBuf = 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
    		}
    	}
    
    	// Release SDK instance
    	client.Free()
    }