gosdk/qyweixin/app.go

185 lines
4.4 KiB
Go
Raw Normal View History

2024-01-22 22:34:59 +08:00
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
}
2024-01-22 22:47:35 +08:00
func NewApp(cfg *AppConfig) *App {
2024-01-22 22:34:59 +08:00
return &App{
2024-01-22 22:47:35 +08:00
config: cfg,
2024-01-22 22:34:59 +08:00
}
}
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) 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
}