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 報到系統 { /// /// EVERY8D 簡訊服務提供者 /// 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); /// /// 發送簡訊到指定手機號碼 /// 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; } } /// /// 解析 EVERY8D API 回應 /// private static bool ParseMMSResponse(string response, out string failMessage) { failMessage = ""; try { EVERY8DMMSResponse responseObj = JsonConvert.DeserializeObject(response.Trim()); if (responseObj.Result) return true; failMessage = GetErrorMessage(responseObj.Status); return false; } catch { failMessage = string.Format("無法解析 API 回應:{0}", response); return false; } } /// /// 取得錯誤訊息 /// private static string GetErrorMessage(string status) { Dictionary errorMessages = new Dictionary { { "-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); } /// /// 驗證帳號額度 /// 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; } } } /// /// EVERY8D 簡訊接收者 /// 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; } } /// /// EVERY8D 請求基礎類 /// 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; } } /// /// EVERY8D MMS 請求 /// 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 RecipientDataList { get; } public EVERY8DParamMMSBody() { SB = "活動通知"; ATTACHMENT = string.Empty; TYPE = "png"; RecipientDataList = new List(); } } /// /// EVERY8D MMS 回應 /// public class EVERY8DMMSResponse { [JsonProperty("Result")] public bool Result { get; set; } [JsonProperty("Status")] public string Status { get; set; } [JsonProperty("Msg")] public string Msg { get; set; } } /// /// EVERY8D Credit 回應 /// public class EVERY8DCreditResponse { [JsonProperty("Credit")] public decimal Credit { get; set; } [JsonProperty("Status")] public string Status { get; set; } [JsonProperty("Msg")] public string Msg { get; set; } } }