package qyweixin import ( "encoding/json" "fmt" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" "github.com/spf13/cast" "gitlab.batiao8.com/open/gosdk/util" "gitlab.batiao8.com/open/gosdk/wechat" "gitlab.batiao8.com/open/gosdk/wechat/cache" "gitlab.batiao8.com/open/gosdk/wechat/message" wutil "gitlab.batiao8.com/open/gosdk/wechat/util" "net/http" "strings" "time" ) var ( wechatCache cache.Cache = cache.NewMemory() ) type AppConfig struct { Corpid string Secret string Agent string Token string AesKey string Replay func(message.MixMessage) *message.Reply } type App struct { tokenExpire int64 token string config *AppConfig } type UserInfo struct { UserId string RealName string } func NewApp(corpId, secret, agent string) *App { return &App{ config: &AppConfig{ Corpid: corpId, Secret: secret, Agent: agent, }, } } func (q *App) GetToken() string { if time.Now().Unix() <= q.tokenExpire-600 { return q.token } q.refreshToken() return q.token } func (q *App) GetResult(rspBody []byte) (map[string]interface{}, error) { result := make(map[string]interface{}) if err := json.Unmarshal(rspBody, &result); err != nil { log.Errorf("result[%s] error :%s", string(rspBody), err.Error()) return nil, err } if cast.ToInt(result["errcode"]) != 0 { log.Errorf("result[%s] error ", string(rspBody)) return nil, fmt.Errorf("%d:%s", cast.ToInt(result["errcode"]), cast.ToString(result["errmsg"])) } return result, nil } func (q *App) GetOpenid(userid string) (string, error) { if err := q.refreshToken(); err != nil { return "", err } reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_openid?access_token=%s", q.GetToken()) rspBody, err := util.HttpPostJson(reqUrl, nil, []byte(fmt.Sprintf(`{"userid" : "%s"}`, userid))) if err != nil { log.Errorf("httpPost url[%s] error :%s", reqUrl, err.Error()) return "", err } result, err := q.GetResult(rspBody) if err != nil { return "", err } return cast.ToString(result["openid"]), nil } func (q *App) GetUserInfo(userid string) (*UserInfo, error) { if err := q.refreshToken(); err != nil { return nil, err } reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=%s&userid=%s", q.GetToken(), userid) rspBody, err := util.HttpGet(reqUrl, nil) if err != nil { log.Errorf("httpPost url[%s] error :%s", reqUrl, err.Error()) return nil, err } result, err := q.GetResult(rspBody) if err != nil { return nil, err } userInfo := new(UserInfo) userInfo.UserId = userid userInfo.RealName = cast.ToString(result["name"]) return userInfo, nil } func (q *App) GetDepartmentUserid(departmentId int) ([]string, error) { if err := q.refreshToken(); err != nil { return nil, err } reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=%s&department_id=%d", q.GetToken(), departmentId) rspBody, err := util.HttpGet(reqUrl, nil) if err != nil { log.Errorf("httpPost url[%s] error :%s", reqUrl, err.Error()) return nil, err } result, err := q.GetResult(rspBody) if err != nil { return nil, err } userids := make([]string, 0) userlist := cast.ToSlice(result["userlist"]) for _, u := range userlist { user := cast.ToStringMap(u) userids = append(userids, cast.ToString(user["userid"])) } return userids, nil } func (q *App) Callback(ctx *gin.Context) { //配置微信参数 wechatConfig := &wechat.Config{ AppID: q.config.Corpid, AppSecret: q.config.Secret, Token: q.config.Token, EncodingAESKey: q.config.AesKey, Cache: wechatCache, } // 首次配置 if strings.ToUpper(ctx.Request.Method) == http.MethodGet { sign := wutil.Signature(ctx.Query("timestamp"), ctx.Query("echostr"), ctx.Query("nonce"), wechatConfig.Token) if sign != ctx.Query("msg_signature") { log.Errorf("sign error forcheck config") return } _, resp, err := wutil.DecryptMsg(wechatConfig.AppID, ctx.Query("echostr"), wechatConfig.EncodingAESKey) if err != nil { log.Errorf("DecryptMsg failed! error:%s", err.Error()) return } ctx.Data(http.StatusOK, "Content-type: text/plain", resp) return } // 2.响应消息 wc := wechat.NewWechat(wechatConfig) ctx.Request.URL.RawQuery += "&encrypt_type=aes" server := wc.GetServer(ctx.Request, ctx.Writer) server.SetMessageHandler(q.config.Replay) server.SetDebug(true) err := server.Serve() if err != nil { log.Errorf("qiye weixin Service err:%s", err.Error()) return } err = server.Send() if err != nil { log.Errorf("qiye weixin Send err:%s", err.Error()) return } } func (q *App) refreshToken() error { if time.Now().Unix() <= q.tokenExpire-600 { return nil } reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s", q.config.Corpid, q.config.Secret) rspBody, err := util.HttpGet(reqUrl, nil) if err != nil { return err } result, err := q.GetResult(rspBody) if err != nil { return err } q.token = cast.ToString(result["access_token"]) q.tokenExpire = time.Now().Unix() + cast.ToInt64(result["expires_in"]) return nil }