/// <summary> /// 扫码操作 /// </summary> /// <param name="recMsg"></param> /// <returns></returns> private async Task <string> DealWxscan(PubReceiveMsgCData recMsg) { // 扫码记录 await wxDbLogHelper.SaveQrLog(recMsg); return(await wxEventScanHelper.Deal(recMsg)); }
/// <summary> /// 微信扫码记录 /// </summary> /// <param name="recMsg"></param> public async Task SaveQrLog(PubReceiveMsgCData recMsg) { try { // 增加扫码记录 if (recMsg.Event == PubEventType.subscribe || recMsg.Event == PubEventType.scan) { var qrLog = new WxQrCodeLog(); qrLog.OpenId = recMsg.FromUserName; qrLog.ScanDate = recMsg.DtCreateTime.Value; qrLog.QrSceneStr = recMsg.EventKey; qrLog.QrTicketId = recMsg.Ticket; qrLog.Creater = "system"; qrLog.CreateTime = recMsg.DtCreateTime.Value; qrLog.Updater = "system"; qrLog.UpdateTime = recMsg.DtCreateTime.Value; await repo.SaveAsync(qrLog); } } catch (Exception ex) { logHelper.Error("DealWxSubscribe:扫码关注失败:" + ex.Message + " " + ex.StackTrace); } }
/// <summary> /// 取消关注 /// </summary> /// <param name="recMsg"></param> private async Task <string> DealWxUnsubscribe(PubReceiveMsgCData recMsg) { // 取关记录 await wxDbLogHelper.SaveSubLog(recMsg, 1); return(wxAutoComResponse.ResponseOK());; }
/// <summary> /// 判断是否客服消息 /// 如果不是事件消息 或者 事件key是联系客服 或者 回复的文本是客服关键字 都属于联系客服 /// </summary> /// <param name="recMsg"></param> /// <returns></returns> public bool IsKfMsg(PubReceiveMsgCData recMsg) { var res = recMsg.MsgType.ToString().ToLower() != "event" || (!string.IsNullOrEmpty(recMsg.EventKey) && recMsg.EventKey.ToLower() == "gotoservices") || (!string.IsNullOrEmpty(recMsg.Content) && LstKfKeywords.Contains(recMsg.Content)); return(res); }
/// <summary> /// 处理企业号推送事件 /// </summary> /// <param name="recMsg"></param> /// <returns></returns> public async Task <string> DealQyEvent(PubReceiveMsgCData recMsg) { try { switch (recMsg.Event) { case PubEventType.subscribe: await DealWxSubscribe(recMsg); // 关注后判断扫码事件处理 await DealWxscan(recMsg); break; case PubEventType.unsubscribe: await DealWxUnsubscribe(recMsg); break; case PubEventType.scan: await DealWxscan(recMsg); break; case PubEventType.location: logHelper.Debug("location"); break; case PubEventType.location_select: logHelper.Debug("location"); break; case PubEventType.click: await DealWxClick(recMsg); break; case PubEventType.view: logHelper.Debug("view"); break; case PubEventType.poi_check_notify: logHelper.Debug("poi_check_notify"); break; default: break; } } catch (Exception ex) { logHelper.Error("DealQyEvent:处理企业号推送事件失败:" + ex.Message + " " + ex.StackTrace); } return(wxAutoComResponse.ResponseOK());; }
/// <summary> /// 保存微信日志到数据库 /// </summary> /// <returns></returns> public async Task SaveWxOptLog(PubReceiveMsgCData recMsg) { try { // 判断是否重复提交 var exist = await repo.FirstOrDefaultAsync <WxUserOptLog>(d => d.FromUserName == recMsg.FromUserName && d.CreateTime == recMsg.DtCreateTime); if (exist != null) { logHelper.Debug("重复的微信请求(微信首次请求我方服务器已保存记录但未返回正确回应的二次请求),不保存!IopenId:" + recMsg.FromUserName); return; } // 保存微信日志 var wxLog = new WxUserOptLog(); wxLog.MsgId = recMsg.MsgId.ToString(); wxLog.ToUserName = recMsg.ToUserName; wxLog.FromUserName = recMsg.FromUserName; wxLog.CreateTime = recMsg.DtCreateTime.Value; wxLog.MsgType = recMsg.MsgType.ToString(); wxLog.Content = recMsg.Content; wxLog.PicUrl = recMsg.PicUrl; wxLog.MediaId = recMsg.MediaId; wxLog.Format = recMsg.Format; wxLog.ThumbMediaId = recMsg.ThumbMediaId; wxLog.LocationX_Latitude = recMsg.Location_X.ToString(); wxLog.LocationY_Longitude = recMsg.Location_Y.ToString(); wxLog.Scale = recMsg.Scale.ToString(); wxLog.LabelPrecision = recMsg.Label; wxLog.Title = recMsg.Title; wxLog.Description = recMsg.Description; wxLog.Url = recMsg.Url; wxLog.Event = recMsg.Event.ToString(); wxLog.EventKey = recMsg.EventKey; wxLog.Ticket = recMsg.Ticket; wxLog.Creater = "system"; wxLog.CreateTime = recMsg.DtCreateTime.Value; wxLog.Updater = "system"; wxLog.UpdateTime = recMsg.DtCreateTime.Value; await repo.SaveAsync(wxLog); logHelper.Debug("SaveWxDbLog:保存微信日志到数据成功:" + ComHelper.JsonSerialize(wxLog)); } catch (Exception ex) { logHelper.Error("SaveWxDbLog:保存微信日志到数据失败:" + ex.Message + " " + ex.StackTrace); } }
/// <summary> /// 公众号推送Text处理 /// </summary> /// <param name="recMsg"></param> /// <returns></returns> public async Task <string> DealQyText(PubReceiveMsgCData recMsg) { try { // 用户 var gzhClient = recMsg.FromUserName; // 公众号 var gzhServer = recMsg.ToUserName; // 文本内容 var keyword = recMsg.Content.ToLower(); return(await wxAutoResponseHelper.DealWithKeyWord(gzhClient, gzhServer, keyword)); } catch (Exception ex) { logHelper.Error("DealQyText:处理Text出错:" + ex.Message + " " + ex.StackTrace); } return(wxAutoComResponse.ResponseOK()); }
/// <summary> /// 关注 /// </summary> /// <param name="recMsg"></param> /// <returns></returns> private async Task <string> DealWxSubscribe(PubReceiveMsgCData recMsg) { // 关注记录 await wxDbLogHelper.SaveSubLog(recMsg, 0); // 发送关注消息 var timeStamp = ComHelper.ConvertDateTimeInt(DateTime.Now); var wxUser = await repo.FirstOrDefaultAsync <WxUserInfo>(x => x.OpenId == recMsg.FromUserName); var subConf = await repo.FirstOrDefaultAsync <DbConfig>(x => x.ConfigName == "subscribeText"); if (wxUser != null && subConf != null) { var msg = subConf.ConfigValue.Replace("{nickname}", wxUser.NickName); return(await wxAutoComResponse.SendWxText(recMsg.FromUserName, recMsg.ToUserName, timeStamp, msg)); } return(wxAutoComResponse.ResponseOK());; }
/// <summary> /// 微信推送菜单点击事件处理 /// </summary> /// <param name="recMsg"></param> /// <returns></returns> public async Task <string> Deal(PubReceiveMsgCData recMsg) { if (!string.IsNullOrEmpty(recMsg.EventKey)) { var keyWord = recMsg.EventKey.Trim().ToLower(); logHelper.Debug("WxEventClick:EventKey:" + keyWord); switch (keyWord) { // 联系客服 case "gotoservices": return(await wxKfTransferHelper.ContactKf(recMsg)); // surprise 或者 其他文本 default: return(await wxAutoResponseHelper.DealWithKeyWord(recMsg.FromUserName, recMsg.ToUserName, keyWord)); } } return(wxAutoComResponse.ResponseOK());; }
/// <summary> /// 联系客服 /// </summary> /// <param name="recMsg"></param> /// <returns></returns> public Result <string> ChatWithKf(PubReceiveMsgCData recMsg) { try { if (IsWorkTime() && IsIn5Min(recMsg.FromUserName) && IsKfMsg(recMsg)) { PubKfApi.SendTextMsg(recMsg.FromUserName, "正在为你转接在线客服,请稍后....."); var msg = PubMsgApi.BuildKfTransferMsg(recMsg.FromUserName, recMsg.ToUserName, recMsg.CreateTime); return(new Result <string> { IsSucc = true, Data = msg }); } } catch (Exception ex) { logHelper.Error("ChatWithKf:联系客服失败:" + ex.Message + " " + ex.StackTrace); } return(new Result <string> { Message = "联系客服失败!" }); }
/// <summary> /// 微信关注/取关记录 /// </summary> /// <param name="recMsg"></param> /// <param name="type">0:关注;1:取关</param> public async Task SaveSubLog(PubReceiveMsgCData recMsg, int type) { try { // 增加关注记录 var subLog = new WxSubScribeLog(); subLog.OpenId = recMsg.FromUserName; subLog.SubScribeType = type; subLog.OptDate = recMsg.DtCreateTime.Value; subLog.QrSceneStr = recMsg.EventKey; subLog.QrTicketId = recMsg.Ticket; subLog.Creater = "system"; subLog.CreateTime = recMsg.DtCreateTime.Value; subLog.Updater = "system"; subLog.UpdateTime = recMsg.DtCreateTime.Value; await repo.SaveAsync(subLog); } catch (Exception ex) { logHelper.Error("DealWxSubscribe:扫码关注失败:" + ex.Message + " " + ex.StackTrace); } }
/// <summary> /// 菜单点击事件 /// </summary> /// <param name="recMsg"></param> /// <returns></returns> private async Task <string> DealWxClick(PubReceiveMsgCData recMsg) { return(await wxEventClickHelper.Deal(recMsg)); }
/// <summary> /// 微信推送扫码事件处理 /// </summary> /// <param name="recMsg"></param> /// <returns></returns> public async Task <string> Deal(PubReceiveMsgCData recMsg) { await Task.CompletedTask; return(wxAutoComResponse.ResponseOK());; }
/// <summary> /// 保存微信用户信息 /// </summary> /// <param name="recMsg"></param> public async Task SaveWxUser(PubReceiveMsgCData recMsg) { try { var exist = await repo.FirstOrDefaultAsync <WxUserInfo>(x => x.OpenId == recMsg.FromUserName); // 只要用户不存在,且不是取消关注就拉取用户信息 var isUnsubscribe = recMsg.Event.HasValue && recMsg.Event == PubEventType.unsubscribe; if (exist == null) { if (!isUnsubscribe) { // 用户信息不存在 var user = PubUserApi.GetUserinfo(recMsg.FromUserName); if (!user.IsSuss) { logHelper.Error("SaveWxUser:保存微信用户信息失败代码:" + user.errcode + " 错误信息:" + user.errmsg); } logHelper.Debug("SaveWxUser:获取到微信用户信息:" + user.JsonSerializeNoNull()); // 保存用户信息 var wxUser = new WxUserInfo(); wxUser.OpenId = user.openid; wxUser.NickName = user.nickname; wxUser.HeadImgUrl = user.headimgurl; wxUser.Sex = (short)user.sex; wxUser.Country = user.country; wxUser.Province = user.province; wxUser.City = user.city; wxUser.Unionid = user.unionid; wxUser.Language = user.language; wxUser.Remark = user.remark; wxUser.Groupid = user.groupid; wxUser.IsSubscribe = 1; wxUser.SubscribeTime = ComHelper.ConvertTimeStampToDate(user.subscribe_time); if (user.privilege != null && user.privilege.Count > 0) { wxUser.Privilege = string.Join("',", user.privilege); } wxUser.Creater = "system"; wxUser.CreateTime = recMsg.DtCreateTime.Value; wxUser.Updater = "system"; wxUser.UpdateTime = recMsg.DtCreateTime.Value; await repo.SaveAsync(wxUser); } } else if (exist != null && !isUnsubscribe && exist.IsSubscribe == 0) { // 重新关注修改状态 exist.IsSubscribe = 1; if (!exist.SubscribeTime.HasValue) { exist.SubscribeTime = recMsg.DtCreateTime; } await repo.UpdateAsync(exist, new List <string> { "IsSubscribe", "SubscribeTime" }); } else if (exist != null && isUnsubscribe) { logHelper.Debug("SaveWxUser:用户:" + exist.OpenId + "于" + DateTime.Now.ToString("yyyyMMddHHmmss") + "取消关注!"); // 用户取消关注 exist.IsSubscribe = 0; await repo.UpdateAsync(exist, new List <string> { "IsSubscribe" }); } } catch (Exception ex) { logHelper.Error("SaveWxUser:保存微信用户信息失败:" + ex.Message + " " + ex.StackTrace); } }
public async Task <dynamic> Process([FromQuery] string signature, string timestamp, string nonce, string openid, string encrypt_type, string msg_signature) { logHelper.Debug("Process:请求Url:" + Request.Host.Value); // 响应 var response = HttpContext.Response; // post过来的数据 Stream stream = HttpContext.Request.Body; byte[] bytes = new byte[stream.Length]; stream.Read(bytes, 0, (int)stream.Length); string postStr = System.Text.Encoding.UTF8.GetString(bytes); logHelper.Debug("Process:推送数据:" + postStr); // 验证数据签名 string decryptMsg = string.Empty; int ret = -1; if (string.IsNullOrEmpty(PubInterface.Conf.EncodingAesKey)) { // 明文验签 ret = WXBizMsgCrypt.VerifySignature(PubInterface.Conf.AppToken, timestamp, nonce, "", signature); decryptMsg = postStr; } else { // 密文验签 ret = QyCrypt.DecryptMsg(msg_signature, timestamp, nonce, postStr, ref decryptMsg); } if (ret != 0) { // 验签、解密失败 logHelper.Error("Process:微信通知消息验证失败:错误代码:" + ret); // 返回Sucess防止微信后续5次的推送(未收到Success之前都会一直推送) return(wxAutoComResponse.ResponseOK());; } logHelper.Debug("Process:解密后内容:" + decryptMsg); // 序列化接收到的消息 PubReceiveMsgCData recMsg = ComHelper.XmlDeserialize <PubReceiveMsgCData>(decryptMsg); logHelper.Debug("ReceiveMsgCData:" + recMsg.JsonSerialize()); // 保存日志到数据库 await wxDbLogHelper.SaveWxOptLog(recMsg); // 保存用户信息 await wxDbLogHelper.SaveWxUser(recMsg); // 判断是否接入客服 var kfRes = wxKfTransferHelper.ChatWithKf(recMsg); if (kfRes.IsSucc) { return(await wxAutoComResponse.AutoMsgResponse(kfRes.Data)); } // 判断消息类型 switch (recMsg.MsgType) { case PubMsgType.text: logHelper.Debug("text"); return(textHandler.DealQyText(recMsg)); case PubMsgType.image: logHelper.Debug("image"); break; case PubMsgType.voice: logHelper.Debug("voice"); break; case PubMsgType.video: logHelper.Debug("video"); break; case PubMsgType.shortvideo: logHelper.Debug("shortvideo"); break; case PubMsgType.location: logHelper.Debug("location"); break; case PubMsgType.link: logHelper.Debug("link"); break; case PubMsgType.@event: logHelper.Debug("event"); return(eventHandler.DealQyEvent(recMsg)); //case PubMsgType.wxcard: // logHelper.Debug("wxcard"); // break; //case PubMsgType.mpnews: // logHelper.Debug("mpnews"); // break; //case PubMsgType.news: // logHelper.Debug("news"); // break; //case PubMsgType.music: // logHelper.Debug("music"); // break; default: break; } return(wxAutoComResponse.ResponseOK());; }