chore: 首次簽入 Thinkyu ASP.NET 專案
- 加入 Visual Studio / ASP.NET .gitignore - 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
This commit is contained in:
@@ -0,0 +1,287 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace 報到系統
|
||||
{
|
||||
/// <summary>
|
||||
/// EVERY8D 簡訊服務提供者
|
||||
/// </summary>
|
||||
public class EVERY8DSMSProvider : BaseSMSProvider
|
||||
{
|
||||
// EVERY8D API 相關常數
|
||||
private static string BASE_URL = "https://new.e8d.tw/API21/HTTP";
|
||||
private static string API_URL_SEND = string.Format("{0}/SendParam.ashx", BASE_URL);
|
||||
private static string API_URL_CHECK_BALANCE = string.Format("{0}/GetCredit.ashx", BASE_URL);
|
||||
|
||||
/// <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 (!IsValidMobileNumber(message.Mobile))
|
||||
{
|
||||
failMessage = "手機號碼格式不正確";
|
||||
return false;
|
||||
}
|
||||
|
||||
var requestBody = new EVERY8DParamMMSBody
|
||||
{
|
||||
SB = message.Subject,
|
||||
UID = message.MMSAccount,
|
||||
PWD = message.MMSPassword,
|
||||
ATTACHMENT = message.QRCode
|
||||
};
|
||||
|
||||
requestBody.RecipientDataList.Add(new EVERY8DRecipient
|
||||
{
|
||||
Mobile = message.Mobile,
|
||||
Param = message.Content,
|
||||
});
|
||||
|
||||
string response = PostJson(API_URL_SEND, requestBody);
|
||||
|
||||
return ParseMMSResponse(response, out failMessage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
failMessage = ex.Message;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析 EVERY8D API 回應
|
||||
/// </summary>
|
||||
private static bool ParseMMSResponse(string response, out string failMessage)
|
||||
{
|
||||
failMessage = "";
|
||||
|
||||
try
|
||||
{
|
||||
EVERY8DMMSResponse responseObj = JsonConvert.DeserializeObject<EVERY8DMMSResponse>(response.Trim());
|
||||
|
||||
if (responseObj.Result)
|
||||
return true;
|
||||
|
||||
failMessage = GetErrorMessage(responseObj.Status);
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
failMessage = string.Format("無法解析 API 回應:{0}", response);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取得錯誤訊息
|
||||
/// </summary>
|
||||
private static string GetErrorMessage(string status)
|
||||
{
|
||||
Dictionary<string, string> errorMessages = new Dictionary<string, string>
|
||||
{
|
||||
{ "-1", "參數錯誤,傳送失敗" },
|
||||
{ "-2", "帳號或密碼錯誤,傳送失敗" },
|
||||
{ "-3", "接收方屬於黑名單,傳送失敗" },
|
||||
{ "-4", "預計發送時間超過24小時,傳送失敗" },
|
||||
{ "-5", "內容長度超出限制,傳送失敗" },
|
||||
{ "-8", "接收方手機號碼格式不符,傳送失敗" },
|
||||
{ "-10", "接收方不支援MMS,傳送失敗" },
|
||||
{ "-300", "帳號密碼不得為空" },
|
||||
{ "101", "電信端回覆因收訊方手機關機、訊號不良、簡訊容量不足等異常原因,收訊失敗" },
|
||||
{ "102", "電信端回覆因網路系統、設備出現異常,收訊失敗" },
|
||||
{ "103", "電信端回覆因收訊方手機門號錯誤、空號或停用中,收訊失敗" },
|
||||
{ "104", "因本手機門號為電信端之黑名單,故傳送失敗" },
|
||||
{ "105", "電信端回覆經判斷因訊息內文含有敏感關鍵字進行阻擋,故傳送失敗" },
|
||||
{ "106", "系統顯示經判斷因訊息內文含有敏感關鍵字進行阻擋,故傳送失敗" },
|
||||
{ "301", "無額度(或額度不足)無法發送" },
|
||||
{ "500", "表該門號為國際門號,請至帳號設定開啟國際簡訊發送功能" }
|
||||
};
|
||||
|
||||
return errorMessages.ContainsKey(status) ? errorMessages[status] : string.Format("未知錯誤代碼:{0}", status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 驗證帳號額度
|
||||
/// </summary>
|
||||
public static bool CheckBalance(out int balance, out string errorMessage)
|
||||
{
|
||||
balance = 0;
|
||||
errorMessage = "";
|
||||
|
||||
try
|
||||
{
|
||||
InitializeSecuritySettings();
|
||||
|
||||
var requestBody = new EVERY8DRequestBody();
|
||||
string response = PostForm(API_URL_CHECK_BALANCE, requestBody.ToFormData());
|
||||
|
||||
if (decimal.TryParse(response, out decimal b))
|
||||
{
|
||||
balance = (int)b;
|
||||
return true;
|
||||
}
|
||||
errorMessage = string.Format("餘額查詢失敗: {0}", response);
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = ex.Message;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EVERY8D 簡訊接收者
|
||||
/// </summary>
|
||||
public class EVERY8DRecipient
|
||||
{
|
||||
[JsonProperty("Name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("Mobile")]
|
||||
public string Mobile { get; set; }
|
||||
|
||||
[JsonProperty("Email")]
|
||||
public string Email { get; set; }
|
||||
|
||||
[JsonProperty("SendTime")]
|
||||
public string SendTime { get; set; }
|
||||
|
||||
[JsonProperty("Param")]
|
||||
public string Param { get; set; }
|
||||
|
||||
public EVERY8DRecipient()
|
||||
{
|
||||
Name = string.Empty;
|
||||
Mobile = string.Empty;
|
||||
Email = string.Empty;
|
||||
SendTime = string.Empty;
|
||||
Param = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EVERY8D 請求基礎類
|
||||
/// </summary>
|
||||
public class EVERY8DRequestBody
|
||||
{
|
||||
[JsonProperty("UID")]
|
||||
public string UID { get; set; }
|
||||
|
||||
[JsonProperty("PWD")]
|
||||
public string PWD { get; set; }
|
||||
|
||||
public EVERY8DRequestBody()
|
||||
{
|
||||
using (var dac = new DAC_MMSPlatform())
|
||||
{
|
||||
var platform = dac.SelectByCode(DAC_ProjectMMSAccount.EVERY8DPlatformCode);
|
||||
if (platform != null)
|
||||
{
|
||||
UID = platform.Account;
|
||||
PWD = platform.Password;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NameValueCollection ToFormData()
|
||||
{
|
||||
var result = new NameValueCollection();
|
||||
var properties = this.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var jsonPropertyAttr = property.GetCustomAttributes(typeof(JsonPropertyAttribute), false).FirstOrDefault() as JsonPropertyAttribute;
|
||||
if (jsonPropertyAttr != null)
|
||||
{
|
||||
var value = property.GetValue(this, null);
|
||||
result.Add(jsonPropertyAttr.PropertyName, value?.ToString() ?? string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EVERY8D MMS 請求
|
||||
/// </summary>
|
||||
public class EVERY8DParamMMSBody : EVERY8DRequestBody
|
||||
{
|
||||
[JsonProperty("SB")]
|
||||
public string SB { get; set; }
|
||||
|
||||
[JsonProperty("ATTACHMENT")]
|
||||
public string ATTACHMENT { get; set; }
|
||||
|
||||
[JsonProperty("TYPE")]
|
||||
public string TYPE { get; set; }
|
||||
|
||||
[JsonProperty("RecipientDataList")]
|
||||
public List<EVERY8DRecipient> RecipientDataList { get; }
|
||||
|
||||
public EVERY8DParamMMSBody()
|
||||
{
|
||||
SB = "活動通知";
|
||||
ATTACHMENT = string.Empty;
|
||||
TYPE = "png";
|
||||
RecipientDataList = new List<EVERY8DRecipient>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EVERY8D MMS 回應
|
||||
/// </summary>
|
||||
public class EVERY8DMMSResponse
|
||||
{
|
||||
[JsonProperty("Result")]
|
||||
public bool Result { get; set; }
|
||||
|
||||
[JsonProperty("Status")]
|
||||
public string Status { get; set; }
|
||||
|
||||
[JsonProperty("Msg")]
|
||||
public string Msg { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EVERY8D Credit 回應
|
||||
/// </summary>
|
||||
public class EVERY8DCreditResponse
|
||||
{
|
||||
[JsonProperty("Credit")]
|
||||
public decimal Credit { get; set; }
|
||||
|
||||
[JsonProperty("Status")]
|
||||
public string Status { get; set; }
|
||||
|
||||
[JsonProperty("Msg")]
|
||||
public string Msg { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user