Git Product home page Git Product logo

wechat's Introduction

WeChat SDK

Build Status Go Report Card GoDoc

微信SDK的golang实现,短小精悍,同时兼容【企业微信/服务号/订阅号/小程序】

快速开始

5行代码,链式消息,快速开启微信API示例:

package main

import (
	"net/http"

	"github.com/esap/wechat" // 微信SDK包
)

func main() {
	wechat.Debug = true
	
	cfg := &wechat.WxConfig{
		Token:          "yourToken",
		AppId:          "yourAppID",
		Secret:         "yourSecret",
		EncodingAESKey: "yourEncodingAesKey",
	}

	app := wechat.New(cfg)
	app.SendText("@all", "Hello,World!")
	
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		app.VerifyURL(w, r).NewText("客服消息1").Send().NewText("客服消息2").Send().NewText("查询OK").Reply()
	})
	
	http.ListenAndServe(":9090", nil)
}

配置方式

	// 创建公众号实例(服务号/订阅号/小程序) 不带aesKey则为明文模式
	cfg := &wechat.WxConfig{
		Token:          "yourToken",
		AppId:          "yourAppID",
		Secret:         "yourSecret",
	}

	// 创建公众号实例(服务号/订阅号/小程序)
	cfg := &wechat.WxConfig{
		Token:          "yourToken",
		AppId:          "yourAppID",
		Secret:         "yourSecret",
		EncodingAESKey: "yourEncodingAesKey",
	}

	// 创建企业微信实例
	cfg := &wechat.WxConfig{
		Token:          "yourToken",
		AppId:          "yourCorpID",
		AgentId:        "yourAgentId",
		Secret:         "yourSecret",
		EncodingAESKey: "yourEncodingAesKey",
		AppType:        1,
	}

主动推送消息

用户关注后,企业微信可以主动推送消息,服务号需要用户48小时内进入过。

	app.SendText(to, msg)
	app.SendImage(to, mediaId)
	app.SendVoice(to, mediaId)
	app.SendFile(to, mediaId)
	app.SendVideo(to, mediaId, title, desc)
	app.SendTextcard(to, title, desc, url)
	app.SendMusic(to, mediaId, title, desc, musicUrl, qhMusicUrl)
	app.SendNews(to, arts...)
	app.SendMpNews(to, arts...)
	app.SendMpNewsId(to, mediaId)
	app.SendMarkDown(to, content)

消息回调

  • 通常将app.VerifyURL(http.ResponseWriter, *http.Request)嵌入http handler

该函数返回*wechat.Context基本对象,其中的Msg为用户消息:

	// 混合用户消息,业务判断的主体
	WxMsg struct {
		XMLName      xml.Name `xml:"xml"`
		ToUserName  
		FromUserName
		CreateTime  64
		MsgId       64
		MsgType     
		Content       // text
		AgentID          // corp
		PicUrl        // image
		MediaId       // image/voice/video/shortvideo
		Format        // voice
		Recognition   // voice
		ThumbMediaId  // video
		LocationX    float32 `xml:"Latitude"`  // location
		LocationY    float32 `xml:"Longitude"` // location
		Precision    float32 // LOCATION
		Scale            // location
		Label         // location
		Title         // link
		Description   // link
		Url           // link
		Event         // event
		EventKey      // event
		SessionFrom   // event|user_enter_tempsession
		Ticket      
		FileKey     
		FileMd5     
		FileTotalLen

		ScanCodeInfo struct {
			ScanType  
			ScanResult
		}
	}
  • 如果使用其他web框架,例如echo/gin/beego等,则把VerifyURL()放入controller或handler
// echo示例 公众号回调接口
func wxApiPost(c echo.Context) error {
	ctx := app.VerifyURL(c.Response().Writer, c.Request())
	
	// TODO: 这里是其他业务操作

	return nil
}

回调回复消息

回调回复消息有两种方式:

  • 被动回复,采用XML格式编码返回(Reply);

  • 客服消息,采用json格式编码返回(Send);

  • 两种方式都可先调用*wechat.Context对象的New方法创建消息,然后调用Reply()或Send()。

  • 支持链式调用,但Reply()只有第一次有效。

	ctx.NewText("正在查询中...").Reply()
	ctx.NewText("客服消息1").Send().NewText("客服消息2").Send()
  • 被动回复可直接调用Reply(),表示已收到,然后调用客服消息。

文本消息

	ctx.NewText("content")

图片/语言/文件消息

	// mediaID 可通过素材管理-上上传多媒体文件获得
	ctx.NewImage("mediaID")
	ctx.NewVoice("mediaID")
	
	// 仅企业号支持
	ctx.NewFile("mediaID")

视频消息

	ctx.NewVideo("mediaID", "title", "description")

音乐消息

	ctx.NewMusic("thumbMediaID","title", "description", "musicURL", "hqMusicURL")

图文消息

	// 先创建三个文章
	art1 := wechat.NewArticle("拥抱AI,享受工作",
		"来自村长的ESAP系统最新技术分享",
		"http://ylin.wang/img/esap18-1.png",
		"http://ylin.wang/2017/07/13/esap18/")
	art2 := wechat.NewArticle("用企业微信代替pda实现扫描入库",
		"来自村长的ESAP系统最新技术分享",
		"http://ylin.wang/img/esap17-2.png",
		"http://ylin.wang/2017/06/23/esap17/")
	art3 := wechat.NewArticle("大道至简的哲学",
		"来自村长的工作日志",
		"http://ylin.wang/img/golang.jpg",
		"http://ylin.wang/2017/01/29/log7/")
	// 打包成新闻
	ctx.NewNews(art1, art2, art3)

模板消息

相关issue

	tlpdata := map[string]struct {
		Value `json:"value"`
		Color `json:"color"`
	}{
		"first": {Value: "我是渣渣涛", Color: "#173177"},
		"keyword1": {Value: "这是一个你从没有玩过的全新游戏", Color: "#173177"},
		"keyword2": {Value: "只要你跟着我一起试玩一下", Color: "#173177"},
		"keyword3": {Value: "你就会爱上这款游戏", Color: "#4B1515"},
		"remark":   {Value: "是兄弟就来砍我", Color: "#071D42"},
	}
	ctx.SendTemplate(
		ctx.Msg.FromUserName,
		"tempid", // 模板ID
		c.Request.Host, // 跳转url
		ctx.AppId, // 跳转小程序,比url优先
		"", // 小程序页面
		tlpdata,
	)

License

MIT

wechat's People

Contributors

deancn avatar esap avatar lucker0087 avatar phpgao avatar qjzydsz avatar rixingyike avatar tomliu-github avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wechat's Issues

发模板消息内容是空的

代码如下

	tlpdata:= map[string]struct {
		value string
		color string
	}{"first": {value: "我是渣渣涛", color: "#173177"},
		"keyword1": {value: "这是一个你从没有玩过的全新游戏", color: "#173177"},
		"keyword2": {value: "只要你跟着我一起试玩一下", color: "#173177"},
		"keyword3": {value: "你就会爱上这款游戏", color: "#4B1515"},
		"remark":   {value: "是兄弟就来砍我", color: "#071D42"},
	}
	msgid,_ := ctx.SendTemplate(
		ctx.Msg.FromUserName,
		"tempid",
		c.Request.Host,
		ctx.AppId,
		"",
		tlpdata,
	)

效果如下

image

要不wechat.New/Set的参数用一个结构体怎样

要不wechat.New/Set的参数用一个结构体怎样 ,那样就可以按需显示传参了

比如

WechatConfig struct {
		token string
		appid string
                secret string
                ExternalTokenHandler func(string)
......
	}
wechat.New(WechatConfig {token:"",appid:"",secret:"",ExternalTokenHandler: func(appId string) *accessToken{}  })

异常抛出panic

当ip不在白名单时,抛出不可恢复的异常
errcode=40164 , errmsg=invalid ip 0.0.0.0, not in whitelist hint:
panic: runtime error: invalid memory address or nil pointer dereference

未知原因嗝屁

2021/12/05 18:38:42 POST | /wx/?signature=054e6f1efa0a99050e1baad62f1720511b23dfd5&timestamp=1638700720&nonce=1388272663&openid=oNf6L5wGUQaA4O9n2J9GOP5lgfcY
2021/12/05 18:38:42 http: panic serving 127.0.0.1:43256: runtime error: index out of range [-1]
goroutine 369 [running]:
net/http.(*conn).serve.func1()
/opt/hostedtoolcache/go/1.17.3/x64/src/net/http/server.go:1801 +0xb9
panic({0x1007540, 0xc00114ff20})
/opt/hostedtoolcache/go/1.17.3/x64/src/runtime/panic.go:1047 +0x266
github.com/rixingyike/wechat/util.PKCS7UnPad(...)
/home/runner/go/pkg/mod/github.com/rixingyike/[email protected]/util/crypto.go:30
github.com/rixingyike/wechat/util.AesDecrypt({0x1badf10, 0x0, 0x0}, {0xc00045b1d0, 0x0, 0x0})
/home/runner/go/pkg/mod/github.com/rixingyike/[email protected]/util/crypto.go:24 +0x16a
github.com/rixingyike/wechat.(*Server).DecryptMsg(0xc000103ba0, {0x0, 0x3})
/home/runner/go/pkg/mod/github.com/rixingyike/[email protected]/server.go:261 +0x53
github.com/rixingyike/wechat.(*Server).VerifyURL(0xc000103ba0, {0x7f3e95de5660, 0xc000622200}, 0xc0007b6800)
/home/runner/go/pkg/mod/github.com/rixingyike/[email protected]/server.go:230 +0x6c5
github.com/cdle/sillyGirl/im/wxmp.init.0.func1(0xc000622200)
/home/runner/work/sillyGirl/sillyGirl/im/wxmp/init.go:31 +0x70
github.com/gin-gonic/gin.(*Context).Next(...)
/home/runner/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:165
github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc000344b60, 0xc000622200)
/home/runner/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:489 +0x63e
github.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc000344b60, {0x1279568, 0xc000410700}, 0xc0007b6800)
/home/runner/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:445 +0x1c5
net/http.serverHandler.ServeHTTP({0x1277340}, {0x1279568, 0xc000410700}, 0xc0007b6800)
/opt/hostedtoolcache/go/1.17.3/x64/src/net/http/server.go:2878 +0x43b
net/http.(*conn).serve(0xc0002fb360, {0x1283f00, 0xc00078dd70})
/opt/hostedtoolcache/go/1.17.3/x64/src/net/http/server.go:1929 +0xb08
created by net/http.(*Server).Serve
/opt/hostedtoolcache/go/1.17.3/x64/src/net/http/server.go:3033 +0x4e8

小程序调用set方法时报错

调用方式: wechat.Set(TOKEN, APPID, SECRET)
报错信息如下:
2018/04/11 17:13:13 公众号用户: [] err: errcode=48001 , errmsg=api unauthorized hint:

原因是 server.go 中func (s *Server) Set() 针对accessToken不为空的情况,118行 调用了 b, err := s.BatchGetAll() , 这个else的功能是否可以去掉。

参数意义

// 创建企业微信实例
cfg := &wechat.WxConfig{
	Token:          "yourToken",
	AppId:          "yourCorpID",
	AgentId:        "yourAgentId",
	Secret:         "yourSecret",
	EncodingAESKey: "yourEncodingAesKey",
	AppType:        1,
}

请问这几个参数都是神魔意义,从企业号的哪里能看到?

在使用时发现会把微信的token打印出来,能关闭掉吗?

***2ccf[0]本地获取token:&{28_8vZw1BLTdZWLehP6k696CJRZm2reQJp5RqBWEV3C4pJTGgpEt-tkKCYYr9ZoFTRDHIeaeic9F1awTlkrI5CG8kVs3dU7pqwPEH1OtZVAhFDo0T216Ded9AVRuKFXiWTtPVq0naXZW6KuZxCFLIDhAIADAV 1576143635 {0 }}

不知道为什么会把我测试的token打印出来,并没有开启Debug

远程获取accesstoken这样写有问题吗,会报错,多谢了

cfg := &wechat.WxConfig{
		Token:          "",
		AppId:          "",
		Secret:         "",
		EncodingAESKey: "",
		ExternalTokenHandler: func(appId string, appName ...string) *wechat.AccessToken {
			fmt.Println("运行getAccessToken")
                        // TODO fetch远程数据,暂时写死
			var accessToken *wechat.AccessToken
			accessToken.AccessToken = "44_eqMb2oNPeuiwS0LKsA42UXRKpuHVbutgLaENZY1j27Mp4_d1Ao64AbnkmMjD4wKKT-ktN17rUddK_sd10RXk7YmstjboRZ84qHIdUnD30_nUg_FDuWoiwswz7RuRUHqccFap8zNLM_rl987dZBJbAIAHJR"
			accessToken.ExpiresIn = 1619153293
			return accessToken
		},
	}
运行getAccessToken
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x12a2a1b]

goroutine 1 [running]:
main.main.func1(0x13344f4, 0x12, 0xc000098db0, 0x1, 0x1, 0x1ed)
	/Users/zyk/go/src/waimai-mp/main.go:44 +0x7b
github.com/esap/wechat.(*Server).getAccessToken(0xc00009e9c0, 0xc00009e9c0, 0x14f1760)
	/Users/zyk/go/pkg/mod/github.com/esap/[email protected]/accesstoken.go:54 +0x19c
github.com/esap/wechat.New(0xc0000b5f00, 0x1041a0a)
	/Users/zyk/go/pkg/mod/github.com/esap/[email protected]/server.go:121 +0x1aa
main.main()
	/Users/zyk/go/src/waimai-mp/main.go:50 +0xcf
exit status 2

TOKEN验证失败是什么原因呢

2021/02/24 15:11:55 GET | /?signature=edb3487a194889b8a434b623c48d1aa6a76f80ad&echostr=6812425678080704511&timestamp=1614150715&nonce=139261658
2021/02/24 15:11:55 api echostr: 6812425678080704511
2021/02/24 15:11:55 Wechat <== &{wxResp:{XMLName:{Space: Local:} ToUserName: ToParty: ToTag: FromUserName: CreateTime:1614150715 MsgType:text AgentId:0 Safe:0} content:{Content:查询OK}}
2021/02/24 15:11:55 [*] 发送消息:&{wxResp:{XMLName:{Space: Local:} ToUserName: ToParty: ToTag: FromUserName: CreateTime:1614150715 MsgType:text AgentId:0 Safe:0} content:{Content:客服消息1}}
[*] 回执:{ErrCode:40003 ErrMsg:invalid openid rid: 6035fc3b-4873a3bb-3f1bb871}
2021/02/24 15:11:55 MsgSend err: invalid openid rid: 6035fc3b-4873a3bb-3f1bb871
2021/02/24 15:11:55 [*] 发送消息:&{wxResp:{XMLName:{Space: Local:} ToUserName: ToParty: ToTag: FromUserName: CreateTime:1614150715 MsgType:text AgentId:0 Safe:0} content:{Content:客服消息2}}
[*] 回执:{ErrCode:40003 ErrMsg:invalid openid rid: 6035fc3b-4e6422d5-5c88cae2}
2021/02/24 15:11:55 MsgSend err: invalid openid rid: 6035fc3b-4e6422d5-5c88cae2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.