GithubHelp home page GithubHelp logo

silenceper / wechat Goto Github PK

View Code? Open in Web Editor NEW
4.7K 121.0 1.1K 5.56 MB

WeChat SDK for Go (微信SDK:简单、易用)

Home Page: https://silenceper.com/wechat/

License: Apache License 2.0

Go 98.53% C 0.62% C++ 0.85%
wechat go wechat-sdk sdk js-sdk weixin golang

wechat's Issues

结合beego 验证失败 http: wrote more than the declared Content-Length

2017/08/07 14:42:14 [C] [asm_amd64.s:514] Handler crashed with error http: wrote more than the declared Content-Length
2017/08/07 14:42:14 [C] [asm_amd64.s:514] /usr/local/go/src/runtime/asm_amd64.s:514
2017/08/07 14:42:14 [C] [asm_amd64.s:514] /usr/local/go/src/runtime/panic.go:489
2017/08/07 14:42:14 [C] [asm_amd64.s:514] /opt/gopath/src/github.com/silenceper/wechat/context/render.go:18
2017/08/07 14:42:14 [C] [asm_amd64.s:514] /opt/gopath/src/github.com/silenceper/wechat/context/render.go:25
2017/08/07 14:42:14 [C] [asm_amd64.s:514] /opt/gopath/src/github.com/silenceper/wechat/server/server.go:51
2017/08/07 14:42:14 [C] [asm_amd64.s:514] /opt/gopath/src/jrqs/service/weixinService.go:33
2017/08/07 14:42:14 [C] [asm_amd64.s:514] /opt/gopath/src/jrqs/controllers/message.go:14
2017/08/07 14:42:14 [C] [asm_amd64.s:514] /opt/gopath/src/github.com/astaxie/beego/router.go:798
2017/08/07 14:42:14 [C] [asm_amd64.s:514] /usr/local/go/src/net/http/server.go:2568
2017/08/07 14:42:14 [C] [asm_amd64.s:514] /usr/local/go/src/net/http/server.go:1825
2017/08/07 14:42:14 [C] [asm_amd64.s:514] /usr/local/go/src/runtime/asm_amd64.s:2197

为什么删除菜单老出错?

代码:
wc := wechat.NewWechat(config)

// 传入request和responseWriter
server := wc.GetServer(req, rw)
mu := wc.GetMenu(req, rw)
mu.DeleteMenu()

出错信息:
runtime error: invalid memory address or nil pointer dereference

小程序的 code2Session api希望加上去

const code2SessionUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"

const openInfoType = 0

type Wechat struct {
*wechat.Wechat
}

type Code2Session struct {
Openid string json:"openid"
SessionKey string json:"session_key"
Unionid string json:"unionid"
ErrCode int64 json:"errcode"
ErrMsg string json:"errMsg"
}

func (w *Wechat) GetCode2Session(code string) (result Code2Session, err error) {
urlStr := fmt.Sprintf(code2SessionUrl, w.Context.AppID, w.Context.AppSecret, code)
var response []byte
response, err = util.HTTPGet(urlStr)
if err != nil {
return
}

err = json.Unmarshal(response, &result)
if err != nil {
	return
}
if result.ErrCode != 0 {
	err = fmt.Errorf("GetCode2Session error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
	return
}
return

}

微信菜单创建不成功

我的代码是这样的

mu := wc.GetMenu(c.Request, c.Writer)

buttons := make([]*menu.Button, 1)
btn := new(menu.Button)
btn.SetClickButton("name", "key123")
buttons[0] = btn

//发送请求
err2 := mu.SetMenu(buttons)
if err2 != nil {
	log.Printf("err= %v", err2)
	return
}

日志报错是:

err2 := mu.SetMenu(buttons)

这条引发的错误

错误是:

runtime error: invalid memory address or nil pointer dereference
/usr/local/go/src/runtime/panic.go:489 (0x42866f)
/usr/local/go/src/runtime/panic.go:63 (0x42751e)
/usr/local/go/src/runtime/signal_unix.go:290 (0x43d43f)
/Users/xxxx/go/src/github.com/silenceper/wechat/context/access_token.go:36 (0x77651b)
/Users/xxxx/go/src/github.com/silenceper/wechat/menu/menu.go:123 (0x77d0d3)
/Users/xxxx/projects/golang/wx/main.go:57 (0x7863db)

生成菜单报错

2016/12/13 09:24:04 http: panic serving [::1]:56630: runtime error: invalid memory address or nil pointer dereference
goroutine 5 [running]:
net/http.(*conn).serve.func1(0xc820070100)
/usr/lib/go/src/net/http/server.go:1389 +0xc1
panic(0x7808a0, 0xc82000a130)
/usr/lib/go/src/runtime/panic.go:443 +0x4e9
github.com/silenceper/wechat/context.(*Context).GetAccessToken(0xc8200f2080, 0x0, 0x0, 0x0, 0x0)
/home/xjk/GoCode/src/github.com/silenceper/wechat/context/access_token.go:36 +0x1da
github.com/silenceper/wechat/menu.(*Menu).SetMenu(0xc82004f9c0, 0xc820104008, 0x1, 0x1, 0x0, 0x0)
/home/xjk/GoCode/src/github.com/silenceper/wechat/menu/menu.go:123 +0x48
main.createMenu(0x7f77da1fc820, 0xc8200fe000, 0xc8200e82a0)
/home/xjk/GoProject/wechat/examples/http/http.go:69 +0x617
net/http.HandlerFunc.ServeHTTP(0x89d380, 0x7f77da1fc820, 0xc8200fe000, 0xc8200e82a0)
/usr/lib/go/src/net/http/server.go:1618 +0x3a
net/http.(*ServeMux).ServeHTTP(0xc820016cc0, 0x7f77da1fc820, 0xc8200fe000, 0xc8200e82a0)
/usr/lib/go/src/net/http/server.go:1910 +0x17d
net/http.serverHandler.ServeHTTP(0xc820070080, 0x7f77da1fc820, 0xc8200fe000, 0xc8200e82a0)
/usr/lib/go/src/net/http/server.go:2081 +0x19e
net/http.(*conn).serve(0xc820070100)
/usr/lib/go/src/net/http/server.go:1472 +0xf2e
created by net/http.(*Server).Serve
/usr/lib/go/src/net/http/server.go:2137 +0x44e
2016/12/13 09:24:04 http: panic serving [::1]:56632: runtime error: invalid memory address or nil pointer dereference
goroutine 6 [running]:
net/http.(*conn).serve.func1(0xc820070180)
/usr/lib/go/src/net/http/server.go:1389 +0xc1
panic(0x7808a0, 0xc82000a130)
/usr/lib/go/src/runtime/panic.go:443 +0x4e9
github.com/silenceper/wechat/context.(*Context).GetAccessToken(0xc8200f2200, 0x0, 0x0, 0x0, 0x0)
/home/xjk/GoCode/src/github.com/silenceper/wechat/context/access_token.go:36 +0x1da
github.com/silenceper/wechat/menu.(*Menu).SetMenu(0xc82004f9c0, 0xc820104018, 0x1, 0x1, 0x0, 0x0)
/home/xjk/GoCode/src/github.com/silenceper/wechat/menu/menu.go:123 +0x48
main.createMenu(0x7f77da1fc820, 0xc8200fe1a0, 0xc8200e80e0)
/home/xjk/GoProject/wechat/examples/http/http.go:69 +0x617
net/http.HandlerFunc.ServeHTTP(0x89d380, 0x7f77da1fc820, 0xc8200fe1a0, 0xc8200e80e0)
/usr/lib/go/src/net/http/server.go:1618 +0x3a
net/http.(*ServeMux).ServeHTTP(0xc820016cc0, 0x7f77da1fc820, 0xc8200fe1a0, 0xc8200e80e0)
/usr/lib/go/src/net/http/server.go:1910 +0x17d
net/http.serverHandler.ServeHTTP(0xc820070080, 0x7f77da1fc820, 0xc8200fe1a0, 0xc8200e80e0)
/usr/lib/go/src/net/http/server.go:2081 +0x19e
net/http.(*conn).serve(0xc820070180)
/usr/lib/go/src/net/http/server.go:1472 +0xf2e
created by net/http.(*Server).Serve
/usr/lib/go/src/net/http/server.go:2137 +0x44e

代码如下

func createMenu(rw http.ResponseWriter, req *http.Request) {
	//配置微信参数
	config := &wechat.Config{
		AppID:          "ai",
		AppSecret:      "as",
		Token:          "token",
		EncodingAESKey: "4f9f7ad4b469492a808993f466e3c69889da3cebfcf",
	}
	wc := wechat.NewWechat(config)
	mu := wc.GetMenu(req, rw)

	buttons := make([]*menu.Button, 1)
	btn := new(menu.Button)

	//创建click类型菜单
	btn.SetClickButton("name", "key123")
	buttons[0] = btn

	//设置btn为二级菜单
	btn2 := new(menu.Button)
	btn2.SetSubButton("subButton", buttons)

	buttons2 := make([]*menu.Button, 1)
	buttons2[0] = btn2

	//发送请求
	err := mu.SetMenu(buttons2)
	if err != nil {
		fmt.Printf("err= %v", err)
		return
	}
}

memcache 线程安全吗?

可不可以全局定义一个 memcache,多个 http request 共用一个 memcache,使用 Get 方法是否安全,会不会多个请求获取数据产生干扰?

发送模板参数需要更新

//Message 发送的模板消息内容 type Message struct { ... MiniProgram struct { AppID string json:"appid"//所需跳转到的小程序appid(该小程序appid必须与发模板消息的公众号是绑定关联关系) **PagePath stringjson:"path"** //**官网是pagepath,但是实际上是path,**所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar) } json:"miniprogram" //可选,跳转至小程序地址 }

请问,如果平台设置为安全模式,这个代码的回复消息,是安全模式还是混合模式呢?

func hello(rw http.ResponseWriter, req *http.Request) {

//打印request基本信息
fmt.Print(req.RequestURI, "\n")
//fmt.Print(req.PostForm, "\n")
//配置微信参数
memcache := cache.NewMemcache("127.0.0.1:11211")
config := &wechat.Config{
	AppID:          "...",
	AppSecret:      "...",
	Token:          "...",
	EncodingAESKey: "...",
	Cache:          memcache,
}
wc := wechat.NewWechat(config)

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

	//回复消息:演示回复用户发送的消息
	text := message.NewText(msg.Content)

	fmt.Printf("Message received:%s\n\n", msg.Content)
	return &message.Reply{message.MsgTypeText, text}
})

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

}

这段代码,c.Request c.Writer从哪里来的呢?有没有完整代码呢?

以下是一个创建二级菜单的例子

mu := wc.GetMenu(c.Request, c.Writer)

buttons := make([]*menu.Button, 1)
btn := new(menu.Button)

//创建click类型菜单
btn.SetClickButton("name", "key123")
buttons[0] = btn

//设置btn为二级菜单
btn2 := new(menu.Button)
btn2.SetSubButton("subButton", buttons)

buttons2 := make([]*menu.Button, 1)
buttons2[0] = btn2

//发送请求
err := mu.SetMenu(buttons2)
if err != nil {
fmt.Printf("err= %v", err)
return
}

关于语音识别字段添加

如果用户在微信公众号打开语音识别,微信返回的消息中会有Recognition string xml:"Recognition"

所以请在message实体中添加,个人已经完成了相关添加。

如何返回一个带url链接的字符串?

aReply := message.NewText(“这里是一个跳转URL”)
return &message.Reply{message.MsgTypeText, aReply}

如何给aReply里加上一个超链接呢?如果直接在NewText里使用<a href="跳转URL">跳转URL</a>,貌似是不行的。

配置代码的效率

这个是例子中的代码,问题是,配置微信参数代码,写在请求回调函数里是不是合适呢?会不会影响效率,还是必须写在这里,不能写在main里?
func hello(rw http.ResponseWriter, req *http.Request) {

//配置微信参数
config := &wechat.Config{
	AppID:          "your app id",
	AppSecret:      "your app secret",
	Token:          "your token",
	EncodingAESKey: "your encoding aes key",
}
wc := wechat.NewWechat(config)

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

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

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

}

func main() {
http.HandleFunc("/", hello)
err := http.ListenAndServe(":8001", nil)
if err != nil {
fmt.Printf("start server error , err=%v", err)
}
}

增加获取 AccessToken 代理设置

获取 AccessToken 需要设置 ip 白名单

开发的时候使用 frp 进行内网穿透方式来调试,ip 不在白名单内

如果可以通过服务器上的代理(服务器 ip 在白名单内)来获取的话会省去很多麻烦

很多地方写的太死,调试不方便

比如说调试接受到数据

type Server struct {
	*context.Context

	openID string

	messageHandler func(message.MixMessage) *message.Reply

	requestRawXMLMsg  []byte
	requestMsg        message.MixMessage
	responseRawXMLMsg []byte
	responseMsg       interface{}

	isSafeMode bool
	random     []byte
	nonce      string
	timestamp  int64
}

私有不太舒服,建议部分改成大写,或者添加一些公开函数获取.

无法返回信息

用的是example里的http.go,微信那边配置好了,发送消息到公众号没有回应,用浏览器访问地址会打印请求校验失败

偶尔会报请求校验失败。

这个代码很规范,谢谢!
用的example里的代码,仅仅改了监听端口,在debug时该错误反复出现,但是直接运行编译后的exe,没有错误输出。但是该错误似乎对功能没有任何影响。

package main

import (
"fmt"
"net/http"

"github.com/silenceper/wechat"
"github.com/silenceper/wechat/message"

)

func hello(rw http.ResponseWriter, req *http.Request) {

//配置微信参数
config := &wechat.Config{
	AppID:          "...",
	AppSecret:      "...",
	Token:          "...",
	EncodingAESKey: "...",
}
wc := wechat.NewWechat(config)

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

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

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

}

func main() {
http.HandleFunc("/", hello)
err := http.ListenAndServe(":80", nil)
if err != nil {
fmt.Printf("start server error , err=%v", err)
}
}

access_token

golang新手:content 获取token的时候为什么要加锁呢 ?

oauth.Redirect 错误

oauth.Redirect 中用到了以下代码

  //location 为完整地址,所以不需要request
 http.Redirect(writer, nil, location, 302)
 return nil

其中
http.Redirect(writer, nil, location, 302)中第二个参数必须不能为空。我在go1.9的版本上测试报错。

beego cache用不上

E:/software/Go/src/runtime/asm_amd64.s:573
E:/software/Go/src/runtime/panic.go:502
E:/software/Go/src/runtime/panic.go:63
E:/software/Go/src/runtime/signal_windows.go:167
E:/go_working_space/src/github.com/silenceper/wechat/context/access_token.go:36
E:/go_working_space/src/github.com/silenceper/wechat/menu/menu.go:123
E:/go_working_space/src/weiboxs.com/new_h_archives/services/WechatApiService.go:54
E:/go_working_space/src/weiboxs.com/new_h_archives/controllers/backend/WechatController.go:100
E:/software/Go/src/runtime/asm_amd64.s:573
E:/software/Go/src/reflect/value.go:447
E:/software/Go/src/reflect/value.go:308
E:/go_working_space/src/github.com/astaxie/beego/router.go:847
E:/software/Go/src/net/http/server.go:2694
E:/software/Go/src/net/http/server.go:1830
E:/software/Go/src/runtime/asm_amd64.s:2361

求指导

template 方法调用问题,

template 里面 调用send()方法时,
accessToken, err = tpl.GetAccessToken() 后面GetAccessToken()方法好像没有实现呀,
accessToken 这个值传不进去呢
新手问下这里该怎么处理,有方法传值进去吗?

获取access Token时报无效指针?

代码如下:
func WechatConfig() {
appid := beego.AppConfig.String("appid")
appsecret := beego.AppConfig.String("appsecret")
config := &wechat.Config{
AppID: appid,
AppSecret: appsecret,
Token: beego.AppConfig.String("token"),
EncodingAESKey: beego.AppConfig.String("encodingAESKey"),
}
wc := wechat.NewWechat(config)
fmt.Println(wc.GetAccessToken())
}

在使用wc.GetAccessToken就出现:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x28 pc=0x81e58e]

goroutine 1 [running]:
github.com/silenceper/wechat/context.(*Context).GetAccessToken(0xc0420fa080, 0x0, 0x0, 0x0, 0x0)
D:/gowork/src/github.com/silenceper/wechat/context/access_token.go:36 +0x13e
github.com/silenceper/wechat.(*Wechat).GetAccessToken(0xc04206bec0, 0xc0421490e0, 0x9, 0xc04204eb00, 0x20)
D:/gowork/src/github.com/silenceper/wechat/wechat.go:58 +0x35
cdbcb/models.WechatConfig()
D:/gowork/src/cdbcb/models/wechat.go:20 +0x27a
main.main()
D:/gowork/src/cdbcb/main.go:11 +0x29

目前不知道是哪个位置出现了无效指针

个人公众号编辑的自定义菜单,利用此project检测菜单事件

对于直接跳转的菜单点击,发现事件类型是view。
但点击菜单,在公众号正文中返回了一个图文标题,需要点击这个标题才能进入。这个事件类型按理应该是click类型(对吧),但用本project调用时发现没有对应的事件。
请问这是因为个人公众号没有认证的原因,还是其他问题?

xml CDATA

The XML message returned in the official document of WeChat is required with CDATA, but it is not implemented in this package

redis封装过于单一

目前只支持get set delete 导致目前我项目中使用了两个redis相关依赖

redisOpts := cache.RedisOpts{
		Host:     redisServerAddr,
		Password: redisServerPwd,
	}
	redis = cache.NewRedis(&redisOpts)

	client = Redis.NewClient(&Redis.Options{
		Addr:     redisServerAddr,
		Password: redisServerPwd, // no password set
		DB:       0,              // use default DB
	})

	_, err := client.Ping().Result()
	if err != nil {
		panic(err)
	}

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.