chore: 首次簽入 Thinkyu ASP.NET 專案
- 加入 Visual Studio / ASP.NET .gitignore - 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
This commit is contained in:
@@ -0,0 +1,309 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Mail;
|
||||
using System.Text;
|
||||
using WebLib;
|
||||
|
||||
namespace 報到系統
|
||||
{
|
||||
/// <summary>
|
||||
/// 三竹(MITAKE)簡訊服務提供者
|
||||
/// </summary>
|
||||
public class MITAKESMSProvider : BaseSMSProvider
|
||||
{
|
||||
private const string ApiBaseUrl = "https://message.mitake.com.tw";
|
||||
|
||||
/// <summary>
|
||||
/// 驗證帳號密碼是否正確,回傳 token(如果驗證成功)或錯誤訊息(如果驗證失敗)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static bool Authenticate(out string token)
|
||||
{
|
||||
token = string.Empty;
|
||||
|
||||
var responseStr = PostJson(ApiBaseUrl + "/AuthorizationService/Token",
|
||||
new MITAKEAuthRequest()
|
||||
);
|
||||
var responseObj = JsonConvert.DeserializeObject<MITAKEAuthResponse>(responseStr);
|
||||
if (responseObj != null && !string.IsNullOrEmpty(responseObj.AccessToken))
|
||||
{
|
||||
token = responseObj.AccessToken;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 發送簡訊到指定手機號碼
|
||||
/// </summary>
|
||||
public static bool SendMMS(MessageQueueItem message, out string failMessage)
|
||||
{
|
||||
failMessage = "";
|
||||
|
||||
try
|
||||
{
|
||||
InitializeSecuritySettings();
|
||||
|
||||
if (string.IsNullOrEmpty(message.Mobile))
|
||||
{
|
||||
failMessage = "手機號碼不能為空";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(message.Content))
|
||||
{
|
||||
failMessage = "簡訊內容不能為空";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Authenticate(out string token))
|
||||
{
|
||||
failMessage = "驗證失敗,無法取得存取權杖";
|
||||
return false;
|
||||
}
|
||||
|
||||
// 組裝簡訊發送請求
|
||||
var smsRequest = new MITAKESMSRequest
|
||||
{
|
||||
Subject = message.Subject,
|
||||
Content = message.Content,
|
||||
};
|
||||
smsRequest.Destinations.Add(new MITAKEDestination { To = message.Mobile });
|
||||
smsRequest.Attachments.Add(new MITAKEAttachment
|
||||
{
|
||||
AttachType = "png",
|
||||
AttachName = string.Format("attach_{0}.png", message.ID),
|
||||
AttachContent = message.QRCode
|
||||
});
|
||||
|
||||
// 組裝 HTTP 標頭
|
||||
var smsHeaders = new Dictionary<string, string>
|
||||
{
|
||||
{ "authorization", "bearer " + token },
|
||||
{ "content-type", "application/json" },
|
||||
{ "clientID", message.MMSAccount },
|
||||
{ "actionType", "push" }
|
||||
};
|
||||
|
||||
// 發送簡訊請求
|
||||
var smsResponseStr = PostJson(ApiBaseUrl + "/msg/mms/json", smsRequest, smsHeaders, 120);
|
||||
var smsResponseObj = JsonConvert.DeserializeObject<MITAKESMSResponse>(smsResponseStr);
|
||||
|
||||
// 檢查回應結果
|
||||
if (smsResponseObj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (smsResponseObj.Messages == null || smsResponseObj.Messages.Count == 0)
|
||||
{
|
||||
string responsePreview = smsResponseStr.Length > 400 ? smsResponseStr.Substring(0, 400) : smsResponseStr;
|
||||
failMessage = $"簡訊發送失敗,未收到有效回應:({responsePreview})";
|
||||
return false;
|
||||
}
|
||||
|
||||
var firstMessage = smsResponseObj.Messages[0];
|
||||
if (firstMessage.Status != "0" && firstMessage.Status != "1" && firstMessage.Status != "2")
|
||||
{
|
||||
failMessage = $"簡訊發送失敗,狀態碼:{firstMessage.Status},說明:{firstMessage.StatusDesc}";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
failMessage = ex.Message;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查詢帳號餘額
|
||||
/// </summary>
|
||||
//public static bool CheckBalance(out int balance, out string errorMessage)
|
||||
//{
|
||||
// balance = 0;
|
||||
// errorMessage = "";
|
||||
|
||||
// try
|
||||
// {
|
||||
// InitializeSecuritySettings();
|
||||
|
||||
// // TODO: 實作三竹查詢餘額邏輯
|
||||
// // GET {ApiBaseUrl}/SmQueryGet.asp
|
||||
// // ?username={account}
|
||||
// // &password={password}
|
||||
// // &CharsetURL=UTF-8
|
||||
// //
|
||||
// // 回傳格式:AccountPoint=100
|
||||
|
||||
// throw new NotImplementedException("三竹查詢餘額尚未實作");
|
||||
// }
|
||||
// catch (NotImplementedException)
|
||||
// {
|
||||
// errorMessage = "三竹查詢餘額尚未實作";
|
||||
// return false;
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// errorMessage = ex.Message;
|
||||
// return false;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 三竹簡訊授權請求
|
||||
/// </summary>
|
||||
public class MITAKEAuthRequest
|
||||
{
|
||||
[JsonProperty("clientID")]
|
||||
public string ClientID { get; set; }
|
||||
|
||||
[JsonProperty("clientSecret")]
|
||||
public string ClientSecret { get; set; }
|
||||
|
||||
public MITAKEAuthRequest()
|
||||
{
|
||||
ClientID = string.Empty;
|
||||
ClientSecret = string.Empty;
|
||||
|
||||
using (var conn = DAC.NewConnection())
|
||||
{
|
||||
var dac = new DAC_MMSPlatform(conn);
|
||||
MMSPlatformItem item = dac.SelectByCode(PublicVariable.CurrentMMSPlatform);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
ClientID = item.Account;
|
||||
ClientSecret = item.Password;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 三竹簡訊授權回應
|
||||
/// </summary>
|
||||
public class MITAKEAuthResponse
|
||||
{
|
||||
[JsonProperty("accessToken")]
|
||||
public string AccessToken { get; set; }
|
||||
|
||||
[JsonProperty("expiresIn")]
|
||||
public int ExpiresIn { get; set; }
|
||||
|
||||
[JsonProperty("tokenType")]
|
||||
public string TokenType { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 三竹簡訊接收者
|
||||
/// </summary>
|
||||
public class MITAKEDestination
|
||||
{
|
||||
[JsonProperty("to")]
|
||||
public string To { get; set; }
|
||||
|
||||
[JsonProperty("cID")]
|
||||
public string CID { get; set; }
|
||||
|
||||
public MITAKEDestination()
|
||||
{
|
||||
CID = Guid.NewGuid().ToString().Replace("-", "");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 三竹簡訊附件
|
||||
/// </summary>
|
||||
public class MITAKEAttachment
|
||||
{
|
||||
[JsonProperty("attachContent")]
|
||||
public string AttachContent { get; set; }
|
||||
|
||||
[JsonProperty("attachType")]
|
||||
public string AttachType { get; set; }
|
||||
|
||||
[JsonProperty("attachName")]
|
||||
public string AttachName { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 三竹簡訊發送請求
|
||||
/// </summary>
|
||||
public class MITAKESMSRequest
|
||||
{
|
||||
[JsonProperty("subject")]
|
||||
public string Subject { get; set; }
|
||||
|
||||
[JsonProperty("content")]
|
||||
public string Content { get; set; }
|
||||
|
||||
[JsonProperty("orderTime")]
|
||||
public string OrderTime { get; set; }
|
||||
|
||||
[JsonProperty("expireTime")]
|
||||
public string ExpireTime { get; set; }
|
||||
|
||||
[JsonProperty("destinations")]
|
||||
public List<MITAKEDestination> Destinations { get; set; }
|
||||
|
||||
[JsonProperty("attachments")]
|
||||
public List<MITAKEAttachment> Attachments { get; set; }
|
||||
|
||||
|
||||
public MITAKESMSRequest()
|
||||
{
|
||||
Subject = string.Empty;
|
||||
Content = string.Empty;
|
||||
OrderTime = PublicVariable.TaiwanNow.ToString("yyyyMMddHHmmss");
|
||||
ExpireTime = PublicVariable.TaiwanNow.AddDays(1).ToString("yyyyMMddHHmmss");
|
||||
Destinations = new List<MITAKEDestination>();
|
||||
Attachments = new List<MITAKEAttachment>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 三竹簡訊發送回應項目
|
||||
/// </summary>
|
||||
public class MITAKESMSResponseItem
|
||||
{
|
||||
[JsonProperty("msgID")]
|
||||
public string MsgID { get; set; }
|
||||
|
||||
[JsonProperty("cID")]
|
||||
public string CID { get; set; }
|
||||
|
||||
[JsonProperty("status")]
|
||||
public string Status { get; set; }
|
||||
|
||||
[JsonProperty("statusDesc")]
|
||||
public string StatusDesc { get; set; }
|
||||
|
||||
[JsonProperty("statusTime")]
|
||||
public string StatusTime { get; set; }
|
||||
|
||||
[JsonProperty("point")]
|
||||
public string Point { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 三竹簡訊發送回應
|
||||
/// </summary>
|
||||
public class MITAKESMSResponse
|
||||
{
|
||||
[JsonProperty("batchID")]
|
||||
public string BatchID { get; set; }
|
||||
|
||||
[JsonProperty("messages")]
|
||||
public List<MITAKESMSResponseItem> Messages { get; set; }
|
||||
|
||||
[JsonProperty("costPoints")]
|
||||
public string CostPoints { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user