760 lines
34 KiB
C#
760 lines
34 KiB
C#
using Hncore.Infrastructure.Common;
|
||
using Hncore.Infrastructure.Extension;
|
||
using Hncore.Infrastructure.Serializer;
|
||
using Hncore.Pass.MsgCenter.Constant;
|
||
using Hncore.Pass.MsgCenter.Util;
|
||
using Hncore.Pass.MsgCenter.WxOpen.Response;
|
||
using Microsoft.EntityFrameworkCore.Internal;
|
||
using Microsoft.Extensions.Configuration;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Net.Http;
|
||
using System.Threading.Tasks;
|
||
using System.Web;
|
||
|
||
namespace Hncore.Wx.Open
|
||
{
|
||
public class WxOpenApi
|
||
{
|
||
private static readonly AsyncLock _mutex1 = new AsyncLock();
|
||
private static readonly AsyncLock _mutex2 = new AsyncLock();
|
||
private static readonly AsyncLock _mutex4 = new AsyncLock();
|
||
|
||
private static Dictionary<string, string> WxAppMap = new Dictionary<string, string>();
|
||
|
||
private static IHttpClientFactory _HttpClientFactory;
|
||
|
||
public static void Init(IConfiguration config, IHttpClientFactory HttpClientFactory)
|
||
{
|
||
_HttpClientFactory = HttpClientFactory;
|
||
var key = config[$"WxApps:AppID"];
|
||
WxAppMap[key] = config[$"WxApps:AppSecret"];
|
||
//var WxMpApps = config.GetSection("WxApps");
|
||
//var nodes = WxMpApps.GetChildren();
|
||
//for (var i = 0; i < nodes.Count(); i++)
|
||
//{
|
||
// var key = config[$"WxApps:{i}:AppID"];
|
||
// var value = config[$"WxApps:{i}:AppSecret"];
|
||
// if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
|
||
// WxAppMap[key] = value;
|
||
//}
|
||
}
|
||
|
||
public static string GetWxAppSecret(string appid)
|
||
{
|
||
if (WxAppMap.ContainsKey(appid))
|
||
return WxAppMap[appid];
|
||
else return "";
|
||
}
|
||
|
||
private static HttpClient GetHttpClient()
|
||
{
|
||
return _HttpClientFactory.CreateClient("WxOpen");
|
||
}
|
||
public static async Task<string> GetComponentTicket()
|
||
{
|
||
return await RedisHelper.GetAsync(ConstantConfig.Redis_Psipwechat_Ticket_Key);
|
||
}
|
||
|
||
public static async Task<bool> SetComponentTicket(string ticket)
|
||
{
|
||
return await RedisHelper.SetAsync(ConstantConfig.Redis_Psipwechat_Ticket_Key, ticket);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开放平台:得到开放平台的accessToken
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static async Task<string> GetComponentAccessToken()
|
||
{
|
||
var component_appid = HostContext.Configuration["WxOpen:AppID"];
|
||
var key =string.Format(ConstantConfig.Redis_ComponentAccessToken_Key, component_appid);
|
||
var tokenJson = await RedisHelper.GetAsync(key);
|
||
var token = tokenJson.FromJsonToOrDefault<GetComponentAccessTokenResponse>();
|
||
if (token == null || token.need_to_refresh_token)
|
||
{
|
||
using (await _mutex1.LockAsync())
|
||
{
|
||
tokenJson = await RedisHelper.GetAsync(key);
|
||
token = tokenJson.FromJsonToOrDefault<GetComponentAccessTokenResponse>();
|
||
if (token != null && !token.need_to_refresh_token)
|
||
{
|
||
return token.component_access_token;
|
||
}
|
||
//重新去微信获取
|
||
var ticket =await GetComponentTicket();
|
||
token = await get_component_access_token(ticket);
|
||
if (token.errcode == 0)
|
||
{
|
||
await RedisHelper.SetAsync(key, token.ToJson(), token.expires_in);
|
||
return token.component_access_token;
|
||
}
|
||
else
|
||
{
|
||
return "";
|
||
}
|
||
}
|
||
}
|
||
return token.component_access_token;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开放平台:得到公众平台的AccessToken
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static async Task<string> GetAuthorizerAccessToken(string authorizer_appid)
|
||
{
|
||
var key = string.Format(ConstantConfig.Redis_AuthorizerAccessToken_Key, authorizer_appid);
|
||
var refresh_key = string.Format(ConstantConfig.Redis_Refresh_AuthorizerAccessToken_Key, authorizer_appid);
|
||
var tokenJson = await RedisHelper.GetAsync(key);
|
||
var token = tokenJson.FromJsonToOrDefault<GetAuthorizerAccessTokenResponse>();
|
||
if (token == null || token.need_to_refresh_token)
|
||
{
|
||
using (await _mutex2.LockAsync())
|
||
{
|
||
tokenJson = await RedisHelper.GetAsync(key);
|
||
token = tokenJson.FromJsonToOrDefault<GetAuthorizerAccessTokenResponse>();
|
||
if (token != null && !token.need_to_refresh_token)
|
||
{
|
||
return token.authorizer_access_token;
|
||
}
|
||
|
||
var authorizer_refresh_token = await RedisHelper.GetAsync(refresh_key);
|
||
var component_access_token = await GetComponentAccessToken();
|
||
token = await get_authorizer_access_token_by_refresh(authorizer_appid, authorizer_refresh_token, component_access_token);
|
||
if (token.errcode == 0)
|
||
{
|
||
await RedisHelper.SetAsync(key, token.ToJson(), token.expires_in);
|
||
await RedisHelper.SetAsync(refresh_key, token.authorizer_refresh_token,60*60*24*30);
|
||
return token.authorizer_access_token;
|
||
}
|
||
else
|
||
{
|
||
return "";
|
||
}
|
||
}
|
||
}
|
||
return token.authorizer_access_token;
|
||
}
|
||
|
||
public static async Task ReFreshAccessToken(string authorizer_appid, string component_access_token)
|
||
{
|
||
var key = string.Format(ConstantConfig.Redis_AuthorizerAccessToken_Key, authorizer_appid);
|
||
var refresh_key = string.Format(ConstantConfig.Redis_Refresh_AuthorizerAccessToken_Key, authorizer_appid);
|
||
var authorizer_refresh_token = await RedisHelper.GetAsync(refresh_key);
|
||
using (await _mutex4.LockAsync())
|
||
{
|
||
var token = await get_authorizer_access_token_by_refresh(authorizer_appid, authorizer_refresh_token, component_access_token);
|
||
if (token.errcode == 0)
|
||
{
|
||
await RedisHelper.SetAsync(key, token.ToJson(), token.expires_in);
|
||
await RedisHelper.SetAsync(refresh_key, token.authorizer_refresh_token,60 * 60 * 24 * 30);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
///开放平台: 通过回调返回授权码的方式获得公众号的accesstoken
|
||
/// </summary>
|
||
/// <param name="authorization_code"></param>
|
||
/// <returns></returns>
|
||
public static async Task<string> GetAuthorizerAccessTokenByCode(string authorization_code,Func<authorization_info, Task<string>> callback)
|
||
{
|
||
var component_access_token = await GetComponentAccessToken();
|
||
var ret = await get_authorizer_access_token_by_callback(authorization_code, component_access_token);
|
||
var authorizer_appid = ret.authorization_info.authorizer_appid;
|
||
//存access_token的key
|
||
var key = string.Format(ConstantConfig.Redis_AuthorizerAccessToken_Key, authorizer_appid);
|
||
|
||
//存refresh_access_token的key
|
||
var refresh_key = string.Format(ConstantConfig.Redis_Refresh_AuthorizerAccessToken_Key, authorizer_appid);
|
||
|
||
var info = new GetAuthorizerAccessTokenResponse()
|
||
{
|
||
authorizer_access_token = ret.authorization_info.authorizer_access_token,
|
||
authorizer_refresh_token = ret.authorization_info.authorizer_refresh_token,
|
||
expires_in = ret.authorization_info.expires_in,
|
||
create_from = DateTime.Now.TimestampFrom19700101()
|
||
};
|
||
|
||
await RedisHelper.SetAsync(key, info.ToJson(), info.expires_in);
|
||
await RedisHelper.SetAsync(refresh_key, info.authorizer_refresh_token);
|
||
|
||
if (callback != null)
|
||
{
|
||
return await callback(ret.authorization_info);
|
||
}
|
||
return info.authorizer_access_token;
|
||
}
|
||
|
||
/// <summary>
|
||
///开放平台: 得到开放平台的预授权码
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static async Task<string> GetPreAuthCode()
|
||
{
|
||
var component_access_token = await GetComponentAccessToken();
|
||
var ret = await get_pre_auth_Code(component_access_token);
|
||
return ret.pre_auth_code;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
///开放平台: 代公众号获取用户在公众号的OpenId,以及AccessToken 信息
|
||
/// </summary>
|
||
/// <param name="req"></param>
|
||
/// <returns>结果对象,里边包含了授权令牌信息</returns>
|
||
public static async Task<wechat_access_token> GetAuthorizerClientUserOpenIdInfo(string appid, string code)
|
||
{
|
||
var component_access_token = await GetComponentAccessToken();
|
||
var ret = await get_authorizer_user_openIdifno(appid, code, component_access_token);
|
||
return ret;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开放平台:为公众平台授权的url
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static async Task<string> GetAuthorizationUrl(string callback_url)
|
||
{
|
||
var appID = HostContext.Configuration["WxOpen:AppID"]; ;
|
||
var pre_auth_code = await GetPreAuthCode();
|
||
var baseUrl = HostContext.Configuration["BaseInfoUrl"];
|
||
callback_url = $"{baseUrl}/{callback_url}";//回调地址
|
||
|
||
callback_url = HttpUtility.UrlEncode(callback_url);
|
||
//开放平台授权地址
|
||
var url = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?" +
|
||
$"component_appid={appID}" +
|
||
$"&pre_auth_code={pre_auth_code}" +
|
||
$"&redirect_uri={callback_url}";
|
||
return url;
|
||
}
|
||
|
||
private static readonly AsyncLock _mutex3 = new AsyncLock();
|
||
/// <summary>
|
||
/// 【公众平台、小程序】:得到公众平台、小程序的accessToken
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static async Task<string> GetAccessToken(string appid, string secret)
|
||
{
|
||
var key = string.Format(ConstantConfig.Redis_MP_AccessToken_Key, appid);
|
||
var tokenJson = await RedisHelper.GetAsync(key);
|
||
var token = tokenJson.FromJsonToOrDefault<GetAccessTokenResponse>();
|
||
if (token == null || token.need_to_refresh_token)
|
||
{
|
||
using (await _mutex3.LockAsync())
|
||
{
|
||
tokenJson = await RedisHelper.GetAsync(key);
|
||
token = tokenJson.FromJsonToOrDefault<GetAccessTokenResponse>();
|
||
if (token != null && !token.need_to_refresh_token)
|
||
{
|
||
return token.access_token;
|
||
}
|
||
token = await get_access_token(appid, secret);
|
||
if (token.errcode == 0)
|
||
{
|
||
await RedisHelper.SetAsync(key, token.ToJson(), token.expires_in);
|
||
return token.access_token;
|
||
}
|
||
return "";
|
||
}
|
||
}
|
||
return token.access_token;
|
||
}
|
||
/// <summary>
|
||
/// 公众平台,通过code换取网页授权access_token
|
||
/// </summary>
|
||
/// <param name="appid"></param>
|
||
/// <param name="secret"></param>
|
||
/// <returns></returns>
|
||
public static async Task<GetGetWebAccessTokenResponse> GetWebAccessToken(string appid, string code)
|
||
{
|
||
var secret = GetWxAppSecret(appid);
|
||
if (string.IsNullOrWhiteSpace(secret))
|
||
{
|
||
LogHelper.Error("GetWebAccessToken", $"appid={appid} 没有配置");
|
||
return null;
|
||
}
|
||
return await get_web_access_token(appid, secret, code);
|
||
|
||
}
|
||
/// <summary>
|
||
/// 通过access_token和openid拉取用户信息
|
||
/// </summary>
|
||
/// <param name="appid"></param>
|
||
/// <param name="code"></param>
|
||
/// <returns></returns>
|
||
public static async Task<GetUserinfoResponse> GetUserinfoByWebAccessToken(string access_token, string openid)
|
||
{
|
||
var key = string.Format(ConstantConfig.Redis_MP_GetUserinfoByWebAccessToken_Key, openid);
|
||
var userInfo = await RedisHelper.GetAsync<GetUserinfoResponse>(key);
|
||
|
||
if (userInfo == null)
|
||
{
|
||
userInfo = await get_userinfo_by_web_access_token(access_token, openid);
|
||
if (userInfo.errcode == 0)
|
||
await RedisHelper.SetAsync(key, userInfo.ToJson(), 2 * 60 * 60);
|
||
}
|
||
return userInfo;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开放平台获得获取用户基本信息(UnionID机制)
|
||
/// </summary>
|
||
/// <param name="access_token"></param>
|
||
/// <param name="openid"></param>
|
||
/// <returns></returns>
|
||
public static async Task<GetUserinfoResponse> GetUserUnionIDinfo(string appid, string openid)
|
||
{
|
||
var key = string.Format(ConstantConfig.Redis_MP_GetUserUnionIDInfo_Key, openid);
|
||
var userInfo = await RedisHelper.GetAsync<GetUserinfoResponse>(key);
|
||
|
||
if (userInfo == null)
|
||
{
|
||
var access_token = await GetAuthorizerAccessToken(appid);
|
||
userInfo = await get_user_openid_info(access_token, openid);
|
||
if (userInfo.errcode == 0)
|
||
await RedisHelper.SetAsync(key, userInfo.ToJson(), 2 * 60 * 60);
|
||
}
|
||
return userInfo;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 公众平台获得获取用户基本信息()
|
||
/// </summary>
|
||
/// <param name="access_token"></param>
|
||
/// <param name="openid"></param>
|
||
/// <returns></returns>
|
||
public static async Task<GetUserinfoResponse> GetUserinfoByOpenId(string appid, string openid)
|
||
{
|
||
var key = string.Format(ConstantConfig.Redis_MP_GetUserOpenIdInfo_Key, openid);
|
||
var userInfo = await RedisHelper.GetAsync<GetUserinfoResponse>(key);
|
||
|
||
if (userInfo == null)
|
||
{
|
||
var access_token = await GetAccessToken(appid,GetWxAppSecret(appid));
|
||
userInfo = await get_user_openid_info(access_token, openid);
|
||
if (userInfo.errcode == 0)
|
||
await RedisHelper.SetAsync(key, userInfo.ToJson(), 2 * 60 * 60);
|
||
}
|
||
return userInfo;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过开放平台获得公众号的信息
|
||
/// </summary>
|
||
/// <param name="access_token"></param>
|
||
/// <param name="openid"></param>
|
||
/// <returns></returns>
|
||
public static async Task<authorizer_info> GetMpInfo(string authorizer_appid)
|
||
{
|
||
var key = string.Format(ConstantConfig.Redis_MP_Info_Key, authorizer_appid);
|
||
var mpInfo = await RedisHelper.GetAsync<GetAuthorizerInfoResponse>(key);
|
||
|
||
if (mpInfo == null)
|
||
{
|
||
var component_token = await GetComponentAccessToken();
|
||
mpInfo = await get_mp_info(component_token, authorizer_appid);
|
||
if (mpInfo.errcode == 0)
|
||
await RedisHelper.SetAsync(key, mpInfo.ToJson(), 1 * 60 * 60);
|
||
}
|
||
return mpInfo.authorizer_info;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 为公众平台创建菜单
|
||
/// </summary>
|
||
/// <param name="authorizer_appid"></param>
|
||
/// <returns></returns>
|
||
public static async Task<bool> CreateMPMenu(string access_token, object menu)
|
||
{
|
||
var ret = await create_mp_menu(access_token, menu);
|
||
return ret.errcode == 0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 为公众平台粉丝添加标签
|
||
/// </summary>
|
||
/// <param name="authorizer_appid"></param>
|
||
/// <returns></returns>
|
||
public static async Task AddTag(string appid, List<string> openIds, string tagId)
|
||
{
|
||
var access_token = await GetAuthorizerAccessToken(appid);
|
||
await add_tag(access_token, openIds, int.Parse(tagId));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 得到公众平台所有标签
|
||
/// </summary>
|
||
/// <param name="authorizer_appid"></param>
|
||
/// <returns></returns>
|
||
public static async Task<GetTagsResponse> GetTags(string appid)
|
||
{
|
||
var access_token = await GetAuthorizerAccessToken(appid);
|
||
return await get_tags(access_token);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 得到公众平台jsapi ticket
|
||
///</summary>
|
||
/// <param name="authorizer_appid"></param>
|
||
/// <returns></returns>
|
||
public static async Task<GetJsApiTicketResponse> GetJsTicket(string authorizer_appid)
|
||
{
|
||
var key = string.Format(ConstantConfig.Redis_MP_Js_Ticket_Key, authorizer_appid);
|
||
var ticketInfo = await RedisHelper.GetAsync<GetJsApiTicketResponse>(key);
|
||
if (ticketInfo == null)
|
||
{
|
||
var access_token = await GetAuthorizerAccessToken(authorizer_appid);
|
||
ticketInfo = await get_jsapi_ticket(access_token);
|
||
if (ticketInfo.errcode == 0)
|
||
await RedisHelper.SetAsync(key, ticketInfo.ToJson(), 1 * 60 * 60);
|
||
}
|
||
return ticketInfo;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 为公众平台创建二维码
|
||
/// </summary>
|
||
/// <param name="authorizer_appid"></param>
|
||
/// <returns></returns>
|
||
public static async Task<CreateQrcodeResponse> CreatePermanentQrcode(string appid, string scene_str)
|
||
{
|
||
var access_token = await GetAuthorizerAccessToken(appid);
|
||
return await create_permanent_qrcode(access_token, scene_str);
|
||
}
|
||
|
||
#region 内部微信接口
|
||
|
||
/// <summary>
|
||
/// 开放平台:得到access_token
|
||
/// </summary>
|
||
/// <param name="ticket"></param>
|
||
/// <returns></returns>
|
||
private static async Task<GetComponentAccessTokenResponse> get_component_access_token(string ticket)
|
||
{
|
||
string url = "cgi-bin/component/api_component_token";
|
||
|
||
var reqData = new
|
||
{
|
||
component_appid = HostContext.Configuration["WxOpen:AppID"],
|
||
component_appsecret = HostContext.Configuration["WxOpen:AppSecret"],
|
||
component_verify_ticket = ticket,
|
||
};
|
||
var respData = await GetHttpClient().PostAsJsonGetString(url, reqData);
|
||
var ret = respData.FromJsonTo<GetComponentAccessTokenResponse>();
|
||
if (ret.errcode > 0)
|
||
{
|
||
LogHelper.Error("get_component_access_token", $"errcode={ret.errcode},errmsg={ret.errmsg}");
|
||
}
|
||
ret.create_from = DateTime.Now.TimestampFrom19700101();
|
||
LogHelper.Debug("get_component_access_token", respData);
|
||
return ret;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
///开放平台:通过刷新的方式获得公众平台的accesstoken
|
||
/// </summary>
|
||
/// <param name="req"></param>
|
||
/// <returns></returns>
|
||
private static async Task<GetAuthorizerAccessTokenResponse> get_authorizer_access_token_by_refresh(string authorizer_appid, string authorizer_refresh_token,string component_access_token)
|
||
{
|
||
string url = $"cgi-bin/component/api_authorizer_token?component_access_token={component_access_token}";
|
||
var reqData = new
|
||
{
|
||
component_appid = HostContext.Configuration["WxOpen:AppID"],
|
||
authorizer_appid,
|
||
authorizer_refresh_token,
|
||
};
|
||
|
||
var respData = await GetHttpClient().PostAsJsonGetString(url, reqData);
|
||
var ret = respData.FromJsonToOrDefault<GetAuthorizerAccessTokenResponse>();
|
||
if (ret.errcode > 0)
|
||
{
|
||
LogHelper.Error("get_authorizer_access_token_by_refresh", $"errcode={ret.errcode},errmsg={ret.errmsg},authorizer_appid={authorizer_appid}");
|
||
}
|
||
ret.create_from = DateTime.Now.TimestampFrom19700101();
|
||
LogHelper.Debug("get_authorizer_access_token_by_callback", respData);
|
||
return ret;
|
||
}
|
||
|
||
/// <summary>
|
||
///开放平台: 通过授权码回调方式获得公众平台的accesstoken
|
||
/// </summary>
|
||
/// <param name="req"></param>
|
||
/// <returns></returns>
|
||
private static async Task<GetAuthorizerInvokeAccessTokenResponse> get_authorizer_access_token_by_callback(string authorization_code,string component_access_token)
|
||
{
|
||
string url = $"cgi-bin/component/api_query_auth?component_access_token={component_access_token}";
|
||
var reqData = new
|
||
{
|
||
component_appid = HostContext.Configuration["WxOpen:AppID"],
|
||
authorization_code,
|
||
};
|
||
var respData = await GetHttpClient().PostAsJsonGetString(url, reqData);
|
||
var ret = respData.FromJsonToOrDefault<GetAuthorizerInvokeAccessTokenResponse>();
|
||
if (ret.errcode > 0)
|
||
{
|
||
LogHelper.Error("get_authorizer_access_token_by_callback", $"errcode={ret.errcode},errmsg={ret.errmsg}");
|
||
}
|
||
ret.create_from = DateTime.Now.TimestampFrom19700101();
|
||
LogHelper.Debug("get_authorizer_access_token_by_callback", respData);
|
||
return ret;
|
||
}
|
||
|
||
/// <summary>
|
||
///开放平台: 获取开放平台预授权代码 用于生成授权url
|
||
/// </summary>
|
||
private static async Task<GetPreAuthCodeResponse> get_pre_auth_Code(string component_access_token)
|
||
{
|
||
string url = $"cgi-bin/component/api_create_preauthcode?component_access_token={component_access_token}";
|
||
var reqData = new
|
||
{
|
||
component_appid = HostContext.Configuration["WxOpen:AppID"],
|
||
};
|
||
|
||
var respData = await GetHttpClient().PostAsJsonGetString(url, reqData);
|
||
var ret = respData.FromJsonToOrDefault<GetPreAuthCodeResponse>();
|
||
if (ret.errcode > 0)
|
||
{
|
||
LogHelper.Error("get_pre_auth_Code", $"errcode={ret.errcode},errmsg={ret.errmsg}");
|
||
}
|
||
ret.create_from = DateTime.Now.TimestampFrom19700101();
|
||
LogHelper.Debug("get_pre_auth_Code", respData);
|
||
return ret;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开放平台:获得公众平台用户openid信息
|
||
/// </summary>
|
||
/// <param name="appid"></param>
|
||
/// <param name="code"></param>
|
||
/// <param name="component_access_token"></param>
|
||
/// <returns></returns>
|
||
private static async Task<wechat_access_token> get_authorizer_user_openIdifno(string appid, string code, string component_access_token)
|
||
{
|
||
LogHelper.Debug("get_authorizer_user_openIdifno_params", $"{appid},{code}");
|
||
var component_appid = HostContext.Configuration["WxOpen:AppID"];
|
||
string url = $"sns/oauth2/component/access_token?appid={appid}&code={code}&grant_type=authorization_code&component_appid={component_appid}&component_access_token={component_access_token}";
|
||
|
||
LogHelper.Debug("get_authorizer_user_openIdifno-url", url);
|
||
var resp = await GetHttpClient().GetStringAsync(url);
|
||
var respData = resp.FromJsonToOrDefault<wechat_access_token>();
|
||
LogHelper.Debug("get_authorizer_user_openIdifno", resp);
|
||
return respData;
|
||
}
|
||
|
||
/// <summary>
|
||
///公众平台,小程序: 直接获得公众平台,小程序的accesstoken
|
||
/// </summary>
|
||
/// <param name="req"></param>
|
||
/// <returns></returns>
|
||
private static async Task<GetAccessTokenResponse> get_access_token(string appid, string secret)
|
||
{
|
||
string url = $"cgi-bin/token?grant_type=client_credential&appid={appid}&secret={secret}";
|
||
|
||
var respData = await GetHttpClient().GetStringAsync(url);
|
||
var ret = respData.FromJsonToOrDefault<GetAccessTokenResponse>();
|
||
if (ret.errcode > 0)
|
||
{
|
||
LogHelper.Error("get_mp_access_token", $"errcode={ret.errcode},errmsg={ret.errmsg}");
|
||
}
|
||
ret.create_from = DateTime.Now.TimestampFrom19700101();
|
||
LogHelper.Debug("get_mp_access_token", respData);
|
||
return ret;
|
||
}
|
||
|
||
/// <summary>
|
||
///公众平台,通过code换取网页授权access_token
|
||
///这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同
|
||
///https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
|
||
/// </summary>
|
||
/// <param name="req"></param>
|
||
/// <returns></returns>
|
||
private static async Task<GetGetWebAccessTokenResponse> get_web_access_token(string appid, string secret,string code)
|
||
{
|
||
string url = $"sns/oauth2/access_token?appid={appid}&secret={secret}&code={code}&grant_type=authorization_code";
|
||
var respData = await GetHttpClient().GetStringAsync(url);
|
||
var ret = respData.FromJsonToOrDefault<GetGetWebAccessTokenResponse>();
|
||
if (ret.errcode > 0)
|
||
{
|
||
LogHelper.Error("get_web_access_token", $"errcode={ret.errcode},errmsg={ret.errmsg}");
|
||
}
|
||
ret.create_from = DateTime.Now.TimestampFrom19700101();
|
||
LogHelper.Debug("get_web_access_token", respData);
|
||
return ret;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了。
|
||
/// https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
|
||
/// </summary>
|
||
/// <param name="access_token">网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同</param>
|
||
/// <param name="openid"></param>
|
||
/// <returns></returns>
|
||
private static async Task<GetUserinfoResponse> get_userinfo_by_web_access_token(string access_token, string openid)
|
||
{
|
||
string url = $"sns/userinfo?access_token={access_token}&openid={openid}&lang=zh_CN";
|
||
var respData = await GetHttpClient().GetStringAsync(url);
|
||
var ret = respData.FromJsonToOrDefault<GetUserinfoResponse>();
|
||
if (ret.errcode > 0)
|
||
{
|
||
LogHelper.Error("get_userinfo_by_web_access_token", $"errcode={ret.errcode},errmsg={ret.errmsg}");
|
||
}
|
||
LogHelper.Debug("get_userinfo_by_web_access_token", respData);
|
||
return ret;
|
||
}
|
||
|
||
private static async Task<GetUserinfoResponse> get_user_openid_info(string access_token, string openid)
|
||
{
|
||
string url = $"cgi-bin/user/info?access_token={access_token}&openid={openid}&lang=zh_CN";
|
||
var respData = await GetHttpClient().GetStringAsync(url);
|
||
var ret = respData.FromJsonToOrDefault<GetUserinfoResponse>();
|
||
if (ret.errcode > 0)
|
||
{
|
||
LogHelper.Error("get_user_openid_info", $"errcode={ret.errcode},errmsg={ret.errmsg}");
|
||
}
|
||
LogHelper.Debug("get_user_openid_info", respData);
|
||
return ret;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 通过开放平台得到公众号的信息,主要是 (authorizer_info)
|
||
/// </summary>
|
||
/// <param name="access_token"></param>
|
||
/// <param name="openid"></param>
|
||
/// <returns></returns>
|
||
private static async Task<GetAuthorizerInfoResponse> get_mp_info(string component_token, string authorizer_appid)
|
||
{
|
||
string url = $"cgi-bin/component/api_get_authorizer_info?component_access_token={component_token}";
|
||
|
||
var reqData = new
|
||
{
|
||
authorizer_appid,
|
||
component_appid = HostContext.Configuration["WxOpen:AppID"],
|
||
};
|
||
var respData = await GetHttpClient().PostAsJsonGetString(url, reqData);
|
||
var ret = respData.FromJsonToOrDefault<GetAuthorizerInfoResponse>();
|
||
if (ret.errcode > 0)
|
||
{
|
||
LogHelper.Error("get_mp_info_resp", $"errcode={ret.errcode},errmsg={ret.errmsg}");
|
||
}
|
||
LogHelper.Debug("get_mp_info_resp", respData);
|
||
return ret;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 为公众平台创建菜单
|
||
/// </summary>
|
||
/// <param name="access_token"></param>
|
||
/// <param name="openid"></param>
|
||
/// <returns></returns>
|
||
private static async Task<ResponseBase> create_mp_menu(string access_token, object menu)
|
||
{
|
||
string url = $"cgi-bin/menu/create?access_token={access_token}";
|
||
var respData = await GetHttpClient().PostAsJsonGetString(url, menu);
|
||
var ret = respData.FromJsonToOrDefault<ResponseBase>();
|
||
if (ret.errcode > 0)
|
||
{
|
||
LogHelper.Error("create_mp_menu", $"errcode={ret.errcode},errmsg={ret.errmsg}");
|
||
}
|
||
LogHelper.Debug("create_mp_menu", respData);
|
||
return ret;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 为公众号粉丝打标签
|
||
/// </summary>
|
||
/// <param name="access_token"></param>
|
||
/// <param name="openid"></param>
|
||
/// <returns></returns>
|
||
private static async Task<ResponseBase> add_tag(string access_token, List<string> openIds,int tagId)
|
||
{
|
||
string url = $"cgi-bin/tags/members/batchtagging?access_token={access_token}";
|
||
|
||
var reqData = new
|
||
{
|
||
openid_list = openIds,
|
||
tagid = tagId
|
||
};
|
||
var respData = await GetHttpClient().PostAsJsonGetString(url, reqData);
|
||
var ret = respData.FromJsonToOrDefault<ResponseBase>();
|
||
if (ret.errcode > 0)
|
||
{
|
||
LogHelper.Error("add_tag", $"errcode={ret.errcode},errmsg={ret.errmsg}");
|
||
}
|
||
LogHelper.Debug("add_tag", respData);
|
||
return ret;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建公众号二维码
|
||
/// </summary>
|
||
/// <param name="access_token"></param>
|
||
/// <param name="openid"></param>
|
||
/// <returns></returns>
|
||
private static async Task<GetTagsResponse> get_tags(string access_token)
|
||
{
|
||
string url = $"cgi-bin/tags/get?access_token={access_token}";
|
||
var respData = await GetHttpClient().GetStringAsync(url);
|
||
var ret = respData.FromJsonToOrDefault<GetTagsResponse>();
|
||
if (ret.errcode > 0)
|
||
{
|
||
LogHelper.Error("get_tags", $"errcode={ret.errcode},errmsg={ret.errmsg}");
|
||
}
|
||
LogHelper.Debug("get_tags", respData);
|
||
return ret;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建公众号二维码
|
||
/// </summary>
|
||
/// <param name="access_token"></param>
|
||
/// <param name="openid"></param>
|
||
/// <returns></returns>
|
||
private static async Task<CreateQrcodeResponse> create_permanent_qrcode(string access_token,string scene_str)
|
||
{
|
||
string url = $"cgi-bin/qrcode/create?access_token={access_token}";
|
||
//{ "action_name": "QR_LIMIT_STR_SCENE", "action_info": { "scene": { "scene_str": "test"} } }
|
||
var reqData = new
|
||
{
|
||
action_name = "QR_LIMIT_STR_SCENE",
|
||
action_info = new
|
||
{
|
||
scene = new
|
||
{
|
||
scene_str
|
||
}
|
||
}
|
||
};
|
||
var respData = await GetHttpClient().PostAsJsonGetString(url, reqData);
|
||
var ret = respData.FromJsonToOrDefault<CreateQrcodeResponse>();
|
||
if (ret.errcode > 0)
|
||
{
|
||
LogHelper.Error("create_permanent_qrcode", $"errcode={ret.errcode},errmsg={ret.errmsg}");
|
||
}
|
||
LogHelper.Debug("create_permanent_qrcode", respData);
|
||
return ret;
|
||
}
|
||
|
||
public static async Task<GetJsApiTicketResponse> get_jsapi_ticket(string access_token)
|
||
{
|
||
string url = $"cgi-bin/ticket/getticket?access_token={access_token}&type=jsapi";
|
||
var respData = await GetHttpClient().GetStringAsync(url);
|
||
var ret = respData.FromJsonToOrDefault<GetJsApiTicketResponse>();
|
||
if (ret.errcode > 0)
|
||
{
|
||
LogHelper.Error("get_jsapi_ticket", $"errcode={ret.errcode},errmsg={ret.errmsg}");
|
||
}
|
||
LogHelper.Debug("get_jsapi_ticket", respData);
|
||
return ret;
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
}
|