Exemple #1
0
func execLevelExamples() {
	// 默认日志级别 debug
	log.Printf("default log level: %s", log.GetLevel())
	log.Tracef("IsTraceEnabled? %t", log.IsTraceEnabled())
	log.Debugf("IsDebugEnabled? %t", log.IsDebugEnabled())
	log.Infof("IsInfoEnabled? %t", log.IsInfoEnabled())

	// trace 级别
	log.SetLevel(log.Ltrace)
	log.Tracef(msgFmt, 1)

	// info 级别
	log.SetLevel(log.Linfo)
	log.Debugf(msgFmt, 2)
	log.Infof(msgFmt, 2)

	// warn 级别
	log.SetLevel(log.Lwarn)
	log.Infof(msgFmt, 3)
	log.Warnf(msgFmt, 3)

	// error 级别
	log.SetLevel(log.Lerror)
	log.Warnf(msgFmt, 4)
	log.Errorf(msgFmt, 4)

	// 恢复默认级别,防止影响其他测试
	// debug 级别
	log.SetLevel(log.Ldebug)
	log.Tracef(msgFmt, 5)
	log.Debugf(msgFmt, 5)
}
Exemple #2
0
// RefreshAccessToken 定时刷新 access_token
func RefreshAccessToken(appId, appSecret string) {
	// 内部变量,外部不可以调用
	var _token = &accessToken{}

	AccessToken = func() string {
		_token.mutex.RLock()
		defer _token.mutex.RUnlock()

		return _token.AccessToken
	}

	go func() {
		url := fmt.Sprintf(tokenURL, appId, appSecret)

		tick := time.Tick(refreshTimeout)
		for {
			new := refresh(url)

			log.Debugf("old access token %+v", _token)
			log.Debugf("new access token %+v", new)

			_token.mutex.Lock()
			_token.AccessToken = new.AccessToken
			_token.ExpiresIn = new.ExpiresIn
			_token.mutex.Unlock()

			<-tick // 等待下一个时钟周期到来
		}
	}()
}
Exemple #3
0
func echoMsgVoice(m *weixin.RecvVoice) weixin.ReplyMsg {
	log.Debugf("%+v", m)

	// echo message
	ret := &weixin.ReplyVoice{
		ToUserName:   m.FromUserName,
		FromUserName: m.ToUserName,
		CreateTime:   m.CreateTime,
		MediaId:      m.MediaId,
	}

	log.Debugf("%+v", ret)
	return ret
}
Exemple #4
0
// EventDefaultHandler 注册默认处理器
func EventDefaultHandler(m *weixin.Message) weixin.ReplyMsg {
	log.Debugf("%+v", m)

	// echo message
	ret := &weixin.ReplyText{
		ToUserName:   m.FromUserName,
		FromUserName: m.ToUserName,
		CreateTime:   m.CreateTime,
		Content:      fmt.Sprintf("Event=%s", m.Event),
	}

	log.Debugf("replay message: %+v", ret)
	return ret
}
Exemple #5
0
func echoMsgText(m *weixin.RecvText) weixin.ReplyMsg {
	log.Debugf("receive message: %+v", m)

	// echo message
	ret := &weixin.ReplyText{
		ToUserName:   m.FromUserName,
		FromUserName: m.ToUserName,
		CreateTime:   m.CreateTime,
		Content:      m.FromUserName + ", " + m.Content,
	}

	log.Debugf("replay message: %+v", ret)
	return ret
}
Exemple #6
0
func echoMsgLocation(m *weixin.RecvLocation) weixin.ReplyMsg {
	log.Debugf("%+v", m)

	// echo message
	ret := &weixin.ReplyText{
		ToUserName:   m.FromUserName,
		FromUserName: m.ToUserName,
		CreateTime:   m.CreateTime,
		Content:      weixin.AccessToken(),
	}

	log.Debugf("replay message: %+v", ret)
	return ret
}
Exemple #7
0
// EventViewHandler 注册点击菜单跳转链接时的事件处理器
func EventViewHandler(m *weixin.EventView) weixin.ReplyMsg {
	log.Debugf("%+v", m)

	// echo message 貌似用户收不到回复的消息???
	ret := &weixin.ReplyText{
		ToUserName:   m.FromUserName,
		FromUserName: m.ToUserName,
		CreateTime:   m.CreateTime,
		Content:      fmt.Sprintf("Event=%s, EventKey=%s", m.Event, m.EventKey),
	}

	log.Debugf("replay message: %+v", ret)
	return ret
}
Exemple #8
0
// EventSubscribeHandler 注册关注事件处理器
func EventSubscribeHandler(m *weixin.EventSubscribe) weixin.ReplyMsg {
	log.Debugf("%+v", m)

	// echo message
	ret := &weixin.ReplyText{
		ToUserName:   m.FromUserName,
		FromUserName: m.ToUserName,
		CreateTime:   m.CreateTime,
		Content:      fmt.Sprintf("Event=%s, EventKey=%s, Ticket=%s", m.Event, m.EventKey, m.Ticket),
	}

	log.Debugf("replay message: %+v", ret)
	return ret
}
Exemple #9
0
// EventTemplateSendJobFinishHandler 模版消息发送结果通知事件
func EventTemplateSendJobFinishHandler(m *weixin.EventTemplateSendJobFinish) weixin.ReplyMsg {
	log.Debugf("%+v", m)

	// echo message
	ret := &weixin.ReplyText{
		ToUserName:   m.FromUserName,
		FromUserName: m.ToUserName,
		CreateTime:   m.CreateTime,
		Content:      fmt.Sprintf("Event=%s, MsgID=%d, Status=%s", m.Event, m.MsgID, m.Status),
	}

	log.Debugf("replay message: %+v", ret)
	return ret
}
Exemple #10
0
func echoMsgImage(m *weixin.RecvImage) weixin.ReplyMsg {
	log.Debugf("%+v", m)

	// echo message
	ret := &weixin.ReplyImage{
		ToUserName:   m.FromUserName,
		FromUserName: m.ToUserName,
		CreateTime:   m.CreateTime,
		PicUrl:       m.PicUrl,
		MediaId:      m.MediaId,
	}

	log.Debugf("%+v", ret)
	return ret
}
Exemple #11
0
// EventLocationHandler 注册上报地理位置事件处理器
func EventLocationHandler(m *weixin.EventLocation) weixin.ReplyMsg {
	log.Debugf("%+v", m)

	// echo message
	ret := &weixin.ReplyText{
		ToUserName:   m.FromUserName,
		FromUserName: m.ToUserName,
		CreateTime:   m.CreateTime,
		Content: fmt.Sprintf("Latitude=%.6f, Longitude=%.6f, Precision=%.6f",
			m.Latitude, m.Longitude, m.Precision),
	}

	log.Debugf("replay message: %+v", ret)
	return ret
}
Exemple #12
0
func echoMsgLink(m *weixin.RecvLink) weixin.ReplyMsg {
	log.Debugf("%+v", m)

	// 回复图文消息

	return nil
}
Exemple #13
0
func main() {
	addr := ":3080"

	weixin.Initialize(originId, appId, appSecret, token, encodingAESKey)

	weixin.RecvTextHandler = echoMsgText             // 注册文本消息处理器
	weixin.RecvImageHandler = echoMsgImage           // 注册图片消息处理器
	weixin.RecvVoiceHandler = echoMsgVoice           // 注册语音消息处理器
	weixin.RecvVideoHandler = echoMsgVideo           // 注册视频消息处理器
	weixin.RecvShortVideoHandler = echoMsgShortVideo // 注册小视频消息处理器
	weixin.RecvLocationHandler = echoMsgLocation     // 注册位置消息处理器
	weixin.RecvLinkHandler = echoMsgLink             // 注册链接消息处理器
	weixin.RecvDefaultHandler = defaultHandler       // 注册默认处理器

	weixin.EventSubscribeHandler = EventSubscribeHandler     // 注册关注事件处理器
	weixin.EventUnsubscribeHandler = EventUnsubscribeHandler // 注册取消关注事件处理器
	weixin.EventLocationHandler = EventLocationHandler       // 注册上报地理位置事件处理器
	weixin.EventClickHandler = EventClickHandler             // 注册点击自定义菜单事件处理器
	weixin.EventViewHandler = EventViewHandler               // 注册点击菜单跳转链接时的事件处理器
	// 模版消息发送结果通知事件
	weixin.EventTemplateSendJobFinishHandler = EventTemplateSendJobFinishHandler
	weixin.EventDefaultHandler = EventDefaultHandler // 注册默认处理器

	http.HandleFunc("/weixin", weixin.HandleAccess)
	http.Handle("/", http.FileServer(http.Dir("examples/static")))
	// http.Handle("/admin/", http.StripPrefix("/admin/", http.FileServer(http.Dir("admin"))))

	log.Debugf("server is running at %s", addr)
	http.ListenAndServe(addr, nil)
}
Exemple #14
0
func echoMsgShortVideo(m *weixin.RecvVideo) weixin.ReplyMsg {
	log.Debugf("%+v", m)

	// MediaId ???
	ret := &weixin.ReplyVideo{
		ToUserName:   m.FromUserName,
		FromUserName: m.ToUserName,
		CreateTime:   m.CreateTime,
		MediaId:      m.ThumbMediaId,
		Title:        "shortvideo",
		Description:  "thist is a test desc...",
	}

	log.Debugf("%+v", ret)
	return ret
}
Exemple #15
0
func parseBody(encryptType, timestamp, nonce, msgSignature string, body []byte) (msg *Message, err error) {
	msg = &Message{}
	// 如果报文被加密了,先要验签解密
	if encryptType == "aes" {
		encMsg := &EncMessage{}
		// 解析加密的 xml
		err = xml.Unmarshal(body, encMsg)
		if err != nil {
			return nil, err
		}
		msg.ToUserName = encMsg.ToUserName
		msg.Encrypt = encMsg.Encrypt

		if !CheckSignature(Token, timestamp, nonce, encMsg.Encrypt, msgSignature) {
			return nil, errors.New("check signature error")
		}

		body, err = DecryptMsg(encMsg.Encrypt, EncodingAESKey, AppId)
		if err != nil {
			return nil, err
		}
		log.Debugf("receive: %s", body)
	}

	// 解析 xml
	err = xml.Unmarshal(body, msg)
	if err != nil {
		return nil, err
	}

	return msg, nil
}
Exemple #16
0
func defaultHandler(msg *weixin.Message) weixin.ReplyMsg {
	log.Debugf("%+v", msg)

	event := weixin.NewRecvEvent(msg)
	js, _ := json.Marshal(event)

	// echo message
	ret := &weixin.ReplyText{
		ToUserName:   msg.FromUserName,
		FromUserName: msg.ToUserName,
		CreateTime:   msg.CreateTime,
		Content:      string(js),
	}

	log.Debugf("replay message: %+v", ret)
	return ret
}
Exemple #17
0
// 处理所有来自微信的消息,已经验证过 URL 和 Method 了
func processMessage(w http.ResponseWriter, r *http.Request) {
	q := r.URL.Query()
	timestamp := q.Get("timestamp")
	nonce := q.Get("nonce")
	encryptType := q.Get("encrypt_type")
	msgSignature := q.Get("msg_signature")

	// 读取报文
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Error(err)
		http.Error(w, "read body error", http.StatusNotAcceptable)
		return
	}
	log.Debugf("from weixin: %s", body)

	msg, err := parseBody(encryptType, timestamp, nonce, msgSignature, body)
	if err != nil {
		log.Error(err)
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// 处理消息
	reply := HandleMessage(msg)

	// 如果返回为 nil,表示不需要回复,结束
	if reply == nil {
		return
	}

	// 如果返回不为 nil,表示需要回复
	ret, err := packReply(reply, encryptType, timestamp, nonce)
	if err != nil {
		log.Error(err)
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	log.Debugf("to weixin: %s", ret)
	w.Header().Set("Content-Type", "text/xml; charset=utf-8")
	w.Write(ret)
}
Exemple #18
0
func TestEventTemplateSendJobFinishHandler(t *testing.T) {
	// EventTemplateSendJobFinishHandler 模版消息发送结果通知事件
	EventTemplateSendJobFinishHandler = func(m *EventTemplateSendJobFinish) ReplyMsg {
		log.Debugf("%+v", m)

		// echo message
		ret := &ReplyText{
			ToUserName:   m.FromUserName,
			FromUserName: m.ToUserName,
			CreateTime:   m.CreateTime,
			Content:      fmt.Sprintf("Event=%s, MsgID=%d, Status=%s", m.Event, m.MsgID, m.Status),
		}

		log.Debugf("replay message: %+v", ret)
		return ret
	}

	body := `<xml>
       <ToUserName><![CDATA[gh_7f083739789a]]></ToUserName>
       <FromUserName><![CDATA[oia2TjuEGTNoeX76QEjQNrcURxG8]]></FromUserName>
       <CreateTime>1395658984</CreateTime>
       <MsgType><![CDATA[event]]></MsgType>
       <Event><![CDATA[TEMPLATESENDJOBFINISH]]></Event>
       <MsgID>200163840</MsgID>
       <Status><![CDATA[failed: system failed]]></Status>
       </xml>`
	req, _ := http.NewRequest("POST", testURL, bytes.NewBufferString(body))

	w := httptest.NewRecorder()
	HandleAccess(w, req)

	if w.Code != http.StatusOK {
		t.Errorf("http request error with status %d: %s", w.Code, w.Body)
		t.FailNow()
	}

	t.Logf("%s", w.Body)
}
Exemple #19
0
// PostUnmarshal 工具类, POST json 并解析返回的报文,返回 error
func PostUnmarshal(url string, js []byte, ret interface{}) (err error) {
	log.Debugf("url=%s, body=%s", url, js)
	resp, err := http.Post(url, "application/json", bytes.NewBuffer(js))
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	err = json.NewDecoder(resp.Body).Decode(ret)
	if err != nil {
		return err
	}

	return nil
}
Exemple #20
0
func main() {
	log.Debugf("this is a test message, %d", 1111)

	format := fmt.Sprintf("%s %s %s %s:%d %s", "2006-01-02 15:04:05.000000", log.TagToken,
		log.LevelToken, log.ProjectToken, log.LineToken, log.MessageToken)
	log.ChangeFormat(format)
	log.Tinfof("6ba7b814-9dad-11d1-80b4-00c04fd430c8", "this is a test message, %d", 1111)

	format = fmt.Sprintf(`{"date": "%s", "time": "%s", "level": "%s", "file": "%s", "line": %d, "log": "%s"}`,
		"2006-01-02", "15:04:05.999", log.LevelToken, log.ProjectToken, log.LineToken, log.MessageToken)
	log.ChangeFormat(format)
	log.Infof("this is a test message, %d", 1111)

	format = fmt.Sprintf(`<log><date>%s</date><time>%s</time><level>%s</level><file>%s</file><line>%d</line><msg>%s</msg><log>`,
		"2006-01-02", "15:04:05.000", log.LevelToken, log.ProjectToken, log.LineToken, log.MessageToken)
	log.ChangeFormat(format)
	log.Tinfof("6ba7b814-9dad-11d1-80b4-00c04fd430c8", "this is a test message, %d", 1111)

	log.Error("level = debug")
	log.Infof("this is a test message, %d", 1111)
	log.Errorf("this is another test message, %d", 22222)
	// Fatalf("%d %s", log.FatalLevel, log.FatalLevel)

	format = fmt.Sprintf("%s %s %s %s:%d %s", "2006-1-2", "3:4:05.9",
		log.LevelToken, log.PathToken, log.LineToken, log.MessageToken)
	log.ChangeFormat(format)
	log.Infof("this is a test message, %d", 1111)

	format = fmt.Sprintf("%s %s %s %s:%d %s", "2006-01-02", "15:04:05.999999",
		log.LevelToken, log.PackageToken, log.LineToken, log.MessageToken)
	log.ChangeFormat(format)
	log.Infof("this is a test message, %d", 1111)

	format = fmt.Sprintf("%s %s %s:%d %s", "2006-01-02 15:04:05.000000",
		log.LevelToken, log.ProjectToken, log.LineToken, log.MessageToken)
	log.ChangeFormat(format)
	log.Infof("this is a test message, %d", 1111)

	format = fmt.Sprintf(`{"date": "%s", "time": "%s", "level": "%s", "file": "%s", "line": %d, "log": "%s"}`,
		"2006-01-02", "15:04:05.999", log.LevelToken, log.ProjectToken, log.LineToken, log.MessageToken)
	log.ChangeFormat(format)
	log.Infof("this is a test message, %d", 1111)

	format = fmt.Sprintf(`<log><date>%s</date><time>%s</time><level>%s</level><file>%s</file><line>%d</line><msg>%s</msg><log>`,
		"2006-01-02", "15:04:05.000", log.LevelToken, log.ProjectToken, log.LineToken, log.MessageToken)
	log.ChangeFormat(format)
	log.Infof("this is a test message, %d", 1111)
}
Exemple #21
0
func packReply(reply ReplyMsg, encryptType, timestamp, nonce string) (ret []byte, err error) {
	switch reply.(type) {
	case *ReplyText:
		reply.SetMsgType(MsgTypeText)
	case *ReplyImage:
		reply.SetMsgType(MsgTypeImage)
	case *ReplyVoice:
		reply.SetMsgType(MsgTypeVoice)
	case *ReplyVideo:
		reply.SetMsgType(MsgTypeVideo)
	case *ReplyMusic:
		reply.SetMsgType(MsgTypeMusic)
	case *ReplyNews:
		reply.SetMsgType(MsgTypeNews)
	default:
		panic("unexpected custom message type")
	}

	ret, err = xml.MarshalIndent(reply, "", "  ")
	if err != nil {
		return nil, err
	}
	log.Debugf("replay: %s", ret)

	// 如果接收的消息加密了,那么回复的消息也需要签名加密
	if encryptType == "aes" {
		b64Enc, err := EncryptMsg(ret, EncodingAESKey, AppId)
		if err != nil {
			return nil, err
		}
		encMsg := EncMessage{
			Encrypt:      b64Enc,
			MsgSignature: Signature(Token, timestamp, nonce, b64Enc),
			TimeStamp:    timestamp,
			Nonce:        nonce, // 随机数
		}
		ret, err = xml.MarshalIndent(encMsg, "", "    ")
		if err != nil {
			return nil, err
		}
	}
	return ret, nil
}
Exemple #22
0
// HandleMessage 处理各类消息
func HandleMessage(msg *Message) (ret ReplyMsg) {
	log.Debugf("process `%s` message", msg.MsgType)

	switch msg.MsgType {
	case MsgTypeText:
		if RecvTextHandler != nil {
			return RecvTextHandler(NewRecvText(msg))
		}
	case MsgTypeImage:
		if RecvImageHandler != nil {
			return RecvImageHandler(NewRecvImage(msg))
		}
	case MsgTypeVoice:
		if RecvVoiceHandler != nil {
			return RecvVoiceHandler(NewRecvVoice(msg))
		}
	case MsgTypeVideo:
		if RecvVideoHandler != nil {
			return RecvVideoHandler(NewRecvVideo(msg))
		}
	case MsgTypeShortVideo:
		if RecvShortVideoHandler != nil {
			return RecvShortVideoHandler(NewRecvVideo(msg))
		}
	case MsgTypeLocation:
		if RecvLocationHandler != nil {
			return RecvLocationHandler(NewRecvLocation(msg))
		}
	case MsgTypeLink:
		if RecvLinkHandler != nil {
			return RecvLinkHandler(NewRecvLink(msg))
		}
	case MsgTypeEvent:
		return HandleEvent(msg)
	default:
		log.Errorf("unexpected receive MsgType: %s", msg.MsgType)
		return nil
	}

	return RecvDefaultHandler(msg)
}
Exemple #23
0
// Upload 工具类, 上传文件
func Upload(url, fieldName string, file *os.File, ret interface{}, desc ...string) (err error) {
	buf := &bytes.Buffer{}
	w := multipart.NewWriter(buf)

	//关键的一步操作
	// fw, err := w.CreateFormField(file.Name())
	fw, err := w.CreateFormFile(fieldName, file.Name())
	if err != nil {
		return err
	}
	_, err = io.Copy(fw, file)
	if err != nil {
		return err
	}
	contentType := w.FormDataContentType()
	if len(desc) > 0 {
		w.WriteField("description", desc[0])
	}
	w.Close()

	log.Debugf("url=%s, fieldName=%s, fileName=%s", url, fieldName, file.Name())
	resp, err := http.Post(url, contentType, buf)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	err = json.NewDecoder(resp.Body).Decode(ret)
	if err != nil {
		return err
	}

	if wxerrer, ok := ret.(WeixinErrorer); ok {
		wxerr := wxerrer.GetWeixinError()
		if wxerr.ErrCode != WeixinErrCodeSuccess {
			return wxerr
		}
	}

	return nil
}
Exemple #24
0
// GetUnmarshal 工具类, Get 并解析返回的报文,返回 error
func GetUnmarshal(url string, ret interface{}) (err error) {
	log.Debugf("url=%s", url)
	resp, err := http.Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	err = json.NewDecoder(resp.Body).Decode(ret)
	if err != nil {
		return err
	}

	if wxerrer, ok := ret.(WeixinErrorer); ok {
		wxerr := wxerrer.GetWeixinError()
		if wxerr.ErrCode != WeixinErrCodeSuccess {
			return wxerr
		}
	}

	return nil
}
Exemple #25
0
// HandleAccess 接入微信公众平台开发,并接口来自微信服务器的消息
func HandleAccess(w http.ResponseWriter, r *http.Request) {
	log.Debugf("%s", r.URL)

	q := r.URL.Query()
	signature := q.Get("signature")
	timestamp := q.Get("timestamp")
	nonce := q.Get("nonce")

	// 每次都验证 URL,以判断来源是否合法
	if !ValidateURL(Token, timestamp, nonce, signature) {
		http.Error(w, "validate url error, request not from weixin?", http.StatusUnauthorized)
		return
	}

	switch r.Method {
	// 如果是 GET 请求,表示这是接入验证请求
	case "GET":
		w.Write([]byte(q.Get("echostr")))
	case "POST":
		processMessage(w, r)
	default:
		http.Error(w, "only GET or POST method allowed", http.StatusUnauthorized)
	}
}
Exemple #26
0
	EventPicSysphotoHandler     func(*EventPicSysphoto) ReplyMsg
	EventPicPhotoOrAlbumHandler func(*EventPicPhotoOrAlbum) ReplyMsg
	EventPicWeixinHandler       func(*EventPicWeixin) ReplyMsg
	EventLocationSelectHandler  func(*EventLocationSelect) ReplyMsg

	EventQualificationVerifySuccessHandler func(*EventQualificationVerifySuccess) ReplyMsg // 资质认证成功
	EventQualificationVerifyFailHandler    func(*EventQualificationVerifyFail) ReplyMsg    // 资质认证失败
	EventNamingVerifySuccessHandler        func(*EventNamingVerifySuccess) ReplyMsg        // 名称认证成功(即命名成功)
	EventNamingVerifyFailHandler           func(*EventNamingVerifyFail) ReplyMsg           // 名称认证失败
	EventAnnualRenewHandler                func(*EventAnnualRenew) ReplyMsg                // 年审通知
	EventVerifyExpiredHandler              func(*EventVerifyExpired) ReplyMsg              // 认证过期失效通知
)

// RecvDefaultHandler 如果没有注册某类消息处理器,那么收到这类消息时,使用这个默认处理器
var RecvDefaultHandler = func(msg *Message) (reply ReplyMsg) {
	log.Debugf("unregistered receive message handler %s, use RecvDefaultHandler", msg.MsgType)
	return nil
}

// EventDefaultHandler 如果没有注册某类事件处理器,那么收到这类事件时,使用这个默认处理器
var EventDefaultHandler = func(msg *Message) (reply ReplyMsg) {
	log.Debugf("unregistered receive event handler %s, use EventDefaultHandler", msg.Event)
	return nil
}

// HandleMessage 处理各类消息
func HandleMessage(msg *Message) (ret ReplyMsg) {
	log.Debugf("process `%s` message", msg.MsgType)

	switch msg.MsgType {
	case MsgTypeText:
Exemple #27
0
// EventUnsubscribeHandler 注册取消关注事件处理器
func EventUnsubscribeHandler(m *weixin.EventSubscribe) weixin.ReplyMsg {
	log.Debugf("someone gone")
	return nil
}
Exemple #28
0
// HandleEvent 处理各类事件
func HandleEvent(msg *Message) (reply ReplyMsg) {
	log.Debugf("process `%s` event", msg.MsgType)

	switch msg.Event {
	case EventTypeSubscribe:
		if EventSubscribeHandler != nil {
			return EventSubscribeHandler(NewEventSubscribe(msg))
		}
	case EventTypeUnsubscribe:
		if EventUnsubscribeHandler != nil {
			return EventUnsubscribeHandler(NewEventSubscribe(msg))
		}
	case EventTypeLocation:
		if EventLocationHandler != nil {
			return EventLocationHandler(NewEventLocation(msg))
		}
	case EventTypeClick:
		if EventClickHandler != nil {
			return EventClickHandler(NewEventClick(msg))
		}
	case EventTypeView:
		if EventViewHandler != nil {
			return EventViewHandler(NewEventView(msg))
		}
	case EventTypeTemplateSendJobFinish:
		if EventTemplateSendJobFinishHandler != nil {
			return EventTemplateSendJobFinishHandler(NewEventTemplateSendJobFinish(msg))
		}
	case EventTypeScancodePush:
		if EventScancodePushHandler != nil {
			return EventScancodePushHandler(NewEventScancodePush(msg))
		}
	case EventTypeScancodeWaitmsg:
		if EventScancodeWaitmsgHandler != nil {
			return EventScancodeWaitmsgHandler(NewEventScancodeWaitmsg(msg))
		}
	case EventTypePicSysphoto:
		if EventPicSysphotoHandler != nil {
			return EventPicSysphotoHandler(NewEventPicSysphoto(msg))
		}
	case EventTypePicPhotoOrAlbum:
		if EventPicPhotoOrAlbumHandler != nil {
			return EventPicPhotoOrAlbumHandler(NewEventPicPhotoOrAlbum(msg))
		}
	case EventTypePicWeixin:
		if EventPicWeixinHandler != nil {
			return EventPicWeixinHandler(NewEventPicWeixin(msg))
		}
	case EventTypeLocationSelect:
		if EventLocationSelectHandler != nil {
			return EventLocationSelectHandler(NewEventLocationSelect(msg))
		}
	case EventTypeQualificationVerifySuccess:
		if EventQualificationVerifySuccessHandler != nil {
			return EventQualificationVerifySuccessHandler(NewEventQualificationVerifySuccess(msg))
		}
	case EventTypeQualificationVerifyFail:
		if EventQualificationVerifyFailHandler != nil {
			return EventQualificationVerifyFailHandler(NewEventQualificationVerifyFail(msg))
		}
	case EventTypeNamingVerifySuccess:
		if EventNamingVerifySuccessHandler != nil {
			return EventNamingVerifySuccessHandler(NewEventNamingVerifySuccess(msg))
		}
	case EventTypeNamingVerifyFail:
		if EventNamingVerifyFailHandler != nil {
			return EventNamingVerifyFailHandler(NewEventNamingVerifyFail(msg))
		}
	case EventTypeAnnualRenew:
		if EventAnnualRenewHandler != nil {
			return EventAnnualRenewHandler(NewEventAnnualRenew(msg))
		}
	case EventTypeVerifyExpired:
		if EventVerifyExpiredHandler != nil {
			return EventVerifyExpiredHandler(NewEventVerifyExpired(msg))
		}
	default:
		log.Errorf("unexpected receive EventType: %s", msg.Event)
		return nil
	}

	return EventDefaultHandler(msg)
}