using Google.Protobuf.WellKnownTypes;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Xml.Linq;
namespace Appointment.Entity
{
public class AizhuhotelHelper
{
private static readonly log4net.ILog _logger = log4net.LogManager.GetLogger(typeof(AizhuhotelHelper));
// ---- 获取公众号 Access_token
private class LoveInnGetAccessTokenRes
{
///
/// 200-成功,400-出错,
///
public int Code { get; set; }
///
/// 返回信息:正确、错误都提示
///
public string Message { get; set; }
///
/// 信息
///
public GetAccessTokenRes Data { get; set; }
}
private class GetAccessTokenRes
{
public string Access_token { get; set; }
public int? Expires_in { get; set; }
public string Errcode { get; set; }
public string Errmsg { get; set; }
}
///
/// 通过爱住接口获取Accesstoken
///
///
public static ApiResult AizhuhotelGetAccesstoken()
{
var url = "https://pay.aizhuhotel.com/dlwx/api/WD/LoveInnGetAccessToken";
string AppId = BaseConfig.App(new string[] { "WeChatService", "AppId" });
if (string.IsNullOrWhiteSpace(AppId)) return ApiResult.Failed("配置文件中未获取有效的消息推送AppId");
string AppName = BaseConfig.App(new string[] { "WeChatService", "AppName" });
if (string.IsNullOrWhiteSpace(AppName)) return ApiResult.Failed("配置文件中未获取有效的消息推送AppName");
string AppSecret = BaseConfig.App(new string[] { "WeChatService", "AppSecret" });
if (string.IsNullOrWhiteSpace(AppSecret)) return ApiResult.Failed("配置文件中未获取有效的消息推送AppSecret");
var json = JsonConvert.SerializeObject(new { AppId, AppName, AppSecret });
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Proxy = null;
request.Method = "POST";
request.ContentType = "application/json";
// request.Timeout = 10000;
using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream()))
{
dataStream.Write(json);
dataStream.Close();
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response == null)
{
return ApiResult.Failed("远程服务器没有响应!");
}
string encoding = response.ContentEncoding;
if (encoding == null || encoding.Length < 1)
{
encoding = "UTF-8"; //默认编码
}
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
string retString = reader.ReadToEnd();
var res = JsonConvert.DeserializeObject(retString);
if (res.Code != 200) return ApiResult.Failed(res.Message);
if (res.Data == null) return ApiResult.Failed("未获取到有效信息");
return ApiResult.Success(string.Empty, res.Data.Access_token);
}
catch (Exception ex)
{
_logger.Debug(ex.ToString());
return ApiResult.Failed("http请求异常,异常信息:" + ex.Message);
}
}
// ---- 通过微信服务器获取access_token
private static WxAccessTokenData accessCacheToken = null;
public class WxAccessTokenData
{
///
/// 获取到的access_token
///
public string Access_token { get; set; }
///
/// 获取时间
///
public DateTime GetDate { get; set; }
}
///
/// 微信授权返回结果
///
public class WxAuthorizationCodeRep
{
///
/// 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
///
public string Access_token { get; set; }
///
/// access_token接口调用凭证超时时间,单位(秒)
/// 错误时不返回
///
public int? Expires_in { get; set; }
///
/// 用户刷新access_token
///
public string Refresh_token { get; set; }
///
/// 用户唯一标识
///
public string Openid { get; set; }
///
/// 用户授权的作用域,使用逗号(,)分隔
///
public string Scope { get; set; }
///
/// 错误码:返回码
/// 正确时不返回
///
public int? Errcode { get; set; }
///
/// 错误信息
///
public string Errmsg { get; set; }
}
///
/// 获取服务号AccessToken
///
/// 强制刷新
///
public static ApiResult GetAccessToken(bool forceUpdate = false)
{
try
{
string AppId = BaseConfig.App(new string[] { "WeChatService", "AppId" });
if (string.IsNullOrWhiteSpace(AppId)) return ApiResult.Failed("配置文件中未获取有效的服务号AppId");
string AppSecret = BaseConfig.App(new string[] { "WeChatService", "AppSecret" });
if (string.IsNullOrWhiteSpace(AppSecret)) return ApiResult.Failed("配置文件中未获取有效的服务号AppSecret");
DateTime now = DateTime.Now;
if (forceUpdate == false && accessCacheToken != null && now.AddSeconds(-1 * 55 * 2) < accessCacheToken.GetDate)
{
return ApiResult.Success(string.Empty, accessCacheToken.Access_token);
}
var url = $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={AppId}&secret={AppSecret}";
using (var http = new HttpClient(new HttpClientHandler()))
{
var res = http.GetAsync(url).Result;
if (res.StatusCode != HttpStatusCode.OK)
{
_logger.Error("获取公众号access_token失败,微信服务接口响应" + res.StatusCode.ToString());
return ApiResult.Failed("获取公众号access_token失败,微信服务接口响应" + res.StatusCode.ToString());
}
var reContent = res.Content.ReadAsStringAsync().Result;
if (!string.IsNullOrWhiteSpace(reContent))
{
var reToken = JsonConvert.DeserializeObject(reContent);
if (!string.IsNullOrEmpty(reToken.Access_token))
{
accessCacheToken = new WxAccessTokenData()
{
Access_token = reToken.Access_token,
GetDate = now
};
return ApiResult.Success(string.Empty, reToken.Access_token);
}
else
{
_logger.Error(reContent);
}
}
return ApiResult.Failed(string.Empty);
}
}
catch (Exception ex)
{
_logger.Error(ex.Message);
return ApiResult.Failed(ex.Message);
}
}
// ---- 获取用户Openid
private class WxServiceRes
{
public string Access_token { get; set; }
public int? Expires_in { get; set; }
public string Refresh_token { get; set; }
public string Openid { get; set; }
public string Errcode { get; set; }
public string Errmsg { get; set; }
}
public static ApiResult GetWxSericeOpenId(string code)
{
if (string.IsNullOrWhiteSpace(code)) return ApiResult.Failed("未获取到有效的code");
string AppId = BaseConfig.App(new string[] { "WeChatService", "AppId" });
if (string.IsNullOrWhiteSpace(AppId)) return ApiResult.Failed("配置文件中未获取有效的消息推送AppId");
string AppSecret = BaseConfig.App(new string[] { "WeChatService", "AppSecret" });
if (string.IsNullOrWhiteSpace(AppSecret)) return ApiResult.Failed("配置文件中未获取有效的消息推送AppSecret");
string url = $"https://api.weixin.qq.com/sns/oauth2/access_token?appid={AppId}&secret={AppSecret}&code={code}&grant_type=authorization_code";
using (var http = new HttpClient(new HttpClientHandler()))
{
var response = http.GetAsync(url).Result;
if (response.StatusCode != HttpStatusCode.OK) return ApiResult.Failed("微信接口无响应");
string res = response.Content.ReadAsStringAsync().Result;
if (!string.IsNullOrWhiteSpace(res))
{
var wxServiceRes = JsonConvert.DeserializeObject(res);
if (!string.IsNullOrWhiteSpace(wxServiceRes.Openid))
{
return ApiResult.Success(string.Empty, wxServiceRes.Openid);
}
else
{
_logger.Error(res);
return ApiResult.Failed(wxServiceRes.Errcode);
}
}
return ApiResult.Failed("返回空");
}
}
// ---- 发送消息模板
public static ApiResult SendTemplateMsg(string touser, string template_id, string url, string first, string remark, params object[] args)
{
try
{
string error = string.Empty;
for (int i = 0; i < 3; i++)
{
error = string.Empty;
var msg = WechatHelper.BuildTemlMsg(touser, template_id, url, first, remark, args);
string accessTokenMode = BaseConfig.App(new string[] { "AccessTokenMode" });
if (string.IsNullOrWhiteSpace(accessTokenMode))
{
_logger.Error("配置文件中未获取有效的AccessTokenMode");
return ApiResult.Failed("配置文件中未获取有效的AccessTokenMode");
}
ApiResult tokenResult = null;
if (i == 0)
{
tokenResult = accessTokenMode == "1" ? AizhuhotelGetAccesstoken() : GetAccessToken();
}
else
{
tokenResult = accessTokenMode == "1" ? AizhuhotelGetAccesstoken() : GetAccessToken(true);
}
if (!tokenResult.IsSuccess)
{
error = "配置文件中未获取有效的AccessTokenMode";
_logger.Error(error);
continue;
}
var postUrl = $"https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={tokenResult.Info}";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(postUrl);
request.Proxy = null;
request.Method = "POST";
request.ContentType = "application/json";
// request.Timeout = 10000;
using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream()))
{
dataStream.Write(msg);
dataStream.Close();
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response == null)
{
error = "远程服务器没有响应!";
_logger.Error(error);
continue;
}
string encoding = response.ContentEncoding;
if (encoding == null || encoding.Length < 1)
{
encoding = "UTF-8"; //默认编码
}
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
string retString = reader.ReadToEnd();
if (!string.IsNullOrWhiteSpace(retString))
{
var sendTemplateMsgRes = JsonConvert.DeserializeObject(retString);
if (sendTemplateMsgRes.Errmsg.ToLower() == "ok")
{
return ApiResult.Success(string.Empty);
}
else
{
error = $"接收者openid:{touser},错误代码{sendTemplateMsgRes.Errcode}";
_logger.Error(error);
continue;
}
}
}
return ApiResult.Failed(msg: "", info: error);
}
catch (Exception ex)
{
_logger.Debug(ex.ToString());
return ApiResult.Failed(msg: "", info: ex.Message);
}
}
///
/// 发送模板消息返回结果
///
private class SendTemplateMsgRes
{
///
/// 返回代码,0-发送成功
///
public int Errcode { get; set; }
///
/// 返回消息:"ok"-成功
///
public string Errmsg { get; set; }
///
/// 发送成功返回编号:失败不返回
///
public long? Msgid { get; set; }
}
public static void SendTemplateMsg(List tousers, string template_id, string url, string first, string remark, params object[] args)
{
if (tousers == null || tousers.Count == 0) return;
string accessTokenMode = BaseConfig.App(new string[] { "AccessTokenMode" });
if (string.IsNullOrWhiteSpace(accessTokenMode))
{
_logger.Error("配置文件中未获取有效的AccessTokenMode");
return;
}
ApiResult tokenResult = accessTokenMode == "1" ? AizhuhotelGetAccesstoken() : GetAccessToken();
if (!tokenResult.IsSuccess)
{
_logger.Error(tokenResult.Msg);
return;
}
List msgList = new List();
foreach (var touser in tousers)
{
msgList.Add(WechatHelper.BuildTemlMsg(touser, template_id, url, first, remark, args));
}
int send = 0;
_logger.Info($"发送推送消息,模板:{template_id}, 接收者openId:{string.Join(",", msgList)} 。");
StringBuilder msg = new StringBuilder();
foreach (var itemMsg in msgList)
{
for (int i = 0; i < 3; i++)
{
if (i > 0)
{
Thread.Sleep(100);
tokenResult = accessTokenMode == "1" ? AizhuhotelGetAccesstoken() : GetAccessToken(true);
if (!tokenResult.IsSuccess)
{
_logger.Error(tokenResult.Msg);
continue;
}
}
var postUrl = $"https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={tokenResult.Info}";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(postUrl);
request.Proxy = null;
request.Method = "POST";
request.ContentType = "application/json";
// request.Timeout = 10000;
using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream()))
{
dataStream.Write(itemMsg);
dataStream.Close();
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response == null)
{
_logger.Error("微信接口远程服务器没有响应");
continue;
}
string encoding = response.ContentEncoding;
if (encoding == null || encoding.Length < 1)
{
encoding = "UTF-8"; //默认编码
}
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
string retString = reader.ReadToEnd();
_logger.Info("-->" + itemMsg + " response-->" + retString);
if (!string.IsNullOrWhiteSpace(retString))
{
var sendTemplateMsgRes = JsonConvert.DeserializeObject(retString);
if (sendTemplateMsgRes.Errmsg.ToLower() == "ok")
{
send += 1;
break;
}
else
{
if (msg.Length == 0) msg.AppendFormat("消息推送失败:消息模板{0}", template_id);
msg.AppendFormat("接收者openid:{0},错误代码{1}", itemMsg, sendTemplateMsgRes.Errcode);
continue;
}
}
}
Thread.Sleep(100);
}
if (msg.Length > 0) _logger.Error(msg.ToString());
}
public static ApiResult SendTempMsg(string msg)
{
try
{
string accessTokenMode = BaseConfig.App(new string[] { "AccessTokenMode" });
if (string.IsNullOrWhiteSpace(accessTokenMode))
{
_logger.Error("配置文件中未获取有效的AccessTokenMode");
return ApiResult.Failed("配置文件中未获取有效的AccessTokenMode");
}
// 获取 AccessToken
string access_token = string.Empty;
for (int i = 0; i < 3; i++)
{
ApiResult tokenResult = null;
if (i == 0)
{
tokenResult = accessTokenMode == "1" ? AizhuhotelGetAccesstoken() : GetAccessToken();
}
else
{
tokenResult = accessTokenMode == "1" ? AizhuhotelGetAccesstoken() : GetAccessToken(true);
}
if (tokenResult.IsSuccess && !string.IsNullOrEmpty(tokenResult.Info))
{
access_token = tokenResult.Info;
break;
}
Thread.Sleep(500);
}
if (string.IsNullOrWhiteSpace(access_token)) return ApiResult.Failed("未获取有效的AccessToken");
// 推送消息
var postUrl = $"https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={access_token}";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(postUrl);
request.Proxy = null;
request.Method = "POST";
request.ContentType = "application/json";
using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream()))
{
dataStream.Write(msg);
dataStream.Close();
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string encoding = response.ContentEncoding;
if (encoding == null || encoding.Length < 1)
{
encoding = "UTF-8"; //默认编码
}
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
string retString = reader.ReadToEnd();
_logger.Info("-->" + msg + " response-->" + retString);
if (!string.IsNullOrWhiteSpace(retString))
{
var sendTemplateMsgRes = JsonConvert.DeserializeObject(retString);
if (sendTemplateMsgRes.Errmsg.ToLower() == "ok")
{
return ApiResult.Success(string.Empty);
}
}
return ApiResult.Failed(msg: "", info: retString);
}
catch (Exception ex)
{
_logger.Debug(ex.ToString());
return ApiResult.Failed(msg: "", info: ex.Message);
}
}
}
}