csharp-sdk-upm/Storage/Storage/Public/AVCloud.cs

315 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using LeanCloud.Storage.Internal;
using System.Net.Http;
namespace LeanCloud {
/// <summary>
/// AVCloud提供与 LeanCloud 云函数交互的接口
/// </summary>
public static class AVCloud {
internal static AVCloudCodeController CloudCodeController {
get {
return AVPlugins.Instance.CloudCodeController;
}
}
/// <summary>
/// Calls a cloud function.
/// </summary>
/// <typeparam name="T">The type of data you will receive from the cloud function. This
/// can be an IDictionary, string, IList, AVObject, or any other type supported by
/// AVObject.</typeparam>
/// <param name="name">The cloud function to call.</param>
/// <param name="parameters">The parameters to send to the cloud function. This
/// dictionary can contain anything that could be passed into a AVObject except for
/// AVObjects themselves.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The result of the cloud call.</returns>
public static Task<T> CallFunctionAsync<T>(string name, IDictionary<string, object> parameters = null, CancellationToken cancellationToken = default) {
return CloudCodeController.CallFunctionAsync<T>(name, parameters, cancellationToken);
}
/// <summary>
/// 远程调用云函数,返回结果会反序列化为 <see cref="AVObject"/>.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name"></param>
/// <param name="parameters"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static Task<T> RPCFunctionAsync<T>(string name, IDictionary<string, object> parameters = null, CancellationToken cancellationToken = default) {
return CloudCodeController.RPCFunction<T>(name, parameters, cancellationToken);
}
/// <summary>
/// 请求发送验证码。
/// </summary>
/// <returns>是否发送成功。</returns>
/// <param name="mobilePhoneNumber">手机号。</param>
/// <param name="name">应用名称。</param>
/// <param name="op">进行的操作名称。</param>
/// <param name="ttl">验证码失效时间。</param>
/// <param name="cancellationToken">Cancellation token。</param>
public static Task RequestSMSCodeAsync(string mobilePhoneNumber, string name, string op, int ttl = 10, CancellationToken cancellationToken = default) {
if (string.IsNullOrEmpty(mobilePhoneNumber)) {
throw new AVException(AVException.ErrorCode.MobilePhoneInvalid, "Moblie Phone number is invalid.", null);
}
Dictionary<string, object> strs = new Dictionary<string, object>()
{
{ "mobilePhoneNumber", mobilePhoneNumber },
};
if (!string.IsNullOrEmpty(name)) {
strs.Add("name", name);
}
if (!string.IsNullOrEmpty(op)) {
strs.Add("op", op);
}
if (ttl > 0) {
strs.Add("TTL", ttl);
}
var command = new EngineCommand {
Path = "requestSmsCode",
Method = HttpMethod.Post,
Content = strs
};
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command, cancellationToken);
}
/// <summary>
/// 请求发送验证码。
/// </summary>
/// <returns>是否发送成功。</returns>
/// <param name="mobilePhoneNumber">手机号。</param>
public static Task RequestSMSCodeAsync(string mobilePhoneNumber) {
return RequestSMSCodeAsync(mobilePhoneNumber, CancellationToken.None);
}
/// <summary>
/// 请求发送验证码。
/// </summary>
/// <returns>是否发送成功。</returns>
/// <param name="mobilePhoneNumber">手机号。</param>
/// <param name="cancellationToken">Cancellation Token.</param>
public static Task RequestSMSCodeAsync(string mobilePhoneNumber, CancellationToken cancellationToken) {
return RequestSMSCodeAsync(mobilePhoneNumber, null, null, 0, cancellationToken);
}
/// <summary>
/// 发送手机短信,并指定模板以及传入模板所需的参数。
/// </summary>
/// <param name="mobilePhoneNumber"></param>
/// <param name="template"></param>
/// <param name="env"></param>
/// <param name="sign"></param>
/// <param name="validateToken"></param>
/// <returns></returns>
public static Task RequestSMSCodeAsync(
string mobilePhoneNumber,
string template,
IDictionary<string, object> env,
string sign = "",
string validateToken = "") {
if (string.IsNullOrEmpty(mobilePhoneNumber)) {
throw new AVException(AVException.ErrorCode.MobilePhoneInvalid, "Moblie Phone number is invalid.", null);
}
Dictionary<string, object> strs = new Dictionary<string, object>()
{
{ "mobilePhoneNumber", mobilePhoneNumber },
};
strs.Add("template", template);
if (string.IsNullOrEmpty(sign)) {
strs.Add("sign", sign);
}
if (string.IsNullOrEmpty(validateToken)) {
strs.Add("validate_token", validateToken);
}
foreach (var key in env.Keys) {
strs.Add(key, env[key]);
}
var command = new EngineCommand {
Path = "requestSmsCode",
Method = HttpMethod.Post,
Content = strs
};
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command);
}
/// <summary>
///
/// </summary>
/// <param name="mobilePhoneNumber"></param>
/// <returns></returns>
public static Task RequestVoiceCodeAsync(string mobilePhoneNumber) {
if (string.IsNullOrEmpty(mobilePhoneNumber)) {
throw new AVException(AVException.ErrorCode.MobilePhoneInvalid, "Moblie Phone number is invalid.", null);
}
Dictionary<string, object> body = new Dictionary<string, object>()
{
{ "mobilePhoneNumber", mobilePhoneNumber },
{ "smsType", "voice" },
{ "IDD", "+86" }
};
var command = new EngineCommand {
Path = "requestSmsCode",
Method = HttpMethod.Post,
Content = body
};
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command);
}
/// <summary>
/// 验证是否是有效短信验证码。
/// </summary>
/// <returns>是否验证通过。</returns>
/// <param name="mobilePhoneNumber">手机号</param>
/// <param name="code">验证码。</param>
public static Task VerifySmsCodeAsync(string code, string mobilePhoneNumber) {
return VerifySmsCodeAsync(code, mobilePhoneNumber, CancellationToken.None);
}
/// <summary>
/// 验证是否是有效短信验证码。
/// </summary>
/// <returns>是否验证通过。</returns>
/// <param name="code">验证码。</param>
/// <param name="mobilePhoneNumber">手机号</param>
/// <param name="cancellationToken">Cancellation token.</param>
public static Task VerifySmsCodeAsync(string code, string mobilePhoneNumber, CancellationToken cancellationToken) {
var command = new AVCommand {
Path = $"verifySmsCode/{code.Trim()}?mobilePhoneNumber={mobilePhoneNumber.Trim()}",
};
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command, cancellationToken);
}
/// <summary>
/// Stands for a captcha result.
/// </summary>
public class Captcha {
/// <summary>
/// Used for captcha verify.
/// </summary>
public string Token { internal set; get; }
/// <summary>
/// Captcha image URL.
/// </summary>
public string Url { internal set; get; }
/// <summary>
/// Verify the user's input of catpcha.
/// </summary>
/// <param name="code">User's input of this captcha.</param>
/// <returns></returns>
public Task VerifyAsync(string code) {
return AVCloud.VerifyCaptchaAsync(code, Token);
}
}
/// <summary>
/// Get a captcha image.
/// </summary>
/// <param name="width">captcha image width.</param>
/// <param name="height">captcha image height.</param>
/// <param name="cancellationToken">CancellationToken.</param>
/// <returns>an instance of Captcha.</returns>
public static Task<Captcha> RequestCaptchaAsync(int width = 85, int height = 30, CancellationToken cancellationToken = default) {
var path = string.Format("requestCaptcha?width={0}&height={1}", width, height);
var command = new AVCommand {
Path = $"requestCaptcha?width={width}&height={height}",
Method = HttpMethod.Get
};
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command, cancellationToken).OnSuccess(t => {
var decoded = AVDecoder.Instance.Decode(t.Result.Item2) as IDictionary<string, object>;
return new Captcha() {
Token = decoded["captcha_token"] as string,
Url = decoded["captcha_url"] as string,
};
});
}
/// <summary>
/// Verify the user's input of catpcha.
/// </summary>
/// <param name="token">The captcha's token, from server.</param>
/// <param name="code">User's input of this captcha.</param>
/// <param name="cancellationToken">CancellationToken.</param>
/// <returns></returns>
public static Task<string> VerifyCaptchaAsync(string code, string token, CancellationToken cancellationToken = default) {
var data = new Dictionary<string, object> {
{ "captcha_token", token },
{ "captcha_code", code },
};
var command = new AVCommand {
Path = "verifyCaptcha",
Method = HttpMethod.Post,
Content = data
};
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command, cancellationToken).ContinueWith(t => {
if (!t.Result.Item2.ContainsKey("validate_token"))
throw new KeyNotFoundException("validate_token");
return t.Result.Item2["validate_token"] as string;
});
}
/// <summary>
/// Get the custom cloud parameters, you can set them at console https://leancloud.cn/dashboard/devcomponent.html?appid={your_app_Id}#/component/custom_param
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static Task<IDictionary<string, object>> GetCustomParametersAsync(CancellationToken cancellationToken = default) {
var command = new AVCommand {
Path = $"statistics/apps/{AVClient.CurrentConfiguration.ApplicationId}/sendPolicy",
Method = HttpMethod.Get
};
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command, cancellationToken).OnSuccess(t => {
var settings = t.Result.Item2;
var CloudParameters = settings["parameters"] as IDictionary<string, object>;
return CloudParameters;
});
}
public class RealtimeSignature {
public string Nonce { internal set; get; }
public long Timestamp { internal set; get; }
public string ClientId { internal set; get; }
public string Signature { internal set; get; }
}
public static Task<RealtimeSignature> RequestRealtimeSignatureAsync(CancellationToken cancellationToken = default) {
var command = new AVCommand {
Path = "rtm/sign",
Method = HttpMethod.Post,
Content = new Dictionary<string, string> {
{ "session_token", AVUser.CurrentUser?.SessionToken }
}
};
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command, cancellationToken).OnSuccess(t => {
var body = t.Result.Item2;
return new RealtimeSignature() {
Nonce = body["nonce"] as string,
Timestamp = (long)body["timestamp"],
ClientId = body["client_id"] as string,
Signature = body["signature"] as string,
};
});
}
/// <summary>
/// Gets the LeanEngine hosting URL for current app async.
/// </summary>
/// <returns>The lean engine hosting URL async.</returns>
public static Task<string> GetLeanEngineHostingUrlAsync() {
return CallFunctionAsync<string>("_internal_extensions_get_domain");
}
}
}