重新造个 go-wechat 轮子

2021-11-17 17:11:30 +08:00
 BeijingBaby

目前 wechat Go 相关 SDK 普遍存在以下问题:

1 、缺失单元测试

2 、代码规范(命名等)不够 Go

3 、不够灵活

举个 Github 上 Star 最高的一个库的例子,不能自定义 http.Client 、http.ServeMux

//使用 memcache 保存 access_token ,也可选择 redis 或自定义 cache
wc := wechat.NewWechat()
memory := cache.NewMemory()
cfg := &offConfig.Config{
    AppID:     "xxx",
    AppSecret: "xxx",
    Token:     "xxx",
    //EncodingAESKey: "xxxx",
    Cache: memory,
}
officialAccount := wc.GetOfficialAccount(cfg)

// 传入 request 和 responseWriter
server := officialAccount.GetServer(req, rw)
//设置接收消息的处理方法
server.SetMessageHandler(func(msg *message.MixMessage) *message.Reply {

    //回复消息:演示回复用户发送的消息
    text := message.NewText(msg.Content)
    return &message.Reply{MsgType: message.MsgTypeText, MsgData: text}
})

//处理消息接收以及回复
err := server.Serve()
if err != nil {
    fmt.Println(err)
    return
}
//发送回复的消息
server.Send()

作为一个库,不够灵活,是属于破坏性代码的一类库。

4 、不能自定义 access_token 的管理逻辑

比如公众号,多个项目都要使用 access_token 的情况下如果不能自定义 token 管理逻辑,则 token 会再重新获取后失效之前的。

所以在新项目中需要 wechat sdk 的时候,单元测试、灵活、易于使用成了优先考虑的。

举个例子:

NewClient 时可以传递自己的 http.Client ,自定义超时等逻辑。

type handler struct{}

func (s *handler) HandleTextMessage(message *officialaccount.TextMessage) (officialaccount.ReplyMessage, error) {
	// 处理业务逻辑
	// 响应消息给微信
}

func main() {
	config := &officialaccount.Config{AppID: "appid", Secret: "secret", Token: "token"}
	client := officialaccount.NewClient(config, nil)

	http.Handle("/wx", client.Serve(&handler{}))
	http.ListenAndServe(":8080", nil)
}

易于使用

	ctx := context.Background()
	client.User.UpdateRemark(ctx, "openid", "remark")

api & testing


// xx.go

type IPListResponse struct {
	IPList []*string `json:"ip_list"`
}

// IPList 获取微信服务器 IP 地址
//
// 参考文档: https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_the_WeChat_server_IP_address.html
func (s *BasicService) IPList(ctx context.Context) (*IPListResponse, *Response, error) {
	req, err := s.client.NewRequest("GET", "get_api_domain_ip", nil)
	if err != nil {
		return nil, nil, err
	}
	ipResp := new(IPListResponse)
	resp, err := s.client.Do(ctx, req, ipResp)
	if err != nil {
		return nil, resp, err
	}
	return ipResp, resp, nil
}




// xx_test.go

	func TestBasicService_IPList(t *testing.T) {
		client, mux, _, teardown := setup()
		defer teardown()

		mux.HandleFunc("/get_api_domain_ip", func(w http.ResponseWriter, r *http.Request) {
			testMethod(t, r, "GET")

			fmt.Fprint(w, `{"ip_list":["127.0.0.1"]}`)
		})

		ctx := context.Background()
		ipList, _, err := client.Basic.IPList(ctx)
		assert.Nil(t, err)

		want := &IPListResponse{IPList: []*string{String("127.0.0.1")}}
		assert.Equal(t, want, ipList)
	}

目前进展:完成了公众号平台接口、单元测试,下一步:小程序

2160 次点击
所在节点    Go 编程语言
5 条回复
ysicing
2021-11-17 17:20:18 +08:00
然后轮子呢?/doge
yanzhiling2001
2021-11-17 17:29:08 +08:00
自己写 go 的时候随心所欲为所欲为,直到看别人写的 go 代码。这个语法。
BeijingBaby
2021-11-17 17:47:36 +08:00
@ysicing sorry 还没写完,所以还没 github
strivemario558
2021-11-17 17:56:06 +08:00
这个是基于 web 的协议吗 还是移动端的
sciel
2021-11-17 18:01:20 +08:00
分享一个 KIVC5B

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/816092

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX