{"id":13469970,"url":"https://github.com/wizjin/weixin","last_synced_at":"2025-10-31T07:11:44.055Z","repository":{"id":12459847,"uuid":"15122937","full_name":"wizjin/weixin","owner":"wizjin","description":"Weixin MP Go Library","archived":false,"fork":false,"pushed_at":"2022-01-12T02:47:28.000Z","size":136,"stargazers_count":190,"open_issues_count":8,"forks_count":76,"subscribers_count":17,"default_branch":"master","last_synced_at":"2024-08-01T16:18:07.813Z","etag":null,"topics":["go","weixin"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wizjin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-12-12T00:20:18.000Z","updated_at":"2024-01-03T08:26:08.000Z","dependencies_parsed_at":"2022-07-15T11:30:33.037Z","dependency_job_id":null,"html_url":"https://github.com/wizjin/weixin","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wizjin%2Fweixin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wizjin%2Fweixin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wizjin%2Fweixin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wizjin%2Fweixin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wizjin","download_url":"https://codeload.github.com/wizjin/weixin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222131035,"owners_count":16936304,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","weixin"],"created_at":"2024-07-31T16:00:20.164Z","updated_at":"2025-10-31T07:11:43.991Z","avatar_url":"https://github.com/wizjin.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# 微信公众平台库 – Go语言版本\r\n\r\n## 简介\r\n\r\n这是一个使用Go语言对微信公众平台的封装。参考了微信公众平台API文档\r\n\r\n[![Build Status](https://travis-ci.org/wizjin/weixin.png?branch=master)](https://travis-ci.org/wizjin/weixin)\r\n[![GoDoc](http://godoc.org/github.com/wizjin/weixin?status.png)](http://godoc.org/github.com/wizjin/weixin)\r\n\r\n## 入门\r\n\r\n### 安装\r\n\r\n通过执行下列语句就可以完成安装\r\n\r\n\tgo get github.com/wizjin/weixin\r\n\r\n### 注册微信公众平台\r\n\r\n注册微信公众平台，填写验证微信公众平台的Token\r\n\r\n### 示例\r\n\r\n```Go\r\npackage main\r\n\r\nimport (\r\n\t\"github.com/wizjin/weixin\"\r\n\t\"net/http\"\r\n)\r\n\r\n// 文本消息的处理函数\r\nfunc Echo(w weixin.ResponseWriter, r *weixin.Request) {\r\n\ttxt := r.Content\t\t\t// 获取用户发送的消息\r\n\tw.ReplyText(txt)\t\t\t// 回复一条文本消息\r\n\tw.PostText(\"Post:\" + txt)\t// 发送一条文本消息\r\n}\r\n\r\n// 关注事件的处理函数\r\nfunc Subscribe(w weixin.ResponseWriter, r *weixin.Request) {\r\n\tw.ReplyText(\"欢迎关注\") // 有新人关注，返回欢迎消息\r\n}\r\n\r\nfunc main() {\r\n\t// my-token 验证微信公众平台的Token\r\n\t// app-id, app-secret用于高级API调用。\r\n\t// 如果仅使用接收/回复消息，则可以不填写，使用下面语句\r\n\t// mux := weixin.New(\"my-token\", \"\", \"\")\r\n\tmux := weixin.New(\"my-token\", \"app-id\", \"app-secret\")\r\n\t// 设置AES密钥，如果不使用AES可以省略这行代码\r\n\tmux.SetEncodingAESKey(\"encoding-AES-key\")\r\n\t// 注册文本消息的处理函数\r\n\tmux.HandleFunc(weixin.MsgTypeText, Echo)\r\n\t// 注册关注事件的处理函数\r\n\tmux.HandleFunc(weixin.MsgTypeEventSubscribe, Subscribe)\r\n\thttp.Handle(\"/\", mux) // 注册接收微信服务器数据的接口URI\r\n\thttp.ListenAndServe(\":80\", nil) // 启动接收微信数据服务器\r\n}\r\n```\r\n\r\n微信公众平台要求在收到消息后5秒内回复消息（Reply接口）\r\n如果时间操作很长，则可以使用Post接口发送消息\r\n如果只使用Post接口发送消息，则需要先调用ReplyOK来告知微信不用等待回复。\r\n\r\n### 处理函数\r\n\r\n处理函数的定义可以使用下面的形式\r\n\r\n```Go\r\nfunc Func(w weixin.ResponseWriter, r *weixin.Request) {\r\n\t...\r\n}\r\n```\r\n\r\n可以注册的处理函数类型有以下几种\r\n\r\n- `weixin.MsgTypeText`\t\t\t\t接收文本消息\r\n- `weixin.MsgTypeImage`\t\t\t\t接收图片消息\r\n- `weixin.MsgTypeVoice`\t\t\t\t接收语音消息\r\n- `weixin.MsgTypeVideo`\t\t\t\t接收视频消息\r\n- `weixin.MsgTypeShortVideo`\t\t接收小视频消息\r\n- `weixin.MsgTypeLocation`\t\t\t接收地理位置消息\r\n- `weixin.MsgTypeLink`\t\t\t\t接收链接消息\r\n- `weixin.MsgTypeEventSubscribe`\t接收关注事件\r\n- `weixin.MsgTypeEventUnsubscribe`\t接收取消关注事件\r\n- `weixin.MsgTypeEventScan`\t\t\t接收扫描二维码事件\r\n- `weixin.MsgTypeEventView`\t\t\t接收点击菜单跳转链接时的事件\r\n- `weixin.MsgTypeEventClick`\t\t接收自定义菜单事件\r\n- `weixin.MsgTypeEventLocation`\t\t接收上报地理位置事件\r\n- `weixin.MsgTypeEventTemplateSent` 接收模版消息发送结果\r\n\r\n### 发送被动响应消息\r\n\r\n需要发送被动响应消息，可通过`weixin.ResponseWriter`的下列方法完成\r\n\r\n- `ReplyOK()`\t\t\t\t\t\t\t\t无同步消息回复\r\n- `ReplyText(text)`\t\t\t\t\t\t\t回复文本消息\r\n- `ReplyImage(mediaId)`\t\t\t\t\t\t回复图片消息\r\n- `ReplyVoice(mediaId)`\t\t\t\t\t\t回复语音消息\r\n- `ReplyVideo(mediaId, title, description)`\t回复视频消息\r\n- `ReplyMusic(music)`\t\t\t\t\t\t回复音乐消息\r\n- `ReplyNews(articles)`\t\t\t\t\t\t回复图文消息\r\n\r\n### 发送客服消息\r\n\r\n- `PostText(text)`\t\t\t\t\t\t\t发送文本消息\r\n- `PostImage(mediaId)`\t\t\t\t\t\t发送图片消息\r\n- `PostVoice(mediaId)`\t\t\t\t\t\t发送语音消息\r\n- `PostVideo(mediaId, title, description)`\t发送视频消息\r\n- `PostMusic(music)`\t\t\t\t\t\t发送音乐消息\r\n- `PostNews(articles)`\t\t\t\t\t\t发送图文消息\r\n\r\n### 发送模版消息\r\n\r\n如需要发送模版消息，需要先获取模版ID，之后再根据ID发送。\r\n\r\n```Go\r\nfunc GetTemplateId(wx *weixin.Weixin) {\r\n\ttid, err := wx.AddTemplate(\"TM00015\")\r\n\tif err != nil {\r\n\t\tfmt.Println(err)\r\n\t} else {\r\n\t\tfmt.Println(ips)\t// 模版ID\r\n\t}\r\n}\r\n```\r\n\r\n随后可以发送模版消息了。\r\n\r\n```Go\r\nfunc SendTemplateMessage(w weixin.ResponseWriter, r *weixin.Request) {\r\n\ttemplateId := ...\r\n\turl := ...\r\n\tmsgid, err := w.PostTemplateMessage(templateId, url,\r\n\t\tweixin.TmplData{ \"first\": weixin.TmplItem{\"Hello World!\", \"#173177\"}})\r\n\tif err != nil {\r\n\t\tfmt.Println(err)\r\n\t} else {\r\n\t\tfmt.Println(msgid)\r\n\t}\r\n}\r\n```\r\n\r\n在模版消息发送成功后，还会通过类型为`MsgTypeEventTemplateSent`的消息推送获得发送结果。\r\n\r\n- `TemplateSentStatusSuccess` \t\t发送成功\r\n- `TemplateSentStatusUserBlock`\t\t发送失败，用户拒绝接收\r\n- `TemplateSentStatusSystemFailed`\t发送失败，系统原因\r\n\r\n\r\n### 上传/下载多媒体文件\r\n\r\n使用如下函数可以用来上传多媒体文件:\r\n\r\n`UploadMediaFromFile(mediaType string, filepath string)`\r\n\r\n示例 (用一张本地图片来返回图片消息):\r\n\r\n```Go\r\nfunc ReciveMessage(w weixin.ResponseWriter, r *weixin.Request) {\r\n\t// 上传本地文件并获取MediaID\r\n\tmediaId, err := w.UploadMediaFromFile(weixin.MediaTypeImage, \"/my-file-path\")\r\n\tif err != nil {\r\n\t\tw.ReplyText(\"上传图片失败\")\r\n\t} else {\r\n\t\tw.ReplyImage(mediaId)\t// 利用获取的MediaId来返回图片消息\r\n\t}\r\n}\r\n```\r\n\r\n使用如下函数可以用来下载多媒体文件:\r\n\r\n`DownloadMediaToFile(mediaId string, filepath string)`\r\n\r\n示例 (收到一条图片消息，然后保存图片到本地文件):\r\n\r\n```Go\r\nfunc ReciveImageMessage(w weixin.ResponseWriter, r *weixin.Request) {\r\n\t// 下载文件并保存到本地\r\n\terr := w.DownloadMediaToFile(r.MediaId, \"/my-file-path\")\r\n\tif err != nil {\r\n\t\tw.ReplyText(\"保存图片失败\")\r\n\t} else {\r\n\t\tw.ReplyText(\"保存图片成功\")\r\n\t}\r\n}\r\n```\r\n\r\n### 获取微信服务器IP地址\r\n\r\n示例，获取微信服务器IP地址列表\r\n\r\n```Go\r\nfunc GetIpList(wx *weixin.Weixin) {\r\n\tips, err := wx.GetIpList()\r\n\tif err != nil {\r\n\t\tfmt.Println(err)\r\n\t} else {\r\n\t\tfmt.Println(ips)\t// Ip地址列表\r\n\t}\r\n}\r\n```\r\n\r\n### 获取AccessToken\r\n\r\n示例，获取AccessToken\r\n\r\n```Go\r\nfunc GetAccessToken(wx *weixin.Weixin) {\r\n\ta := wx.GetAccessToken\r\n\tif time.Until(token.Expires).Seconds() \u003e 0 {\r\n\t\tfmt.Println(a.Token)\t// AccessToken\r\n\t} else {\r\n\t\tfmt.Println(\"Timeout\")\t// 超时\r\n\t}\r\n}\r\n```\r\n\r\n### 创建/换取二维码\r\n\r\n示例，创建临时二维码\r\n\r\n```Go\r\nfunc CreateQRScene(wx *weixin.Weixin) {\r\n\t// 二维码ID - 1000\r\n\t// 过期时间 - 1800秒\r\n\tqr, err := wx.CreateQRScene(1000, 1800)\r\n\tif err != nil {\r\n\t\tfmt.Println(err)\r\n\t} else {\r\n\t\turl := qr.ToURL() // 获取二维码的URL\r\n\t\tfmt.Println(url)\r\n\t}\r\n}\r\n```\r\n\r\n示例，创建永久二维码\r\n\r\n```Go\r\nfunc CreateQRScene(wx *weixin.Weixin) {\r\n\t// 二维码ID - 1001\r\n\tqr, err := wx.CreateQRLimitScene(1001)\r\n\tif err != nil {\r\n\t\tfmt.Println(err)\r\n\t} else {\r\n\t\turl := qr.ToURL() // 获取二维码的URL\r\n\t\tfmt.Println(url)\r\n\t}\r\n}\r\n```\r\n\r\n### 长链接转短链接接口\r\n\r\n```Go\r\nfunc ShortURL(wx *weixin.Weixin) {\r\n\t// 长链接转短链接\r\n\turl, err := wx.ShortURL(\"http://mp.weixin.qq.com/wiki/10/165c9b15eddcfbd8699ac12b0bd89ae6.html\")\r\n\tif err != nil {\r\n\t\tfmt.Println(err)\r\n\t} else {\r\n\t\tfmt.Println(url)\r\n\t}\r\n}\r\n```\r\n\r\n### 自定义菜单\r\n\r\n示例，创建自定义菜单\r\n\r\n```Go\r\nfunc CreateMenu(wx *weixin.Weixin) {\r\n\tmenu := \u0026weixin.Menu{make([]weixin.MenuButton, 2)}\r\n\tmenu.Buttons[0].Name = \"我的菜单\"\r\n\tmenu.Buttons[0].Type = weixin.MenuButtonTypeUrl\r\n\tmenu.Buttons[0].Url = \"https://mp.weixin.qq.com\"\r\n\tmenu.Buttons[1].Name = \"我的子菜单\"\r\n\tmenu.Buttons[1].SubButtons = make([]weixin.MenuButton, 1)\r\n\tmenu.Buttons[1].SubButtons[0].Name = \"测试\"\r\n\tmenu.Buttons[1].SubButtons[0].Type = weixin.MenuButtonTypeKey\r\n\tmenu.Buttons[1].SubButtons[0].Key = \"MyKey001\"\r\n\terr := wx.CreateMenu(menu)\r\n\tif err != nil {\r\n\t\tfmt.Println(err)\r\n\t}\r\n}\r\n```\r\n\r\n自定义菜单的类型有如下几种\r\n\r\n- `weixin.MenuButtonTypeKey`\t\t\t\t点击推事件\r\n- `weixin.MenuButtonTypeUrl`\t\t\t\t跳转URL\r\n- `weixin.MenuButtonTypeScancodePush`\t\t扫码推事件\r\n- `weixin.MenuButtonTypeScancodeWaitmsg`\t扫码推事件且弹出“消息接收中”提示框\r\n- `weixin.MenuButtonTypePicSysphoto`\t\t弹出系统拍照发图\r\n- `weixin.MenuButtonTypePicPhotoOrAlbum`\t弹出拍照或者相册发图\r\n- `weixin.MenuButtonTypePicWeixin`\t\t\t弹出微信相册发图器\r\n- `weixin.MenuButtonTypeLocationSelect`\t\t弹出地理位置选择器\r\n- `weixin.MenuButtonTypeMediaId`\t\t\t下发消息（除文本消息）\r\n- `weixin.MenuButtonTypeViewLimited`\t\t跳转图文消息URL\r\n\r\n示例，获取自定义菜单\r\n\r\n```Go\r\nfunc DeleteMenu(wx *weixin.Weixin) {\r\n\tmenu, err := wx.GetMenu()\r\n\tif err != nil {\r\n\t\tfmt.Println(err)\r\n\t} else {\r\n\t\tfmt.Println(menu)\r\n\t}\r\n}\r\n```\r\n\r\n示例，删除自定义菜单\r\n\r\n```Go\r\nfunc DeleteMenu(wx *weixin.Weixin) {\r\n\terr := wx.DeleteMenu()\r\n\tif err != nil {\r\n\t\tfmt.Println(err)\r\n\t}\r\n}\r\n```\r\n\r\n### JSSDK签名\r\n\r\n示例，生成JSSDK签名\r\n```Go\r\nfunc SignJSSDK(wx *weixin.Weixin, url string) {\r\n\ttimestamp := time.Now().Unix()\r\n\tnoncestr := fmt.Sprintf(\"%d\", c.randreader.Int())\r\n\tsign, err := wx.JsSignature(url, timestamp, noncestr)\r\n\tif err != nil {\r\n\t\tfmt.Println(err)\r\n\t} else {\r\n\t\tfmt.Println(sign)\r\n\t}\r\n}\r\n```\r\n\r\n### 重定向URL生成\r\n\r\n示例，生成重定向URL\r\n```Go\r\nfunc CreateRedirect(wx *weixin.Weixin, url string) {\r\n\tredirect := wx.CreateRedirectURL(url, weixin.RedirectURLScopeBasic, \"\")\r\n}\r\n```\r\n\r\nURL的类型有如下几种:\r\n\r\n- `RedirectURLScopeBasic`\t\t\t\t\t基本授权，仅用来获取OpenId或UnionId\r\n- `RedirectURLScopeUserInfo`\t\t\t\t高级授权，可以用于获取用户基本信息，需要用户同意\r\n\r\n### 用户OpenId和UnionId获取\r\n\r\n示例，获取用户OpenId和UnionId\r\n```Go\r\nfunc GetUserId(wx *weixin.Weixin, code string) {\r\n\tuser, err := wx.GetUserAccessToken(code)\r\n\tif err != nil {\r\n\t\tfmt.Println(err)\r\n\t} else {\r\n\t\tfmt.Println(user.OpenId)\r\n\t\tfmt.Println(user.UnionId)\r\n\t}\r\n}\r\n```\r\n\r\n### 用户信息获取\r\n\r\n示例，获取用户信息\r\n```Go\r\nfunc GetUserInfo(wx *weixin.Weixin, openid string) {\r\n\tuser, err := wx.GetUserInfo(openid)\r\n\tif err != nil {\r\n\t\tfmt.Println(err)\r\n\t} else {\r\n\t\tfmt.Println(user.Nickname)\r\n\t\tfmt.Println(user.Sex)\r\n\t\tfmt.Println(user.City)\r\n\t\tfmt.Println(user.Country)\r\n\t\tfmt.Println(user.Province)\r\n\t\tfmt.Println(user.HeadImageUrl)\r\n\t\tfmt.Println(user.SubscribeTime)\r\n\t\tfmt.Println(user.Remark)\r\n\t}\r\n}\r\n```\r\n\r\n\r\n## 参考连接\r\n\r\n* [Wiki](https://github.com/wizjin/weixin/wiki)\r\n* [API文档](http://godoc.org/github.com/wizjin/weixin)\r\n* [微信公众平台](https://mp.weixin.qq.com)\r\n* [微信公众平台API文档](http://mp.weixin.qq.com/wiki/index.php)\r\n\r\n## 版权声明\r\n\r\nThis project is licensed under the MIT license, see [LICENSE](LICENSE).\r\n\r\n## 更新日志\r\n\r\n### Version 0.5.4 - upcoming\r\n\r\n- 用户管理\r\n- 支持AES\r\n\r\n### Version 0.5.3 - 2016/01/05\r\n\r\n- 添加模版消息送\r\n\r\n### Version 0.5.2 - 2015/12/05\r\n\r\n- 添加JSSDK签名生成\r\n- 添加重定向URL生成\r\n- 添加获取用户OpenId和UnionId\r\n- 添加获取授权用户信息\r\n\r\n### Version 0.5.1 - 2015/06/26\r\n\r\n- 获取微信服务器IP地址\r\n- 接收小视频消息\r\n\r\n### Version 0.5.0 - 2015/06/25\r\n\r\n- 自定义菜单\r\n- 长链接转短链接\r\n\r\n### Version 0.4.1 - 2014/09/07\r\n\r\n- 添加将消息转发到多客服功能\r\n\r\n### Version 0.4.0 - 2014/02/07\r\n\r\n- 创建/换取二维码\r\n\r\n### Version 0.3.0 - 2014/01/07\r\n\r\n- 多媒体文件处理：上传/下载多媒体文件\r\n\r\n### Version 0.2.0 - 2013/12/19\r\n\r\n- 发送客服消息：文本消息，图片消息，语音消息，视频消息，音乐消息，图文消息\r\n\r\n### Version 0.1.0 – 2013/12/17\r\n\r\n- Token验证URL有效性\r\n- 接收普通消息：文本消息，图片消息，语音消息，视频消息，地理位置消息，链接消息\r\n- 接收事件推送：关注/取消关注，扫描二维码事件，上报地理位置，自定义菜单\r\n- 发送被动响应消息：文本消息，图片消息，语音消息，视频消息，音乐消息，图文消息\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwizjin%2Fweixin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwizjin%2Fweixin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwizjin%2Fweixin/lists"}