package controllers import ( "bytes" "encoding/base64" "encoding/json" "io/ioutil" "net/http" "wechat-conf/models" "wechat-conf/models/model" "wechat-conf/service/autoreply" "wechat-conf/service/wechat" "wechat-conf/utils" "github.com/astaxie/beego" "github.com/kinisky564477/wechat/component" "github.com/kinisky564477/wechat/core" ) // WechatController 用户 type WechatController struct { BaseController serv *autoreply.AutoreplyServ wechatServ *wechat.WechatServ } // Constructor 初始化 Controller // @Title Constructor // @Description 初始化 Controller, 系统自动调用 func (c *WechatController) Constructor() { c.serv = autoreply.NewAutoreplyServ(c.Context) c.wechatServ = wechat.NewWechatServ(c.Context) } const ( INFOTYPE_TICKET = "component_verify_ticket" INFOTYPE_AUTHORIZED = "authorized" INFOTYPE_UNAUTHORIZED = "unauthorized" INFOTYPE_UPDATEAUTHORIZED = "updateauthorized" ) // ComponentPush 第三方平台推送 func (c *WechatController) ComponentPush() { utils.LogError("推送开始") r := c.Ctx.Request defer r.Body.Close() con, _ := ioutil.ReadAll(r.Body) utils.LogError("推送消息:", string(con)) // 解析xml xp := &core.XMLParse{} resMsg, err := xp.Parse(string(con)) if err != nil { utils.LogError("xml解析失败:", err) c.ResponseRaw([]byte("success")) } encrypt := resMsg["Encrypt"] conf, err := c.wechatServ.GetComponentInfo() if err != nil || conf == nil || conf.Appid == "" { utils.LogError("读取微信配置文件失败") c.ResponseRaw([]byte("success")) } EncodingAESKey := conf.Aeskey AESKey, err := base64.StdEncoding.DecodeString(EncodingAESKey + "=") if err != nil { utils.LogError("DecodeString失败:", err) c.ResponseRaw([]byte("success")) } EncryptVal, err := base64.StdEncoding.DecodeString(encrypt) if err != nil { utils.LogError("密文base64解析", err) c.ResponseRaw([]byte("success")) } msgbyte, err := utils.AesDecrypt(EncryptVal, AESKey) if err != nil { utils.LogError("解密失败:", err) c.ResponseRaw([]byte("success")) } utils.LogError("解密成功") // 解析xml msg, err := xp.Parse(string(msgbyte)) if err != nil { utils.LogError("xml解析失败:", err) c.ResponseRaw([]byte("success")) } utils.LogError("xml解析成功:", msg) switch msg["InfoType"] { case INFOTYPE_TICKET: // 更新ticket conf.Ticket = msg["ComponentVerifyTicket"] err := c.wechatServ.UpdateComponentTicket(conf) if err != nil { utils.LogError("修改ticket失败:", err) } utils.RefreshComponentTicket(msg["ComponentVerifyTicket"]) break case INFOTYPE_AUTHORIZED: // 授权成功 var cert = map[string]string{ "appid": msg["AuthorizerAppid"], "authorization_code": msg["AuthorizationCode"], } beego.Error("授权成功参数:", cert) wxclient := utils.WechatInit(cert, c.wechatServ.UpdateToken) if wxclient == nil { utils.LogError("获取wxclient失败") c.ResponseRaw([]byte("success")) } beego.Error(wxclient) utils.AppendWxClient(wxclient) // 获取微信信息 info, err := wxclient.GetWechatInfo() if err != nil { utils.LogError("获取微信信息失败") c.ResponseRaw([]byte("success")) } beego.Error(info) authorizerInfo := (info["authorizer_info"]).(map[string]interface{}) beego.Error(info["authorizer_info"]) // 插入数据库 mjson, _ := json.Marshal(msg) HeadImg := "" if authorizerInfo["head_img"] != nil { HeadImg = authorizerInfo["head_img"].(string) } var conf = model.SysWechatConf{ Appid: msg["AuthorizerAppid"], AuthorizationCode: msg["AuthorizationCode"], AuthorizationInfo: string(mjson), WxNikeName: authorizerInfo["nick_name"].(string), HeadImg: HeadImg, UserName: authorizerInfo["user_name"].(string), PrincipalName: authorizerInfo["principal_name"].(string), QrcodeUrl: authorizerInfo["qrcode_url"].(string), } err = c.wechatServ.SaveWechatConf(conf) if err != nil { utils.LogError("保存微信授权信息失败:", err) c.ResponseRaw([]byte("success")) } break case INFOTYPE_UPDATEAUTHORIZED: // 授权更新 break case INFOTYPE_UNAUTHORIZED: // 取消授权 // 删除wechatConf信息,同时将org解绑 appid := msg["AuthorizerAppid"] c.wechatServ.UnAuthorized(appid) // 删除第三方中的微信信息 utils.Component.DelWxClient(appid) break } c.ResponseRaw([]byte("success")) } // WechatInfo 微信接入 func (c *WechatController) WechatInfo() { method := c.Ctx.Input.Method() if method == http.MethodGet { echostr := c.GetString("echostr") c.ResponseRaw([]byte(echostr)) } else { c.WxReceive() } } // WxReceive 微信消息接收 func (c *WechatController) WxReceive() { beego.Error("微信消息接入") appid := c.GetString(":appid") wechat, err := utils.Component.GetWxClient(appid) if err != nil { utils.LogError("获取微信失败: " + err.Error()) } msg, err := wechat.TransformMessage(string(c.Ctx.Input.RequestBody)) if err != nil { utils.LogError("读取微信服务发送内容失败: " + err.Error()) c.ResponseRaw([]byte("")) } xp := &core.XMLParse{} beego.Error("消息:", msg) encrypt := msg["Encrypt"] conf, err := c.wechatServ.GetComponentInfo() if err != nil || conf == nil || conf.Appid == "" { utils.LogError("读取微信配置文件失败") c.ResponseRaw([]byte("success")) } EncodingAESKey := conf.Aeskey AESKey, err := base64.StdEncoding.DecodeString(EncodingAESKey + "=") if err != nil { utils.LogError("DecodeString失败:", err) c.ResponseRaw([]byte("success")) } EncryptVal, err := base64.StdEncoding.DecodeString(encrypt) if err != nil { utils.LogError("密文base64解析", err) c.ResponseRaw([]byte("success")) } msgbyte, err := utils.AesDecrypt(EncryptVal, AESKey) if err != nil { utils.LogError("解密失败:", err) c.ResponseRaw([]byte("success")) } utils.LogError("解密成功") // 解析xml val, err := xp.Parse(string(msgbyte)) if err != nil { utils.LogError("xml解析失败:", err) c.ResponseRaw([]byte("success")) } utils.LogError("xml解析成功:", val) var replay = new(model.TaAutoReply) switch val["MsgType"] { case "text": content := val["Content"] // 获取数据库存储返回类型 replay, err = c.serv.GetAutoReplayByAppID(appid, content) break case "event": beego.Error(val) switch val["Event"] { case "subscribe": replay, err = c.serv.GetSubscribeByAppID(appid) break case "LICK": // 点击事件 // key:=val["EventKey"] // keyreplay,err:=c.serv.GetReplayByKey(appid,key) // if err!=nil{ // utils.LogError("获取按钮点击key失败: " + err.Error()) // c.ResponseRaw([]byte("")) // } // if keyreplay!=nil && keyreplay.KeywordsId==""{ // c.ResponseRaw([]byte("")) // } break } break } if err != nil { utils.LogError("获取微信自动回复信息失败: " + err.Error()) c.ResponseRaw([]byte("")) } if replay == nil { c.ResponseRaw([]byte("")) } openID := val["FromUserName"] message, err := c.getReplayMessage(replay, openID, wechat) if err != nil { utils.LogError("转换回复信息失败: " + err.Error()) c.ResponseRaw([]byte("")) } cipher, err := core.NewCipher(utils.Component.GetToken(), EncodingAESKey, appid) if err != nil { utils.LogError("获取解密失败: " + err.Error()) c.ResponseRaw([]byte("")) } dt := bytes.NewBuffer([]byte{}) cipher.Encrypt(dt, []byte(message)) beego.Error("=========>", dt) c.ResponseRaw(dt.Bytes()) // c.ResponseRaw([]byte("success")) } func (c *WechatController) getReplayMessage(replay *model.TaAutoReply, openid string, wx *component.WxClient) ([]byte, error) { switch replay.MessageType { case models.MESSAGE_TYPE_PARAGRAPH: msg, err := wx.ResponseMessageText(openid, replay.MessageParagraph) return msg, err case models.MESSAGE_TYPE_IMG: msg, err := wx.ResponseMessageImage(openid, replay.MessageImg) return msg, err // case models.MESSAGE_TYPE_PARAGRAPH: // msg, err := wx.ResponseMessageNews(openid, replay.MessageImg) // return msg, err } return nil, nil } // GetPreAuthCode 获取预授权码 func (c *WechatController) GetPreAuthCode() { code, err := utils.Component.GetPreAuthCode() if err != nil { utils.LogError("获取预授权码错误: " + err.Error()) c.ResponseError(err) } appid := utils.Component.GetCertificate()["appid"] c.ResponseJSON(map[string]string{ "appid": appid, "code": code, }) } // GetWechatMenuByAppID 根据appid获取微信详情 func (c *WechatController) GetWechatInfoByAppID() { appid := c.GetString(":appid") wxclient, err := utils.Component.GetWxClient(appid) if err != nil { utils.LogError("获取微信信息失败: " + err.Error()) c.ResponseError(err) } info, err := wxclient.GetWechatInfo() if err != nil { utils.LogError("获取微信详情失败: " + err.Error()) c.ResponseError(err) } c.ResponseJSON(info) } // GetWechatMenuByAppID 获取菜单 func (c *WechatController) GetMaterialByAppID() { appid := c.GetString(":appid") wxclient, err := utils.Component.GetWxClient(appid) if err != nil { utils.LogError("获取微信信息失败: " + err.Error()) c.ResponseError(err) } var data = map[string]string{} data["offset"] = "0" data["type"] = "image" data["count"] = "10" menus, err := wxclient.GetMaterialList(data) if err != nil { utils.LogError("获取微信详情失败: " + err.Error()) c.ResponseError(err) } c.ResponseJSON(menus) } // GetWechatByCode 根据code获取微信信息 func (c *WechatController) GetWechatByCode() { code := c.GetString(":code") beego.Error(code) conf, err := c.wechatServ.GetWechatByCode(code) if err != nil { utils.LogError("获取微信详情失败: " + err.Error()) c.ResponseError(err) } beego.Error(conf) if conf == nil || conf.ConfId == "" || conf.Status == models.STATUS_NORMAL { c.ResponseJSON("") } c.ResponseJSON(map[string]string{ "ConfId": conf.ConfId, "NickName": conf.WxNikeName, "HeadImg": conf.HeadImg, }) }