Library / SDK
xen0n/go-workwx avatar
xen0n/go-workwx

go-workwx: a typed Go client for WeCom, still short of a v2 release

a sensible WeCom (企业微信, Wechat Work, Work Weixin) SDK for Go

808 stars206 forksGoMIT

At a glance

What is it?
go-workwx wraps the WeCom, Work Weixin, APIs for a Go program that wants to push notifications without hand-writing requests, and it takes access token handling seriously with automatic refresh and exponential backoff. The catch is stated in the README's own warning: v2 may still change incompatibly between test tags, and there is no stable v2 tag.
Who is it for?
Adopt go-workwx if you need to send WeCom notifications and group messages from Go, and you value a small typed API over coverage of every endpoint. Do not adopt it if you need the full API surface, because the supported list has large gaps in contact management, application management, tag management, OA approvals and session archiving, and do not build on the v2 line expecting stable tags, since the README warns that v2 may still break incompatibly and has no non-test tag.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 123 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

It started because the only alternative was bad

The Why another wheel section tells the origin plainly, and it is worth reading because it explains the design. The author needed to implement simple message push in Go, looked for an open source library, found that the only existing open source WeCom Go SDK had poor code quality, and wrote one instead. The update notes that by August 2019 there were already three or four similar projects, but that comparing them with his own, the type design, the public interface and the access token handling still looked decent. The rhetorical target is specific: why do people hardcode the request Host, use globals, and split packages apart for the sake of it, even at the cost of exposing internal methods? The library is described as battle-tested and pretty serious about its types, and it has been in production since late 2018 pushing notifications and alerts in at least two of Qiniu's internal systems. The 2026 update adds that the author changed jobs and has not actively maintained it for a long time, and notes the accidental benefit that most of the repository is still free of AI slop.

Getting started and how the token handling works

The package is imported under its versioned module path, which is how you pull the v2 line:

go
import (
    "github.com/xen0n/go-workwx/v2" // package workwx
)

The feature list is short and the token story is the centre of it. You can simply make an API call and the library will request the access token for you, or you can start a background access token refresh goroutine in one line, and it comes with exponential backoff retry built in. The token.go file in the repository is where that lives, and the go.mod confirms the backoff dependency, github.com/cenkalti/backoff/v4. There is also support for overriding the API Host, which the README describes as being for putting your own gateway in front, temporary debugging and similar unusual needs, and support for supplying your own http.Client. That combination is the difference between an SDK you can put in production and one you cannot. A token that silently expires in the middle of a retry storm is the classic way an otherwise good notification client fails at 3am, and having the library own that behaviour is worth more than covering another ten endpoints.

A deliberately small public surface

The README states the principles in the first person, and they are testable. Publicly exposed interfaces are minimised, and you construct a WorkwxApp object in two steps and then use it directly. The raw WeCom request and response types are deliberately not exposed. A possible future lowlevel package would expose the raw API, but is unlikely to happen. There is no polymorphism for its own sake, and the author would rather duplicate code inside the SDK than break the rule that one interface means one action, so downstream users get static dispatch. Some data models were adjusted or even redone, with UserInfo and Recipient named as examples, in order to encourage idiomatic Go. And it does not overstep: it will not panic on you, and all existing panics exist only in unit tests or the library's own test command, so they cannot affect business code calling the library normally. The tradeoff is real. A user who needs an endpoint the SDK has not modelled has no lowlevel escape hatch, so the answer is an upstream issue rather than a workaround.

Coverage is uneven, and the README admits it

The supported APIs table is the most useful thing in the document, and it is a list of checkboxes rather than a marketing claim. Message sending is fully supported, with all ten message types implemented: text, image, voice, video, file, text card, news, news in mpnews form, markdown and task card. Message receiving, the WeCom login interface and the identity lookup interface are supported. Material management supports uploading, though fetching temporary uploads and high definition voice uploads are not implemented. Contact management is partial, and the details show which member and department operations are missing, with member creation, deletion, batch deletion, department update and deletion, and the whole tag management group unchecked. Customer contact, WeChat customer service, OA and session content archiving are each described as mostly or partially supported with their own gaps, and application management is not supported at all. If you are integrating a WeCom app that reads the organisation directory, expect to be reading a half-covered API.

The v2 line has no stable tag, and the README says so

The warning at the top of the README is the first thing an adopter should read, and it is unusually precise. The v2 version may still have incompatible API changes, such as field name and method name adjustments, and there will be no non-test v2 tag until all the known edge cases have been dealt with. They do not guarantee compatibility between any two test tags of v2, but they will try to provide migration guides for incompatible changes separately. The most recent release listed is v2.0.0-alpha.1 from 2026-01-05, with v1.7.0 from 2024-04-08 before it and v1.6.0 from 2023-07-06 before that. The default branch is v2, and the import path carries the major version, so the code in the tree and the version you would depend on are not the same thing. The README also asks users who depend on the library to react to the v2 tracking issue, since the author now maintains the project entirely in spare time and needs the feedback.

Go version floors, and a stated willingness to break you

The supported Go versions section is frank about a policy that would be unusual in most libraries. The v2.x branch supports at least the previous stable version of Go, which as of January 2026 is go1.24, and if you need to pair it with an older Go you should use the v1.x branch, whose code still supports go1.17 at minimum. CI runs the tests on the current stable and previous stable Go versions, and a pull request can only be merged if all tests pass. Then comes the part that matters most for planning. Because Go upstream keeps developing, the maintainers need to keep pace at a relatively low cost, and if a go.mod specifying a low Go version would hinder the library's own iteration or refactoring, the maintainers will not specially consider locking the Go version for downstream users at the cost of slowing down necessary upgrades. If you have that requirement, the project asks you to open an issue. In practice this means the v2 line will keep moving its Go floor, and a downstream consumer pinned to an old Go toolchain has to plan around that rather than assume a frozen floor.

A debugging CLI and a secret-message caveat

Two smaller details that tell you how the library is used. There is a workwxctl command line tool included for debugging, with the README asking you to file an issue if it is not pleasant to use. The repository has a cmd/ directory for it, and the Go dependency list includes urfave/cli v2 for the command line parsing. The second detail is a caveat about confidential messages. Markdown and similar message types are not currently supported as confidential messages, and forcing it will return an error. The README explains why the send methods still carry an isSafe parameter anyway: the WeCom service side might support confidential sending for more message types in future and client code should not have to be recompiled, and since the response errors regardless, you would not keep that logic around, so it is left as is. That is a good example of the project documenting its own inconsistencies rather than hiding them. The MIT licence is in the LICENSE file at the root.

Editorial conclusion

Adopt go-workwx if you need to send WeCom notifications and group messages from Go, and you value a small typed API over coverage of every endpoint. Do not adopt it if you need the full API surface, because the supported list has large gaps in contact management, application management, tag management, OA approvals and session archiving, and do not build on the v2 line expecting stable tags, since the README warns that v2 may still break incompatibly and has no non-test tag. Before you commit, read the supported APIs list against your actual requirements, and check the issue tracker for the v2 tracking ticket.

Frequently asked questions

What is go-workwx?

It is an MIT licensed Go client SDK for Work Weixin, also known as Wechat Work or WeCom. It covers message sending and receiving, customer contact, customer service, OA, session archiving and identity APIs, and the README notes it has run in production since late 2018 in at least two of Qiniu's internal systems.

How does go-workwx handle access tokens?

You can call the API directly and it will request the access token automatically, or start a background access token refresh goroutine in one line. Exponential backoff retry is built in, the token logic lives in token.go, and the go.mod depends on github.com/cenkalti/backoff/v4.

Is the v2 version of go-workwx stable?

Not yet. The README warns that the v2 version may still have incompatible API changes such as field and method name adjustments, that there will be no non-test v2 tag until the known edge cases are resolved, and that compatibility between any two v2 test tags is not guaranteed. The newest listed release is v2.0.0-alpha.1 from 2026-01-05.

Which WeCom APIs are not covered by go-workwx?

Application management is not supported at all. Contact management is partial, with member creation and deletion, batch deletion, department update and deletion and the whole tag management group missing. OA approvals, session content archiving and customer service also have unchecked operations, including knowledge base management and statistics.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. xen0n/go-workwx on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/xen0n-go-workwx.svg)](https://hysenlabs.com/projects/xen0n-go-workwx)

Was this useful?