企业微信开发——企业内部自建应用开发(第三篇)---JS_SDK的wx.agentConfig配置

  1. 客户端调起客户联系、聊天工具栏等高级功能,需要配置wx.agentConfig,该配置与微信环境的配置一致,但是与wx.config的获取不一样,下面我将用代码详细说明。

  1. 需要在企业微信后管添加客户联系的人、添加可以使用客户联系的企业应用(这两个不添加会报错:fail_no permission)

  1. 在index.html页面引用 <script src="" target="_blank">//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> <script src="" target="_blank">https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>两个js,

千万不要通过npm方式安装,如果安装了请卸载wx_js_sdk,这个npm方式目前存在缺陷。

开发环境:前端vue脚手架 后端 .net5 web api

前端代码如下:


created() {
    this.initQyConfig();
 },
methons:{
    initQyConfig() {
      let that = this;
      var postData = {
        url: window.location.href,
      };
      xapi.ajax({
        url: "/api/WxComHandle/Common/AccessAgentConfigBaseMessage",
        type: "POST",
        contentType: "application/json",
        data: postData,
        success: function (data, status, xhr) {
          that.configQy(data.Data);
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
          xapi.alert(
            "错误:" +
              textStatus +
              ":" +
              errorThrown +
              ":" +
              XMLHttpRequest.status
          );
        },
        complete: function (xhr, status) {
          $.hideLoading();
        },
      });
    },
    configQy(data) {
      var that = this;
      wx.agentConfig({
        corpid: data.corpid, // 必填,企业微信的corpid,必须与当前登录的企业一致
        agentid: data.agentid, // 必填,企业微信的应用id (e.g. 1000247)
        timestamp: data.timestamp, // 必填,生成签名的时间戳
        nonceStr: data.nonceStr, // 必填,生成签名的随机串
        signature: data.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
        jsApiList: ["getContext", "getCurExternalContact", "sendChatMessage"], //必填,传入需要使用的接口名称
        success: function (res) {
          console.log("configQy调用成功");
          console.log(JSON.stringify(res));
         //wx.invoke就是wx.agentConfig配置成功后才可以使用的。
          wx.invoke("getContext", {}, function (res) { 
            if (res.err_msg == "getContext:ok") {
              var entry = res.entry; //返回进入H5页面的入口类型,目前有normal、contact_profile、single_chat_tools、group_chat_tools、chat_attachment
              that.shareTicket = res.shareTicket; //可用于调用getShareInfo接口
              if (entry == "single_chat_tools" || entry == "group_chat_tools") {
                that.entryFlag = true;
                wx.invoke("getCurExternalContact", {}, function (res) {
                  if (res.err_msg == "getCurExternalContact:ok") {
                    var userId = res.userId; //返回当前外部联系人userId
                  } else {
                    //错误处理
                  }
                });
              }
            } else {
              //错误处理
            }
          });
        },
        fail: function (res) {
          if (res.errMsg.indexOf("function not exist") > -1) {
            alert("版本过低请升级");
          }
        },
      });
    },
}

c#后端代码:关键代码已经全部提供,各位需要自己把代码调整下,可能存在引用或类的错误,修改下就行。本人已经在项目中实践过了,只要照着我的文档花点时间一定能实现。


        /// <summary>
        /// 获得企业微信应用的配置信息
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public CommonResult AccessAgentConfigBaseMessage([FromBody] dynamic req)
        {
            var url = "https://www.***.com/TestApi/dist/index.html#/indexPage";// ((string)req.url).HasValue("页面url").Trim();
            var data = bll.AccessAgentConfigDto(QyMpId, url);
            return new CommonResult
            {
                Result = true,
                Data = data
            };
        }

        public AnentConfigDto AccessAgentConfigDto(string mpId, string url)
        {
            GlobalTools.WriteLog("AccessAgentConfigDto", 0, $"url:{url}");
            var targetIndex = url.IndexOf("#");
            if (targetIndex != -1)
            {
                url = url.Split('#')[0];
            }
            string qyWxTicket = GetWeiXinJsapi_Ticket(mpId);
            string nonceStr = CreatenNonce_str();
            long timestamp = CreatenTimestamp();
            GetSignature(qyWxTicket, nonceStr, timestamp, url, out string signature);
            AnentConfigDto anentConfigDto = new AnentConfigDto()
            {
                corpid = "ww6**********",
                agentid = "10******",
                timestamp = timestamp,
                nonceStr = nonceStr,
                signature = signature
            };
            return anentConfigDto;
        }

        public string GetWeiXinJsapi_Ticket(string mpId)
        {
            string accessToken = GetAccessToken(mpId);
            string reqUrl = string.Format("https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token={0}&type=agent_config", accessToken);
            CommonBll.GetQyJsApiTicket(mpId, accessToken, "jsTicket", reqUrl, out string ticketValue);
            return ticketValue;

        }

        public string GetAccessToken(string mpId)
        {
            string contackMpId = mpId;
            var mp = _mp.Get(p => p.MP_ID == contackMpId);
            if (mp == null)
            {
                throw new ValidateException("未找到MpId信息");
            }
            CommonBll.GetQyWxToken(mp.MP_APP_ID, mp.MP_APP_SECRET, contackMpId, out string accessToken);
            return accessToken;
        }

        public static void GetQyWxToken(string corpid, string corpsecret, string mpId, out string token)
        {
            try
            {
                MPTools.GetMPCachedAccessToken(mpId, out token, out DateTime expTime);
                if (string.IsNullOrEmpty(token))
                {
                    lock (tokenLock)
                    {
                        string url = string.Format("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={0}&corpsecret={1}", corpid, corpsecret);
                        HttpHelper helper = new HttpHelper();
                        string back = helper.SendGetMessage(url, mpId);
                        GlobalTools.WriteLog("GetQyWxToken", 0, $"back:{back}");
                        var tokenDto = JsonConvert.DeserializeObject<TokenDto>(back);
                        token = tokenDto.access_token;
                        GlobalTools.WriteLog("GetQyWxToken", 0, $"token:{token}");
                        MPTools.SaveMPCachedAccessToken(mpId, token, DateTime.Now, DateTime.Now.AddMinutes(90));
                    }

                }
            }
            catch (Exception ex)
            {
                GlobalTools.WriteErrLog("GetQyWxToken", ex);
                token = "";
            }
        }

        /// <summary>
        /// 发生get请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="MpId"></param>
        /// <exception cref="WXAdvException"></exception>
        public string SendGetMessage(string url, string MpId)
        {
            NewHttpClient newHttpClient = new NewHttpClient();
            var back = newHttpClient.GetStringAsync(url).Result;
            GlobalTools.WriteLog("SendGetMessage", 0, $"back:{back}");
            JObject jsonObj = JObject.Parse(back);
            string errCode;
            string errMsg;
            if (ParseErrorMsg(jsonObj, MpId, out errCode, out errMsg))
            {
                if (errCode != "0")
                {
                    throw new WXAdvException(errCode, errMsg, back);
                }
            }
            return back;
        }
        public static void GetQyJsApiTicket(string mpId, string accessToken, string key, string reqUrl, out string ticketValue)
        {
            try
            {
                MPTools.GetMPCachedAccessToken(key, out ticketValue, out DateTime expTime);
                if (string.IsNullOrEmpty(ticketValue))
                {
                    lock (ticketLock)
                    {
                        string ticketUrl = reqUrl;
                        HttpHelper helper = new HttpHelper();
                        string back = helper.SendGetMessage(ticketUrl, mpId);
                        GlobalTools.WriteLog("GetQyWxToken", 0, $"back:{back}");
                        TicketDto ticketDto = JsonConvert.DeserializeObject<TicketDto>(back);
                        MPTools.SaveMPCachedAccessToken(key, ticketDto.ticket, DateTime.Now, DateTime.Now.AddMinutes(90));
                    }
                }
            }
            catch (Exception ex)
            {
                ticketValue = "";
                MPTools.RemoveMPCachedAccessToken(key);
                GlobalTools.WriteErrLog("GetQyJsApiTicket", ex);
            }
        }

        public static string[] strs = new string[]
                               {
                                  "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
                                  "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"
                               };

        public string CreatenNonce_str()
        {
            Random r = new Random();
            var sb = new StringBuilder();
            var length = strs.Length;
            for (int i = 0; i < 15; i++)
            {
                sb.Append(strs[r.Next(length - 1)]);
            }
            return sb.ToString();
        }

        private long CreatenTimestamp()
        {
            return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
        }

        public void GetSignature(string jsapi_ticket, string noncestr, long timestamp, string url, out string signature)
        {
            var string1Builder = new StringBuilder();
            string1Builder.Append("jsapi_ticket=").Append(jsapi_ticket).Append("&")
                          .Append("noncestr=").Append(noncestr).Append("&")
                          .Append("timestamp=").Append(timestamp).Append("&")
                          .Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url);
            string string1 = string1Builder.ToString();
            signature = Sha1Encrypt(string1, Encoding.UTF8);
            GlobalTools.WriteLog("GetSignature", 0, $"signature:{signature}");
        }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值