Skip to content

Commit

Permalink
MP v16.18.5 新增 OpenApi 接口,包括:“查询 openAPI 调用quota”“查询 rid 信息”接口 单元测试已通过
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffreySu committed Jul 30, 2022
1 parent 1a4cb19 commit 610ded8
Show file tree
Hide file tree
Showing 6 changed files with 310 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Senparc.CO2NET.Extensions;
using Senparc.Weixin.MP.OpenAPIs;
using Senparc.Weixin.MP.Test.CommonAPIs;
using Senparc.WeixinTests;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

namespace Senparc.Weixin.MP.OpenAPIs.Tests
{
[TestClass()]
public class OpenApiTests : CommonApiTest
{
[TestMethod()]
public void QuotaGetTest()
{
var appId = base._appId;

var result1 = OpenApi.QuotaGet(appId, "/cgi-bin/message/custom/send");

Assert.IsNotNull(result1);
Console.WriteLine(result1.ToJson(true));

var openId = "oxRg0uLsnpHjb8o93uVnwMK_WAVw";
var sendResult = AdvancedAPIs.CustomApi.SendText(appId, openId, "测试客服接口,增加接口调用次数");

var result2 = OpenApi.QuotaGet(appId, "/cgi-bin/message/custom/send");
Assert.IsNotNull(result2);
Console.WriteLine(result2.ToJson(true));

Assert.AreEqual(result2.quota.used, result1.quota.used + 1);

}

[TestMethod()]
public void RidGetTest()
{
var appId = base._appId;
var urlPath = "/cgi-bin/message/custom/send/worongApi";
try
{
var result = OpenApi.QuotaGet(appId, urlPath);
Console.WriteLine(result.ToJson(true));
}
catch (Senparc.Weixin.Exceptions.ErrorJsonResultException ex)
{
Console.WriteLine(ex.JsonResult.ToJson(true));

Thread.Sleep(1000);//时间太快rid还没有被记录

var regex = new Regex("rid:(?<rid>[^\"]+)");
var ridResult = regex.Match(ex.JsonResult.errmsg);
Assert.IsTrue(ridResult.Success);
var rid = ridResult.Groups["rid"].Value;
Console.WriteLine("rid:" + rid);

var result = OpenApi.RidGet(appId, "62e56973-0c7be0b1-368b3439");
Assert.IsNotNull(result);
Console.WriteLine(result.ToJson(true));

Assert.IsTrue(result.request.request_body.Contains(urlPath));
Assert.IsTrue(result.request.response_body.Contains("cgi_path not found"));
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ namespace Senparc.Weixin.MP.CommonAPIs
/// 通用接口
/// 通用接口用于和微信服务器通讯,一般不涉及自有网站服务器的通讯
/// </summary>
[NcApiBind(NeuChar.PlatformType.WeChat_OfficialAccount,true)]
[NcApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, true)]
public partial class CommonApi
{
#region 同步方法
Expand Down Expand Up @@ -181,13 +181,13 @@ public static GetCallBackIpResult GetCallBackIp(string accessTokenOrAppId)
}

/// <summary>
///公众号调用或第三方平台帮公众号调用对公众号的所有api调用(包括第三方帮其调用)次数进行清零
/// 公众号调用或第三方平台帮公众号调用对公众号的所有api调用(包括第三方帮其调用)次数进行清零
/// </summary>
/// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
/// <param name="appId"></param>
/// <param name="timeOut"></param>
/// <returns></returns>
public static WxJsonResult Clear_quota(string accessTokenOrAppId, string appId, int timeOut = Config.TIME_OUT)
public static WxJsonResult ClearQuota(string accessTokenOrAppId, string appId, int timeOut = Config.TIME_OUT)
{
return ApiHandlerWapper.TryCommonApi(accessToken =>
{
Expand Down Expand Up @@ -307,7 +307,7 @@ public static async Task<GetCallBackIpResult> GetCallBackIpAsync(string accessTo
/// <param name="appId"></param>
/// <param name="timeOut"></param>
/// <returns></returns>
public static async Task<WxJsonResult> Clear_quotaAsync(string accessTokenOrAppId, string appId, int timeOut = Config.TIME_OUT)
public static async Task<WxJsonResult> ClearQuotaAsync(string accessTokenOrAppId, string appId, int timeOut = Config.TIME_OUT)
{
return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
{
Expand Down
165 changes: 165 additions & 0 deletions src/Senparc.Weixin.MP/Senparc.Weixin.MP/OpenAPIs/OpenApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#region Apache License Version 2.0
/*----------------------------------------------------------------
Copyright 2022 Jeffrey Su & Suzhou Senparc Network Technology Co.,Ltd.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied. See the License for the specific language governing permissions
and limitations under the License.
Detail: https://github.com/JeffreySu/WeiXinMPSDK/blob/master/license.md
----------------------------------------------------------------*/
#endregion Apache License Version 2.0

/*----------------------------------------------------------------
Copyright (C) 2022 Senparc
文件名:OpenApi.cs
文件功能描述:OpenApi 接口
创建标识:Senparc - 20220731
----------------------------------------------------------------*/

using Senparc.CO2NET.Extensions;
using Senparc.Weixin.CommonAPIs;
using Senparc.Weixin.Entities;
using Senparc.Weixin.MP.OpenAPIs.OpenApiJson;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Senparc.Weixin.MP.OpenAPIs
{
/// <summary>
/// OpenApi 接口
/// </summary>
public static class OpenApi
{
#region 同步方法

/// <summary>
/// 查询 openAPI 调用quota
/// <para>1、如果查询的 api 属于公众号的接口,则需要用公众号的access_token;如果查询的 api 属于小程序的接口,则需要用小程序的access_token;如果查询的接口属于第三方平台的接口,则需要用第三方平台的component_access_token;否则会出现76022报错。</para>
/// <para>2、如果是第三方服务商代公众号或者小程序查询公众号或者小程序的api,则需要用authorizer_access_token</para>
/// <para>3、每个接口都有调用次数限制,请开发者合理调用接口</para>
/// <para>4、”/xxx/sns/xxx“这类接口不支持使用该接口,会出现76022报错。</para>
/// https://developers.weixin.qq.com/doc/offiaccount/openApi/get_api_quota.html
/// </summary>
/// <param name="accessTokenOrAppId">依据需要查询的接口属于的账号类型不同而使用不同的token</param>
/// <param name="cgiPath">api的请求地址,例如"/cgi-bin/message/custom/send";不要前缀“https://api.weixin.qq.com” ,也不要漏了"/",否则都会76003的报错</param>
/// <param name="timeOut"></param>
/// <returns></returns>
public static QuotaGetJsonResult QuotaGet(string accessTokenOrAppId, string cgiPath, int timeOut = Config.TIME_OUT)
{
return ApiHandlerWapper.TryCommonApi(accessToken =>
{
var urlFormat = string.Format(Config.ApiMpHost + "/cgi-bin/openapi/quota/get?access_token={0}", accessToken.AsUrlData());

var data = new
{
cgi_path = cgiPath
};

return CommonJsonSend.Send<QuotaGetJsonResult>(null, urlFormat, data, CommonJsonSendType.POST, timeOut: timeOut);
}, accessTokenOrAppId);
}

/// <summary>
/// 查询 rid 信息
/// https://developers.weixin.qq.com/doc/offiaccount/openApi/get_rid_info.html
/// <para>1、由于查询 rid 信息属于开发者私密行为,因此仅支持同账号的查询。举个例子,rid=1111,是小程序账号 A 调用某接口出现的报错,那么则需要使用小程序账号 A 的access_token调用当前接口查询rid=1111的详情信息,如果使用小程序账号 B 的身份查询,则出现报错,错误码为xxx。公众号、第三方平台账号的接口同理。</para>
/// <para>2、如果是第三方服务商代公众号或者小程序查询公众号或者小程序的 api 返回的rid,则使用同一账号的authorizer_access_token调用即可</para>
/// <para>3、rid的有效期只有7天,即只可查询最近7天的rid,查询超过7天的 rid 会出现报错,错误码为76001</para>
/// </summary>
/// <param name="accessTokenOrAppId">据需要查询的接口属于的账号类型不同而使用不同的token</param>
/// <param name="rid">调用接口报错返回的rid</param>
/// <param name="timeOut"></param>
/// <returns></returns>
public static RidGetJsonResult RidGet(string accessTokenOrAppId, string rid, int timeOut = Config.TIME_OUT)
{
return ApiHandlerWapper.TryCommonApi(accessToken =>
{
var urlFormat = string.Format(Config.ApiMpHost + "/cgi-bin/openapi/rid/get?access_token={0}", accessToken.AsUrlData());

var data = new
{
rid
};

return CommonJsonSend.Send<RidGetJsonResult>(null, urlFormat, data, CommonJsonSendType.POST, timeOut: timeOut);
}, accessTokenOrAppId);
}


#endregion

#region 异步方法

/// <summary>
/// 【异步方法】查询 openAPI 调用quota
/// <para>1、如果查询的 api 属于公众号的接口,则需要用公众号的access_token;如果查询的 api 属于小程序的接口,则需要用小程序的access_token;如果查询的接口属于第三方平台的接口,则需要用第三方平台的component_access_token;否则会出现76022报错。</para>
/// <para>2、如果是第三方服务商代公众号或者小程序查询公众号或者小程序的api,则需要用authorizer_access_token</para>
/// <para>3、每个接口都有调用次数限制,请开发者合理调用接口</para>
/// <para>4、”/xxx/sns/xxx“这类接口不支持使用该接口,会出现76022报错。</para>
/// https://developers.weixin.qq.com/doc/offiaccount/openApi/get_api_quota.html
/// </summary>
/// <param name="accessTokenOrAppId">依据需要查询的接口属于的账号类型不同而使用不同的token</param>
/// <param name="cgiPath">api的请求地址,例如"/cgi-bin/message/custom/send";不要前缀“https://api.weixin.qq.com” ,也不要漏了"/",否则都会76003的报错</param>
/// <param name="timeOut"></param>
/// <returns></returns>
public static async Task<QuotaGetJsonResult> QuotaGetAsync(string accessTokenOrAppId, string cgiPath, int timeOut = Config.TIME_OUT)
{
return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
{
var urlFormat = string.Format(Config.ApiMpHost + "/cgi-bin/openapi/quota/get?access_token={0}", accessToken.AsUrlData());

var data = new
{
cgi_path = cgiPath
};

return await CommonJsonSend.SendAsync<QuotaGetJsonResult>(null, urlFormat, data, CommonJsonSendType.POST, timeOut: timeOut);
}, accessTokenOrAppId);
}

/// <summary>
/// 【异步方法】查询 rid 信息
/// https://developers.weixin.qq.com/doc/offiaccount/openApi/get_rid_info.html
/// <para>1、由于查询 rid 信息属于开发者私密行为,因此仅支持同账号的查询。举个例子,rid=1111,是小程序账号 A 调用某接口出现的报错,那么则需要使用小程序账号 A 的access_token调用当前接口查询rid=1111的详情信息,如果使用小程序账号 B 的身份查询,则出现报错,错误码为xxx。公众号、第三方平台账号的接口同理。</para>
/// <para>2、如果是第三方服务商代公众号或者小程序查询公众号或者小程序的 api 返回的rid,则使用同一账号的authorizer_access_token调用即可</para>
/// <para>3、rid的有效期只有7天,即只可查询最近7天的rid,查询超过7天的 rid 会出现报错,错误码为76001</para>
/// </summary>
/// <param name="accessTokenOrAppId">据需要查询的接口属于的账号类型不同而使用不同的token</param>
/// <param name="rid">调用接口报错返回的rid</param>
/// <param name="timeOut"></param>
/// <returns></returns>
public static async Task<RidGetJsonResult> RidGetAsync(string accessTokenOrAppId, string rid, int timeOut = Config.TIME_OUT)
{
return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
{
var urlFormat = string.Format(Config.ApiMpHost + "/cgi-bin/openapi/rid/get?access_token={0}", accessToken.AsUrlData());

var data = new
{
rid
};

return await CommonJsonSend.SendAsync<RidGetJsonResult>(null, urlFormat, data, CommonJsonSendType.POST, timeOut: timeOut);
}, accessTokenOrAppId);
}

#endregion
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Senparc.Weixin.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Senparc.Weixin.MP.OpenAPIs.OpenApiJson
{
public class QuotaGetJsonResult : WxJsonResult
{
public Quota quota { get; set; }
}

public class Quota
{
public int daily_limit { get; set; }
public int used { get; set; }
public int remain { get; set; }
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Senparc.Weixin.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Senparc.Weixin.MP.OpenAPIs.OpenApiJson
{
public class RidGetJsonResult: WxJsonResult
{
public Request request { get; set; }
}

public class Request
{
/// <summary>
/// 发起请求的时间戳
/// </summary>
public long invoke_time { get; set; }
/// <summary>
/// 请求毫秒级耗时
/// </summary>
public int cost_in_ms { get; set; }
/// <summary>
/// 请求的 URL 参数
/// </summary>
public string request_url { get; set; }
/// <summary>
/// post请求的请求参数
/// </summary>
public string request_body { get; set; }
/// <summary>
/// 接口请求返回参数
/// </summary>
public string response_body { get; set; }
/// <summary>
/// 接口请求的客户端ip
/// </summary>
public string client_ip { get; set; }
}



}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net462;netstandard2.0;netstandard2.1</TargetFrameworks>
<Version>16.18.4</Version>
<Version>16.18.5</Version>
<AssemblyName>Senparc.Weixin.MP</AssemblyName>
<RootNamespace>Senparc.Weixin.MP</RootNamespace>
<GeneratePackageOnBuild Condition=" '$(Configuration)' == 'Release' ">true</GeneratePackageOnBuild>
Expand Down Expand Up @@ -518,6 +518,7 @@
v16.18.1 公众号菜单添加 article_id、article_view_limited 类型
v16.18.2 完善客服接口
v16.18.4 完善 GetDraftResultJson 字段
v16.18.5 新增 OpenApi 接口,包括:“查询 openAPI 调用quota”“查询 rid 信息”接口
</PackageReleaseNotes>
<RepositoryUrl>https://github.com/JeffreySu/WeiXinMPSDK</RepositoryUrl>
</PropertyGroup>
Expand Down

0 comments on commit 610ded8

Please sign in to comment.